From: Tomi Valkeinen Date: Mon, 15 Apr 2013 08:57:18 +0000 (+0300) Subject: OMAPDSS: Merge omapdss topic branches X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3d62fe5b214fce69ae14abbdb88794a753418614;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git OMAPDSS: Merge omapdss topic branches --- 3d62fe5b214fce69ae14abbdb88794a753418614 diff --cc drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 1e0097de3a23,c4e9c2b1b465,bd3ad8830a54..20c3cd91ff9b --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c @@@@ -81,35 -84,72 -84,72 +81,35 @@@@ static struct omap_video_timings nec_80 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, }; --static int nec_8048_bl_update_status(struct backlight_device *bl) --{ -- struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev); -- int level; -- -- if (!dssdev->set_backlight) -- return -EINVAL; -- -- if (bl->props.fb_blank == FB_BLANK_UNBLANK && -- bl->props.power == FB_BLANK_UNBLANK) -- level = bl->props.brightness; -- else -- level = 0; -- -- return dssdev->set_backlight(dssdev, level); --} -- --static int nec_8048_bl_get_brightness(struct backlight_device *bl) ++static inline struct panel_nec_nl8048_data ++*get_panel_data(const struct omap_dss_device *dssdev) { -- if (bl->props.fb_blank == FB_BLANK_UNBLANK && -- bl->props.power == FB_BLANK_UNBLANK) -- return bl->props.brightness; -- -- return 0; ++ return (struct panel_nec_nl8048_data *) dssdev->data; } --static const struct backlight_ops nec_8048_bl_ops = { -- .get_brightness = nec_8048_bl_get_brightness, -- .update_status = nec_8048_bl_update_status, --}; -- static int nec_8048_panel_probe(struct omap_dss_device *dssdev) { -- struct backlight_device *bl; -- struct nec_8048_data *necd; -- struct backlight_properties props; ++ struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); int r; -- dssdev->panel.timings = nec_8048_panel_timings; -- -- necd = kzalloc(sizeof(*necd), GFP_KERNEL); -- if (!necd) -- return -ENOMEM; -- -- dev_set_drvdata(&dssdev->dev, necd); ++ if (!pd) ++ return -EINVAL; -- memset(&props, 0, sizeof(struct backlight_properties)); -- props.max_brightness = 255; ++ dssdev->panel.timings = nec_8048_panel_timings; -- bl = backlight_device_register("nec-8048", &dssdev->dev, dssdev, -- &nec_8048_bl_ops, &props); -- if (IS_ERR(bl)) { -- r = PTR_ERR(bl); -- kfree(necd); -- return r; ++ if (gpio_is_valid(pd->qvga_gpio)) { ++ r = devm_gpio_request_one(&dssdev->dev, pd->qvga_gpio, ++ GPIOF_OUT_INIT_HIGH, "lcd QVGA"); ++ if (r) ++ return r; } -- necd->bl = bl; - - bl->props.fb_blank = FB_BLANK_UNBLANK; - bl->props.power = FB_BLANK_UNBLANK; - bl->props.max_brightness = dssdev->max_backlight_level; - bl->props.brightness = dssdev->max_backlight_level; - bl->props.fb_blank = FB_BLANK_UNBLANK; - bl->props.power = FB_BLANK_UNBLANK; - bl->props.max_brightness = dssdev->max_backlight_level; - bl->props.brightness = dssdev->max_backlight_level; - -- r = nec_8048_bl_update_status(bl); -- if (r < 0) -- dev_err(&dssdev->dev, "failed to set lcd brightness\n"); ++ if (gpio_is_valid(pd->res_gpio)) { ++ r = devm_gpio_request_one(&dssdev->dev, pd->res_gpio, ++ GPIOF_OUT_INIT_LOW, "lcd RES"); ++ if (r) ++ return r; ++ } return 0; } diff --cc drivers/video/omap2/dss/dsi.c index 28d41d16b7be,8db29bff0423,36de3fedc3f6..9b1c5ecee115 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@@@ -4881,64 -4653,481 -4881,64 +4653,481 @@@@ int omapdss_dsi_enable_te(struct omap_d } EXPORT_SYMBOL(omapdss_dsi_enable_te); - -void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, - - struct omap_video_timings *timings) + +#ifdef PRINT_VERBOSE_VM_TIMINGS + +static void print_dsi_vm(const char *str, + + const struct omap_dss_dsi_videomode_timings *t) + +{ + + unsigned long byteclk = t->hsclk / 4; + + int bl, wc, pps, tot; + + + + wc = DIV_ROUND_UP(t->hact * t->bitspp, 8); + + pps = DIV_ROUND_UP(wc + 6, t->ndl); /* pixel packet size */ + + bl = t->hss + t->hsa + t->hse + t->hbp + t->hfp; + + tot = bl + pps; + + + +#define TO_DSI_T(x) ((u32)div64_u64((u64)x * 1000000000llu, byteclk)) + + + + pr_debug("%s bck %lu, %u/%u/%u/%u/%u/%u = %u+%u = %u, " + + "%u/%u/%u/%u/%u/%u = %u + %u = %u\n", + + str, + + byteclk, + + t->hss, t->hsa, t->hse, t->hbp, pps, t->hfp, + + bl, pps, tot, + + TO_DSI_T(t->hss), + + TO_DSI_T(t->hsa), + + TO_DSI_T(t->hse), + + TO_DSI_T(t->hbp), + + TO_DSI_T(pps), + + TO_DSI_T(t->hfp), + + + + TO_DSI_T(bl), + + TO_DSI_T(pps), + + + + TO_DSI_T(tot)); + +#undef TO_DSI_T + +} + + + +static void print_dispc_vm(const char *str, const struct omap_video_timings *t) + +{ + + unsigned long pck = t->pixel_clock * 1000; + + int hact, bl, tot; + + + + hact = t->x_res; + + bl = t->hsw + t->hbp + t->hfp; + + tot = hact + bl; + + + +#define TO_DISPC_T(x) ((u32)div64_u64((u64)x * 1000000000llu, pck)) + + + + pr_debug("%s pck %lu, %u/%u/%u/%u = %u+%u = %u, " + + "%u/%u/%u/%u = %u + %u = %u\n", + + str, + + pck, + + t->hsw, t->hbp, hact, t->hfp, + + bl, hact, tot, + + TO_DISPC_T(t->hsw), + + TO_DISPC_T(t->hbp), + + TO_DISPC_T(hact), + + TO_DISPC_T(t->hfp), + + TO_DISPC_T(bl), + + TO_DISPC_T(hact), + + TO_DISPC_T(tot)); + +#undef TO_DISPC_T + +} + + + +/* note: this is not quite accurate */ + +static void print_dsi_dispc_vm(const char *str, + + const struct omap_dss_dsi_videomode_timings *t) + +{ + + struct omap_video_timings vm = { 0 }; + + unsigned long byteclk = t->hsclk / 4; + + unsigned long pck; + + u64 dsi_tput; + + int dsi_hact, dsi_htot; + + + + dsi_tput = (u64)byteclk * t->ndl * 8; + + pck = (u32)div64_u64(dsi_tput, t->bitspp); + + dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl); + + dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp; + + + + vm.pixel_clock = pck / 1000; + + vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk); + + vm.hbp = div64_u64((u64)t->hbp * pck, byteclk); + + vm.hfp = div64_u64((u64)t->hfp * pck, byteclk); + + vm.x_res = t->hact; + + + + print_dispc_vm(str, &vm); + +} + +#endif /* PRINT_VERBOSE_VM_TIMINGS */ + + + +static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, + + unsigned long pck, void *data) { - - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + + struct dsi_clk_calc_ctx *ctx = data; + + struct omap_video_timings *t = &ctx->dispc_vm; - - mutex_lock(&dsi->lock); + + ctx->dispc_cinfo.lck_div = lckd; + + ctx->dispc_cinfo.pck_div = pckd; + + ctx->dispc_cinfo.lck = lck; + + ctx->dispc_cinfo.pck = pck; - - dsi->timings = *timings; + + *t = *ctx->config->timings; + + t->pixel_clock = pck / 1000; + + t->x_res = ctx->config->timings->x_res; + + t->y_res = ctx->config->timings->y_res; + + t->hsw = t->hfp = t->hbp = t->vsw = 1; + + t->vfp = t->vbp = 0; - - mutex_unlock(&dsi->lock); + + return true; } - -EXPORT_SYMBOL(omapdss_dsi_set_timings); - -void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) + +static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, + + void *data) { - - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + + struct dsi_clk_calc_ctx *ctx = data; - - mutex_lock(&dsi->lock); + + ctx->dsi_cinfo.regm_dispc = regm_dispc; + + ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; - - dsi->timings.x_res = w; - - dsi->timings.y_res = h; + + return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max, + + dsi_cm_calc_dispc_cb, ctx); + +} - - mutex_unlock(&dsi->lock); + +static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint, + + unsigned long pll, void *data) + +{ + + struct dsi_clk_calc_ctx *ctx = data; + + + + ctx->dsi_cinfo.regn = regn; + + ctx->dsi_cinfo.regm = regm; + + ctx->dsi_cinfo.fint = fint; + + ctx->dsi_cinfo.clkin4ddr = pll; + + + + return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, + + dsi_cm_calc_hsdiv_cb, ctx); } - -EXPORT_SYMBOL(omapdss_dsi_set_size); - -void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, - - enum omap_dss_dsi_pixel_format fmt) + +static bool dsi_cm_calc(struct dsi_data *dsi, + + const struct omap_dss_dsi_config *cfg, + + struct dsi_clk_calc_ctx *ctx) { - - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + + unsigned long clkin; + + int bitspp, ndl; + + unsigned long pll_min, pll_max; + + unsigned long pck, txbyteclk; - - mutex_lock(&dsi->lock); + + clkin = clk_get_rate(dsi->sys_clk); + + bitspp = dsi_get_pixel_size(cfg->pixel_format); + + ndl = dsi->num_lanes_used - 1; + - dsi->pix_fmt = fmt; + + /* + + * Here we should calculate minimum txbyteclk to be able to send the + + * frame in time, and also to handle TE. That's not very simple, though, + + * especially as we go to LP between each pixel packet due to HW + + * "feature". So let's just estimate very roughly and multiply by 1.5. + + */ + + pck = cfg->timings->pixel_clock * 1000; + + pck = pck * 3 / 2; + + txbyteclk = pck * bitspp / 8 / ndl; - dsi->pix_fmt = fmt; - mutex_unlock(&dsi->lock); + + memset(ctx, 0, sizeof(*ctx)); + + ctx->dsidev = dsi->pdev; + + ctx->config = cfg; + + ctx->req_pck_min = pck; + + ctx->req_pck_nom = pck; + + ctx->req_pck_max = pck * 3 / 2; + + ctx->dsi_cinfo.clkin = clkin; + - mutex_unlock(&dsi->lock); + + pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); + + pll_max = cfg->hs_clk_max * 4; + + + + return dsi_pll_calc(dsi->pdev, clkin, + + pll_min, pll_max, + + dsi_cm_calc_pll_cb, ctx); } - -EXPORT_SYMBOL(omapdss_dsi_set_pixel_format); - -void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, - - enum omap_dss_dsi_mode mode) + +static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx) { - - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + + struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev); + + const struct omap_dss_dsi_config *cfg = ctx->config; + + int bitspp = dsi_get_pixel_size(cfg->pixel_format); + + int ndl = dsi->num_lanes_used - 1; + + unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4; + + unsigned long byteclk = hsclk / 4; - - mutex_lock(&dsi->lock); + + unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max; + + int xres; + + int panel_htot, panel_hbl; /* pixels */ + + int dispc_htot, dispc_hbl; /* pixels */ + + int dsi_htot, dsi_hact, dsi_hbl, hss, hse; /* byteclks */ + + int hfp, hsa, hbp; + + const struct omap_video_timings *req_vm; + + struct omap_video_timings *dispc_vm; + + struct omap_dss_dsi_videomode_timings *dsi_vm; + + u64 dsi_tput, dispc_tput; - - dsi->mode = mode; + + dsi_tput = (u64)byteclk * ndl * 8; - - mutex_unlock(&dsi->lock); + + req_vm = cfg->timings; + + req_pck_min = ctx->req_pck_min; + + req_pck_max = ctx->req_pck_max; + + req_pck_nom = ctx->req_pck_nom; + + + + dispc_pck = ctx->dispc_cinfo.pck; + + dispc_tput = (u64)dispc_pck * bitspp; + + + + xres = req_vm->x_res; + + + + panel_hbl = req_vm->hfp + req_vm->hbp + req_vm->hsw; + + panel_htot = xres + panel_hbl; + + + + dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(xres * bitspp, 8) + 6, ndl); + + + + /* + + * When there are no line buffers, DISPC and DSI must have the + + * same tput. Otherwise DISPC tput needs to be higher than DSI's. + + */ + + if (dsi->line_buffer_size < xres * bitspp / 8) { + + if (dispc_tput != dsi_tput) + + return false; + + } else { + + if (dispc_tput < dsi_tput) + + return false; + + } + + + + /* DSI tput must be over the min requirement */ + + if (dsi_tput < (u64)bitspp * req_pck_min) + + return false; + + + + /* When non-burst mode, DSI tput must be below max requirement. */ + + if (cfg->trans_mode != OMAP_DSS_DSI_BURST_MODE) { + + if (dsi_tput > (u64)bitspp * req_pck_max) + + return false; + + } + + + + hss = DIV_ROUND_UP(4, ndl); + + + + if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) { + + if (ndl == 3 && req_vm->hsw == 0) + + hse = 1; + + else + + hse = DIV_ROUND_UP(4, ndl); + + } else { + + hse = 0; + + } + + + + /* DSI htot to match the panel's nominal pck */ + + dsi_htot = div64_u64((u64)panel_htot * byteclk, req_pck_nom); + + + + /* fail if there would be no time for blanking */ + + if (dsi_htot < hss + hse + dsi_hact) + + return false; + + + + /* total DSI blanking needed to achieve panel's TL */ + + dsi_hbl = dsi_htot - dsi_hact; + + + + /* DISPC htot to match the DSI TL */ + + dispc_htot = div64_u64((u64)dsi_htot * dispc_pck, byteclk); + + + + /* verify that the DSI and DISPC TLs are the same */ + + if ((u64)dsi_htot * dispc_pck != (u64)dispc_htot * byteclk) + + return false; + + + + dispc_hbl = dispc_htot - xres; + + + + /* setup DSI videomode */ + + + + dsi_vm = &ctx->dsi_vm; + + memset(dsi_vm, 0, sizeof(*dsi_vm)); + + + + dsi_vm->hsclk = hsclk; + + + + dsi_vm->ndl = ndl; + + dsi_vm->bitspp = bitspp; + + + + if (cfg->trans_mode != OMAP_DSS_DSI_PULSE_MODE) { + + hsa = 0; + + } else if (ndl == 3 && req_vm->hsw == 0) { + + hsa = 0; + + } else { + + hsa = div64_u64((u64)req_vm->hsw * byteclk, req_pck_nom); + + hsa = max(hsa - hse, 1); + + } + + + + hbp = div64_u64((u64)req_vm->hbp * byteclk, req_pck_nom); + + hbp = max(hbp, 1); + + + + hfp = dsi_hbl - (hss + hsa + hse + hbp); + + if (hfp < 1) { + + int t; + + /* we need to take cycles from hbp */ + + + + t = 1 - hfp; + + hbp = max(hbp - t, 1); + + hfp = dsi_hbl - (hss + hsa + hse + hbp); + + + + if (hfp < 1 && hsa > 0) { + + /* we need to take cycles from hsa */ + + t = 1 - hfp; + + hsa = max(hsa - t, 1); + + hfp = dsi_hbl - (hss + hsa + hse + hbp); + + } + + } + + + + if (hfp < 1) + + return false; + + + + dsi_vm->hss = hss; + + dsi_vm->hsa = hsa; + + dsi_vm->hse = hse; + + dsi_vm->hbp = hbp; + + dsi_vm->hact = xres; + + dsi_vm->hfp = hfp; + + + + dsi_vm->vsa = req_vm->vsw; + + dsi_vm->vbp = req_vm->vbp; + + dsi_vm->vact = req_vm->y_res; + + dsi_vm->vfp = req_vm->vfp; + + + + dsi_vm->trans_mode = cfg->trans_mode; + + + + dsi_vm->blanking_mode = 0; + + dsi_vm->hsa_blanking_mode = 1; + + dsi_vm->hfp_blanking_mode = 1; + + dsi_vm->hbp_blanking_mode = 1; + + + + dsi_vm->ddr_clk_always_on = cfg->ddr_clk_always_on; + + dsi_vm->window_sync = 4; + + + + /* setup DISPC videomode */ + + + + dispc_vm = &ctx->dispc_vm; + + *dispc_vm = *req_vm; + + dispc_vm->pixel_clock = dispc_pck / 1000; + + + + if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) { + + hsa = div64_u64((u64)req_vm->hsw * dispc_pck, + + req_pck_nom); + + hsa = max(hsa, 1); + + } else { + + hsa = 1; + + } + + + + hbp = div64_u64((u64)req_vm->hbp * dispc_pck, req_pck_nom); + + hbp = max(hbp, 1); + + + + hfp = dispc_hbl - hsa - hbp; + + if (hfp < 1) { + + int t; + + /* we need to take cycles from hbp */ + + + + t = 1 - hfp; + + hbp = max(hbp - t, 1); + + hfp = dispc_hbl - hsa - hbp; + + + + if (hfp < 1) { + + /* we need to take cycles from hsa */ + + t = 1 - hfp; + + hsa = max(hsa - t, 1); + + hfp = dispc_hbl - hsa - hbp; + + } + + } + + + + if (hfp < 1) + + return false; + + + + dispc_vm->hfp = hfp; + + dispc_vm->hsw = hsa; + + dispc_vm->hbp = hbp; + + + + return true; + +} + + + + + +static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, + + unsigned long pck, void *data) + +{ + + struct dsi_clk_calc_ctx *ctx = data; + + + + ctx->dispc_cinfo.lck_div = lckd; + + ctx->dispc_cinfo.pck_div = pckd; + + ctx->dispc_cinfo.lck = lck; + + ctx->dispc_cinfo.pck = pck; + + + + if (dsi_vm_calc_blanking(ctx) == false) + + return false; + + + +#ifdef PRINT_VERBOSE_VM_TIMINGS + + print_dispc_vm("dispc", &ctx->dispc_vm); + + print_dsi_vm("dsi ", &ctx->dsi_vm); + + print_dispc_vm("req ", ctx->config->timings); + + print_dsi_dispc_vm("act ", &ctx->dsi_vm); + +#endif + + + + return true; + +} + + + +static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, + + void *data) + +{ + + struct dsi_clk_calc_ctx *ctx = data; + + unsigned long pck_max; + + + + ctx->dsi_cinfo.regm_dispc = regm_dispc; + + ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; + + + + /* + + * In burst mode we can let the dispc pck be arbitrarily high, but it + + * limits our scaling abilities. So for now, don't aim too high. + + */ + + + + if (ctx->config->trans_mode == OMAP_DSS_DSI_BURST_MODE) + + pck_max = ctx->req_pck_max + 10000000; + + else + + pck_max = ctx->req_pck_max; + + + + return dispc_div_calc(dispc, ctx->req_pck_min, pck_max, + + dsi_vm_calc_dispc_cb, ctx); + +} + + + +static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint, + + unsigned long pll, void *data) + +{ + + struct dsi_clk_calc_ctx *ctx = data; + + + + ctx->dsi_cinfo.regn = regn; + + ctx->dsi_cinfo.regm = regm; + + ctx->dsi_cinfo.fint = fint; + + ctx->dsi_cinfo.clkin4ddr = pll; + + + + return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, + + dsi_vm_calc_hsdiv_cb, ctx); + } -EXPORT_SYMBOL(omapdss_dsi_set_operation_mode); + -void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, - struct omap_dss_dsi_videomode_timings *timings) + +static bool dsi_vm_calc(struct dsi_data *dsi, + + const struct omap_dss_dsi_config *cfg, + + struct dsi_clk_calc_ctx *ctx) + +{ + + const struct omap_video_timings *t = cfg->timings; + + unsigned long clkin; + + unsigned long pll_min; + + unsigned long pll_max; + + int ndl = dsi->num_lanes_used - 1; + + int bitspp = dsi_get_pixel_size(cfg->pixel_format); + + unsigned long byteclk_min; + + + + clkin = clk_get_rate(dsi->sys_clk); + + + + memset(ctx, 0, sizeof(*ctx)); + + ctx->dsidev = dsi->pdev; + + ctx->config = cfg; + + + + ctx->dsi_cinfo.clkin = clkin; + + + + /* these limits should come from the panel driver */ + + ctx->req_pck_min = t->pixel_clock * 1000 - 1000; + + ctx->req_pck_nom = t->pixel_clock * 1000; + + ctx->req_pck_max = t->pixel_clock * 1000 + 1000; + + + + byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8); + + pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4); + + + + if (cfg->trans_mode == OMAP_DSS_DSI_BURST_MODE) { + + pll_max = cfg->hs_clk_max * 4; + + } else { + + unsigned long byteclk_max; + + byteclk_max = div64_u64((u64)ctx->req_pck_max * bitspp, + + ndl * 8); + + + + pll_max = byteclk_max * 4 * 4; + + } + + + + return dsi_pll_calc(dsi->pdev, clkin, + + pll_min, pll_max, + + dsi_vm_calc_pll_cb, ctx); +} - EXPORT_SYMBOL(omapdss_dsi_set_operation_mode); + - void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, - struct omap_dss_dsi_videomode_timings *timings) + +int omapdss_dsi_set_config(struct omap_dss_device *dssdev, + + const struct omap_dss_dsi_config *config) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);