diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-06-06 03:16:51 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-06-06 03:16:51 -0400 |
commit | ecf140dfc3fe169aaff8f5561d345f6b96d7b476 (patch) | |
tree | 5e360dedcb193a4b321abf427f1629a7c35a5bf0 /drivers/gpu/drm/omapdrm | |
parent | 449c5e9c33fd03625e12e3ed32b84bbbb9243d99 (diff) | |
parent | 31dca077056afd0a6089b9eaca1e4e485acc1ddc (diff) |
Merge branch '4.8/omapdrm-pll' (omapdrm PLL work)
Merge omapdrm PLL work, which makes it possible to use the DSS PLLs in a
versatile manner, for example, HDMI PLL can be used for LCDs.
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 | }; |