diff options
Diffstat (limited to 'drivers/video/fbdev/omap2/dss/dsi.c')
-rw-r--r-- | drivers/video/fbdev/omap2/dss/dsi.c | 659 |
1 files changed, 240 insertions, 419 deletions
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index 0793bc67a275..73af35159468 100644 --- a/drivers/video/fbdev/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c | |||
@@ -219,6 +219,10 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev, | |||
219 | 219 | ||
220 | static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); | 220 | static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); |
221 | 221 | ||
222 | /* DSI PLL HSDIV indices */ | ||
223 | #define HSDIV_DISPC 0 | ||
224 | #define HSDIV_DSI 1 | ||
225 | |||
222 | #define DSI_MAX_NR_ISRS 2 | 226 | #define DSI_MAX_NR_ISRS 2 |
223 | #define DSI_MAX_NR_LANES 5 | 227 | #define DSI_MAX_NR_LANES 5 |
224 | 228 | ||
@@ -271,6 +275,7 @@ struct dsi_isr_tables { | |||
271 | 275 | ||
272 | struct dsi_clk_calc_ctx { | 276 | struct dsi_clk_calc_ctx { |
273 | struct platform_device *dsidev; | 277 | struct platform_device *dsidev; |
278 | struct dss_pll *pll; | ||
274 | 279 | ||
275 | /* inputs */ | 280 | /* inputs */ |
276 | 281 | ||
@@ -280,13 +285,18 @@ struct dsi_clk_calc_ctx { | |||
280 | 285 | ||
281 | /* outputs */ | 286 | /* outputs */ |
282 | 287 | ||
283 | struct dsi_clock_info dsi_cinfo; | 288 | struct dss_pll_clock_info dsi_cinfo; |
284 | struct dispc_clock_info dispc_cinfo; | 289 | struct dispc_clock_info dispc_cinfo; |
285 | 290 | ||
286 | struct omap_video_timings dispc_vm; | 291 | struct omap_video_timings dispc_vm; |
287 | struct omap_dss_dsi_videomode_timings dsi_vm; | 292 | struct omap_dss_dsi_videomode_timings dsi_vm; |
288 | }; | 293 | }; |
289 | 294 | ||
295 | struct dsi_lp_clock_info { | ||
296 | unsigned long lp_clk; | ||
297 | u16 lp_clk_div; | ||
298 | }; | ||
299 | |||
290 | struct dsi_data { | 300 | struct dsi_data { |
291 | struct platform_device *pdev; | 301 | struct platform_device *pdev; |
292 | void __iomem *proto_base; | 302 | void __iomem *proto_base; |
@@ -300,12 +310,14 @@ struct dsi_data { | |||
300 | bool is_enabled; | 310 | bool is_enabled; |
301 | 311 | ||
302 | struct clk *dss_clk; | 312 | struct clk *dss_clk; |
303 | struct clk *sys_clk; | ||
304 | 313 | ||
305 | struct dispc_clock_info user_dispc_cinfo; | 314 | struct dispc_clock_info user_dispc_cinfo; |
306 | struct dsi_clock_info user_dsi_cinfo; | 315 | struct dss_pll_clock_info user_dsi_cinfo; |
316 | |||
317 | struct dsi_lp_clock_info user_lp_cinfo; | ||
318 | struct dsi_lp_clock_info current_lp_cinfo; | ||
307 | 319 | ||
308 | struct dsi_clock_info current_cinfo; | 320 | struct dss_pll pll; |
309 | 321 | ||
310 | bool vdds_dsi_enabled; | 322 | bool vdds_dsi_enabled; |
311 | struct regulator *vdds_dsi_reg; | 323 | struct regulator *vdds_dsi_reg; |
@@ -321,8 +333,6 @@ struct dsi_data { | |||
321 | struct mutex lock; | 333 | struct mutex lock; |
322 | struct semaphore bus_lock; | 334 | struct semaphore bus_lock; |
323 | 335 | ||
324 | unsigned pll_locked; | ||
325 | |||
326 | spinlock_t irq_lock; | 336 | spinlock_t irq_lock; |
327 | struct dsi_isr_tables isr_tables; | 337 | struct dsi_isr_tables isr_tables; |
328 | /* space for a copy used by the interrupt handler */ | 338 | /* space for a copy used by the interrupt handler */ |
@@ -347,7 +357,7 @@ struct dsi_data { | |||
347 | 357 | ||
348 | unsigned long cache_req_pck; | 358 | unsigned long cache_req_pck; |
349 | unsigned long cache_clk_freq; | 359 | unsigned long cache_clk_freq; |
350 | struct dsi_clock_info cache_cinfo; | 360 | struct dss_pll_clock_info cache_cinfo; |
351 | 361 | ||
352 | u32 errors; | 362 | u32 errors; |
353 | spinlock_t errors_lock; | 363 | spinlock_t errors_lock; |
@@ -362,11 +372,6 @@ struct dsi_data { | |||
362 | spinlock_t irq_stats_lock; | 372 | spinlock_t irq_stats_lock; |
363 | struct dsi_irq_stats irq_stats; | 373 | struct dsi_irq_stats irq_stats; |
364 | #endif | 374 | #endif |
365 | /* DSI PLL Parameter Ranges */ | ||
366 | unsigned long regm_max, regn_max; | ||
367 | unsigned long regm_dispc_max, regm_dsi_max; | ||
368 | unsigned long fint_min, fint_max; | ||
369 | unsigned long lpdiv_max; | ||
370 | 375 | ||
371 | unsigned num_lanes_supported; | 376 | unsigned num_lanes_supported; |
372 | unsigned line_buffer_size; | 377 | unsigned line_buffer_size; |
@@ -412,7 +417,7 @@ static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss | |||
412 | return to_platform_device(dssdev->dev); | 417 | return to_platform_device(dssdev->dev); |
413 | } | 418 | } |
414 | 419 | ||
415 | struct platform_device *dsi_get_dsidev_from_id(int module) | 420 | static struct platform_device *dsi_get_dsidev_from_id(int module) |
416 | { | 421 | { |
417 | struct omap_dss_device *out; | 422 | struct omap_dss_device *out; |
418 | enum omap_dss_output_id id; | 423 | enum omap_dss_output_id id; |
@@ -1134,7 +1139,7 @@ static u32 dsi_get_errors(struct platform_device *dsidev) | |||
1134 | return e; | 1139 | return e; |
1135 | } | 1140 | } |
1136 | 1141 | ||
1137 | int dsi_runtime_get(struct platform_device *dsidev) | 1142 | static int dsi_runtime_get(struct platform_device *dsidev) |
1138 | { | 1143 | { |
1139 | int r; | 1144 | int r; |
1140 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1145 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -1146,7 +1151,7 @@ int dsi_runtime_get(struct platform_device *dsidev) | |||
1146 | return r < 0 ? r : 0; | 1151 | return r < 0 ? r : 0; |
1147 | } | 1152 | } |
1148 | 1153 | ||
1149 | void dsi_runtime_put(struct platform_device *dsidev) | 1154 | static void dsi_runtime_put(struct platform_device *dsidev) |
1150 | { | 1155 | { |
1151 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1156 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1152 | int r; | 1157 | int r; |
@@ -1188,23 +1193,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) | |||
1188 | return 0; | 1193 | return 0; |
1189 | } | 1194 | } |
1190 | 1195 | ||
1191 | /* source clock for DSI PLL. this could also be PCLKFREE */ | ||
1192 | static inline void dsi_enable_pll_clock(struct platform_device *dsidev, | ||
1193 | bool enable) | ||
1194 | { | ||
1195 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1196 | |||
1197 | if (enable) | ||
1198 | clk_prepare_enable(dsi->sys_clk); | ||
1199 | else | ||
1200 | clk_disable_unprepare(dsi->sys_clk); | ||
1201 | |||
1202 | if (enable && dsi->pll_locked) { | ||
1203 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) | ||
1204 | DSSERR("cannot lock PLL when enabling clocks\n"); | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | static void _dsi_print_reset_status(struct platform_device *dsidev) | 1196 | static void _dsi_print_reset_status(struct platform_device *dsidev) |
1209 | { | 1197 | { |
1210 | u32 l; | 1198 | u32 l; |
@@ -1256,25 +1244,25 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable) | |||
1256 | return 0; | 1244 | return 0; |
1257 | } | 1245 | } |
1258 | 1246 | ||
1259 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) | 1247 | static unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) |
1260 | { | 1248 | { |
1261 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1249 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1262 | 1250 | ||
1263 | return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk; | 1251 | return dsi->pll.cinfo.clkout[HSDIV_DISPC]; |
1264 | } | 1252 | } |
1265 | 1253 | ||
1266 | static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) | 1254 | static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) |
1267 | { | 1255 | { |
1268 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1256 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1269 | 1257 | ||
1270 | return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk; | 1258 | return dsi->pll.cinfo.clkout[HSDIV_DSI]; |
1271 | } | 1259 | } |
1272 | 1260 | ||
1273 | static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) | 1261 | static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) |
1274 | { | 1262 | { |
1275 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1263 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1276 | 1264 | ||
1277 | return dsi->current_cinfo.clkin4ddr / 16; | 1265 | return dsi->pll.cinfo.clkdco / 16; |
1278 | } | 1266 | } |
1279 | 1267 | ||
1280 | static unsigned long dsi_fclk_rate(struct platform_device *dsidev) | 1268 | static unsigned long dsi_fclk_rate(struct platform_device *dsidev) |
@@ -1293,10 +1281,10 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev) | |||
1293 | return r; | 1281 | return r; |
1294 | } | 1282 | } |
1295 | 1283 | ||
1296 | static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo, | 1284 | static int dsi_lp_clock_calc(unsigned long dsi_fclk, |
1297 | unsigned long lp_clk_min, unsigned long lp_clk_max) | 1285 | unsigned long lp_clk_min, unsigned long lp_clk_max, |
1286 | struct dsi_lp_clock_info *lp_cinfo) | ||
1298 | { | 1287 | { |
1299 | unsigned long dsi_fclk = cinfo->dsi_pll_hsdiv_dsi_clk; | ||
1300 | unsigned lp_clk_div; | 1288 | unsigned lp_clk_div; |
1301 | unsigned long lp_clk; | 1289 | unsigned long lp_clk; |
1302 | 1290 | ||
@@ -1306,8 +1294,8 @@ static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo, | |||
1306 | if (lp_clk < lp_clk_min || lp_clk > lp_clk_max) | 1294 | if (lp_clk < lp_clk_min || lp_clk > lp_clk_max) |
1307 | return -EINVAL; | 1295 | return -EINVAL; |
1308 | 1296 | ||
1309 | cinfo->lp_clk_div = lp_clk_div; | 1297 | lp_cinfo->lp_clk_div = lp_clk_div; |
1310 | cinfo->lp_clk = lp_clk; | 1298 | lp_cinfo->lp_clk = lp_clk; |
1311 | 1299 | ||
1312 | return 0; | 1300 | return 0; |
1313 | } | 1301 | } |
@@ -1318,10 +1306,12 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev) | |||
1318 | unsigned long dsi_fclk; | 1306 | unsigned long dsi_fclk; |
1319 | unsigned lp_clk_div; | 1307 | unsigned lp_clk_div; |
1320 | unsigned long lp_clk; | 1308 | unsigned long lp_clk; |
1309 | unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); | ||
1310 | |||
1321 | 1311 | ||
1322 | lp_clk_div = dsi->user_dsi_cinfo.lp_clk_div; | 1312 | lp_clk_div = dsi->user_lp_cinfo.lp_clk_div; |
1323 | 1313 | ||
1324 | if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) | 1314 | if (lp_clk_div == 0 || lp_clk_div > lpdiv_max) |
1325 | return -EINVAL; | 1315 | return -EINVAL; |
1326 | 1316 | ||
1327 | dsi_fclk = dsi_fclk_rate(dsidev); | 1317 | dsi_fclk = dsi_fclk_rate(dsidev); |
@@ -1329,8 +1319,8 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev) | |||
1329 | lp_clk = dsi_fclk / 2 / lp_clk_div; | 1319 | lp_clk = dsi_fclk / 2 / lp_clk_div; |
1330 | 1320 | ||
1331 | DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); | 1321 | DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); |
1332 | dsi->current_cinfo.lp_clk = lp_clk; | 1322 | dsi->current_lp_cinfo.lp_clk = lp_clk; |
1333 | dsi->current_cinfo.lp_clk_div = lp_clk_div; | 1323 | dsi->current_lp_cinfo.lp_clk_div = lp_clk_div; |
1334 | 1324 | ||
1335 | /* LP_CLK_DIVISOR */ | 1325 | /* LP_CLK_DIVISOR */ |
1336 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); | 1326 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); |
@@ -1391,286 +1381,33 @@ static int dsi_pll_power(struct platform_device *dsidev, | |||
1391 | return 0; | 1381 | return 0; |
1392 | } | 1382 | } |
1393 | 1383 | ||
1394 | unsigned long dsi_get_pll_clkin(struct platform_device *dsidev) | ||
1395 | { | ||
1396 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1397 | return clk_get_rate(dsi->sys_clk); | ||
1398 | } | ||
1399 | |||
1400 | bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll, | ||
1401 | unsigned long out_min, dsi_hsdiv_calc_func func, void *data) | ||
1402 | { | ||
1403 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1404 | int regm, regm_start, regm_stop; | ||
1405 | unsigned long out_max; | ||
1406 | unsigned long out; | ||
1407 | |||
1408 | out_min = out_min ? out_min : 1; | ||
1409 | out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | ||
1410 | |||
1411 | regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul); | ||
1412 | regm_stop = min(pll / out_min, dsi->regm_dispc_max); | ||
1413 | |||
1414 | for (regm = regm_start; regm <= regm_stop; ++regm) { | ||
1415 | out = pll / regm; | ||
1416 | |||
1417 | if (func(regm, out, data)) | ||
1418 | return true; | ||
1419 | } | ||
1420 | |||
1421 | return false; | ||
1422 | } | ||
1423 | |||
1424 | bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin, | ||
1425 | unsigned long pll_min, unsigned long pll_max, | ||
1426 | dsi_pll_calc_func func, void *data) | ||
1427 | { | ||
1428 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1429 | int regn, regn_start, regn_stop; | ||
1430 | int regm, regm_start, regm_stop; | ||
1431 | unsigned long fint, pll; | ||
1432 | const unsigned long pll_hw_max = 1800000000; | ||
1433 | unsigned long fint_hw_min, fint_hw_max; | ||
1434 | |||
1435 | fint_hw_min = dsi->fint_min; | ||
1436 | fint_hw_max = dsi->fint_max; | ||
1437 | 1384 | ||
1438 | regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); | 1385 | static void dsi_pll_calc_dsi_fck(struct dss_pll_clock_info *cinfo) |
1439 | regn_stop = min(clkin / fint_hw_min, dsi->regn_max); | ||
1440 | |||
1441 | pll_max = pll_max ? pll_max : ULONG_MAX; | ||
1442 | |||
1443 | for (regn = regn_start; regn <= regn_stop; ++regn) { | ||
1444 | fint = clkin / regn; | ||
1445 | |||
1446 | regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), | ||
1447 | 1ul); | ||
1448 | regm_stop = min3(pll_max / fint / 2, | ||
1449 | pll_hw_max / fint / 2, | ||
1450 | dsi->regm_max); | ||
1451 | |||
1452 | for (regm = regm_start; regm <= regm_stop; ++regm) { | ||
1453 | pll = 2 * regm * fint; | ||
1454 | |||
1455 | if (func(regn, regm, fint, pll, data)) | ||
1456 | return true; | ||
1457 | } | ||
1458 | } | ||
1459 | |||
1460 | return false; | ||
1461 | } | ||
1462 | |||
1463 | /* calculate clock rates using dividers in cinfo */ | ||
1464 | static int dsi_calc_clock_rates(struct platform_device *dsidev, | ||
1465 | struct dsi_clock_info *cinfo) | ||
1466 | { | ||
1467 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1468 | |||
1469 | if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) | ||
1470 | return -EINVAL; | ||
1471 | |||
1472 | if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max) | ||
1473 | return -EINVAL; | ||
1474 | |||
1475 | if (cinfo->regm_dispc > dsi->regm_dispc_max) | ||
1476 | return -EINVAL; | ||
1477 | |||
1478 | if (cinfo->regm_dsi > dsi->regm_dsi_max) | ||
1479 | return -EINVAL; | ||
1480 | |||
1481 | cinfo->clkin = clk_get_rate(dsi->sys_clk); | ||
1482 | cinfo->fint = cinfo->clkin / cinfo->regn; | ||
1483 | |||
1484 | if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) | ||
1485 | return -EINVAL; | ||
1486 | |||
1487 | cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; | ||
1488 | |||
1489 | if (cinfo->clkin4ddr > 1800 * 1000 * 1000) | ||
1490 | return -EINVAL; | ||
1491 | |||
1492 | if (cinfo->regm_dispc > 0) | ||
1493 | cinfo->dsi_pll_hsdiv_dispc_clk = | ||
1494 | cinfo->clkin4ddr / cinfo->regm_dispc; | ||
1495 | else | ||
1496 | cinfo->dsi_pll_hsdiv_dispc_clk = 0; | ||
1497 | |||
1498 | if (cinfo->regm_dsi > 0) | ||
1499 | cinfo->dsi_pll_hsdiv_dsi_clk = | ||
1500 | cinfo->clkin4ddr / cinfo->regm_dsi; | ||
1501 | else | ||
1502 | cinfo->dsi_pll_hsdiv_dsi_clk = 0; | ||
1503 | |||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo) | ||
1508 | { | 1386 | { |
1509 | unsigned long max_dsi_fck; | 1387 | unsigned long max_dsi_fck; |
1510 | 1388 | ||
1511 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); | 1389 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); |
1512 | 1390 | ||
1513 | cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); | 1391 | cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck); |
1514 | cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; | 1392 | cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI]; |
1515 | } | 1393 | } |
1516 | 1394 | ||
1517 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1395 | static int dsi_pll_enable(struct dss_pll *pll) |
1518 | struct dsi_clock_info *cinfo) | ||
1519 | { | 1396 | { |
1520 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1397 | struct dsi_data *dsi = container_of(pll, struct dsi_data, pll); |
1398 | struct platform_device *dsidev = dsi->pdev; | ||
1521 | int r = 0; | 1399 | int r = 0; |
1522 | u32 l; | ||
1523 | int f = 0; | ||
1524 | u8 regn_start, regn_end, regm_start, regm_end; | ||
1525 | u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; | ||
1526 | |||
1527 | DSSDBG("DSI PLL clock config starts"); | ||
1528 | |||
1529 | dsi->current_cinfo.clkin = cinfo->clkin; | ||
1530 | dsi->current_cinfo.fint = cinfo->fint; | ||
1531 | dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; | ||
1532 | dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = | ||
1533 | cinfo->dsi_pll_hsdiv_dispc_clk; | ||
1534 | dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk = | ||
1535 | cinfo->dsi_pll_hsdiv_dsi_clk; | ||
1536 | |||
1537 | dsi->current_cinfo.regn = cinfo->regn; | ||
1538 | dsi->current_cinfo.regm = cinfo->regm; | ||
1539 | dsi->current_cinfo.regm_dispc = cinfo->regm_dispc; | ||
1540 | dsi->current_cinfo.regm_dsi = cinfo->regm_dsi; | ||
1541 | |||
1542 | DSSDBG("DSI Fint %ld\n", cinfo->fint); | ||
1543 | |||
1544 | DSSDBG("clkin rate %ld\n", cinfo->clkin); | ||
1545 | |||
1546 | /* DSIPHY == CLKIN4DDR */ | ||
1547 | DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n", | ||
1548 | cinfo->regm, | ||
1549 | cinfo->regn, | ||
1550 | cinfo->clkin, | ||
1551 | cinfo->clkin4ddr); | ||
1552 | |||
1553 | DSSDBG("Data rate on 1 DSI lane %ld Mbps\n", | ||
1554 | cinfo->clkin4ddr / 1000 / 1000 / 2); | ||
1555 | |||
1556 | DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); | ||
1557 | |||
1558 | DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, | ||
1559 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | ||
1560 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | ||
1561 | cinfo->dsi_pll_hsdiv_dispc_clk); | ||
1562 | DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, | ||
1563 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | ||
1564 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | ||
1565 | cinfo->dsi_pll_hsdiv_dsi_clk); | ||
1566 | |||
1567 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end); | ||
1568 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, ®m_start, ®m_end); | ||
1569 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, ®m_dispc_start, | ||
1570 | ®m_dispc_end); | ||
1571 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start, | ||
1572 | ®m_dsi_end); | ||
1573 | |||
1574 | /* DSI_PLL_AUTOMODE = manual */ | ||
1575 | REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0); | ||
1576 | |||
1577 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1); | ||
1578 | l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ | ||
1579 | /* DSI_PLL_REGN */ | ||
1580 | l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); | ||
1581 | /* DSI_PLL_REGM */ | ||
1582 | l = FLD_MOD(l, cinfo->regm, regm_start, regm_end); | ||
1583 | /* DSI_CLOCK_DIV */ | ||
1584 | l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0, | ||
1585 | regm_dispc_start, regm_dispc_end); | ||
1586 | /* DSIPROTO_CLOCK_DIV */ | ||
1587 | l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, | ||
1588 | regm_dsi_start, regm_dsi_end); | ||
1589 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l); | ||
1590 | |||
1591 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); | ||
1592 | |||
1593 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1594 | |||
1595 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { | ||
1596 | f = cinfo->fint < 1000000 ? 0x3 : | ||
1597 | cinfo->fint < 1250000 ? 0x4 : | ||
1598 | cinfo->fint < 1500000 ? 0x5 : | ||
1599 | cinfo->fint < 1750000 ? 0x6 : | ||
1600 | 0x7; | ||
1601 | |||
1602 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | ||
1603 | } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { | ||
1604 | f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; | ||
1605 | |||
1606 | l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */ | ||
1607 | } | ||
1608 | |||
1609 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | ||
1610 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | ||
1611 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | ||
1612 | if (dss_has_feature(FEAT_DSI_PLL_REFSEL)) | ||
1613 | l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ | ||
1614 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); | ||
1615 | |||
1616 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ | ||
1617 | |||
1618 | if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) { | ||
1619 | DSSERR("dsi pll go bit not going down.\n"); | ||
1620 | r = -EIO; | ||
1621 | goto err; | ||
1622 | } | ||
1623 | |||
1624 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) { | ||
1625 | DSSERR("cannot lock PLL\n"); | ||
1626 | r = -EIO; | ||
1627 | goto err; | ||
1628 | } | ||
1629 | |||
1630 | dsi->pll_locked = 1; | ||
1631 | |||
1632 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1633 | l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ | ||
1634 | l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ | ||
1635 | l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ | ||
1636 | l = FLD_MOD(l, 0, 7, 7); /* DSI_PLL_TIGHTPHASELOCK */ | ||
1637 | l = FLD_MOD(l, 0, 8, 8); /* DSI_PLL_DRIFTGUARDEN */ | ||
1638 | l = FLD_MOD(l, 0, 10, 9); /* DSI_PLL_LOCKSEL */ | ||
1639 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | ||
1640 | l = FLD_MOD(l, 1, 14, 14); /* DSIPHY_CLKINEN */ | ||
1641 | l = FLD_MOD(l, 0, 15, 15); /* DSI_BYPASSEN */ | ||
1642 | l = FLD_MOD(l, 1, 16, 16); /* DSS_CLOCK_EN */ | ||
1643 | l = FLD_MOD(l, 0, 17, 17); /* DSS_CLOCK_PWDN */ | ||
1644 | l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ | ||
1645 | l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ | ||
1646 | l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ | ||
1647 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); | ||
1648 | |||
1649 | DSSDBG("PLL config done\n"); | ||
1650 | err: | ||
1651 | return r; | ||
1652 | } | ||
1653 | |||
1654 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, | ||
1655 | bool enable_hsdiv) | ||
1656 | { | ||
1657 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1658 | int r = 0; | ||
1659 | enum dsi_pll_power_state pwstate; | ||
1660 | 1400 | ||
1661 | DSSDBG("PLL init\n"); | 1401 | DSSDBG("PLL init\n"); |
1662 | 1402 | ||
1663 | /* | ||
1664 | * It seems that on many OMAPs we need to enable both to have a | ||
1665 | * functional HSDivider. | ||
1666 | */ | ||
1667 | enable_hsclk = enable_hsdiv = true; | ||
1668 | |||
1669 | r = dsi_regulator_init(dsidev); | 1403 | r = dsi_regulator_init(dsidev); |
1670 | if (r) | 1404 | if (r) |
1671 | return r; | 1405 | return r; |
1672 | 1406 | ||
1673 | dsi_enable_pll_clock(dsidev, 1); | 1407 | r = dsi_runtime_get(dsidev); |
1408 | if (r) | ||
1409 | return r; | ||
1410 | |||
1674 | /* | 1411 | /* |
1675 | * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. | 1412 | * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. |
1676 | */ | 1413 | */ |
@@ -1697,16 +1434,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, | |||
1697 | * fill the whole display. No idea about this */ | 1434 | * fill the whole display. No idea about this */ |
1698 | dispc_pck_free_enable(0); | 1435 | dispc_pck_free_enable(0); |
1699 | 1436 | ||
1700 | if (enable_hsclk && enable_hsdiv) | 1437 | r = dsi_pll_power(dsidev, DSI_PLL_POWER_ON_ALL); |
1701 | pwstate = DSI_PLL_POWER_ON_ALL; | ||
1702 | else if (enable_hsclk) | ||
1703 | pwstate = DSI_PLL_POWER_ON_HSCLK; | ||
1704 | else if (enable_hsdiv) | ||
1705 | pwstate = DSI_PLL_POWER_ON_DIV; | ||
1706 | else | ||
1707 | pwstate = DSI_PLL_POWER_OFF; | ||
1708 | |||
1709 | r = dsi_pll_power(dsidev, pwstate); | ||
1710 | 1438 | ||
1711 | if (r) | 1439 | if (r) |
1712 | goto err1; | 1440 | goto err1; |
@@ -1721,15 +1449,14 @@ err1: | |||
1721 | } | 1449 | } |
1722 | err0: | 1450 | err0: |
1723 | dsi_disable_scp_clk(dsidev); | 1451 | dsi_disable_scp_clk(dsidev); |
1724 | dsi_enable_pll_clock(dsidev, 0); | 1452 | dsi_runtime_put(dsidev); |
1725 | return r; | 1453 | return r; |
1726 | } | 1454 | } |
1727 | 1455 | ||
1728 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) | 1456 | static void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) |
1729 | { | 1457 | { |
1730 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1458 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1731 | 1459 | ||
1732 | dsi->pll_locked = 0; | ||
1733 | dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); | 1460 | dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); |
1734 | if (disconnect_lanes) { | 1461 | if (disconnect_lanes) { |
1735 | WARN_ON(!dsi->vdds_dsi_enabled); | 1462 | WARN_ON(!dsi->vdds_dsi_enabled); |
@@ -1738,18 +1465,27 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) | |||
1738 | } | 1465 | } |
1739 | 1466 | ||
1740 | dsi_disable_scp_clk(dsidev); | 1467 | dsi_disable_scp_clk(dsidev); |
1741 | dsi_enable_pll_clock(dsidev, 0); | 1468 | dsi_runtime_put(dsidev); |
1742 | 1469 | ||
1743 | DSSDBG("PLL uninit done\n"); | 1470 | DSSDBG("PLL uninit done\n"); |
1744 | } | 1471 | } |
1745 | 1472 | ||
1473 | static void dsi_pll_disable(struct dss_pll *pll) | ||
1474 | { | ||
1475 | struct dsi_data *dsi = container_of(pll, struct dsi_data, pll); | ||
1476 | struct platform_device *dsidev = dsi->pdev; | ||
1477 | |||
1478 | dsi_pll_uninit(dsidev, true); | ||
1479 | } | ||
1480 | |||
1746 | static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | 1481 | static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, |
1747 | struct seq_file *s) | 1482 | struct seq_file *s) |
1748 | { | 1483 | { |
1749 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1484 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1750 | struct dsi_clock_info *cinfo = &dsi->current_cinfo; | 1485 | struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; |
1751 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; | 1486 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; |
1752 | int dsi_module = dsi->module_id; | 1487 | int dsi_module = dsi->module_id; |
1488 | struct dss_pll *pll = &dsi->pll; | ||
1753 | 1489 | ||
1754 | dispc_clk_src = dss_get_dispc_clk_source(); | 1490 | dispc_clk_src = dss_get_dispc_clk_source(); |
1755 | dsi_clk_src = dss_get_dsi_clk_source(dsi_module); | 1491 | dsi_clk_src = dss_get_dsi_clk_source(dsi_module); |
@@ -1759,28 +1495,28 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
1759 | 1495 | ||
1760 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); | 1496 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); |
1761 | 1497 | ||
1762 | seq_printf(s, "dsi pll clkin\t%lu\n", cinfo->clkin); | 1498 | seq_printf(s, "dsi pll clkin\t%lu\n", clk_get_rate(pll->clkin)); |
1763 | 1499 | ||
1764 | seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); | 1500 | seq_printf(s, "Fint\t\t%-16lun %u\n", cinfo->fint, cinfo->n); |
1765 | 1501 | ||
1766 | seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", | 1502 | seq_printf(s, "CLKIN4DDR\t%-16lum %u\n", |
1767 | cinfo->clkin4ddr, cinfo->regm); | 1503 | cinfo->clkdco, cinfo->m); |
1768 | 1504 | ||
1769 | seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n", | 1505 | seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n", |
1770 | dss_feat_get_clk_source_name(dsi_module == 0 ? | 1506 | dss_feat_get_clk_source_name(dsi_module == 0 ? |
1771 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : | 1507 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : |
1772 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), | 1508 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), |
1773 | cinfo->dsi_pll_hsdiv_dispc_clk, | 1509 | cinfo->clkout[HSDIV_DISPC], |
1774 | cinfo->regm_dispc, | 1510 | cinfo->mX[HSDIV_DISPC], |
1775 | dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? | 1511 | dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? |
1776 | "off" : "on"); | 1512 | "off" : "on"); |
1777 | 1513 | ||
1778 | seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n", | 1514 | seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n", |
1779 | dss_feat_get_clk_source_name(dsi_module == 0 ? | 1515 | dss_feat_get_clk_source_name(dsi_module == 0 ? |
1780 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : | 1516 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : |
1781 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), | 1517 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), |
1782 | cinfo->dsi_pll_hsdiv_dsi_clk, | 1518 | cinfo->clkout[HSDIV_DSI], |
1783 | cinfo->regm_dsi, | 1519 | cinfo->mX[HSDIV_DSI], |
1784 | dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? | 1520 | dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? |
1785 | "off" : "on"); | 1521 | "off" : "on"); |
1786 | 1522 | ||
@@ -1793,11 +1529,11 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, | |||
1793 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); | 1529 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); |
1794 | 1530 | ||
1795 | seq_printf(s, "DDR_CLK\t\t%lu\n", | 1531 | seq_printf(s, "DDR_CLK\t\t%lu\n", |
1796 | cinfo->clkin4ddr / 4); | 1532 | cinfo->clkdco / 4); |
1797 | 1533 | ||
1798 | seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev)); | 1534 | seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev)); |
1799 | 1535 | ||
1800 | seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); | 1536 | seq_printf(s, "LP_CLK\t\t%lu\n", dsi->current_lp_cinfo.lp_clk); |
1801 | 1537 | ||
1802 | dsi_runtime_put(dsidev); | 1538 | dsi_runtime_put(dsidev); |
1803 | } | 1539 | } |
@@ -2132,7 +1868,7 @@ static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns) | |||
2132 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1868 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2133 | 1869 | ||
2134 | /* convert time in ns to ddr ticks, rounding up */ | 1870 | /* convert time in ns to ddr ticks, rounding up */ |
2135 | unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; | 1871 | unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4; |
2136 | return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; | 1872 | return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; |
2137 | } | 1873 | } |
2138 | 1874 | ||
@@ -2140,7 +1876,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr) | |||
2140 | { | 1876 | { |
2141 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1877 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2142 | 1878 | ||
2143 | unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; | 1879 | unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4; |
2144 | return ddr * 1000 * 1000 / (ddr_clk / 1000); | 1880 | return ddr * 1000 * 1000 / (ddr_clk / 1000); |
2145 | } | 1881 | } |
2146 | 1882 | ||
@@ -3730,7 +3466,7 @@ static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev) | |||
3730 | struct omap_video_timings *timings = &dsi->timings; | 3466 | struct omap_video_timings *timings = &dsi->timings; |
3731 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); | 3467 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
3732 | int ndl = dsi->num_lanes_used - 1; | 3468 | int ndl = dsi->num_lanes_used - 1; |
3733 | int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_dsi + 1; | 3469 | int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1; |
3734 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; | 3470 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; |
3735 | int hfp_interleave_hs = 0, hfp_interleave_lp = 0; | 3471 | int hfp_interleave_hs = 0, hfp_interleave_lp = 0; |
3736 | int hbp_interleave_hs = 0, hbp_interleave_lp = 0; | 3472 | int hbp_interleave_hs = 0, hbp_interleave_lp = 0; |
@@ -4441,18 +4177,12 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev, | |||
4441 | static int dsi_configure_dsi_clocks(struct platform_device *dsidev) | 4177 | static int dsi_configure_dsi_clocks(struct platform_device *dsidev) |
4442 | { | 4178 | { |
4443 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4179 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4444 | struct dsi_clock_info cinfo; | 4180 | struct dss_pll_clock_info cinfo; |
4445 | int r; | 4181 | int r; |
4446 | 4182 | ||
4447 | cinfo = dsi->user_dsi_cinfo; | 4183 | cinfo = dsi->user_dsi_cinfo; |
4448 | 4184 | ||
4449 | r = dsi_calc_clock_rates(dsidev, &cinfo); | 4185 | r = dss_pll_set_config(&dsi->pll, &cinfo); |
4450 | if (r) { | ||
4451 | DSSERR("Failed to calc dsi clocks\n"); | ||
4452 | return r; | ||
4453 | } | ||
4454 | |||
4455 | r = dsi_pll_set_clock_div(dsidev, &cinfo); | ||
4456 | if (r) { | 4186 | if (r) { |
4457 | DSSERR("Failed to set dsi clocks\n"); | 4187 | DSSERR("Failed to set dsi clocks\n"); |
4458 | return r; | 4188 | return r; |
@@ -4466,7 +4196,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev) | |||
4466 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4196 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4467 | int r; | 4197 | int r; |
4468 | 4198 | ||
4469 | r = dsi_pll_init(dsidev, true, true); | 4199 | r = dss_pll_enable(&dsi->pll); |
4470 | if (r) | 4200 | if (r) |
4471 | goto err0; | 4201 | goto err0; |
4472 | 4202 | ||
@@ -4510,7 +4240,7 @@ err3: | |||
4510 | err2: | 4240 | err2: |
4511 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4241 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
4512 | err1: | 4242 | err1: |
4513 | dsi_pll_uninit(dsidev, true); | 4243 | dss_pll_disable(&dsi->pll); |
4514 | err0: | 4244 | err0: |
4515 | return r; | 4245 | return r; |
4516 | } | 4246 | } |
@@ -4551,8 +4281,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) | |||
4551 | if (r) | 4281 | if (r) |
4552 | goto err_get_dsi; | 4282 | goto err_get_dsi; |
4553 | 4283 | ||
4554 | dsi_enable_pll_clock(dsidev, 1); | ||
4555 | |||
4556 | _dsi_initialize_irq(dsidev); | 4284 | _dsi_initialize_irq(dsidev); |
4557 | 4285 | ||
4558 | r = dsi_display_init_dsi(dsidev); | 4286 | r = dsi_display_init_dsi(dsidev); |
@@ -4564,7 +4292,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev) | |||
4564 | return 0; | 4292 | return 0; |
4565 | 4293 | ||
4566 | err_init_dsi: | 4294 | err_init_dsi: |
4567 | dsi_enable_pll_clock(dsidev, 0); | ||
4568 | dsi_runtime_put(dsidev); | 4295 | dsi_runtime_put(dsidev); |
4569 | err_get_dsi: | 4296 | err_get_dsi: |
4570 | mutex_unlock(&dsi->lock); | 4297 | mutex_unlock(&dsi->lock); |
@@ -4592,7 +4319,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev, | |||
4592 | dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps); | 4319 | dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps); |
4593 | 4320 | ||
4594 | dsi_runtime_put(dsidev); | 4321 | dsi_runtime_put(dsidev); |
4595 | dsi_enable_pll_clock(dsidev, 0); | ||
4596 | 4322 | ||
4597 | mutex_unlock(&dsi->lock); | 4323 | mutex_unlock(&dsi->lock); |
4598 | } | 4324 | } |
@@ -4713,29 +4439,30 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, | |||
4713 | return true; | 4439 | return true; |
4714 | } | 4440 | } |
4715 | 4441 | ||
4716 | static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, | 4442 | static bool dsi_cm_calc_hsdiv_cb(int m_dispc, unsigned long dispc, |
4717 | void *data) | 4443 | void *data) |
4718 | { | 4444 | { |
4719 | struct dsi_clk_calc_ctx *ctx = data; | 4445 | struct dsi_clk_calc_ctx *ctx = data; |
4720 | 4446 | ||
4721 | ctx->dsi_cinfo.regm_dispc = regm_dispc; | 4447 | ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc; |
4722 | ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; | 4448 | ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc; |
4723 | 4449 | ||
4724 | return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max, | 4450 | return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max, |
4725 | dsi_cm_calc_dispc_cb, ctx); | 4451 | dsi_cm_calc_dispc_cb, ctx); |
4726 | } | 4452 | } |
4727 | 4453 | ||
4728 | static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint, | 4454 | static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint, |
4729 | unsigned long pll, void *data) | 4455 | unsigned long clkdco, void *data) |
4730 | { | 4456 | { |
4731 | struct dsi_clk_calc_ctx *ctx = data; | 4457 | struct dsi_clk_calc_ctx *ctx = data; |
4732 | 4458 | ||
4733 | ctx->dsi_cinfo.regn = regn; | 4459 | ctx->dsi_cinfo.n = n; |
4734 | ctx->dsi_cinfo.regm = regm; | 4460 | ctx->dsi_cinfo.m = m; |
4735 | ctx->dsi_cinfo.fint = fint; | 4461 | ctx->dsi_cinfo.fint = fint; |
4736 | ctx->dsi_cinfo.clkin4ddr = pll; | 4462 | ctx->dsi_cinfo.clkdco = clkdco; |
4737 | 4463 | ||
4738 | return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, | 4464 | return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, |
4465 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), | ||
4739 | dsi_cm_calc_hsdiv_cb, ctx); | 4466 | dsi_cm_calc_hsdiv_cb, ctx); |
4740 | } | 4467 | } |
4741 | 4468 | ||
@@ -4748,7 +4475,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi, | |||
4748 | unsigned long pll_min, pll_max; | 4475 | unsigned long pll_min, pll_max; |
4749 | unsigned long pck, txbyteclk; | 4476 | unsigned long pck, txbyteclk; |
4750 | 4477 | ||
4751 | clkin = clk_get_rate(dsi->sys_clk); | 4478 | clkin = clk_get_rate(dsi->pll.clkin); |
4752 | bitspp = dsi_get_pixel_size(cfg->pixel_format); | 4479 | bitspp = dsi_get_pixel_size(cfg->pixel_format); |
4753 | ndl = dsi->num_lanes_used - 1; | 4480 | ndl = dsi->num_lanes_used - 1; |
4754 | 4481 | ||
@@ -4764,16 +4491,16 @@ static bool dsi_cm_calc(struct dsi_data *dsi, | |||
4764 | 4491 | ||
4765 | memset(ctx, 0, sizeof(*ctx)); | 4492 | memset(ctx, 0, sizeof(*ctx)); |
4766 | ctx->dsidev = dsi->pdev; | 4493 | ctx->dsidev = dsi->pdev; |
4494 | ctx->pll = &dsi->pll; | ||
4767 | ctx->config = cfg; | 4495 | ctx->config = cfg; |
4768 | ctx->req_pck_min = pck; | 4496 | ctx->req_pck_min = pck; |
4769 | ctx->req_pck_nom = pck; | 4497 | ctx->req_pck_nom = pck; |
4770 | ctx->req_pck_max = pck * 3 / 2; | 4498 | ctx->req_pck_max = pck * 3 / 2; |
4771 | ctx->dsi_cinfo.clkin = clkin; | ||
4772 | 4499 | ||
4773 | pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); | 4500 | pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); |
4774 | pll_max = cfg->hs_clk_max * 4; | 4501 | pll_max = cfg->hs_clk_max * 4; |
4775 | 4502 | ||
4776 | return dsi_pll_calc(dsi->pdev, clkin, | 4503 | return dss_pll_calc(ctx->pll, clkin, |
4777 | pll_min, pll_max, | 4504 | pll_min, pll_max, |
4778 | dsi_cm_calc_pll_cb, ctx); | 4505 | dsi_cm_calc_pll_cb, ctx); |
4779 | } | 4506 | } |
@@ -4784,7 +4511,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx) | |||
4784 | const struct omap_dss_dsi_config *cfg = ctx->config; | 4511 | const struct omap_dss_dsi_config *cfg = ctx->config; |
4785 | int bitspp = dsi_get_pixel_size(cfg->pixel_format); | 4512 | int bitspp = dsi_get_pixel_size(cfg->pixel_format); |
4786 | int ndl = dsi->num_lanes_used - 1; | 4513 | int ndl = dsi->num_lanes_used - 1; |
4787 | unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4; | 4514 | unsigned long hsclk = ctx->dsi_cinfo.clkdco / 4; |
4788 | unsigned long byteclk = hsclk / 4; | 4515 | unsigned long byteclk = hsclk / 4; |
4789 | 4516 | ||
4790 | unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max; | 4517 | unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max; |
@@ -4999,14 +4726,14 @@ static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck, | |||
4999 | return true; | 4726 | return true; |
5000 | } | 4727 | } |
5001 | 4728 | ||
5002 | static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, | 4729 | static bool dsi_vm_calc_hsdiv_cb(int m_dispc, unsigned long dispc, |
5003 | void *data) | 4730 | void *data) |
5004 | { | 4731 | { |
5005 | struct dsi_clk_calc_ctx *ctx = data; | 4732 | struct dsi_clk_calc_ctx *ctx = data; |
5006 | unsigned long pck_max; | 4733 | unsigned long pck_max; |
5007 | 4734 | ||
5008 | ctx->dsi_cinfo.regm_dispc = regm_dispc; | 4735 | ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc; |
5009 | ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; | 4736 | ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc; |
5010 | 4737 | ||
5011 | /* | 4738 | /* |
5012 | * In burst mode we can let the dispc pck be arbitrarily high, but it | 4739 | * In burst mode we can let the dispc pck be arbitrarily high, but it |
@@ -5022,17 +4749,18 @@ static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, | |||
5022 | dsi_vm_calc_dispc_cb, ctx); | 4749 | dsi_vm_calc_dispc_cb, ctx); |
5023 | } | 4750 | } |
5024 | 4751 | ||
5025 | static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint, | 4752 | static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint, |
5026 | unsigned long pll, void *data) | 4753 | unsigned long clkdco, void *data) |
5027 | { | 4754 | { |
5028 | struct dsi_clk_calc_ctx *ctx = data; | 4755 | struct dsi_clk_calc_ctx *ctx = data; |
5029 | 4756 | ||
5030 | ctx->dsi_cinfo.regn = regn; | 4757 | ctx->dsi_cinfo.n = n; |
5031 | ctx->dsi_cinfo.regm = regm; | 4758 | ctx->dsi_cinfo.m = m; |
5032 | ctx->dsi_cinfo.fint = fint; | 4759 | ctx->dsi_cinfo.fint = fint; |
5033 | ctx->dsi_cinfo.clkin4ddr = pll; | 4760 | ctx->dsi_cinfo.clkdco = clkdco; |
5034 | 4761 | ||
5035 | return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, | 4762 | return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, |
4763 | dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), | ||
5036 | dsi_vm_calc_hsdiv_cb, ctx); | 4764 | dsi_vm_calc_hsdiv_cb, ctx); |
5037 | } | 4765 | } |
5038 | 4766 | ||
@@ -5048,14 +4776,13 @@ static bool dsi_vm_calc(struct dsi_data *dsi, | |||
5048 | int bitspp = dsi_get_pixel_size(cfg->pixel_format); | 4776 | int bitspp = dsi_get_pixel_size(cfg->pixel_format); |
5049 | unsigned long byteclk_min; | 4777 | unsigned long byteclk_min; |
5050 | 4778 | ||
5051 | clkin = clk_get_rate(dsi->sys_clk); | 4779 | clkin = clk_get_rate(dsi->pll.clkin); |
5052 | 4780 | ||
5053 | memset(ctx, 0, sizeof(*ctx)); | 4781 | memset(ctx, 0, sizeof(*ctx)); |
5054 | ctx->dsidev = dsi->pdev; | 4782 | ctx->dsidev = dsi->pdev; |
4783 | ctx->pll = &dsi->pll; | ||
5055 | ctx->config = cfg; | 4784 | ctx->config = cfg; |
5056 | 4785 | ||
5057 | ctx->dsi_cinfo.clkin = clkin; | ||
5058 | |||
5059 | /* these limits should come from the panel driver */ | 4786 | /* these limits should come from the panel driver */ |
5060 | ctx->req_pck_min = t->pixelclock - 1000; | 4787 | ctx->req_pck_min = t->pixelclock - 1000; |
5061 | ctx->req_pck_nom = t->pixelclock; | 4788 | ctx->req_pck_nom = t->pixelclock; |
@@ -5074,7 +4801,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi, | |||
5074 | pll_max = byteclk_max * 4 * 4; | 4801 | pll_max = byteclk_max * 4 * 4; |
5075 | } | 4802 | } |
5076 | 4803 | ||
5077 | return dsi_pll_calc(dsi->pdev, clkin, | 4804 | return dss_pll_calc(ctx->pll, clkin, |
5078 | pll_min, pll_max, | 4805 | pll_min, pll_max, |
5079 | dsi_vm_calc_pll_cb, ctx); | 4806 | dsi_vm_calc_pll_cb, ctx); |
5080 | } | 4807 | } |
@@ -5106,8 +4833,8 @@ static int dsi_set_config(struct omap_dss_device *dssdev, | |||
5106 | 4833 | ||
5107 | dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo); | 4834 | dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo); |
5108 | 4835 | ||
5109 | r = dsi_lp_clock_calc(&ctx.dsi_cinfo, config->lp_clk_min, | 4836 | r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI], |
5110 | config->lp_clk_max); | 4837 | config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo); |
5111 | if (r) { | 4838 | if (r) { |
5112 | DSSERR("failed to find suitable DSI LP clock settings\n"); | 4839 | DSSERR("failed to find suitable DSI LP clock settings\n"); |
5113 | goto err; | 4840 | goto err; |
@@ -5234,35 +4961,6 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel) | |||
5234 | } | 4961 | } |
5235 | } | 4962 | } |
5236 | 4963 | ||
5237 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev) | ||
5238 | { | ||
5239 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1) | ||
5240 | DSSERR("%s (%s) not active\n", | ||
5241 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | ||
5242 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); | ||
5243 | } | ||
5244 | |||
5245 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev) | ||
5246 | { | ||
5247 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1) | ||
5248 | DSSERR("%s (%s) not active\n", | ||
5249 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | ||
5250 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); | ||
5251 | } | ||
5252 | |||
5253 | static void dsi_calc_clock_param_ranges(struct platform_device *dsidev) | ||
5254 | { | ||
5255 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
5256 | |||
5257 | dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); | ||
5258 | dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); | ||
5259 | dsi->regm_dispc_max = | ||
5260 | dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); | ||
5261 | dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); | ||
5262 | dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); | ||
5263 | dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); | ||
5264 | dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); | ||
5265 | } | ||
5266 | 4964 | ||
5267 | static int dsi_get_clocks(struct platform_device *dsidev) | 4965 | static int dsi_get_clocks(struct platform_device *dsidev) |
5268 | { | 4966 | { |
@@ -5277,14 +4975,6 @@ static int dsi_get_clocks(struct platform_device *dsidev) | |||
5277 | 4975 | ||
5278 | dsi->dss_clk = clk; | 4976 | dsi->dss_clk = clk; |
5279 | 4977 | ||
5280 | clk = devm_clk_get(&dsidev->dev, "sys_clk"); | ||
5281 | if (IS_ERR(clk)) { | ||
5282 | DSSERR("can't get sys_clk\n"); | ||
5283 | return PTR_ERR(clk); | ||
5284 | } | ||
5285 | |||
5286 | dsi->sys_clk = clk; | ||
5287 | |||
5288 | return 0; | 4978 | return 0; |
5289 | } | 4979 | } |
5290 | 4980 | ||
@@ -5453,6 +5143,135 @@ err: | |||
5453 | return r; | 5143 | return r; |
5454 | } | 5144 | } |
5455 | 5145 | ||
5146 | static const struct dss_pll_ops dsi_pll_ops = { | ||
5147 | .enable = dsi_pll_enable, | ||
5148 | .disable = dsi_pll_disable, | ||
5149 | .set_config = dss_pll_write_config_type_a, | ||
5150 | }; | ||
5151 | |||
5152 | static const struct dss_pll_hw dss_omap3_dsi_pll_hw = { | ||
5153 | .n_max = (1 << 7) - 1, | ||
5154 | .m_max = (1 << 11) - 1, | ||
5155 | .mX_max = (1 << 4) - 1, | ||
5156 | .fint_min = 750000, | ||
5157 | .fint_max = 2100000, | ||
5158 | .clkdco_low = 1000000000, | ||
5159 | .clkdco_max = 1800000000, | ||
5160 | |||
5161 | .n_msb = 7, | ||
5162 | .n_lsb = 1, | ||
5163 | .m_msb = 18, | ||
5164 | .m_lsb = 8, | ||
5165 | |||
5166 | .mX_msb[0] = 22, | ||
5167 | .mX_lsb[0] = 19, | ||
5168 | .mX_msb[1] = 26, | ||
5169 | .mX_lsb[1] = 23, | ||
5170 | |||
5171 | .has_stopmode = true, | ||
5172 | .has_freqsel = true, | ||
5173 | .has_selfreqdco = false, | ||
5174 | .has_refsel = false, | ||
5175 | }; | ||
5176 | |||
5177 | static const struct dss_pll_hw dss_omap4_dsi_pll_hw = { | ||
5178 | .n_max = (1 << 8) - 1, | ||
5179 | .m_max = (1 << 12) - 1, | ||
5180 | .mX_max = (1 << 5) - 1, | ||
5181 | .fint_min = 500000, | ||
5182 | .fint_max = 2500000, | ||
5183 | .clkdco_low = 1000000000, | ||
5184 | .clkdco_max = 1800000000, | ||
5185 | |||
5186 | .n_msb = 8, | ||
5187 | .n_lsb = 1, | ||
5188 | .m_msb = 20, | ||
5189 | .m_lsb = 9, | ||
5190 | |||
5191 | .mX_msb[0] = 25, | ||
5192 | .mX_lsb[0] = 21, | ||
5193 | .mX_msb[1] = 30, | ||
5194 | .mX_lsb[1] = 26, | ||
5195 | |||
5196 | .has_stopmode = true, | ||
5197 | .has_freqsel = false, | ||
5198 | .has_selfreqdco = false, | ||
5199 | .has_refsel = false, | ||
5200 | }; | ||
5201 | |||
5202 | static const struct dss_pll_hw dss_omap5_dsi_pll_hw = { | ||
5203 | .n_max = (1 << 8) - 1, | ||
5204 | .m_max = (1 << 12) - 1, | ||
5205 | .mX_max = (1 << 5) - 1, | ||
5206 | .fint_min = 150000, | ||
5207 | .fint_max = 52000000, | ||
5208 | .clkdco_low = 1000000000, | ||
5209 | .clkdco_max = 1800000000, | ||
5210 | |||
5211 | .n_msb = 8, | ||
5212 | .n_lsb = 1, | ||
5213 | .m_msb = 20, | ||
5214 | .m_lsb = 9, | ||
5215 | |||
5216 | .mX_msb[0] = 25, | ||
5217 | .mX_lsb[0] = 21, | ||
5218 | .mX_msb[1] = 30, | ||
5219 | .mX_lsb[1] = 26, | ||
5220 | |||
5221 | .has_stopmode = true, | ||
5222 | .has_freqsel = false, | ||
5223 | .has_selfreqdco = true, | ||
5224 | .has_refsel = true, | ||
5225 | }; | ||
5226 | |||
5227 | static int dsi_init_pll_data(struct platform_device *dsidev) | ||
5228 | { | ||
5229 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
5230 | struct dss_pll *pll = &dsi->pll; | ||
5231 | struct clk *clk; | ||
5232 | int r; | ||
5233 | |||
5234 | clk = devm_clk_get(&dsidev->dev, "sys_clk"); | ||
5235 | if (IS_ERR(clk)) { | ||
5236 | DSSERR("can't get sys_clk\n"); | ||
5237 | return PTR_ERR(clk); | ||
5238 | } | ||
5239 | |||
5240 | pll->name = dsi->module_id == 0 ? "dsi0" : "dsi1"; | ||
5241 | pll->clkin = clk; | ||
5242 | pll->base = dsi->pll_base; | ||
5243 | |||
5244 | switch (omapdss_get_version()) { | ||
5245 | case OMAPDSS_VER_OMAP34xx_ES1: | ||
5246 | case OMAPDSS_VER_OMAP34xx_ES3: | ||
5247 | case OMAPDSS_VER_OMAP3630: | ||
5248 | case OMAPDSS_VER_AM35xx: | ||
5249 | pll->hw = &dss_omap3_dsi_pll_hw; | ||
5250 | break; | ||
5251 | |||
5252 | case OMAPDSS_VER_OMAP4430_ES1: | ||
5253 | case OMAPDSS_VER_OMAP4430_ES2: | ||
5254 | case OMAPDSS_VER_OMAP4: | ||
5255 | pll->hw = &dss_omap4_dsi_pll_hw; | ||
5256 | break; | ||
5257 | |||
5258 | case OMAPDSS_VER_OMAP5: | ||
5259 | pll->hw = &dss_omap5_dsi_pll_hw; | ||
5260 | break; | ||
5261 | |||
5262 | default: | ||
5263 | return -ENODEV; | ||
5264 | } | ||
5265 | |||
5266 | pll->ops = &dsi_pll_ops; | ||
5267 | |||
5268 | r = dss_pll_register(pll); | ||
5269 | if (r) | ||
5270 | return r; | ||
5271 | |||
5272 | return 0; | ||
5273 | } | ||
5274 | |||
5456 | /* DSI1 HW IP initialisation */ | 5275 | /* DSI1 HW IP initialisation */ |
5457 | static int omap_dsihw_probe(struct platform_device *dsidev) | 5276 | static int omap_dsihw_probe(struct platform_device *dsidev) |
5458 | { | 5277 | { |
@@ -5598,12 +5417,12 @@ static int omap_dsihw_probe(struct platform_device *dsidev) | |||
5598 | dsi->vc[i].vc_id = 0; | 5417 | dsi->vc[i].vc_id = 0; |
5599 | } | 5418 | } |
5600 | 5419 | ||
5601 | dsi_calc_clock_param_ranges(dsidev); | ||
5602 | |||
5603 | r = dsi_get_clocks(dsidev); | 5420 | r = dsi_get_clocks(dsidev); |
5604 | if (r) | 5421 | if (r) |
5605 | return r; | 5422 | return r; |
5606 | 5423 | ||
5424 | dsi_init_pll_data(dsidev); | ||
5425 | |||
5607 | pm_runtime_enable(&dsidev->dev); | 5426 | pm_runtime_enable(&dsidev->dev); |
5608 | 5427 | ||
5609 | r = dsi_runtime_get(dsidev); | 5428 | r = dsi_runtime_get(dsidev); |
@@ -5672,6 +5491,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) | |||
5672 | 5491 | ||
5673 | WARN_ON(dsi->scp_clk_refcount > 0); | 5492 | WARN_ON(dsi->scp_clk_refcount > 0); |
5674 | 5493 | ||
5494 | dss_pll_unregister(&dsi->pll); | ||
5495 | |||
5675 | dsi_uninit_output(dsidev); | 5496 | dsi_uninit_output(dsidev); |
5676 | 5497 | ||
5677 | pm_runtime_disable(&dsidev->dev); | 5498 | pm_runtime_disable(&dsidev->dev); |