From 6e555e2752ea284bda55b0ee477a512e1525b84a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 1 Nov 2013 11:26:43 +0200 Subject: OMAPDSS: fix omap2 dss fck handling The driver considers OMAP2 DSS's functional clock as a fixed clock. However, it can be changed, but the possible dividers are not continuous which is why it was just handled as a fixed clock. As a partial fix, this patch changes the code to handle the continous part of the dividers, from 1 to 6. This let's us handle the OMAP2 fck the same way as fcks on other OMAPs. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index bd01608e67e2..e59577a2c41c 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -484,11 +484,6 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) unsigned m; if (dss.dpll4_m4_ck == NULL) { - /* - * TODO: dss1_fclk can be changed on OMAP2, but the available - * dividers are not continuous. We just use the pre-set rate for - * now. - */ fck = clk_get_rate(dss.dss_clk); fckd = 1; return func(fckd, fck, data); @@ -761,9 +756,13 @@ void dss_debug_dump_clocks(struct seq_file *s) #endif static const struct dss_features omap24xx_dss_feats __initconst = { - .fck_div_max = 16, + /* + * fck div max is really 16, but the divider range has gaps. The range + * from 1 to 6 has no gaps, so let's use that as a max. + */ + .fck_div_max = 6, .dss_fck_multiplier = 2, - .clk_name = NULL, + .clk_name = "dss1_fck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; -- cgit v1.2.3 From d0f58bd3bba3877fb1af4664c4e33273d36f00e4 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 31 Oct 2013 14:44:23 +0200 Subject: OMAPDSS: remove struct dss_clock_info Remove struct dss_clock_info, as it is not usable in a case where DSS fclk comes from a dedicated PLL. Instead, just use the fclk rate in place of dss_clock_info, as that is all that's needed. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 13 +++++----- drivers/video/omap2/dss/dss.c | 59 ++++++++++--------------------------------- drivers/video/omap2/dss/dss.h | 13 ++-------- drivers/video/omap2/dss/sdi.c | 19 +++++++------- 4 files changed, 30 insertions(+), 74 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index bd48cde53561..16acdddc94e3 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -117,7 +117,7 @@ struct dpi_clk_calc_ctx { /* outputs */ struct dsi_clock_info dsi_cinfo; - struct dss_clock_info dss_cinfo; + unsigned long long fck; struct dispc_clock_info dispc_cinfo; }; @@ -184,12 +184,11 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint, dpi_calc_hsdiv_cb, ctx); } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data) { struct dpi_clk_calc_ctx *ctx = data; - ctx->dss_cinfo.fck = fck; - ctx->dss_cinfo.fck_div = fckd; + ctx->fck = fck; return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, dpi_calc_dispc_cb, ctx); @@ -286,13 +285,13 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, if (!ok) return -EINVAL; - r = dss_set_clock_div(&ctx.dss_cinfo); + r = dss_set_fck_rate(ctx.fck); if (r) return r; dpi.mgr_config.clock_info = ctx.dispc_cinfo; - *fck = ctx.dss_cinfo.fck; + *fck = ctx.fck; *lck_div = ctx.dispc_cinfo.lck_div; *pck_div = ctx.dispc_cinfo.pck_div; @@ -495,7 +494,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, if (!ok) return -EINVAL; - fck = ctx.dss_cinfo.fck; + fck = ctx.fck; } lck_div = ctx.dispc_cinfo.lck_div; diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index e59577a2c41c..c37d934e1a57 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -81,7 +81,6 @@ static struct { unsigned long cache_req_pck; unsigned long cache_prate; - struct dss_clock_info cache_dss_cinfo; struct dispc_clock_info cache_dispc_cinfo; enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI]; @@ -451,29 +450,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) } } -/* calculate clock rates using dividers in cinfo */ -int dss_calc_clock_rates(struct dss_clock_info *cinfo) -{ - if (dss.dpll4_m4_ck) { - unsigned long prate; - - if (cinfo->fck_div > dss.feat->fck_div_max || - cinfo->fck_div == 0) - return -EINVAL; - - prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - - cinfo->fck = prate / cinfo->fck_div * - dss.feat->dss_fck_multiplier; - } else { - if (cinfo->fck_div != 0) - return -EINVAL; - cinfo->fck = clk_get_rate(dss.dss_clk); - } - - return 0; -} - bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) { int fckd, fckd_start, fckd_stop; @@ -485,8 +461,7 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) if (dss.dpll4_m4_ck == NULL) { fck = clk_get_rate(dss.dss_clk); - fckd = 1; - return func(fckd, fck, data); + return func(fck, data); } fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); @@ -503,38 +478,35 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { fck = prate / fckd * m; - if (func(fckd, fck, data)) + if (func(fck, data)) return true; } return false; } -int dss_set_clock_div(struct dss_clock_info *cinfo) +int dss_set_fck_rate(unsigned long rate) { + DSSDBG("set fck to %lu\n", rate); + if (dss.dpll4_m4_ck) { unsigned long prate; + unsigned m; int r; prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - DSSDBG("dpll4_m4 = %ld\n", prate); + m = dss.feat->dss_fck_multiplier; - r = clk_set_rate(dss.dpll4_m4_ck, - DIV_ROUND_UP(prate, cinfo->fck_div)); + r = clk_set_rate(dss.dpll4_m4_ck, rate * m); if (r) return r; - } else { - if (cinfo->fck_div != 0) - return -EINVAL; } dss.dss_clk_rate = clk_get_rate(dss.dss_clk); - WARN_ONCE(dss.dss_clk_rate != cinfo->fck, + WARN_ONCE(dss.dss_clk_rate != rate, "clk rate mismatch: %lu != %lu", dss.dss_clk_rate, - cinfo->fck); - - DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); + rate); return 0; } @@ -555,8 +527,8 @@ unsigned long dss_get_dispc_clk_rate(void) static int dss_setup_default_clock(void) { unsigned long max_dss_fck, prate; + unsigned long fck; unsigned fck_div; - struct dss_clock_info dss_cinfo = { 0 }; int r; if (dss.dpll4_m4_ck == NULL) @@ -568,14 +540,9 @@ static int dss_setup_default_clock(void) fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, max_dss_fck); + fck = prate / fck_div * dss.feat->dss_fck_multiplier; - dss_cinfo.fck_div = fck_div; - - r = dss_calc_clock_rates(&dss_cinfo); - if (r) - return r; - - r = dss_set_clock_div(&dss_cinfo); + r = dss_set_fck_rate(fck); if (r) return r; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index e172531d196b..ead1960ad9d8 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -100,14 +100,6 @@ enum dss_writeback_channel { DSS_WB_LCD3_MGR = 7, }; -struct dss_clock_info { - /* rates that we get with dividers below */ - unsigned long fck; - - /* dividers */ - u16 fck_div; -}; - struct dispc_clock_info { /* rates that we get with dividers below */ unsigned long lck; @@ -251,10 +243,9 @@ void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); unsigned long dss_get_dpll4_rate(void); -int dss_calc_clock_rates(struct dss_clock_info *cinfo); -int dss_set_clock_div(struct dss_clock_info *cinfo); +int dss_set_fck_rate(unsigned long rate); -typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data); +typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data); /* SDI */ diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index ccc569ae7cca..221fd34c42ff 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -46,7 +46,7 @@ static struct { struct sdi_clk_calc_ctx { unsigned long pck_min, pck_max; - struct dss_clock_info dss_cinfo; + unsigned long long fck; struct dispc_clock_info dispc_cinfo; }; @@ -63,19 +63,18 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, return true; } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data) { struct sdi_clk_calc_ctx *ctx = data; - ctx->dss_cinfo.fck = fck; - ctx->dss_cinfo.fck_div = fckd; + ctx->fck = fck; return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, dpi_calc_dispc_cb, ctx); } static int sdi_calc_clock_div(unsigned long pclk, - struct dss_clock_info *dss_cinfo, + unsigned long *fck, struct dispc_clock_info *dispc_cinfo) { int i; @@ -100,7 +99,7 @@ static int sdi_calc_clock_div(unsigned long pclk, ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx); if (ok) { - *dss_cinfo = ctx.dss_cinfo; + *fck = ctx.fck; *dispc_cinfo = ctx.dispc_cinfo; return 0; } @@ -128,7 +127,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &sdi.output; struct omap_video_timings *t = &sdi.timings; - struct dss_clock_info dss_cinfo; + unsigned long fck; struct dispc_clock_info dispc_cinfo; unsigned long pck; int r; @@ -150,13 +149,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; - r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); + r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo); if (r) goto err_calc_clock_div; sdi.mgr_config.clock_info = dispc_cinfo; - pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; + pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; if (pck != t->pixel_clock) { DSSWARN("Could not find exact pixel clock. Requested %d kHz, " @@ -169,7 +168,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) dss_mgr_set_timings(out->manager, t); - r = dss_set_clock_div(&dss_cinfo); + r = dss_set_fck_rate(fck); if (r) goto err_set_dss_clock_div; -- cgit v1.2.3 From 9c15d76200dbd9c0ae5b1c6bfa17cbfdfaa2e2ae Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 1 Nov 2013 11:36:10 +0200 Subject: OMAPDSS: simplify dss clk dump Simplify dss_dump_clocks() so that it doesn't make any presumptions about the DSS fclks nature. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index c37d934e1a57..3dea532daf4c 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -264,8 +264,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) void dss_dump_clocks(struct seq_file *s) { - unsigned long dpll4_ck_rate; - unsigned long dpll4_m4_ck_rate; const char *fclk_name, *fclk_real_name; unsigned long fclk_rate; @@ -278,21 +276,9 @@ void dss_dump_clocks(struct seq_file *s) fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK); fclk_rate = clk_get_rate(dss.dss_clk); - if (dss.dpll4_m4_ck) { - dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); - - seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); - - seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n", - fclk_name, fclk_real_name, dpll4_ck_rate, - dpll4_ck_rate / dpll4_m4_ck_rate, - dss.feat->dss_fck_multiplier, fclk_rate); - } else { - seq_printf(s, "%s (%s) = %lu\n", - fclk_name, fclk_real_name, - fclk_rate); - } + seq_printf(s, "%s (%s) = %lu\n", + fclk_name, fclk_real_name, + fclk_rate); dss_runtime_put(); } -- cgit v1.2.3 From 64ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 1 Nov 2013 11:38:04 +0200 Subject: OMAPDSS: rename parent clk variables Rename the variables related to DSS fclk's parent: "clk_name" and "dpll4_m4_ck", to "parent_clk_name" and "parent_clk", which much better tell what they mean. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 3dea532daf4c..d510ba333e7d 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -67,7 +67,7 @@ static void dss_runtime_put(void); struct dss_features { u8 fck_div_max; u8 dss_fck_multiplier; - const char *clk_name; + const char *parent_clk_name; int (*dpi_select_source)(enum omap_channel channel); }; @@ -75,7 +75,7 @@ static struct { struct platform_device *pdev; void __iomem *base; - struct clk *dpll4_m4_ck; + struct clk *parent_clk; struct clk *dss_clk; unsigned long dss_clk_rate; @@ -445,7 +445,7 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) unsigned long prate; unsigned m; - if (dss.dpll4_m4_ck == NULL) { + if (dss.parent_clk == NULL) { fck = clk_get_rate(dss.dss_clk); return func(fck, data); } @@ -475,15 +475,15 @@ int dss_set_fck_rate(unsigned long rate) { DSSDBG("set fck to %lu\n", rate); - if (dss.dpll4_m4_ck) { + if (dss.parent_clk) { unsigned long prate; unsigned m; int r; - prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); + prate = clk_get_rate(clk_get_parent(dss.parent_clk)); m = dss.feat->dss_fck_multiplier; - r = clk_set_rate(dss.dpll4_m4_ck, rate * m); + r = clk_set_rate(dss.parent_clk, rate * m); if (r) return r; } @@ -499,8 +499,8 @@ int dss_set_fck_rate(unsigned long rate) unsigned long dss_get_dpll4_rate(void) { - if (dss.dpll4_m4_ck) - return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); + if (dss.parent_clk) + return clk_get_rate(clk_get_parent(dss.parent_clk)); else return 0; } @@ -517,7 +517,7 @@ static int dss_setup_default_clock(void) unsigned fck_div; int r; - if (dss.dpll4_m4_ck == NULL) + if (dss.parent_clk == NULL) return 0; max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); @@ -654,25 +654,25 @@ static int dss_get_clocks(void) dss.dss_clk = clk; - if (dss.feat->clk_name) { - clk = clk_get(NULL, dss.feat->clk_name); + if (dss.feat->parent_clk_name) { + clk = clk_get(NULL, dss.feat->parent_clk_name); if (IS_ERR(clk)) { - DSSERR("Failed to get %s\n", dss.feat->clk_name); + DSSERR("Failed to get %s\n", dss.feat->parent_clk_name); return PTR_ERR(clk); } } else { clk = NULL; } - dss.dpll4_m4_ck = clk; + dss.parent_clk = clk; return 0; } static void dss_put_clocks(void) { - if (dss.dpll4_m4_ck) - clk_put(dss.dpll4_m4_ck); + if (dss.parent_clk) + clk_put(dss.parent_clk); } static int dss_runtime_get(void) @@ -715,35 +715,35 @@ static const struct dss_features omap24xx_dss_feats __initconst = { */ .fck_div_max = 6, .dss_fck_multiplier = 2, - .clk_name = "dss1_fck", + .parent_clk_name = "dss1_fck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap34xx_dss_feats __initconst = { .fck_div_max = 16, .dss_fck_multiplier = 2, - .clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_m4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap3630_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_m4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap44xx_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .clk_name = "dpll_per_m5x2_ck", + .parent_clk_name = "dpll_per_m5x2_ck", .dpi_select_source = &dss_dpi_select_source_omap4, }; static const struct dss_features omap54xx_dss_feats __initconst = { .fck_div_max = 64, .dss_fck_multiplier = 1, - .clk_name = "dpll_per_h12x2_ck", + .parent_clk_name = "dpll_per_h12x2_ck", .dpi_select_source = &dss_dpi_select_source_omap5, }; -- cgit v1.2.3 From ada9443ff407f83a96abc15ea44a106250dd23f2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 31 Oct 2013 16:06:38 +0200 Subject: OMAPDSS: cleanup fck parent handling The dss parent_clk_name currently points to a clock node which we use to change the fclk rate. Now that we have CLK_SET_RATE_PARENT properly set, we can set the rate directly to the fclk node. However, we still need to calculate the possible clock rates. For this, we need the rate of the parent of the current parent_clk. To simplify the code, this patch changes the parent_clk_name to point to the above mentioned parent, so that we can get the rate directly. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 39 ++++++++++++--------------------------- drivers/video/omap2/dss/dss.h | 1 - 2 files changed, 12 insertions(+), 28 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index d510ba333e7d..7af97199c905 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -454,7 +454,7 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) fckd_hw_max = dss.feat->fck_div_max; m = dss.feat->dss_fck_multiplier; - prate = dss_get_dpll4_rate(); + prate = clk_get_rate(dss.parent_clk); fck_min = fck_min ? fck_min : 1; @@ -473,20 +473,13 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) int dss_set_fck_rate(unsigned long rate) { - DSSDBG("set fck to %lu\n", rate); - - if (dss.parent_clk) { - unsigned long prate; - unsigned m; - int r; + int r; - prate = clk_get_rate(clk_get_parent(dss.parent_clk)); - m = dss.feat->dss_fck_multiplier; + DSSDBG("set fck to %lu\n", rate); - r = clk_set_rate(dss.parent_clk, rate * m); - if (r) - return r; - } + r = clk_set_rate(dss.dss_clk, rate); + if (r) + return r; dss.dss_clk_rate = clk_get_rate(dss.dss_clk); @@ -497,14 +490,6 @@ int dss_set_fck_rate(unsigned long rate) return 0; } -unsigned long dss_get_dpll4_rate(void) -{ - if (dss.parent_clk) - return clk_get_rate(clk_get_parent(dss.parent_clk)); - else - return 0; -} - unsigned long dss_get_dispc_clk_rate(void) { return dss.dss_clk_rate; @@ -522,7 +507,7 @@ static int dss_setup_default_clock(void) max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); - prate = dss_get_dpll4_rate(); + prate = clk_get_rate(dss.parent_clk); fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, max_dss_fck); @@ -715,35 +700,35 @@ static const struct dss_features omap24xx_dss_feats __initconst = { */ .fck_div_max = 6, .dss_fck_multiplier = 2, - .parent_clk_name = "dss1_fck", + .parent_clk_name = "core_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap34xx_dss_feats __initconst = { .fck_div_max = 16, .dss_fck_multiplier = 2, - .parent_clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap3630_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .parent_clk_name = "dpll4_m4_ck", + .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, }; static const struct dss_features omap44xx_dss_feats __initconst = { .fck_div_max = 32, .dss_fck_multiplier = 1, - .parent_clk_name = "dpll_per_m5x2_ck", + .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap4, }; static const struct dss_features omap54xx_dss_feats __initconst = { .fck_div_max = 64, .dss_fck_multiplier = 1, - .parent_clk_name = "dpll_per_h12x2_ck", + .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap5, }; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index ead1960ad9d8..6fc786fddbcb 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -242,7 +242,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); -unsigned long dss_get_dpll4_rate(void); int dss_set_fck_rate(unsigned long rate); typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); -- cgit v1.2.3 From 688af02d22c11a077532d6437e4afc7bdc972f82 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 31 Oct 2013 16:41:57 +0200 Subject: OMAPDSS: pass pck to dss fck clock calc We need the required pixel clock rate when calculating the dss fclk on SoCs that have a dedicated DSS PLL. This patch changes the code to pass the pck to the calc functions. The pck rate is taken into use in the next patch. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 2 +- drivers/video/omap2/dss/dss.c | 3 ++- drivers/video/omap2/dss/dss.h | 3 ++- drivers/video/omap2/dss/sdi.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 16acdddc94e3..ae1c8b9d39ca 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -236,7 +236,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) ctx->pck_min = 0; ctx->pck_max = pck + 1000 * i * i * i; - ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx); + ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx); if (ok) return ok; } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 7af97199c905..08c58ebe219c 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -436,7 +436,8 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) } } -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) +bool dss_div_calc(unsigned long pck, unsigned long fck_min, + dss_div_calc_func func, void *data) { int fckd, fckd_start, fckd_stop; unsigned long fck; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 6fc786fddbcb..2acc6615b984 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -245,7 +245,8 @@ void dss_set_dac_pwrdn_bgz(bool enable); int dss_set_fck_rate(unsigned long rate); typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data); +bool dss_div_calc(unsigned long pck, unsigned long fck_min, + dss_div_calc_func func, void *data); /* SDI */ int sdi_init_platform_driver(void) __init; diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 221fd34c42ff..3bf47c92aedf 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -97,7 +97,7 @@ static int sdi_calc_clock_div(unsigned long pclk, ctx.pck_min = 0; ctx.pck_max = pclk + 1000 * i * i * i; - ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx); + ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx); if (ok) { *fck = ctx.fck; *dispc_cinfo = ctx.dispc_cinfo; -- cgit v1.2.3 From fc1fe6e794cc85fcdb63daa9c7a977940ff49e4f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 31 Oct 2013 16:42:13 +0200 Subject: OMAPDSS: add dedicated fck PLL support This patch adds support for SoCs that have a dedicated DSS PLL used for DSS function clock. If there is no dss parent clock defined, it is presumed that the functionl clock rate can be set (almost) freely. The code calculates the highest allowed fck rate, which when divided with some integer gives the required pck. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 08c58ebe219c..9a145da35ad3 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -446,12 +446,20 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min, unsigned long prate; unsigned m; + fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); + if (dss.parent_clk == NULL) { - fck = clk_get_rate(dss.dss_clk); + unsigned pckd; + + pckd = fck_hw_max / pck; + + fck = pck * pckd; + + fck = clk_round_rate(dss.dss_clk, fck); + return func(fck, data); } - fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); fckd_hw_max = dss.feat->fck_div_max; m = dss.feat->dss_fck_multiplier; @@ -503,16 +511,17 @@ static int dss_setup_default_clock(void) unsigned fck_div; int r; - if (dss.parent_clk == NULL) - return 0; - max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); - prate = clk_get_rate(dss.parent_clk); + if (dss.parent_clk == NULL) { + fck = clk_round_rate(dss.dss_clk, max_dss_fck); + } else { + prate = clk_get_rate(dss.parent_clk); - fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, - max_dss_fck); - fck = prate / fck_div * dss.feat->dss_fck_multiplier; + fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, + max_dss_fck); + fck = prate / fck_div * dss.feat->dss_fck_multiplier; + } r = dss_set_fck_rate(fck); if (r) -- cgit v1.2.3 From ca7a97add4d4a7b0602b3bd1eff5c89da8636713 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 1 Dec 2013 13:04:03 -0200 Subject: backlight: pwm_bl: Remove error message upon devm_kzalloc() failure No need to have a specific OOM message, since there is generic MM out of memory message in place. Signed-off-by: Fabio Estevam Signed-off-by: Thierry Reding --- drivers/video/backlight/pwm_bl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index fb80d68f4d33..b75201ff46f6 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -241,7 +241,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL); if (!pb) { - dev_err(&pdev->dev, "no memory for state\n"); ret = -ENOMEM; goto err_alloc; } -- cgit v1.2.3 From 46eeb2c144956e88197439b5ee5cf221a91b0a81 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Dec 2013 15:57:39 +0000 Subject: video/fb: Propagate error code from failing to unregister conflicting fb If we fail to remove a conflicting fb driver, we need to abort the loading of the second driver to avoid likely kernel panics. Signed-off-by: Chris Wilson Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie --- drivers/video/fbmem.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 010d19105ebc..e296967a3abb 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1577,10 +1577,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, static int do_unregister_framebuffer(struct fb_info *fb_info); #define VGA_FB_PHYS 0xA0000 -static void do_remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) +static int do_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) { - int i; + int i, ret; /* check all firmware fbs and kick off if the base addr overlaps */ for (i = 0 ; i < FB_MAX; i++) { @@ -1599,22 +1599,29 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a, printk(KERN_INFO "fb: conflicting fb hw usage " "%s vs %s - removing generic driver\n", name, registered_fb[i]->fix.id); - do_unregister_framebuffer(registered_fb[i]); + ret = do_unregister_framebuffer(registered_fb[i]); + if (ret) + return ret; } } + + return 0; } static int do_register_framebuffer(struct fb_info *fb_info) { - int i; + int i, ret; struct fb_event event; struct fb_videomode mode; if (fb_check_foreignness(fb_info)) return -ENOSYS; - do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, - fb_is_primary_device(fb_info)); + ret = do_remove_conflicting_framebuffers(fb_info->apertures, + fb_info->fix.id, + fb_is_primary_device(fb_info)); + if (ret) + return ret; if (num_registered_fb == FB_MAX) return -ENXIO; @@ -1739,12 +1746,16 @@ int unlink_framebuffer(struct fb_info *fb_info) } EXPORT_SYMBOL(unlink_framebuffer); -void remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) +int remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) { + int ret; + mutex_lock(®istration_lock); - do_remove_conflicting_framebuffers(a, name, primary); + ret = do_remove_conflicting_framebuffers(a, name, primary); mutex_unlock(®istration_lock); + + return ret; } EXPORT_SYMBOL(remove_conflicting_framebuffers); -- cgit v1.2.3 From 77d84ff87e9d38072abcca665ca22cb1da41cb86 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 9 Dec 2013 00:22:53 +0900 Subject: treewide: Fix typos in printk Correct spelling typo in various part of kernel Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- drivers/video/udlfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index 025f14e30eed..77b890e4d296 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -1624,7 +1624,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, } if (pixel_limit) { - pr_warn("DL chip limit of %d overriden" + pr_warn("DL chip limit of %d overridden" " by module param to %d\n", dev->sku_pixel_limit, pixel_limit); dev->sku_pixel_limit = pixel_limit; -- cgit v1.2.3 From fc2798502f860b18f3c7121e4dc659d3d9d28d74 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 9 Dec 2013 22:54:40 -0800 Subject: PCI: Convert pcibios_resource_to_bus() to take a pci_bus, not a pci_dev These interfaces: pcibios_resource_to_bus(struct pci_dev *dev, *bus_region, *resource) pcibios_bus_to_resource(struct pci_dev *dev, *resource, *bus_region) took a pci_dev, but they really depend only on the pci_bus. And we want to use them in resource allocation paths where we have the bus but not a device, so this patch converts them to take the pci_bus instead of the pci_dev: pcibios_resource_to_bus(struct pci_bus *bus, *bus_region, *resource) pcibios_bus_to_resource(struct pci_bus *bus, *resource, *bus_region) In fact, with standard PCI-PCI bridges, they only depend on the host bridge, because that's the only place address translation occurs, but we aren't going that far yet. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/video/arkfb.c | 2 +- drivers/video/s3fb.c | 2 +- drivers/video/vt8623fb.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c index a6b29bd4a12a..adc4ea2cc5a0 100644 --- a/drivers/video/arkfb.c +++ b/drivers/video/arkfb.c @@ -1014,7 +1014,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) vga_res.flags = IORESOURCE_IO; - pcibios_bus_to_resource(dev, &vga_res, &bus_reg); + pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); par->state.vgabase = (void __iomem *) vga_res.start; diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 968b2997175a..9a3f8f1c6aab 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c @@ -1180,7 +1180,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) vga_res.flags = IORESOURCE_IO; - pcibios_bus_to_resource(dev, &vga_res, &bus_reg); + pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); par->state.vgabase = (void __iomem *) vga_res.start; diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c index 8bc6e0958a09..5c7cbc6c6236 100644 --- a/drivers/video/vt8623fb.c +++ b/drivers/video/vt8623fb.c @@ -729,7 +729,7 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) vga_res.flags = IORESOURCE_IO; - pcibios_bus_to_resource(dev, &vga_res, &bus_reg); + pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); par->state.vgabase = (void __iomem *) vga_res.start; -- cgit v1.2.3 From 8ee5c8427110e53e4eb71a872092e97973d9b940 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Nov 2013 10:07:20 +0200 Subject: OMAPDSS: fix missing EXPORT_SYMBOL()s Functions dispc_ovl_set_fifo_threshold and dispc_ovl_compute_fifo_thresholds need to be exported. Add the EXPORT_SYMBOLs. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 4ec59ca72e5d..d8f4aeeaeec4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1201,6 +1201,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) FLD_VAL(high, hi_start, hi_end) | FLD_VAL(low, lo_start, lo_end)); } +EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold); void dispc_enable_fifomerge(bool enable) { @@ -1259,6 +1260,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, *fifo_high = total_fifo_size - buf_unit; } } +EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds); static void dispc_ovl_set_fir(enum omap_plane plane, int hinc, int vinc, -- cgit v1.2.3 From ac9f24211e4cf9cc30122a7e0d830eba2cace14b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Nov 2013 13:46:32 +0200 Subject: OMAPDSS: fix debug prints Fix debug prints all over omapdss: * add missing linefeeds * change pr_err/pr_debug to DSSERR/DSSDBG * add missing DSS_SUBSYS_NAMEs Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 8 ++++---- drivers/video/omap2/dss/hdmi4_core.c | 16 +++++++++------- drivers/video/omap2/dss/hdmi_common.c | 2 ++ drivers/video/omap2/dss/hdmi_pll.c | 16 +++++++++------- drivers/video/omap2/dss/hdmi_wp.c | 12 +++++++----- 5 files changed, 31 insertions(+), 23 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 60758dbefd79..24cd7c248504 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -629,7 +629,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) struct mgr_priv_data *mp; int r; - DSSDBG("writing ovl %d regs", ovl->id); + DSSDBG("writing ovl %d regs\n", ovl->id); if (!op->enabled || !op->info_dirty) return; @@ -664,7 +664,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl) struct ovl_priv_data *op = get_ovl_priv(ovl); struct mgr_priv_data *mp; - DSSDBG("writing ovl %d regs extra", ovl->id); + DSSDBG("writing ovl %d regs extra\n", ovl->id); if (!op->extra_info_dirty) return; @@ -687,7 +687,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) struct mgr_priv_data *mp = get_mgr_priv(mgr); struct omap_overlay *ovl; - DSSDBG("writing mgr %d regs", mgr->id); + DSSDBG("writing mgr %d regs\n", mgr->id); if (!mp->enabled) return; @@ -713,7 +713,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); - DSSDBG("writing mgr %d regs extra", mgr->id); + DSSDBG("writing mgr %d regs extra\n", mgr->id); if (!mp->extra_info_dirty) return; diff --git a/drivers/video/omap2/dss/hdmi4_core.c b/drivers/video/omap2/dss/hdmi4_core.c index 5dd5e5489b41..2386a3d9a2a2 100644 --- a/drivers/video/omap2/dss/hdmi4_core.c +++ b/drivers/video/omap2/dss/hdmi4_core.c @@ -19,6 +19,8 @@ * this program. If not, see . */ +#define DSS_SUBSYS_NAME "HDMICORE" + #include #include #include @@ -125,12 +127,12 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core, /* HDMI_CORE_DDC_STATUS_BUS_LOW */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { - pr_err("I2C Bus Low?\n"); + DSSERR("I2C Bus Low?\n"); return -EIO; } /* HDMI_CORE_DDC_STATUS_NO_ACK */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { - pr_err("I2C No Ack\n"); + DSSERR("I2C No Ack\n"); return -EIO; } @@ -161,7 +163,7 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core, checksum += pedid[i]; if (checksum != 0) { - pr_err("E-EDID checksum failed!!\n"); + DSSERR("E-EDID checksum failed!!\n"); return -EIO; } @@ -199,7 +201,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, struct hdmi_core_infoframe_avi *avi_cfg, struct hdmi_core_packet_enable_repeat *repeat_cfg) { - pr_debug("Enter hdmi_core_init\n"); + DSSDBG("Enter hdmi_core_init\n"); /* video core */ video_cfg->ip_bus_width = HDMI_INPUT_8BIT; @@ -241,19 +243,19 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) { - pr_debug("Enter hdmi_core_powerdown_disable\n"); + DSSDBG("Enter hdmi_core_powerdown_disable\n"); REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); } static void hdmi_core_swreset_release(struct hdmi_core_data *core) { - pr_debug("Enter hdmi_core_swreset_release\n"); + DSSDBG("Enter hdmi_core_swreset_release\n"); REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0); } static void hdmi_core_swreset_assert(struct hdmi_core_data *core) { - pr_debug("Enter hdmi_core_swreset_assert\n"); + DSSDBG("Enter hdmi_core_swreset_assert\n"); REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0); } diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/omap2/dss/hdmi_common.c index 5586aaad9d63..0614922902dd 100644 --- a/drivers/video/omap2/dss/hdmi_common.c +++ b/drivers/video/omap2/dss/hdmi_common.c @@ -13,6 +13,8 @@ * map it to corresponding CEA or VESA index. */ +#define DSS_SUBSYS_NAME "HDMI" + #include #include #include