diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dispc.c | 91 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dpi.c | 133 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dsi.c | 55 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dss.c | 252 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dss.h | 45 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dss_features.c | 43 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dss_features.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/hdmi.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/hdmi4.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/hdmi5.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 75 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/pll.c | 126 | ||||
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/video-pll.c | 6 |
13 files changed, 494 insertions, 348 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index f83608b69e68..7b78da6d51cf 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c | |||
| @@ -3299,30 +3299,21 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div, | |||
| 3299 | 3299 | ||
| 3300 | static unsigned long dispc_fclk_rate(void) | 3300 | static unsigned long dispc_fclk_rate(void) |
| 3301 | { | 3301 | { |
| 3302 | struct dss_pll *pll; | 3302 | unsigned long r; |
| 3303 | unsigned long r = 0; | 3303 | enum dss_clk_source src; |
| 3304 | |||
| 3305 | src = dss_get_dispc_clk_source(); | ||
| 3304 | 3306 | ||
| 3305 | switch (dss_get_dispc_clk_source()) { | 3307 | if (src == DSS_CLK_SRC_FCK) { |
| 3306 | case OMAP_DSS_CLK_SRC_FCK: | ||
| 3307 | r = dss_get_dispc_clk_rate(); | 3308 | r = dss_get_dispc_clk_rate(); |
| 3308 | break; | 3309 | } else { |
| 3309 | case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: | 3310 | struct dss_pll *pll; |
| 3310 | pll = dss_pll_find("dsi0"); | 3311 | unsigned clkout_idx; |
| 3311 | if (!pll) | ||
| 3312 | pll = dss_pll_find("video0"); | ||
| 3313 | 3312 | ||
| 3314 | r = pll->cinfo.clkout[0]; | 3313 | pll = dss_pll_find_by_src(src); |
| 3315 | break; | 3314 | clkout_idx = dss_pll_get_clkout_idx_for_src(src); |
| 3316 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: | ||
| 3317 | pll = dss_pll_find("dsi1"); | ||
| 3318 | if (!pll) | ||
| 3319 | pll = dss_pll_find("video1"); | ||
| 3320 | 3315 | ||
| 3321 | r = pll->cinfo.clkout[0]; | 3316 | r = pll->cinfo.clkout[clkout_idx]; |
| 3322 | break; | ||
| 3323 | default: | ||
| 3324 | BUG(); | ||
| 3325 | return 0; | ||
| 3326 | } | 3317 | } |
| 3327 | 3318 | ||
| 3328 | return r; | 3319 | return r; |
| @@ -3330,43 +3321,31 @@ static unsigned long dispc_fclk_rate(void) | |||
| 3330 | 3321 | ||
| 3331 | static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) | 3322 | static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) |
| 3332 | { | 3323 | { |
| 3333 | struct dss_pll *pll; | ||
| 3334 | int lcd; | 3324 | int lcd; |
| 3335 | unsigned long r; | 3325 | unsigned long r; |
| 3336 | u32 l; | 3326 | enum dss_clk_source src; |
| 3337 | 3327 | ||
| 3338 | if (dss_mgr_is_lcd(channel)) { | 3328 | /* for TV, LCLK rate is the FCLK rate */ |
| 3339 | l = dispc_read_reg(DISPC_DIVISORo(channel)); | 3329 | if (!dss_mgr_is_lcd(channel)) |
| 3340 | 3330 | return dispc_fclk_rate(); | |
| 3341 | lcd = FLD_GET(l, 23, 16); | ||
| 3342 | 3331 | ||
| 3343 | switch (dss_get_lcd_clk_source(channel)) { | 3332 | src = dss_get_lcd_clk_source(channel); |
| 3344 | case OMAP_DSS_CLK_SRC_FCK: | ||
| 3345 | r = dss_get_dispc_clk_rate(); | ||
| 3346 | break; | ||
| 3347 | case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: | ||
| 3348 | pll = dss_pll_find("dsi0"); | ||
| 3349 | if (!pll) | ||
| 3350 | pll = dss_pll_find("video0"); | ||
| 3351 | 3333 | ||
| 3352 | r = pll->cinfo.clkout[0]; | 3334 | if (src == DSS_CLK_SRC_FCK) { |
| 3353 | break; | 3335 | r = dss_get_dispc_clk_rate(); |
| 3354 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: | 3336 | } else { |
| 3355 | pll = dss_pll_find("dsi1"); | 3337 | struct dss_pll *pll; |
| 3356 | if (!pll) | 3338 | unsigned clkout_idx; |
| 3357 | pll = dss_pll_find("video1"); | ||
| 3358 | 3339 | ||
| 3359 | r = pll->cinfo.clkout[0]; | 3340 | pll = dss_pll_find_by_src(src); |
| 3360 | break; | 3341 | clkout_idx = dss_pll_get_clkout_idx_for_src(src); |
| 3361 | default: | ||
| 3362 | BUG(); | ||
| 3363 | return 0; | ||
| 3364 | } | ||
| 3365 | 3342 | ||
| 3366 | return r / lcd; | 3343 | r = pll->cinfo.clkout[clkout_idx]; |
| 3367 | } else { | ||
| 3368 | return dispc_fclk_rate(); | ||
| 3369 | } | 3344 | } |
| 3345 | |||
| 3346 | lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16); | ||
| 3347 | |||
| 3348 | return r / lcd; | ||
| 3370 | } | 3349 | } |
| 3371 | 3350 | ||
| 3372 | static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) | 3351 | static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) |
| @@ -3426,15 +3405,14 @@ static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) | |||
| 3426 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) | 3405 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) |
| 3427 | { | 3406 | { |
| 3428 | int lcd, pcd; | 3407 | int lcd, pcd; |
| 3429 | enum omap_dss_clk_source lcd_clk_src; | 3408 | enum dss_clk_source lcd_clk_src; |
| 3430 | 3409 | ||
| 3431 | seq_printf(s, "- %s -\n", mgr_desc[channel].name); | 3410 | seq_printf(s, "- %s -\n", mgr_desc[channel].name); |
| 3432 | 3411 | ||
| 3433 | lcd_clk_src = dss_get_lcd_clk_source(channel); | 3412 | lcd_clk_src = dss_get_lcd_clk_source(channel); |
| 3434 | 3413 | ||
| 3435 | seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name, | 3414 | seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name, |
| 3436 | dss_get_generic_clk_source_name(lcd_clk_src), | 3415 | dss_get_clk_source_name(lcd_clk_src)); |
| 3437 | dss_feat_get_clk_source_name(lcd_clk_src)); | ||
| 3438 | 3416 | ||
| 3439 | dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd); | 3417 | dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd); |
| 3440 | 3418 | ||
| @@ -3448,16 +3426,15 @@ void dispc_dump_clocks(struct seq_file *s) | |||
| 3448 | { | 3426 | { |
| 3449 | int lcd; | 3427 | int lcd; |
| 3450 | u32 l; | 3428 | u32 l; |
| 3451 | enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); | 3429 | enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); |
| 3452 | 3430 | ||
| 3453 | if (dispc_runtime_get()) | 3431 | if (dispc_runtime_get()) |
| 3454 | return; | 3432 | return; |
| 3455 | 3433 | ||
| 3456 | seq_printf(s, "- DISPC -\n"); | 3434 | seq_printf(s, "- DISPC -\n"); |
| 3457 | 3435 | ||
| 3458 | seq_printf(s, "dispc fclk source = %s (%s)\n", | 3436 | seq_printf(s, "dispc fclk source = %s\n", |
| 3459 | dss_get_generic_clk_source_name(dispc_clk_src), | 3437 | dss_get_clk_source_name(dispc_clk_src)); |
| 3460 | dss_feat_get_clk_source_name(dispc_clk_src)); | ||
| 3461 | 3438 | ||
| 3462 | seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); | 3439 | seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); |
| 3463 | 3440 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index 97ea60257884..db72b507384b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c | |||
| @@ -39,12 +39,11 @@ | |||
| 39 | #include "dss.h" | 39 | #include "dss.h" |
| 40 | #include "dss_features.h" | 40 | #include "dss_features.h" |
| 41 | 41 | ||
| 42 | #define HSDIV_DISPC 0 | ||
| 43 | |||
| 44 | struct dpi_data { | 42 | struct dpi_data { |
| 45 | struct platform_device *pdev; | 43 | struct platform_device *pdev; |
| 46 | 44 | ||
| 47 | struct regulator *vdds_dsi_reg; | 45 | struct regulator *vdds_dsi_reg; |
| 46 | enum dss_clk_source clk_src; | ||
| 48 | struct dss_pll *pll; | 47 | struct dss_pll *pll; |
| 49 | 48 | ||
| 50 | struct mutex lock; | 49 | struct mutex lock; |
| @@ -69,7 +68,7 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev) | |||
| 69 | return dev_get_drvdata(&pdev->dev); | 68 | return dev_get_drvdata(&pdev->dev); |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | static struct dss_pll *dpi_get_pll(enum omap_channel channel) | 71 | static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel) |
| 73 | { | 72 | { |
| 74 | /* | 73 | /* |
| 75 | * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL | 74 | * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL |
| @@ -83,64 +82,51 @@ static struct dss_pll *dpi_get_pll(enum omap_channel channel) | |||
| 83 | case OMAPDSS_VER_OMAP3630: | 82 | case OMAPDSS_VER_OMAP3630: |
| 84 | case OMAPDSS_VER_AM35xx: | 83 | case OMAPDSS_VER_AM35xx: |
| 85 | case OMAPDSS_VER_AM43xx: | 84 | case OMAPDSS_VER_AM43xx: |
| 86 | return NULL; | 85 | return DSS_CLK_SRC_FCK; |
| 87 | 86 | ||
| 88 | case OMAPDSS_VER_OMAP4430_ES1: | 87 | case OMAPDSS_VER_OMAP4430_ES1: |
| 89 | case OMAPDSS_VER_OMAP4430_ES2: | 88 | case OMAPDSS_VER_OMAP4430_ES2: |
| 90 | case OMAPDSS_VER_OMAP4: | 89 | case OMAPDSS_VER_OMAP4: |
| 91 | switch (channel) { | 90 | switch (channel) { |
| 92 | case OMAP_DSS_CHANNEL_LCD: | 91 | case OMAP_DSS_CHANNEL_LCD: |
| 93 | return dss_pll_find("dsi0"); | 92 | return DSS_CLK_SRC_PLL1_1; |
| 94 | case OMAP_DSS_CHANNEL_LCD2: | 93 | case OMAP_DSS_CHANNEL_LCD2: |
| 95 | return dss_pll_find("dsi1"); | 94 | return DSS_CLK_SRC_PLL2_1; |
| 96 | default: | 95 | default: |
| 97 | return NULL; | 96 | return DSS_CLK_SRC_FCK; |
| 98 | } | 97 | } |
| 99 | 98 | ||
| 100 | case OMAPDSS_VER_OMAP5: | 99 | case OMAPDSS_VER_OMAP5: |
| 101 | switch (channel) { | 100 | switch (channel) { |
| 102 | case OMAP_DSS_CHANNEL_LCD: | 101 | case OMAP_DSS_CHANNEL_LCD: |
| 103 | return dss_pll_find("dsi0"); | 102 | return DSS_CLK_SRC_PLL1_1; |
| 104 | case OMAP_DSS_CHANNEL_LCD3: | 103 | case OMAP_DSS_CHANNEL_LCD3: |
| 105 | return dss_pll_find("dsi1"); | 104 | return DSS_CLK_SRC_PLL2_1; |
| 105 | case OMAP_DSS_CHANNEL_LCD2: | ||
| 106 | default: | 106 | default: |
| 107 | return NULL; | 107 | return DSS_CLK_SRC_FCK; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | case OMAPDSS_VER_DRA7xx: | 110 | case OMAPDSS_VER_DRA7xx: |
| 111 | switch (channel) { | 111 | switch (channel) { |
| 112 | case OMAP_DSS_CHANNEL_LCD: | 112 | case OMAP_DSS_CHANNEL_LCD: |
| 113 | return DSS_CLK_SRC_PLL1_1; | ||
| 113 | case OMAP_DSS_CHANNEL_LCD2: | 114 | case OMAP_DSS_CHANNEL_LCD2: |
| 114 | return dss_pll_find("video0"); | 115 | return DSS_CLK_SRC_PLL1_3; |
| 115 | case OMAP_DSS_CHANNEL_LCD3: | 116 | case OMAP_DSS_CHANNEL_LCD3: |
| 116 | return dss_pll_find("video1"); | 117 | return DSS_CLK_SRC_PLL2_1; |
| 117 | default: | 118 | default: |
| 118 | return NULL; | 119 | return DSS_CLK_SRC_FCK; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | default: | 122 | default: |
| 122 | return NULL; | 123 | return DSS_CLK_SRC_FCK; |
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel) | ||
| 127 | { | ||
| 128 | switch (channel) { | ||
| 129 | case OMAP_DSS_CHANNEL_LCD: | ||
| 130 | return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC; | ||
| 131 | case OMAP_DSS_CHANNEL_LCD2: | ||
| 132 | return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; | ||
| 133 | case OMAP_DSS_CHANNEL_LCD3: | ||
| 134 | return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; | ||
| 135 | default: | ||
| 136 | /* this shouldn't happen */ | ||
| 137 | WARN_ON(1); | ||
| 138 | return OMAP_DSS_CLK_SRC_FCK; | ||
| 139 | } | 124 | } |
| 140 | } | 125 | } |
| 141 | 126 | ||
| 142 | struct dpi_clk_calc_ctx { | 127 | struct dpi_clk_calc_ctx { |
| 143 | struct dss_pll *pll; | 128 | struct dss_pll *pll; |
| 129 | unsigned clkout_idx; | ||
| 144 | 130 | ||
| 145 | /* inputs */ | 131 | /* inputs */ |
| 146 | 132 | ||
| @@ -148,7 +134,7 @@ struct dpi_clk_calc_ctx { | |||
| 148 | 134 | ||
| 149 | /* outputs */ | 135 | /* outputs */ |
| 150 | 136 | ||
| 151 | struct dss_pll_clock_info dsi_cinfo; | 137 | struct dss_pll_clock_info pll_cinfo; |
| 152 | unsigned long fck; | 138 | unsigned long fck; |
| 153 | struct dispc_clock_info dispc_cinfo; | 139 | struct dispc_clock_info dispc_cinfo; |
| 154 | }; | 140 | }; |
| @@ -193,8 +179,8 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc, | |||
| 193 | if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000) | 179 | if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000) |
| 194 | return false; | 180 | return false; |
| 195 | 181 | ||
| 196 | ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc; | 182 | ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc; |
| 197 | ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc; | 183 | ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc; |
| 198 | 184 | ||
| 199 | return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, | 185 | return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, |
| 200 | dpi_calc_dispc_cb, ctx); | 186 | dpi_calc_dispc_cb, ctx); |
| @@ -207,12 +193,12 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint, | |||
| 207 | { | 193 | { |
| 208 | struct dpi_clk_calc_ctx *ctx = data; | 194 | struct dpi_clk_calc_ctx *ctx = data; |
| 209 | 195 | ||
| 210 | ctx->dsi_cinfo.n = n; | 196 | ctx->pll_cinfo.n = n; |
| 211 | ctx->dsi_cinfo.m = m; | 197 | ctx->pll_cinfo.m = m; |
| 212 | ctx->dsi_cinfo.fint = fint; | 198 | ctx->pll_cinfo.fint = fint; |
| 213 | ctx->dsi_cinfo.clkdco = clkdco; | 199 | ctx->pll_cinfo.clkdco = clkdco; |
| 214 | 200 | ||
| 215 | return dss_pll_hsdiv_calc(ctx->pll, clkdco, | 201 | return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, |
| 216 | ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), | 202 | ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), |
| 217 | dpi_calc_hsdiv_cb, ctx); | 203 | dpi_calc_hsdiv_cb, ctx); |
| 218 | } | 204 | } |
| @@ -227,25 +213,39 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data) | |||
| 227 | dpi_calc_dispc_cb, ctx); | 213 | dpi_calc_dispc_cb, ctx); |
| 228 | } | 214 | } |
| 229 | 215 | ||
| 230 | static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck, | 216 | static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck, |
| 231 | struct dpi_clk_calc_ctx *ctx) | 217 | struct dpi_clk_calc_ctx *ctx) |
| 232 | { | 218 | { |
| 233 | unsigned long clkin; | 219 | unsigned long clkin; |
| 234 | unsigned long pll_min, pll_max; | ||
| 235 | 220 | ||
| 236 | memset(ctx, 0, sizeof(*ctx)); | 221 | memset(ctx, 0, sizeof(*ctx)); |
| 237 | ctx->pll = dpi->pll; | 222 | ctx->pll = dpi->pll; |
| 238 | ctx->pck_min = pck - 1000; | 223 | ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src); |
| 239 | ctx->pck_max = pck + 1000; | ||
| 240 | 224 | ||
| 241 | pll_min = 0; | 225 | clkin = clk_get_rate(dpi->pll->clkin); |
| 242 | pll_max = 0; | ||
| 243 | 226 | ||
| 244 | clkin = clk_get_rate(ctx->pll->clkin); | 227 | if (dpi->pll->hw->type == DSS_PLL_TYPE_A) { |
| 228 | unsigned long pll_min, pll_max; | ||
| 245 | 229 | ||
| 246 | return dss_pll_calc(ctx->pll, clkin, | 230 | ctx->pck_min = pck - 1000; |
| 247 | pll_min, pll_max, | 231 | ctx->pck_max = pck + 1000; |
| 248 | dpi_calc_pll_cb, ctx); | 232 | |
| 233 | pll_min = 0; | ||
| 234 | pll_max = 0; | ||
| 235 | |||
| 236 | return dss_pll_calc_a(ctx->pll, clkin, | ||
| 237 | pll_min, pll_max, | ||
| 238 | dpi_calc_pll_cb, ctx); | ||
| 239 | } else { /* DSS_PLL_TYPE_B */ | ||
| 240 | dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo); | ||
| 241 | |||
| 242 | ctx->dispc_cinfo.lck_div = 1; | ||
| 243 | ctx->dispc_cinfo.pck_div = 1; | ||
| 244 | ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0]; | ||
| 245 | ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck; | ||
| 246 | |||
| 247 | return true; | ||
| 248 | } | ||
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) | 251 | static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) |
| @@ -279,7 +279,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) | |||
| 279 | 279 | ||
| 280 | 280 | ||
| 281 | 281 | ||
| 282 | static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel, | 282 | static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel, |
| 283 | unsigned long pck_req, unsigned long *fck, int *lck_div, | 283 | unsigned long pck_req, unsigned long *fck, int *lck_div, |
| 284 | int *pck_div) | 284 | int *pck_div) |
| 285 | { | 285 | { |
| @@ -287,20 +287,19 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel, | |||
| 287 | int r; | 287 | int r; |
| 288 | bool ok; | 288 | bool ok; |
| 289 | 289 | ||
| 290 | ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx); | 290 | ok = dpi_pll_clk_calc(dpi, pck_req, &ctx); |
| 291 | if (!ok) | 291 | if (!ok) |
| 292 | return -EINVAL; | 292 | return -EINVAL; |
| 293 | 293 | ||
| 294 | r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo); | 294 | r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo); |
| 295 | if (r) | 295 | if (r) |
| 296 | return r; | 296 | return r; |
| 297 | 297 | ||
| 298 | dss_select_lcd_clk_source(channel, | 298 | dss_select_lcd_clk_source(channel, dpi->clk_src); |
| 299 | dpi_get_alt_clk_src(channel)); | ||
| 300 | 299 | ||
| 301 | dpi->mgr_config.clock_info = ctx.dispc_cinfo; | 300 | dpi->mgr_config.clock_info = ctx.dispc_cinfo; |
| 302 | 301 | ||
| 303 | *fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC]; | 302 | *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; |
| 304 | *lck_div = ctx.dispc_cinfo.lck_div; | 303 | *lck_div = ctx.dispc_cinfo.lck_div; |
| 305 | *pck_div = ctx.dispc_cinfo.pck_div; | 304 | *pck_div = ctx.dispc_cinfo.pck_div; |
| 306 | 305 | ||
| @@ -342,7 +341,7 @@ static int dpi_set_mode(struct dpi_data *dpi) | |||
| 342 | int r = 0; | 341 | int r = 0; |
| 343 | 342 | ||
| 344 | if (dpi->pll) | 343 | if (dpi->pll) |
| 345 | r = dpi_set_dsi_clk(dpi, channel, t->pixelclock, &fck, | 344 | r = dpi_set_pll_clk(dpi, channel, t->pixelclock, &fck, |
| 346 | &lck_div, &pck_div); | 345 | &lck_div, &pck_div); |
| 347 | else | 346 | else |
| 348 | r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck, | 347 | r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck, |
| @@ -419,7 +418,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) | |||
| 419 | if (dpi->pll) { | 418 | if (dpi->pll) { |
| 420 | r = dss_pll_enable(dpi->pll); | 419 | r = dss_pll_enable(dpi->pll); |
| 421 | if (r) | 420 | if (r) |
| 422 | goto err_dsi_pll_init; | 421 | goto err_pll_init; |
| 423 | } | 422 | } |
| 424 | 423 | ||
| 425 | r = dpi_set_mode(dpi); | 424 | r = dpi_set_mode(dpi); |
| @@ -442,7 +441,7 @@ err_mgr_enable: | |||
| 442 | err_set_mode: | 441 | err_set_mode: |
| 443 | if (dpi->pll) | 442 | if (dpi->pll) |
| 444 | dss_pll_disable(dpi->pll); | 443 | dss_pll_disable(dpi->pll); |
| 445 | err_dsi_pll_init: | 444 | err_pll_init: |
| 446 | err_src_sel: | 445 | err_src_sel: |
| 447 | dispc_runtime_put(); | 446 | dispc_runtime_put(); |
| 448 | err_get_dispc: | 447 | err_get_dispc: |
| @@ -465,7 +464,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) | |||
| 465 | dss_mgr_disable(channel); | 464 | dss_mgr_disable(channel); |
| 466 | 465 | ||
| 467 | if (dpi->pll) { | 466 | if (dpi->pll) { |
| 468 | dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); | 467 | dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); |
| 469 | dss_pll_disable(dpi->pll); | 468 | dss_pll_disable(dpi->pll); |
| 470 | } | 469 | } |
| 471 | 470 | ||
| @@ -524,11 +523,11 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, | |||
| 524 | return -EINVAL; | 523 | return -EINVAL; |
| 525 | 524 | ||
| 526 | if (dpi->pll) { | 525 | if (dpi->pll) { |
| 527 | ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx); | 526 | ok = dpi_pll_clk_calc(dpi, timings->pixelclock, &ctx); |
| 528 | if (!ok) | 527 | if (!ok) |
| 529 | return -EINVAL; | 528 | return -EINVAL; |
| 530 | 529 | ||
| 531 | fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC]; | 530 | fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; |
| 532 | } else { | 531 | } else { |
| 533 | ok = dpi_dss_clk_calc(timings->pixelclock, &ctx); | 532 | ok = dpi_dss_clk_calc(timings->pixelclock, &ctx); |
| 534 | if (!ok) | 533 | if (!ok) |
| @@ -558,7 +557,7 @@ static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | |||
| 558 | mutex_unlock(&dpi->lock); | 557 | mutex_unlock(&dpi->lock); |
| 559 | } | 558 | } |
| 560 | 559 | ||
| 561 | static int dpi_verify_dsi_pll(struct dss_pll *pll) | 560 | static int dpi_verify_pll(struct dss_pll *pll) |
| 562 | { | 561 | { |
| 563 | int r; | 562 | int r; |
| 564 | 563 | ||
| @@ -602,16 +601,14 @@ static void dpi_init_pll(struct dpi_data *dpi) | |||
| 602 | if (dpi->pll) | 601 | if (dpi->pll) |
| 603 | return; | 602 | return; |
| 604 | 603 | ||
| 605 | pll = dpi_get_pll(dpi->output.dispc_channel); | 604 | dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel); |
| 605 | |||
| 606 | pll = dss_pll_find_by_src(dpi->clk_src); | ||
| 606 | if (!pll) | 607 | if (!pll) |
| 607 | return; | 608 | return; |
| 608 | 609 | ||
| 609 | /* On DRA7 we need to set a mux to use the PLL */ | 610 | if (dpi_verify_pll(pll)) { |
| 610 | if (omapdss_get_version() == OMAPDSS_VER_DRA7xx) | 611 | DSSWARN("PLL not operational\n"); |
| 611 | dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel); | ||
| 612 | |||
| 613 | if (dpi_verify_dsi_pll(pll)) { | ||
| 614 | DSSWARN("DSI PLL not operational\n"); | ||
| 615 | return; | 612 | return; |
| 616 | } | 613 | } |
| 617 | 614 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 9ed8272e54ae..0a634438ba3b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c | |||
| @@ -1262,7 +1262,7 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev) | |||
| 1262 | unsigned long r; | 1262 | unsigned long r; |
| 1263 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1263 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 1264 | 1264 | ||
| 1265 | if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) { | 1265 | if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) { |
| 1266 | /* DSI FCLK source is DSS_CLK_FCK */ | 1266 | /* DSI FCLK source is DSS_CLK_FCK */ |
| 1267 | r = clk_get_rate(dsi->dss_clk); | 1267 | r = clk_get_rate(dsi->dss_clk); |
| 1268 | } else { | 1268 | } else { |
| @@ -1475,7 +1475,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
| 1475 | { | 1475 | { |
| 1476 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1476 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 1477 | struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; | 1477 | struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; |
| 1478 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; | 1478 | enum dss_clk_source dispc_clk_src, dsi_clk_src; |
| 1479 | int dsi_module = dsi->module_id; | 1479 | int dsi_module = dsi->module_id; |
| 1480 | struct dss_pll *pll = &dsi->pll; | 1480 | struct dss_pll *pll = &dsi->pll; |
| 1481 | 1481 | ||
| @@ -1495,28 +1495,27 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
| 1495 | cinfo->clkdco, cinfo->m); | 1495 | cinfo->clkdco, cinfo->m); |
| 1496 | 1496 | ||
| 1497 | seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n", | 1497 | seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n", |
| 1498 | dss_feat_get_clk_source_name(dsi_module == 0 ? | 1498 | dss_get_clk_source_name(dsi_module == 0 ? |
| 1499 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : | 1499 | DSS_CLK_SRC_PLL1_1 : |
| 1500 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), | 1500 | DSS_CLK_SRC_PLL2_1), |
| 1501 | cinfo->clkout[HSDIV_DISPC], | 1501 | cinfo->clkout[HSDIV_DISPC], |
| 1502 | cinfo->mX[HSDIV_DISPC], | 1502 | cinfo->mX[HSDIV_DISPC], |
| 1503 | dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? | 1503 | dispc_clk_src == DSS_CLK_SRC_FCK ? |
| 1504 | "off" : "on"); | 1504 | "off" : "on"); |
| 1505 | 1505 | ||
| 1506 | seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n", | 1506 | seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n", |
| 1507 | dss_feat_get_clk_source_name(dsi_module == 0 ? | 1507 | dss_get_clk_source_name(dsi_module == 0 ? |
| 1508 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : | 1508 | DSS_CLK_SRC_PLL1_2 : |
| 1509 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), | 1509 | DSS_CLK_SRC_PLL2_2), |
| 1510 | cinfo->clkout[HSDIV_DSI], | 1510 | cinfo->clkout[HSDIV_DSI], |
| 1511 | cinfo->mX[HSDIV_DSI], | 1511 | cinfo->mX[HSDIV_DSI], |
| 1512 | dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? | 1512 | dsi_clk_src == DSS_CLK_SRC_FCK ? |
| 1513 | "off" : "on"); | 1513 | "off" : "on"); |
| 1514 | 1514 | ||
| 1515 | seq_printf(s, "- DSI%d -\n", dsi_module + 1); | 1515 | seq_printf(s, "- DSI%d -\n", dsi_module + 1); |
| 1516 | 1516 | ||
| 1517 | seq_printf(s, "dsi fclk source = %s (%s)\n", | 1517 | seq_printf(s, "dsi fclk source = %s\n", |
| 1518 | dss_get_generic_clk_source_name(dsi_clk_src), | 1518 | dss_get_clk_source_name(dsi_clk_src)); |
| 1519 | dss_feat_get_clk_source_name(dsi_clk_src)); | ||
| 1520 | 1519 | ||
| 1521 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); | 1520 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); |
| 1522 | 1521 | ||
| @@ -4102,8 +4101,8 @@ static int dsi_display_init_dispc(struct platform_device *dsidev, | |||
| 4102 | int r; | 4101 | int r; |
| 4103 | 4102 | ||
| 4104 | dss_select_lcd_clk_source(channel, dsi->module_id == 0 ? | 4103 | dss_select_lcd_clk_source(channel, dsi->module_id == 0 ? |
| 4105 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : | 4104 | DSS_CLK_SRC_PLL1_1 : |
| 4106 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC); | 4105 | DSS_CLK_SRC_PLL2_1); |
| 4107 | 4106 | ||
| 4108 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { | 4107 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { |
| 4109 | r = dss_mgr_register_framedone_handler(channel, | 4108 | r = dss_mgr_register_framedone_handler(channel, |
| @@ -4150,7 +4149,7 @@ err1: | |||
| 4150 | dss_mgr_unregister_framedone_handler(channel, | 4149 | dss_mgr_unregister_framedone_handler(channel, |
| 4151 | dsi_framedone_irq_callback, dsidev); | 4150 | dsi_framedone_irq_callback, dsidev); |
| 4152 | err: | 4151 | err: |
| 4153 | dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); | 4152 | dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); |
| 4154 | return r; | 4153 | return r; |
| 4155 | } | 4154 | } |
| 4156 | 4155 | ||
| @@ -4163,7 +4162,7 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev, | |||
| 4163 | dss_mgr_unregister_framedone_handler(channel, | 4162 | dss_mgr_unregister_framedone_handler(channel, |
| 4164 | dsi_framedone_irq_callback, dsidev); | 4163 | dsi_framedone_irq_callback, dsidev); |
| 4165 | 4164 | ||
| 4166 | dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); | 4165 | dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); |
| 4167 | } | 4166 | } |
| 4168 | 4167 | ||
| 4169 | static int dsi_configure_dsi_clocks(struct platform_device *dsidev) | 4168 | static int dsi_configure_dsi_clocks(struct platform_device *dsidev) |
| @@ -4197,8 +4196,8 @@ static int dsi_display_init_dsi(struct platform_device *dsidev) | |||
| 4197 | goto err1; | 4196 | goto err1; |
| 4198 | 4197 | ||
| 4199 | dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ? | 4198 | dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ? |
| 4200 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : | 4199 | DSS_CLK_SRC_PLL1_2 : |
| 4201 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI); | 4200 | DSS_CLK_SRC_PLL2_2); |
| 4202 | 4201 | ||
| 4203 | DSSDBG("PLL OK\n"); | 4202 | DSSDBG("PLL OK\n"); |
| 4204 | 4203 | ||
| @@ -4230,7 +4229,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev) | |||
| 4230 | err3: | 4229 | err3: |
| 4231 | dsi_cio_uninit(dsidev); | 4230 | dsi_cio_uninit(dsidev); |
| 4232 | err2: | 4231 | err2: |
| 4233 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4232 | dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK); |
| 4234 | err1: | 4233 | err1: |
| 4235 | dss_pll_disable(&dsi->pll); | 4234 | dss_pll_disable(&dsi->pll); |
| 4236 | err0: | 4235 | err0: |
| @@ -4252,7 +4251,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev, | |||
| 4252 | dsi_vc_enable(dsidev, 2, 0); | 4251 | dsi_vc_enable(dsidev, 2, 0); |
| 4253 | dsi_vc_enable(dsidev, 3, 0); | 4252 | dsi_vc_enable(dsidev, 3, 0); |
| 4254 | 4253 | ||
| 4255 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4254 | dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK); |
| 4256 | dsi_cio_uninit(dsidev); | 4255 | dsi_cio_uninit(dsidev); |
| 4257 | dsi_pll_uninit(dsidev, disconnect_lanes); | 4256 | dsi_pll_uninit(dsidev, disconnect_lanes); |
| 4258 | } | 4257 | } |
| @@ -4453,7 +4452,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint, | |||
| 4453 | ctx->dsi_cinfo.fint = fint; | 4452 | ctx->dsi_cinfo.fint = fint; |
| 4454 | ctx->dsi_cinfo.clkdco = clkdco; | 4453 | ctx->dsi_cinfo.clkdco = clkdco; |
| 4455 | 4454 | ||
| 4456 | return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, | 4455 | return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min, |
| 4457 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), | 4456 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), |
| 4458 | dsi_cm_calc_hsdiv_cb, ctx); | 4457 | dsi_cm_calc_hsdiv_cb, ctx); |
| 4459 | } | 4458 | } |
| @@ -4492,7 +4491,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi, | |||
| 4492 | pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); | 4491 | pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); |
| 4493 | pll_max = cfg->hs_clk_max * 4; | 4492 | pll_max = cfg->hs_clk_max * 4; |
| 4494 | 4493 | ||
| 4495 | return dss_pll_calc(ctx->pll, clkin, | 4494 | return dss_pll_calc_a(ctx->pll, clkin, |
| 4496 | pll_min, pll_max, | 4495 | pll_min, pll_max, |
| 4497 | dsi_cm_calc_pll_cb, ctx); | 4496 | dsi_cm_calc_pll_cb, ctx); |
| 4498 | } | 4497 | } |
| @@ -4751,7 +4750,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint, | |||
| 4751 | ctx->dsi_cinfo.fint = fint; | 4750 | ctx->dsi_cinfo.fint = fint; |
| 4752 | ctx->dsi_cinfo.clkdco = clkdco; | 4751 | ctx->dsi_cinfo.clkdco = clkdco; |
| 4753 | 4752 | ||
| 4754 | return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, | 4753 | return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min, |
| 4755 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), | 4754 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), |
| 4756 | dsi_vm_calc_hsdiv_cb, ctx); | 4755 | dsi_vm_calc_hsdiv_cb, ctx); |
| 4757 | } | 4756 | } |
| @@ -4793,7 +4792,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi, | |||
| 4793 | pll_max = byteclk_max * 4 * 4; | 4792 | pll_max = byteclk_max * 4 * 4; |
| 4794 | } | 4793 | } |
| 4795 | 4794 | ||
| 4796 | return dss_pll_calc(ctx->pll, clkin, | 4795 | return dss_pll_calc_a(ctx->pll, clkin, |
| 4797 | pll_min, pll_max, | 4796 | pll_min, pll_max, |
| 4798 | dsi_vm_calc_pll_cb, ctx); | 4797 | dsi_vm_calc_pll_cb, ctx); |
| 4799 | } | 4798 | } |
| @@ -5139,6 +5138,8 @@ static const struct dss_pll_ops dsi_pll_ops = { | |||
| 5139 | }; | 5138 | }; |
| 5140 | 5139 | ||
| 5141 | static const struct dss_pll_hw dss_omap3_dsi_pll_hw = { | 5140 | static const struct dss_pll_hw dss_omap3_dsi_pll_hw = { |
| 5141 | .type = DSS_PLL_TYPE_A, | ||
| 5142 | |||
| 5142 | .n_max = (1 << 7) - 1, | 5143 | .n_max = (1 << 7) - 1, |
| 5143 | .m_max = (1 << 11) - 1, | 5144 | .m_max = (1 << 11) - 1, |
| 5144 | .mX_max = (1 << 4) - 1, | 5145 | .mX_max = (1 << 4) - 1, |
| @@ -5164,6 +5165,8 @@ static const struct dss_pll_hw dss_omap3_dsi_pll_hw = { | |||
| 5164 | }; | 5165 | }; |
| 5165 | 5166 | ||
| 5166 | static const struct dss_pll_hw dss_omap4_dsi_pll_hw = { | 5167 | static const struct dss_pll_hw dss_omap4_dsi_pll_hw = { |
| 5168 | .type = DSS_PLL_TYPE_A, | ||
| 5169 | |||
| 5167 | .n_max = (1 << 8) - 1, | 5170 | .n_max = (1 << 8) - 1, |
| 5168 | .m_max = (1 << 12) - 1, | 5171 | .m_max = (1 << 12) - 1, |
| 5169 | .mX_max = (1 << 5) - 1, | 5172 | .mX_max = (1 << 5) - 1, |
| @@ -5189,6 +5192,8 @@ static const struct dss_pll_hw dss_omap4_dsi_pll_hw = { | |||
| 5189 | }; | 5192 | }; |
| 5190 | 5193 | ||
| 5191 | static const struct dss_pll_hw dss_omap5_dsi_pll_hw = { | 5194 | static const struct dss_pll_hw dss_omap5_dsi_pll_hw = { |
| 5195 | .type = DSS_PLL_TYPE_A, | ||
| 5196 | |||
| 5192 | .n_max = (1 << 8) - 1, | 5197 | .n_max = (1 << 8) - 1, |
| 5193 | .m_max = (1 << 12) - 1, | 5198 | .m_max = (1 << 12) - 1, |
| 5194 | .mX_max = (1 << 5) - 1, | 5199 | .mX_max = (1 << 5) - 1, |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 3303cfad4838..6ac54c35227e 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c | |||
| @@ -76,6 +76,8 @@ struct dss_features { | |||
| 76 | const enum omap_display_type *ports; | 76 | const enum omap_display_type *ports; |
| 77 | int num_ports; | 77 | int num_ports; |
| 78 | int (*dpi_select_source)(int port, enum omap_channel channel); | 78 | int (*dpi_select_source)(int port, enum omap_channel channel); |
| 79 | int (*select_lcd_source)(enum omap_channel channel, | ||
| 80 | enum dss_clk_source clk_src); | ||
| 79 | }; | 81 | }; |
| 80 | 82 | ||
| 81 | static struct { | 83 | static struct { |
| @@ -92,9 +94,9 @@ static struct { | |||
| 92 | unsigned long cache_prate; | 94 | unsigned long cache_prate; |
| 93 | struct dispc_clock_info cache_dispc_cinfo; | 95 | struct dispc_clock_info cache_dispc_cinfo; |
| 94 | 96 | ||
| 95 | enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI]; | 97 | enum dss_clk_source dsi_clk_source[MAX_NUM_DSI]; |
| 96 | enum omap_dss_clk_source dispc_clk_source; | 98 | enum dss_clk_source dispc_clk_source; |
| 97 | enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; | 99 | enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; |
| 98 | 100 | ||
| 99 | bool ctx_valid; | 101 | bool ctx_valid; |
| 100 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; | 102 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; |
| @@ -106,11 +108,14 @@ static struct { | |||
| 106 | } dss; | 108 | } dss; |
| 107 | 109 | ||
| 108 | static const char * const dss_generic_clk_source_names[] = { | 110 | static const char * const dss_generic_clk_source_names[] = { |
| 109 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", | 111 | [DSS_CLK_SRC_FCK] = "FCK", |
| 110 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", | 112 | [DSS_CLK_SRC_PLL1_1] = "PLL1:1", |
| 111 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", | 113 | [DSS_CLK_SRC_PLL1_2] = "PLL1:2", |
| 112 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC", | 114 | [DSS_CLK_SRC_PLL1_3] = "PLL1:3", |
| 113 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", | 115 | [DSS_CLK_SRC_PLL2_1] = "PLL2:1", |
| 116 | [DSS_CLK_SRC_PLL2_2] = "PLL2:2", | ||
| 117 | [DSS_CLK_SRC_PLL2_3] = "PLL2:3", | ||
| 118 | [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL", | ||
| 114 | }; | 119 | }; |
| 115 | 120 | ||
| 116 | static bool dss_initialized; | 121 | static bool dss_initialized; |
| @@ -203,68 +208,70 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable) | |||
| 203 | 1 << shift, val << shift); | 208 | 1 << shift, val << shift); |
| 204 | } | 209 | } |
| 205 | 210 | ||
| 206 | void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id, | 211 | static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, |
| 207 | enum omap_channel channel) | 212 | enum omap_channel channel) |
| 208 | { | 213 | { |
| 209 | unsigned shift, val; | 214 | unsigned shift, val; |
| 210 | 215 | ||
| 211 | if (!dss.syscon_pll_ctrl) | 216 | if (!dss.syscon_pll_ctrl) |
| 212 | return; | 217 | return -EINVAL; |
| 213 | 218 | ||
| 214 | switch (channel) { | 219 | switch (channel) { |
| 215 | case OMAP_DSS_CHANNEL_LCD: | 220 | case OMAP_DSS_CHANNEL_LCD: |
| 216 | shift = 3; | 221 | shift = 3; |
| 217 | 222 | ||
| 218 | switch (pll_id) { | 223 | switch (clk_src) { |
| 219 | case DSS_PLL_VIDEO1: | 224 | case DSS_CLK_SRC_PLL1_1: |
| 220 | val = 0; break; | 225 | val = 0; break; |
| 221 | case DSS_PLL_HDMI: | 226 | case DSS_CLK_SRC_HDMI_PLL: |
| 222 | val = 1; break; | 227 | val = 1; break; |
| 223 | default: | 228 | default: |
| 224 | DSSERR("error in PLL mux config for LCD\n"); | 229 | DSSERR("error in PLL mux config for LCD\n"); |
| 225 | return; | 230 | return -EINVAL; |
| 226 | } | 231 | } |
| 227 | 232 | ||
| 228 | break; | 233 | break; |
| 229 | case OMAP_DSS_CHANNEL_LCD2: | 234 | case OMAP_DSS_CHANNEL_LCD2: |
| 230 | shift = 5; | 235 | shift = 5; |
| 231 | 236 | ||
| 232 | switch (pll_id) { | 237 | switch (clk_src) { |
| 233 | case DSS_PLL_VIDEO1: | 238 | case DSS_CLK_SRC_PLL1_3: |
| 234 | val = 0; break; | 239 | val = 0; break; |
| 235 | case DSS_PLL_VIDEO2: | 240 | case DSS_CLK_SRC_PLL2_3: |
| 236 | val = 1; break; | 241 | val = 1; break; |
| 237 | case DSS_PLL_HDMI: | 242 | case DSS_CLK_SRC_HDMI_PLL: |
| 238 | val = 2; break; | 243 | val = 2; break; |
| 239 | default: | 244 | default: |
| 240 | DSSERR("error in PLL mux config for LCD2\n"); | 245 | DSSERR("error in PLL mux config for LCD2\n"); |
| 241 | return; | 246 | return -EINVAL; |
| 242 | } | 247 | } |
| 243 | 248 | ||
| 244 | break; | 249 | break; |
| 245 | case OMAP_DSS_CHANNEL_LCD3: | 250 | case OMAP_DSS_CHANNEL_LCD3: |
| 246 | shift = 7; | 251 | shift = 7; |
| 247 | 252 | ||
| 248 | switch (pll_id) { | 253 | switch (clk_src) { |
| 249 | case DSS_PLL_VIDEO1: | 254 | case DSS_CLK_SRC_PLL2_1: |
| 250 | val = 1; break; | ||
| 251 | case DSS_PLL_VIDEO2: | ||
| 252 | val = 0; break; | 255 | val = 0; break; |
| 253 | case DSS_PLL_HDMI: | 256 | case DSS_CLK_SRC_PLL1_3: |
| 257 | val = 1; break; | ||
| 258 | case DSS_CLK_SRC_HDMI_PLL: | ||
| 254 | val = 2; break; | 259 | val = 2; break; |
| 255 | default: | 260 | default: |
| 256 | DSSERR("error in PLL mux config for LCD3\n"); | 261 | DSSERR("error in PLL mux config for LCD3\n"); |
| 257 | return; | 262 | return -EINVAL; |
| 258 | } | 263 | } |
| 259 | 264 | ||
| 260 | break; | 265 | break; |
| 261 | default: | 266 | default: |
| 262 | DSSERR("error in PLL mux config\n"); | 267 | DSSERR("error in PLL mux config\n"); |
| 263 | return; | 268 | return -EINVAL; |
| 264 | } | 269 | } |
| 265 | 270 | ||
| 266 | regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, | 271 | regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, |
| 267 | 0x3 << shift, val << shift); | 272 | 0x3 << shift, val << shift); |
| 273 | |||
| 274 | return 0; | ||
| 268 | } | 275 | } |
| 269 | 276 | ||
| 270 | void dss_sdi_init(int datapairs) | 277 | void dss_sdi_init(int datapairs) |
| @@ -354,14 +361,14 @@ void dss_sdi_disable(void) | |||
| 354 | REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ | 361 | REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ |
| 355 | } | 362 | } |
| 356 | 363 | ||
| 357 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) | 364 | const char *dss_get_clk_source_name(enum dss_clk_source clk_src) |
| 358 | { | 365 | { |
| 359 | return dss_generic_clk_source_names[clk_src]; | 366 | return dss_generic_clk_source_names[clk_src]; |
| 360 | } | 367 | } |
| 361 | 368 | ||
| 362 | void dss_dump_clocks(struct seq_file *s) | 369 | void dss_dump_clocks(struct seq_file *s) |
| 363 | { | 370 | { |
| 364 | const char *fclk_name, *fclk_real_name; | 371 | const char *fclk_name; |
| 365 | unsigned long fclk_rate; | 372 | unsigned long fclk_rate; |
| 366 | 373 | ||
| 367 | if (dss_runtime_get()) | 374 | if (dss_runtime_get()) |
| @@ -369,12 +376,11 @@ void dss_dump_clocks(struct seq_file *s) | |||
| 369 | 376 | ||
| 370 | seq_printf(s, "- DSS -\n"); | 377 | seq_printf(s, "- DSS -\n"); |
| 371 | 378 | ||
| 372 | fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK); | 379 | fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK); |
| 373 | fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK); | ||
| 374 | fclk_rate = clk_get_rate(dss.dss_clk); | 380 | fclk_rate = clk_get_rate(dss.dss_clk); |
| 375 | 381 | ||
| 376 | seq_printf(s, "%s (%s) = %lu\n", | 382 | seq_printf(s, "%s = %lu\n", |
| 377 | fclk_name, fclk_real_name, | 383 | fclk_name, |
| 378 | fclk_rate); | 384 | fclk_rate); |
| 379 | 385 | ||
| 380 | dss_runtime_put(); | 386 | dss_runtime_put(); |
| @@ -403,19 +409,42 @@ static void dss_dump_regs(struct seq_file *s) | |||
| 403 | #undef DUMPREG | 409 | #undef DUMPREG |
| 404 | } | 410 | } |
| 405 | 411 | ||
| 406 | static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) | 412 | static int dss_get_channel_index(enum omap_channel channel) |
| 413 | { | ||
| 414 | switch (channel) { | ||
| 415 | case OMAP_DSS_CHANNEL_LCD: | ||
| 416 | return 0; | ||
| 417 | case OMAP_DSS_CHANNEL_LCD2: | ||
| 418 | return 1; | ||
| 419 | case OMAP_DSS_CHANNEL_LCD3: | ||
| 420 | return 2; | ||
| 421 | default: | ||
| 422 | WARN_ON(1); | ||
| 423 | return 0; | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | static void dss_select_dispc_clk_source(enum dss_clk_source clk_src) | ||
| 407 | { | 428 | { |
| 408 | int b; | 429 | int b; |
| 409 | u8 start, end; | 430 | u8 start, end; |
| 410 | 431 | ||
| 432 | /* | ||
| 433 | * We always use PRCM clock as the DISPC func clock, except on DSS3, | ||
| 434 | * where we don't have separate DISPC and LCD clock sources. | ||
| 435 | */ | ||
| 436 | if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) && | ||
| 437 | clk_src != DSS_CLK_SRC_FCK)) | ||
| 438 | return; | ||
| 439 | |||
| 411 | switch (clk_src) { | 440 | switch (clk_src) { |
| 412 | case OMAP_DSS_CLK_SRC_FCK: | 441 | case DSS_CLK_SRC_FCK: |
| 413 | b = 0; | 442 | b = 0; |
| 414 | break; | 443 | break; |
| 415 | case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: | 444 | case DSS_CLK_SRC_PLL1_1: |
| 416 | b = 1; | 445 | b = 1; |
| 417 | break; | 446 | break; |
| 418 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: | 447 | case DSS_CLK_SRC_PLL2_1: |
| 419 | b = 2; | 448 | b = 2; |
| 420 | break; | 449 | break; |
| 421 | default: | 450 | default: |
| @@ -431,19 +460,19 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) | |||
| 431 | } | 460 | } |
| 432 | 461 | ||
| 433 | void dss_select_dsi_clk_source(int dsi_module, | 462 | void dss_select_dsi_clk_source(int dsi_module, |
| 434 | enum omap_dss_clk_source clk_src) | 463 | enum dss_clk_source clk_src) |
| 435 | { | 464 | { |
| 436 | int b, pos; | 465 | int b, pos; |
| 437 | 466 | ||
| 438 | switch (clk_src) { | 467 | switch (clk_src) { |
| 439 | case OMAP_DSS_CLK_SRC_FCK: | 468 | case DSS_CLK_SRC_FCK: |
| 440 | b = 0; | 469 | b = 0; |
| 441 | break; | 470 | break; |
| 442 | case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: | 471 | case DSS_CLK_SRC_PLL1_2: |
| 443 | BUG_ON(dsi_module != 0); | 472 | BUG_ON(dsi_module != 0); |
| 444 | b = 1; | 473 | b = 1; |
| 445 | break; | 474 | break; |
| 446 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI: | 475 | case DSS_CLK_SRC_PLL2_2: |
| 447 | BUG_ON(dsi_module != 1); | 476 | BUG_ON(dsi_module != 1); |
| 448 | b = 1; | 477 | b = 1; |
| 449 | break; | 478 | break; |
| @@ -458,59 +487,125 @@ void dss_select_dsi_clk_source(int dsi_module, | |||
| 458 | dss.dsi_clk_source[dsi_module] = clk_src; | 487 | dss.dsi_clk_source[dsi_module] = clk_src; |
| 459 | } | 488 | } |
| 460 | 489 | ||
| 490 | static int dss_lcd_clk_mux_dra7(enum omap_channel channel, | ||
| 491 | enum dss_clk_source clk_src) | ||
| 492 | { | ||
| 493 | const u8 ctrl_bits[] = { | ||
| 494 | [OMAP_DSS_CHANNEL_LCD] = 0, | ||
| 495 | [OMAP_DSS_CHANNEL_LCD2] = 12, | ||
| 496 | [OMAP_DSS_CHANNEL_LCD3] = 19, | ||
| 497 | }; | ||
| 498 | |||
| 499 | u8 ctrl_bit = ctrl_bits[channel]; | ||
| 500 | int r; | ||
| 501 | |||
| 502 | if (clk_src == DSS_CLK_SRC_FCK) { | ||
| 503 | /* LCDx_CLK_SWITCH */ | ||
| 504 | REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); | ||
| 505 | return -EINVAL; | ||
| 506 | } | ||
| 507 | |||
| 508 | r = dss_ctrl_pll_set_control_mux(clk_src, channel); | ||
| 509 | if (r) | ||
| 510 | return r; | ||
| 511 | |||
| 512 | REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); | ||
| 513 | |||
| 514 | return 0; | ||
| 515 | } | ||
| 516 | |||
| 517 | static int dss_lcd_clk_mux_omap5(enum omap_channel channel, | ||
| 518 | enum dss_clk_source clk_src) | ||
| 519 | { | ||
| 520 | const u8 ctrl_bits[] = { | ||
| 521 | [OMAP_DSS_CHANNEL_LCD] = 0, | ||
| 522 | [OMAP_DSS_CHANNEL_LCD2] = 12, | ||
| 523 | [OMAP_DSS_CHANNEL_LCD3] = 19, | ||
| 524 | }; | ||
| 525 | const enum dss_clk_source allowed_plls[] = { | ||
| 526 | [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1, | ||
| 527 | [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK, | ||
| 528 | [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1, | ||
| 529 | }; | ||
| 530 | |||
| 531 | u8 ctrl_bit = ctrl_bits[channel]; | ||
| 532 | |||
| 533 | if (clk_src == DSS_CLK_SRC_FCK) { | ||
| 534 | /* LCDx_CLK_SWITCH */ | ||
| 535 | REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); | ||
| 536 | return -EINVAL; | ||
| 537 | } | ||
| 538 | |||
| 539 | if (WARN_ON(allowed_plls[channel] != clk_src)) | ||
| 540 | return -EINVAL; | ||
| 541 | |||
| 542 | REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); | ||
| 543 | |||
| 544 | return 0; | ||
| 545 | } | ||
| 546 | |||
| 547 | static int dss_lcd_clk_mux_omap4(enum omap_channel channel, | ||
| 548 | enum dss_clk_source clk_src) | ||
| 549 | { | ||
| 550 | const u8 ctrl_bits[] = { | ||
| 551 | [OMAP_DSS_CHANNEL_LCD] = 0, | ||
| 552 | [OMAP_DSS_CHANNEL_LCD2] = 12, | ||
| 553 | }; | ||
| 554 | const enum dss_clk_source allowed_plls[] = { | ||
| 555 | [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1, | ||
| 556 | [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1, | ||
| 557 | }; | ||
| 558 | |||
| 559 | u8 ctrl_bit = ctrl_bits[channel]; | ||
| 560 | |||
| 561 | if (clk_src == DSS_CLK_SRC_FCK) { | ||
| 562 | /* LCDx_CLK_SWITCH */ | ||
| 563 | REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); | ||
| 564 | return 0; | ||
| 565 | } | ||
| 566 | |||
| 567 | if (WARN_ON(allowed_plls[channel] != clk_src)) | ||
| 568 | return -EINVAL; | ||
| 569 | |||
| 570 | REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); | ||
| 571 | |||
| 572 | return 0; | ||
| 573 | } | ||
| 574 | |||
| 461 | void dss_select_lcd_clk_source(enum omap_channel channel, | 575 | void dss_select_lcd_clk_source(enum omap_channel channel, |
| 462 | enum omap_dss_clk_source clk_src) | 576 | enum dss_clk_source clk_src) |
| 463 | { | 577 | { |
| 464 | int b, ix, pos; | 578 | int idx = dss_get_channel_index(channel); |
| 579 | int r; | ||
| 465 | 580 | ||
| 466 | if (!dss_has_feature(FEAT_LCD_CLK_SRC)) { | 581 | if (!dss_has_feature(FEAT_LCD_CLK_SRC)) { |
| 467 | dss_select_dispc_clk_source(clk_src); | 582 | dss_select_dispc_clk_source(clk_src); |
| 583 | dss.lcd_clk_source[idx] = clk_src; | ||
| 468 | return; | 584 | return; |
| 469 | } | 585 | } |
| 470 | 586 | ||
| 471 | switch (clk_src) { | 587 | r = dss.feat->select_lcd_source(channel, clk_src); |
| 472 | case OMAP_DSS_CLK_SRC_FCK: | 588 | if (r) |
| 473 | b = 0; | ||
| 474 | break; | ||
| 475 | case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: | ||
| 476 | BUG_ON(channel != OMAP_DSS_CHANNEL_LCD); | ||
| 477 | b = 1; | ||
| 478 | break; | ||
| 479 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: | ||
| 480 | BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 && | ||
| 481 | channel != OMAP_DSS_CHANNEL_LCD3); | ||
| 482 | b = 1; | ||
| 483 | break; | ||
| 484 | default: | ||
| 485 | BUG(); | ||
| 486 | return; | 589 | return; |
| 487 | } | ||
| 488 | |||
| 489 | pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : | ||
| 490 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19); | ||
| 491 | REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ | ||
| 492 | 590 | ||
| 493 | ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : | 591 | dss.lcd_clk_source[idx] = clk_src; |
| 494 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2); | ||
| 495 | dss.lcd_clk_source[ix] = clk_src; | ||
| 496 | } | 592 | } |
| 497 | 593 | ||
| 498 | enum omap_dss_clk_source dss_get_dispc_clk_source(void) | 594 | enum dss_clk_source dss_get_dispc_clk_source(void) |
| 499 | { | 595 | { |
| 500 | return dss.dispc_clk_source; | 596 | return dss.dispc_clk_source; |
| 501 | } | 597 | } |
| 502 | 598 | ||
| 503 | enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module) | 599 | enum dss_clk_source dss_get_dsi_clk_source(int dsi_module) |
| 504 | { | 600 | { |
| 505 | return dss.dsi_clk_source[dsi_module]; | 601 | return dss.dsi_clk_source[dsi_module]; |
| 506 | } | 602 | } |
| 507 | 603 | ||
| 508 | enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) | 604 | enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) |
| 509 | { | 605 | { |
| 510 | if (dss_has_feature(FEAT_LCD_CLK_SRC)) { | 606 | if (dss_has_feature(FEAT_LCD_CLK_SRC)) { |
| 511 | int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : | 607 | int idx = dss_get_channel_index(channel); |
| 512 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2); | 608 | return dss.lcd_clk_source[idx]; |
| 513 | return dss.lcd_clk_source[ix]; | ||
| 514 | } else { | 609 | } else { |
| 515 | /* LCD_CLK source is the same as DISPC_FCLK source for | 610 | /* LCD_CLK source is the same as DISPC_FCLK source for |
| 516 | * OMAP2 and OMAP3 */ | 611 | * OMAP2 and OMAP3 */ |
| @@ -859,6 +954,7 @@ static const struct dss_features omap44xx_dss_feats = { | |||
| 859 | .dpi_select_source = &dss_dpi_select_source_omap4, | 954 | .dpi_select_source = &dss_dpi_select_source_omap4, |
| 860 | .ports = omap2plus_ports, | 955 | .ports = omap2plus_ports, |
| 861 | .num_ports = ARRAY_SIZE(omap2plus_ports), | 956 | .num_ports = ARRAY_SIZE(omap2plus_ports), |
| 957 | .select_lcd_source = &dss_lcd_clk_mux_omap4, | ||
| 862 | }; | 958 | }; |
| 863 | 959 | ||
| 864 | static const struct dss_features omap54xx_dss_feats = { | 960 | static const struct dss_features omap54xx_dss_feats = { |
| @@ -868,6 +964,7 @@ static const struct dss_features omap54xx_dss_feats = { | |||
| 868 | .dpi_select_source = &dss_dpi_select_source_omap5, | 964 | .dpi_select_source = &dss_dpi_select_source_omap5, |
| 869 | .ports = omap2plus_ports, | 965 | .ports = omap2plus_ports, |
| 870 | .num_ports = ARRAY_SIZE(omap2plus_ports), | 966 | .num_ports = ARRAY_SIZE(omap2plus_ports), |
| 967 | .select_lcd_source = &dss_lcd_clk_mux_omap5, | ||
| 871 | }; | 968 | }; |
| 872 | 969 | ||
| 873 | static const struct dss_features am43xx_dss_feats = { | 970 | static const struct dss_features am43xx_dss_feats = { |
| @@ -886,6 +983,7 @@ static const struct dss_features dra7xx_dss_feats = { | |||
| 886 | .dpi_select_source = &dss_dpi_select_source_dra7xx, | 983 | .dpi_select_source = &dss_dpi_select_source_dra7xx, |
| 887 | .ports = dra7xx_ports, | 984 | .ports = dra7xx_ports, |
| 888 | .num_ports = ARRAY_SIZE(dra7xx_ports), | 985 | .num_ports = ARRAY_SIZE(dra7xx_ports), |
| 986 | .select_lcd_source = &dss_lcd_clk_mux_dra7, | ||
| 889 | }; | 987 | }; |
| 890 | 988 | ||
| 891 | static int dss_init_features(struct platform_device *pdev) | 989 | static int dss_init_features(struct platform_device *pdev) |
| @@ -1143,18 +1241,18 @@ static int dss_bind(struct device *dev) | |||
| 1143 | /* Select DPLL */ | 1241 | /* Select DPLL */ |
| 1144 | REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); | 1242 | REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); |
| 1145 | 1243 | ||
| 1146 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 1244 | dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); |
| 1147 | 1245 | ||
| 1148 | #ifdef CONFIG_OMAP2_DSS_VENC | 1246 | #ifdef CONFIG_OMAP2_DSS_VENC |
| 1149 | REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ | 1247 | REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ |
| 1150 | REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ | 1248 | REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ |
| 1151 | REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ | 1249 | REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ |
| 1152 | #endif | 1250 | #endif |
| 1153 | dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; | 1251 | dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK; |
| 1154 | dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; | 1252 | dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK; |
| 1155 | dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK; | 1253 | dss.dispc_clk_source = DSS_CLK_SRC_FCK; |
| 1156 | dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; | 1254 | dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; |
| 1157 | dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; | 1255 | dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; |
| 1158 | 1256 | ||
| 1159 | rev = dss_read_reg(DSS_REVISION); | 1257 | rev = dss_read_reg(DSS_REVISION); |
| 1160 | printk(KERN_INFO "OMAP DSS rev %d.%d\n", | 1258 | printk(KERN_INFO "OMAP DSS rev %d.%d\n", |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 38e6ab50142d..4fd06dc41cb3 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h | |||
| @@ -102,6 +102,20 @@ enum dss_writeback_channel { | |||
| 102 | DSS_WB_LCD3_MGR = 7, | 102 | DSS_WB_LCD3_MGR = 7, |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | enum dss_clk_source { | ||
| 106 | DSS_CLK_SRC_FCK = 0, | ||
| 107 | |||
| 108 | DSS_CLK_SRC_PLL1_1, | ||
| 109 | DSS_CLK_SRC_PLL1_2, | ||
| 110 | DSS_CLK_SRC_PLL1_3, | ||
| 111 | |||
| 112 | DSS_CLK_SRC_PLL2_1, | ||
| 113 | DSS_CLK_SRC_PLL2_2, | ||
| 114 | DSS_CLK_SRC_PLL2_3, | ||
| 115 | |||
| 116 | DSS_CLK_SRC_HDMI_PLL, | ||
| 117 | }; | ||
| 118 | |||
| 105 | enum dss_pll_id { | 119 | enum dss_pll_id { |
| 106 | DSS_PLL_DSI1, | 120 | DSS_PLL_DSI1, |
| 107 | DSS_PLL_DSI2, | 121 | DSS_PLL_DSI2, |
| @@ -114,6 +128,11 @@ struct dss_pll; | |||
| 114 | 128 | ||
| 115 | #define DSS_PLL_MAX_HSDIVS 4 | 129 | #define DSS_PLL_MAX_HSDIVS 4 |
| 116 | 130 | ||
| 131 | enum dss_pll_type { | ||
| 132 | DSS_PLL_TYPE_A, | ||
| 133 | DSS_PLL_TYPE_B, | ||
| 134 | }; | ||
| 135 | |||
| 117 | /* | 136 | /* |
| 118 | * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7. | 137 | * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7. |
| 119 | * Type-B PLLs: clkout[0] refers to m2. | 138 | * Type-B PLLs: clkout[0] refers to m2. |
| @@ -140,6 +159,8 @@ struct dss_pll_ops { | |||
| 140 | }; | 159 | }; |
| 141 | 160 | ||
| 142 | struct dss_pll_hw { | 161 | struct dss_pll_hw { |
| 162 | enum dss_pll_type type; | ||
| 163 | |||
| 143 | unsigned n_max; | 164 | unsigned n_max; |
| 144 | unsigned m_min; | 165 | unsigned m_min; |
| 145 | unsigned m_max; | 166 | unsigned m_max; |
| @@ -227,7 +248,7 @@ unsigned long dss_get_dispc_clk_rate(void); | |||
| 227 | int dss_dpi_select_source(int port, enum omap_channel channel); | 248 | int dss_dpi_select_source(int port, enum omap_channel channel); |
| 228 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 249 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
| 229 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | 250 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); |
| 230 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 251 | const char *dss_get_clk_source_name(enum dss_clk_source clk_src); |
| 231 | void dss_dump_clocks(struct seq_file *s); | 252 | void dss_dump_clocks(struct seq_file *s); |
| 232 | 253 | ||
| 233 | /* DSS VIDEO PLL */ | 254 | /* DSS VIDEO PLL */ |
| @@ -244,20 +265,18 @@ void dss_debug_dump_clocks(struct seq_file *s); | |||
| 244 | #endif | 265 | #endif |
| 245 | 266 | ||
| 246 | void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); | 267 | void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); |
| 247 | void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id, | ||
| 248 | enum omap_channel channel); | ||
| 249 | 268 | ||
| 250 | void dss_sdi_init(int datapairs); | 269 | void dss_sdi_init(int datapairs); |
| 251 | int dss_sdi_enable(void); | 270 | int dss_sdi_enable(void); |
| 252 | void dss_sdi_disable(void); | 271 | void dss_sdi_disable(void); |
| 253 | 272 | ||
| 254 | void dss_select_dsi_clk_source(int dsi_module, | 273 | void dss_select_dsi_clk_source(int dsi_module, |
| 255 | enum omap_dss_clk_source clk_src); | 274 | enum dss_clk_source clk_src); |
| 256 | void dss_select_lcd_clk_source(enum omap_channel channel, | 275 | void dss_select_lcd_clk_source(enum omap_channel channel, |
| 257 | enum omap_dss_clk_source clk_src); | 276 | enum dss_clk_source clk_src); |
| 258 | enum omap_dss_clk_source dss_get_dispc_clk_source(void); | 277 | enum dss_clk_source dss_get_dispc_clk_source(void); |
| 259 | enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module); | 278 | enum dss_clk_source dss_get_dsi_clk_source(int dsi_module); |
| 260 | enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); | 279 | enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); |
| 261 | 280 | ||
| 262 | void dss_set_venc_output(enum omap_dss_venc_type type); | 281 | void dss_set_venc_output(enum omap_dss_venc_type type); |
| 263 | void dss_set_dac_pwrdn_bgz(bool enable); | 282 | void dss_set_dac_pwrdn_bgz(bool enable); |
| @@ -409,17 +428,23 @@ typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc, | |||
| 409 | int dss_pll_register(struct dss_pll *pll); | 428 | int dss_pll_register(struct dss_pll *pll); |
| 410 | void dss_pll_unregister(struct dss_pll *pll); | 429 | void dss_pll_unregister(struct dss_pll *pll); |
| 411 | struct dss_pll *dss_pll_find(const char *name); | 430 | struct dss_pll *dss_pll_find(const char *name); |
| 431 | struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src); | ||
| 432 | unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src); | ||
| 412 | int dss_pll_enable(struct dss_pll *pll); | 433 | int dss_pll_enable(struct dss_pll *pll); |
| 413 | void dss_pll_disable(struct dss_pll *pll); | 434 | void dss_pll_disable(struct dss_pll *pll); |
| 414 | int dss_pll_set_config(struct dss_pll *pll, | 435 | int dss_pll_set_config(struct dss_pll *pll, |
| 415 | const struct dss_pll_clock_info *cinfo); | 436 | const struct dss_pll_clock_info *cinfo); |
| 416 | 437 | ||
| 417 | bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, | 438 | bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco, |
| 418 | unsigned long out_min, unsigned long out_max, | 439 | unsigned long out_min, unsigned long out_max, |
| 419 | dss_hsdiv_calc_func func, void *data); | 440 | dss_hsdiv_calc_func func, void *data); |
| 420 | bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, | 441 | bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin, |
| 421 | unsigned long pll_min, unsigned long pll_max, | 442 | unsigned long pll_min, unsigned long pll_max, |
| 422 | dss_pll_calc_func func, void *data); | 443 | dss_pll_calc_func func, void *data); |
| 444 | |||
| 445 | bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin, | ||
| 446 | unsigned long target_clkout, struct dss_pll_clock_info *cinfo); | ||
| 447 | |||
| 423 | int dss_pll_write_config_type_a(struct dss_pll *pll, | 448 | int dss_pll_write_config_type_a(struct dss_pll *pll, |
| 424 | const struct dss_pll_clock_info *cinfo); | 449 | const struct dss_pll_clock_info *cinfo); |
| 425 | int dss_pll_write_config_type_b(struct dss_pll *pll, | 450 | int dss_pll_write_config_type_b(struct dss_pll *pll, |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c index c886a2927f73..c025d44ae164 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss_features.c +++ b/drivers/gpu/drm/omapdrm/dss/dss_features.c | |||
| @@ -50,7 +50,6 @@ struct omap_dss_features { | |||
| 50 | const enum omap_dss_output_id *supported_outputs; | 50 | const enum omap_dss_output_id *supported_outputs; |
| 51 | const enum omap_color_mode *supported_color_modes; | 51 | const enum omap_color_mode *supported_color_modes; |
| 52 | const enum omap_overlay_caps *overlay_caps; | 52 | const enum omap_overlay_caps *overlay_caps; |
| 53 | const char * const *clksrc_names; | ||
| 54 | const struct dss_param_range *dss_params; | 53 | const struct dss_param_range *dss_params; |
| 55 | 54 | ||
| 56 | const enum omap_dss_rotation_type supported_rotation_types; | 55 | const enum omap_dss_rotation_type supported_rotation_types; |
| @@ -389,34 +388,6 @@ static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { | |||
| 389 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | 388 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, |
| 390 | }; | 389 | }; |
| 391 | 390 | ||
| 392 | static const char * const omap2_dss_clk_source_names[] = { | ||
| 393 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A", | ||
| 394 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A", | ||
| 395 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1", | ||
| 396 | }; | ||
| 397 | |||
| 398 | static const char * const omap3_dss_clk_source_names[] = { | ||
| 399 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK", | ||
| 400 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK", | ||
| 401 | [OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK", | ||
| 402 | }; | ||
| 403 | |||
| 404 | static const char * const omap4_dss_clk_source_names[] = { | ||
| 405 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1", | ||
| 406 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2", | ||
| 407 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK", | ||
| 408 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1", | ||
| 409 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", | ||
| 410 | }; | ||
| 411 | |||
| 412 | static const char * const omap5_dss_clk_source_names[] = { | ||
| 413 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1", | ||
| 414 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2", | ||
| 415 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK", | ||
| 416 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1", | ||
| 417 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2", | ||
| 418 | }; | ||
| 419 | |||
| 420 | static const struct dss_param_range omap2_dss_param_range[] = { | 391 | static const struct dss_param_range omap2_dss_param_range[] = { |
| 421 | [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, | 392 | [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, |
| 422 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, | 393 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, |
| @@ -631,7 +602,6 @@ static const struct omap_dss_features omap2_dss_features = { | |||
| 631 | .supported_outputs = omap2_dss_supported_outputs, | 602 | .supported_outputs = omap2_dss_supported_outputs, |
| 632 | .supported_color_modes = omap2_dss_supported_color_modes, | 603 | .supported_color_modes = omap2_dss_supported_color_modes, |
| 633 | .overlay_caps = omap2_dss_overlay_caps, | 604 | .overlay_caps = omap2_dss_overlay_caps, |
| 634 | .clksrc_names = omap2_dss_clk_source_names, | ||
| 635 | .dss_params = omap2_dss_param_range, | 605 | .dss_params = omap2_dss_param_range, |
| 636 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | 606 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, |
| 637 | .buffer_size_unit = 1, | 607 | .buffer_size_unit = 1, |
| @@ -652,7 +622,6 @@ static const struct omap_dss_features omap3430_dss_features = { | |||
| 652 | .supported_outputs = omap3430_dss_supported_outputs, | 622 | .supported_outputs = omap3430_dss_supported_outputs, |
| 653 | .supported_color_modes = omap3_dss_supported_color_modes, | 623 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 654 | .overlay_caps = omap3430_dss_overlay_caps, | 624 | .overlay_caps = omap3430_dss_overlay_caps, |
| 655 | .clksrc_names = omap3_dss_clk_source_names, | ||
| 656 | .dss_params = omap3_dss_param_range, | 625 | .dss_params = omap3_dss_param_range, |
| 657 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | 626 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, |
| 658 | .buffer_size_unit = 1, | 627 | .buffer_size_unit = 1, |
| @@ -676,7 +645,6 @@ static const struct omap_dss_features am35xx_dss_features = { | |||
| 676 | .supported_outputs = omap3430_dss_supported_outputs, | 645 | .supported_outputs = omap3430_dss_supported_outputs, |
| 677 | .supported_color_modes = omap3_dss_supported_color_modes, | 646 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 678 | .overlay_caps = omap3430_dss_overlay_caps, | 647 | .overlay_caps = omap3430_dss_overlay_caps, |
| 679 | .clksrc_names = omap3_dss_clk_source_names, | ||
| 680 | .dss_params = omap3_dss_param_range, | 648 | .dss_params = omap3_dss_param_range, |
| 681 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | 649 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, |
| 682 | .buffer_size_unit = 1, | 650 | .buffer_size_unit = 1, |
| @@ -696,7 +664,6 @@ static const struct omap_dss_features am43xx_dss_features = { | |||
| 696 | .supported_outputs = am43xx_dss_supported_outputs, | 664 | .supported_outputs = am43xx_dss_supported_outputs, |
| 697 | .supported_color_modes = omap3_dss_supported_color_modes, | 665 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 698 | .overlay_caps = omap3430_dss_overlay_caps, | 666 | .overlay_caps = omap3430_dss_overlay_caps, |
| 699 | .clksrc_names = omap2_dss_clk_source_names, | ||
| 700 | .dss_params = am43xx_dss_param_range, | 667 | .dss_params = am43xx_dss_param_range, |
| 701 | .supported_rotation_types = OMAP_DSS_ROT_DMA, | 668 | .supported_rotation_types = OMAP_DSS_ROT_DMA, |
| 702 | .buffer_size_unit = 1, | 669 | .buffer_size_unit = 1, |
| @@ -716,7 +683,6 @@ static const struct omap_dss_features omap3630_dss_features = { | |||
| 716 | .supported_outputs = omap3630_dss_supported_outputs, | 683 | .supported_outputs = omap3630_dss_supported_outputs, |
| 717 | .supported_color_modes = omap3_dss_supported_color_modes, | 684 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 718 | .overlay_caps = omap3630_dss_overlay_caps, | 685 | .overlay_caps = omap3630_dss_overlay_caps, |
| 719 | .clksrc_names = omap3_dss_clk_source_names, | ||
| 720 | .dss_params = omap3_dss_param_range, | 686 | .dss_params = omap3_dss_param_range, |
| 721 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | 687 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, |
| 722 | .buffer_size_unit = 1, | 688 | .buffer_size_unit = 1, |
| @@ -738,7 +704,6 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { | |||
| 738 | .supported_outputs = omap4_dss_supported_outputs, | 704 | .supported_outputs = omap4_dss_supported_outputs, |
| 739 | .supported_color_modes = omap4_dss_supported_color_modes, | 705 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 740 | .overlay_caps = omap4_dss_overlay_caps, | 706 | .overlay_caps = omap4_dss_overlay_caps, |
| 741 | .clksrc_names = omap4_dss_clk_source_names, | ||
| 742 | .dss_params = omap4_dss_param_range, | 707 | .dss_params = omap4_dss_param_range, |
| 743 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | 708 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, |
| 744 | .buffer_size_unit = 16, | 709 | .buffer_size_unit = 16, |
| @@ -759,7 +724,6 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { | |||
| 759 | .supported_outputs = omap4_dss_supported_outputs, | 724 | .supported_outputs = omap4_dss_supported_outputs, |
| 760 | .supported_color_modes = omap4_dss_supported_color_modes, | 725 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 761 | .overlay_caps = omap4_dss_overlay_caps, | 726 | .overlay_caps = omap4_dss_overlay_caps, |
| 762 | .clksrc_names = omap4_dss_clk_source_names, | ||
| 763 | .dss_params = omap4_dss_param_range, | 727 | .dss_params = omap4_dss_param_range, |
| 764 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | 728 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, |
| 765 | .buffer_size_unit = 16, | 729 | .buffer_size_unit = 16, |
| @@ -780,7 +744,6 @@ static const struct omap_dss_features omap4_dss_features = { | |||
| 780 | .supported_outputs = omap4_dss_supported_outputs, | 744 | .supported_outputs = omap4_dss_supported_outputs, |
| 781 | .supported_color_modes = omap4_dss_supported_color_modes, | 745 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 782 | .overlay_caps = omap4_dss_overlay_caps, | 746 | .overlay_caps = omap4_dss_overlay_caps, |
| 783 | .clksrc_names = omap4_dss_clk_source_names, | ||
| 784 | .dss_params = omap4_dss_param_range, | 747 | .dss_params = omap4_dss_param_range, |
| 785 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | 748 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, |
| 786 | .buffer_size_unit = 16, | 749 | .buffer_size_unit = 16, |
| @@ -801,7 +764,6 @@ static const struct omap_dss_features omap5_dss_features = { | |||
| 801 | .supported_outputs = omap5_dss_supported_outputs, | 764 | .supported_outputs = omap5_dss_supported_outputs, |
| 802 | .supported_color_modes = omap4_dss_supported_color_modes, | 765 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 803 | .overlay_caps = omap4_dss_overlay_caps, | 766 | .overlay_caps = omap4_dss_overlay_caps, |
| 804 | .clksrc_names = omap5_dss_clk_source_names, | ||
| 805 | .dss_params = omap5_dss_param_range, | 767 | .dss_params = omap5_dss_param_range, |
| 806 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | 768 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, |
| 807 | .buffer_size_unit = 16, | 769 | .buffer_size_unit = 16, |
| @@ -859,11 +821,6 @@ bool dss_feat_color_mode_supported(enum omap_plane plane, | |||
| 859 | color_mode; | 821 | color_mode; |
| 860 | } | 822 | } |
| 861 | 823 | ||
| 862 | const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id) | ||
| 863 | { | ||
| 864 | return omap_current_dss_features->clksrc_names[id]; | ||
| 865 | } | ||
| 866 | |||
| 867 | u32 dss_feat_get_buffer_size_unit(void) | 824 | u32 dss_feat_get_buffer_size_unit(void) |
| 868 | { | 825 | { |
| 869 | return omap_current_dss_features->buffer_size_unit; | 826 | return omap_current_dss_features->buffer_size_unit; |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h index 3d67d39f192f..bb4b7f0e642b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss_features.h +++ b/drivers/gpu/drm/omapdrm/dss/dss_features.h | |||
| @@ -91,7 +91,6 @@ unsigned long dss_feat_get_param_max(enum dss_range_param param); | |||
| 91 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); | 91 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); |
| 92 | bool dss_feat_color_mode_supported(enum omap_plane plane, | 92 | bool dss_feat_color_mode_supported(enum omap_plane plane, |
| 93 | enum omap_color_mode color_mode); | 93 | enum omap_color_mode color_mode); |
| 94 | const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); | ||
| 95 | 94 | ||
| 96 | u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ | 95 | u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ |
| 97 | u32 dss_feat_get_burst_size_unit(void); /* in bytes */ | 96 | u32 dss_feat_get_burst_size_unit(void); /* in bytes */ |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index 53616b02b613..597ee204d699 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h | |||
| @@ -240,6 +240,7 @@ struct hdmi_pll_data { | |||
| 240 | 240 | ||
| 241 | void __iomem *base; | 241 | void __iomem *base; |
| 242 | 242 | ||
| 243 | struct platform_device *pdev; | ||
| 243 | struct hdmi_wp_data *wp; | 244 | struct hdmi_wp_data *wp; |
| 244 | }; | 245 | }; |
| 245 | 246 | ||
| @@ -306,8 +307,6 @@ phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp); | |||
| 306 | 307 | ||
| 307 | /* HDMI PLL funcs */ | 308 | /* HDMI PLL funcs */ |
| 308 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); | 309 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); |
| 309 | void hdmi_pll_compute(struct hdmi_pll_data *pll, | ||
| 310 | unsigned long target_tmds, struct dss_pll_clock_info *pi); | ||
| 311 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, | 310 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, |
| 312 | struct hdmi_wp_data *wp); | 311 | struct hdmi_wp_data *wp); |
| 313 | void hdmi_pll_uninit(struct hdmi_pll_data *hpll); | 312 | void hdmi_pll_uninit(struct hdmi_pll_data *hpll); |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 4d46cdf7a037..ca4abb499242 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c | |||
| @@ -177,7 +177,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
| 177 | if (p->double_pixel) | 177 | if (p->double_pixel) |
| 178 | pc *= 2; | 178 | pc *= 2; |
| 179 | 179 | ||
| 180 | hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); | 180 | /* DSS_HDMI_TCLK is bitclk / 10 */ |
| 181 | pc *= 10; | ||
| 182 | |||
| 183 | dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin), | ||
| 184 | pc, &hdmi_cinfo); | ||
| 181 | 185 | ||
| 182 | r = dss_pll_enable(&hdmi.pll.pll); | 186 | r = dss_pll_enable(&hdmi.pll.pll); |
| 183 | if (r) { | 187 | if (r) { |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index e129245eb8a9..cbcf4bb5248c 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c | |||
| @@ -190,7 +190,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
| 190 | if (p->double_pixel) | 190 | if (p->double_pixel) |
| 191 | pc *= 2; | 191 | pc *= 2; |
| 192 | 192 | ||
| 193 | hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); | 193 | /* DSS_HDMI_TCLK is bitclk / 10 */ |
| 194 | pc *= 10; | ||
| 195 | |||
| 196 | dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin), | ||
| 197 | pc, &hdmi_cinfo); | ||
| 194 | 198 | ||
| 195 | /* disable and clear irqs */ | 199 | /* disable and clear irqs */ |
| 196 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); | 200 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c index f1015e8b8267..dc0212a9754e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | #include <linux/pm_runtime.h> | ||
| 20 | 21 | ||
| 21 | #include <video/omapdss.h> | 22 | #include <video/omapdss.h> |
| 22 | 23 | ||
| @@ -39,71 +40,14 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) | |||
| 39 | DUMPPLL(PLLCTRL_CFG4); | 40 | DUMPPLL(PLLCTRL_CFG4); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | void hdmi_pll_compute(struct hdmi_pll_data *pll, | ||
| 43 | unsigned long target_tmds, struct dss_pll_clock_info *pi) | ||
| 44 | { | ||
| 45 | unsigned long fint, clkdco, clkout; | ||
| 46 | unsigned long target_bitclk, target_clkdco; | ||
| 47 | unsigned long min_dco; | ||
| 48 | unsigned n, m, mf, m2, sd; | ||
| 49 | unsigned long clkin; | ||
| 50 | const struct dss_pll_hw *hw = pll->pll.hw; | ||
| 51 | |||
| 52 | clkin = clk_get_rate(pll->pll.clkin); | ||
| 53 | |||
| 54 | DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds); | ||
| 55 | |||
| 56 | target_bitclk = target_tmds * 10; | ||
| 57 | |||
| 58 | /* Fint */ | ||
| 59 | n = DIV_ROUND_UP(clkin, hw->fint_max); | ||
| 60 | fint = clkin / n; | ||
| 61 | |||
| 62 | /* adjust m2 so that the clkdco will be high enough */ | ||
| 63 | min_dco = roundup(hw->clkdco_min, fint); | ||
| 64 | m2 = DIV_ROUND_UP(min_dco, target_bitclk); | ||
| 65 | if (m2 == 0) | ||
| 66 | m2 = 1; | ||
| 67 | |||
| 68 | target_clkdco = target_bitclk * m2; | ||
| 69 | m = target_clkdco / fint; | ||
| 70 | |||
| 71 | clkdco = fint * m; | ||
| 72 | |||
| 73 | /* adjust clkdco with fractional mf */ | ||
| 74 | if (WARN_ON(target_clkdco - clkdco > fint)) | ||
| 75 | mf = 0; | ||
| 76 | else | ||
| 77 | mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint); | ||
| 78 | |||
| 79 | if (mf > 0) | ||
| 80 | clkdco += (u32)div_u64((u64)mf * fint, 262144); | ||
| 81 | |||
| 82 | clkout = clkdco / m2; | ||
| 83 | |||
| 84 | /* sigma-delta */ | ||
| 85 | sd = DIV_ROUND_UP(fint * m, 250000000); | ||
| 86 | |||
| 87 | DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n", | ||
| 88 | n, m, mf, m2, sd); | ||
| 89 | DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout); | ||
| 90 | |||
| 91 | pi->n = n; | ||
| 92 | pi->m = m; | ||
| 93 | pi->mf = mf; | ||
| 94 | pi->mX[0] = m2; | ||
| 95 | pi->sd = sd; | ||
| 96 | |||
| 97 | pi->fint = fint; | ||
| 98 | pi->clkdco = clkdco; | ||
| 99 | pi->clkout[0] = clkout; | ||
| 100 | } | ||
| 101 | |||
| 102 | static int hdmi_pll_enable(struct dss_pll *dsspll) | 43 | static int hdmi_pll_enable(struct dss_pll *dsspll) |
| 103 | { | 44 | { |
| 104 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); | 45 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); |
| 105 | struct hdmi_wp_data *wp = pll->wp; | 46 | struct hdmi_wp_data *wp = pll->wp; |
| 106 | u16 r = 0; | 47 | int r; |
| 48 | |||
| 49 | r = pm_runtime_get_sync(&pll->pdev->dev); | ||
| 50 | WARN_ON(r < 0); | ||
| 107 | 51 | ||
| 108 | dss_ctrl_pll_enable(DSS_PLL_HDMI, true); | 52 | dss_ctrl_pll_enable(DSS_PLL_HDMI, true); |
| 109 | 53 | ||
| @@ -118,10 +62,14 @@ static void hdmi_pll_disable(struct dss_pll *dsspll) | |||
| 118 | { | 62 | { |
| 119 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); | 63 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); |
| 120 | struct hdmi_wp_data *wp = pll->wp; | 64 | struct hdmi_wp_data *wp = pll->wp; |
| 65 | int r; | ||
| 121 | 66 | ||
| 122 | hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); | 67 | hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); |
| 123 | 68 | ||
| 124 | dss_ctrl_pll_enable(DSS_PLL_HDMI, false); | 69 | dss_ctrl_pll_enable(DSS_PLL_HDMI, false); |
| 70 | |||
| 71 | r = pm_runtime_put_sync(&pll->pdev->dev); | ||
| 72 | WARN_ON(r < 0 && r != -ENOSYS); | ||
| 125 | } | 73 | } |
| 126 | 74 | ||
| 127 | static const struct dss_pll_ops dsi_pll_ops = { | 75 | static const struct dss_pll_ops dsi_pll_ops = { |
| @@ -131,6 +79,8 @@ static const struct dss_pll_ops dsi_pll_ops = { | |||
| 131 | }; | 79 | }; |
| 132 | 80 | ||
| 133 | static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { | 81 | static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { |
| 82 | .type = DSS_PLL_TYPE_B, | ||
| 83 | |||
| 134 | .n_max = 255, | 84 | .n_max = 255, |
| 135 | .m_min = 20, | 85 | .m_min = 20, |
| 136 | .m_max = 4095, | 86 | .m_max = 4095, |
| @@ -154,6 +104,8 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { | |||
| 154 | }; | 104 | }; |
| 155 | 105 | ||
| 156 | static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { | 106 | static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { |
| 107 | .type = DSS_PLL_TYPE_B, | ||
| 108 | |||
| 157 | .n_max = 255, | 109 | .n_max = 255, |
| 158 | .m_min = 20, | 110 | .m_min = 20, |
| 159 | .m_max = 2045, | 111 | .m_max = 2045, |
| @@ -225,6 +177,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, | |||
| 225 | int r; | 177 | int r; |
| 226 | struct resource *res; | 178 | struct resource *res; |
| 227 | 179 | ||
| 180 | pll->pdev = pdev; | ||
| 228 | pll->wp = wp; | 181 | pll->wp = wp; |
| 229 | 182 | ||
| 230 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); | 183 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); |
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c index f974ddcd3b6e..4768a85e6c73 100644 --- a/drivers/gpu/drm/omapdrm/dss/pll.c +++ b/drivers/gpu/drm/omapdrm/dss/pll.c | |||
| @@ -76,6 +76,59 @@ struct dss_pll *dss_pll_find(const char *name) | |||
| 76 | return NULL; | 76 | return NULL; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src) | ||
| 80 | { | ||
| 81 | struct dss_pll *pll; | ||
| 82 | |||
| 83 | switch (src) { | ||
| 84 | default: | ||
| 85 | case DSS_CLK_SRC_FCK: | ||
| 86 | return NULL; | ||
| 87 | |||
| 88 | case DSS_CLK_SRC_HDMI_PLL: | ||
| 89 | return dss_pll_find("hdmi"); | ||
| 90 | |||
| 91 | case DSS_CLK_SRC_PLL1_1: | ||
| 92 | case DSS_CLK_SRC_PLL1_2: | ||
| 93 | case DSS_CLK_SRC_PLL1_3: | ||
| 94 | pll = dss_pll_find("dsi0"); | ||
| 95 | if (!pll) | ||
| 96 | pll = dss_pll_find("video0"); | ||
| 97 | return pll; | ||
| 98 | |||
| 99 | case DSS_CLK_SRC_PLL2_1: | ||
| 100 | case DSS_CLK_SRC_PLL2_2: | ||
| 101 | case DSS_CLK_SRC_PLL2_3: | ||
| 102 | pll = dss_pll_find("dsi1"); | ||
| 103 | if (!pll) | ||
| 104 | pll = dss_pll_find("video1"); | ||
| 105 | return pll; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src) | ||
| 110 | { | ||
| 111 | switch (src) { | ||
| 112 | case DSS_CLK_SRC_HDMI_PLL: | ||
| 113 | return 0; | ||
| 114 | |||
| 115 | case DSS_CLK_SRC_PLL1_1: | ||
| 116 | case DSS_CLK_SRC_PLL2_1: | ||
| 117 | return 0; | ||
| 118 | |||
| 119 | case DSS_CLK_SRC_PLL1_2: | ||
| 120 | case DSS_CLK_SRC_PLL2_2: | ||
| 121 | return 1; | ||
| 122 | |||
| 123 | case DSS_CLK_SRC_PLL1_3: | ||
| 124 | case DSS_CLK_SRC_PLL2_3: | ||
| 125 | return 2; | ||
| 126 | |||
| 127 | default: | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 79 | int dss_pll_enable(struct dss_pll *pll) | 132 | int dss_pll_enable(struct dss_pll *pll) |
| 80 | { | 133 | { |
| 81 | int r; | 134 | int r; |
| @@ -129,7 +182,7 @@ int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cin | |||
| 129 | return 0; | 182 | return 0; |
| 130 | } | 183 | } |
| 131 | 184 | ||
| 132 | bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, | 185 | bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco, |
| 133 | unsigned long out_min, unsigned long out_max, | 186 | unsigned long out_min, unsigned long out_max, |
| 134 | dss_hsdiv_calc_func func, void *data) | 187 | dss_hsdiv_calc_func func, void *data) |
| 135 | { | 188 | { |
| @@ -154,7 +207,11 @@ bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, | |||
| 154 | return false; | 207 | return false; |
| 155 | } | 208 | } |
| 156 | 209 | ||
| 157 | bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, | 210 | /* |
| 211 | * clkdco = clkin / n * m * 2 | ||
| 212 | * clkoutX = clkdco / mX | ||
| 213 | */ | ||
| 214 | bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin, | ||
| 158 | unsigned long pll_min, unsigned long pll_max, | 215 | unsigned long pll_min, unsigned long pll_max, |
| 159 | dss_pll_calc_func func, void *data) | 216 | dss_pll_calc_func func, void *data) |
| 160 | { | 217 | { |
| @@ -195,6 +252,71 @@ bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, | |||
| 195 | return false; | 252 | return false; |
| 196 | } | 253 | } |
| 197 | 254 | ||
| 255 | /* | ||
| 256 | * This calculates a PLL config that will provide the target_clkout rate | ||
| 257 | * for clkout. Additionally clkdco rate will be the same as clkout rate | ||
| 258 | * when clkout rate is >= min_clkdco. | ||
| 259 | * | ||
| 260 | * clkdco = clkin / n * m + clkin / n * mf / 262144 | ||
| 261 | * clkout = clkdco / m2 | ||
| 262 | */ | ||
| 263 | bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin, | ||
| 264 | unsigned long target_clkout, struct dss_pll_clock_info *cinfo) | ||
| 265 | { | ||
| 266 | unsigned long fint, clkdco, clkout; | ||
| 267 | unsigned long target_clkdco; | ||
| 268 | unsigned long min_dco; | ||
| 269 | unsigned n, m, mf, m2, sd; | ||
| 270 | const struct dss_pll_hw *hw = pll->hw; | ||
| 271 | |||
| 272 | DSSDBG("clkin %lu, target clkout %lu\n", clkin, target_clkout); | ||
| 273 | |||
| 274 | /* Fint */ | ||
| 275 | n = DIV_ROUND_UP(clkin, hw->fint_max); | ||
| 276 | fint = clkin / n; | ||
| 277 | |||
| 278 | /* adjust m2 so that the clkdco will be high enough */ | ||
| 279 | min_dco = roundup(hw->clkdco_min, fint); | ||
| 280 | m2 = DIV_ROUND_UP(min_dco, target_clkout); | ||
| 281 | if (m2 == 0) | ||
| 282 | m2 = 1; | ||
| 283 | |||
| 284 | target_clkdco = target_clkout * m2; | ||
| 285 | m = target_clkdco / fint; | ||
| 286 | |||
| 287 | clkdco = fint * m; | ||
| 288 | |||
| 289 | /* adjust clkdco with fractional mf */ | ||
| 290 | if (WARN_ON(target_clkdco - clkdco > fint)) | ||
| 291 | mf = 0; | ||
| 292 | else | ||
| 293 | mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint); | ||
| 294 | |||
| 295 | if (mf > 0) | ||
| 296 | clkdco += (u32)div_u64((u64)mf * fint, 262144); | ||
| 297 | |||
| 298 | clkout = clkdco / m2; | ||
| 299 | |||
| 300 | /* sigma-delta */ | ||
| 301 | sd = DIV_ROUND_UP(fint * m, 250000000); | ||
| 302 | |||
| 303 | DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n", | ||
| 304 | n, m, mf, m2, sd); | ||
| 305 | DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout); | ||
| 306 | |||
| 307 | cinfo->n = n; | ||
| 308 | cinfo->m = m; | ||
| 309 | cinfo->mf = mf; | ||
| 310 | cinfo->mX[0] = m2; | ||
| 311 | cinfo->sd = sd; | ||
| 312 | |||
| 313 | cinfo->fint = fint; | ||
| 314 | cinfo->clkdco = clkdco; | ||
| 315 | cinfo->clkout[0] = clkout; | ||
| 316 | |||
| 317 | return true; | ||
| 318 | } | ||
| 319 | |||
| 198 | static int wait_for_bit_change(void __iomem *reg, int bitnum, int value) | 320 | static int wait_for_bit_change(void __iomem *reg, int bitnum, int value) |
| 199 | { | 321 | { |
| 200 | unsigned long timeout; | 322 | unsigned long timeout; |
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c index b1ec59e42940..c13e1accda17 100644 --- a/drivers/gpu/drm/omapdrm/dss/video-pll.c +++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c | |||
| @@ -108,6 +108,8 @@ static const struct dss_pll_ops dss_pll_ops = { | |||
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | static const struct dss_pll_hw dss_dra7_video_pll_hw = { | 110 | static const struct dss_pll_hw dss_dra7_video_pll_hw = { |
| 111 | .type = DSS_PLL_TYPE_A, | ||
| 112 | |||
| 111 | .n_max = (1 << 8) - 1, | 113 | .n_max = (1 << 8) - 1, |
| 112 | .m_max = (1 << 12) - 1, | 114 | .m_max = (1 << 12) - 1, |
| 113 | .mX_max = (1 << 5) - 1, | 115 | .mX_max = (1 << 5) - 1, |
| @@ -124,6 +126,10 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = { | |||
| 124 | .mX_lsb[0] = 21, | 126 | .mX_lsb[0] = 21, |
| 125 | .mX_msb[1] = 30, | 127 | .mX_msb[1] = 30, |
| 126 | .mX_lsb[1] = 26, | 128 | .mX_lsb[1] = 26, |
| 129 | .mX_msb[2] = 4, | ||
| 130 | .mX_lsb[2] = 0, | ||
| 131 | .mX_msb[3] = 9, | ||
| 132 | .mX_lsb[3] = 5, | ||
| 127 | 133 | ||
| 128 | .has_refsel = true, | 134 | .has_refsel = true, |
| 129 | }; | 135 | }; |
