aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dsi.c')
-rw-r--r--drivers/video/omap2/dss/dsi.c296
1 files changed, 179 insertions, 117 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 345757cfcbee..7adbbeb84334 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -36,6 +36,7 @@
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/pm_runtime.h>
39 40
40#include <video/omapdss.h> 41#include <video/omapdss.h>
41#include <plat/clock.h> 42#include <plat/clock.h>
@@ -267,8 +268,12 @@ struct dsi_isr_tables {
267struct dsi_data { 268struct dsi_data {
268 struct platform_device *pdev; 269 struct platform_device *pdev;
269 void __iomem *base; 270 void __iomem *base;
271
270 int irq; 272 int irq;
271 273
274 struct clk *dss_clk;
275 struct clk *sys_clk;
276
272 void (*dsi_mux_pads)(bool enable); 277 void (*dsi_mux_pads)(bool enable);
273 278
274 struct dsi_clock_info current_cinfo; 279 struct dsi_clock_info current_cinfo;
@@ -389,15 +394,6 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
389 return __raw_readl(dsi->base + idx.idx); 394 return __raw_readl(dsi->base + idx.idx);
390} 395}
391 396
392
393void dsi_save_context(void)
394{
395}
396
397void dsi_restore_context(void)
398{
399}
400
401void dsi_bus_lock(struct omap_dss_device *dssdev) 397void dsi_bus_lock(struct omap_dss_device *dssdev)
402{ 398{
403 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 399 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -493,9 +489,18 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
493 total_bytes * 1000 / total_us); 489 total_bytes * 1000 / total_us);
494} 490}
495#else 491#else
496#define dsi_perf_mark_setup(x) 492static inline void dsi_perf_mark_setup(struct platform_device *dsidev)
497#define dsi_perf_mark_start(x) 493{
498#define dsi_perf_show(x, y) 494}
495
496static inline void dsi_perf_mark_start(struct platform_device *dsidev)
497{
498}
499
500static inline void dsi_perf_show(struct platform_device *dsidev,
501 const char *name)
502{
503}
499#endif 504#endif
500 505
501static void print_irq_status(u32 status) 506static void print_irq_status(u32 status)
@@ -1039,13 +1044,27 @@ static u32 dsi_get_errors(struct platform_device *dsidev)
1039 return e; 1044 return e;
1040} 1045}
1041 1046
1042/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */ 1047int dsi_runtime_get(struct platform_device *dsidev)
1043static inline void enable_clocks(bool enable)
1044{ 1048{
1045 if (enable) 1049 int r;
1046 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1050 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1047 else 1051
1048 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1052 DSSDBG("dsi_runtime_get\n");
1053
1054 r = pm_runtime_get_sync(&dsi->pdev->dev);
1055 WARN_ON(r < 0);
1056 return r < 0 ? r : 0;
1057}
1058
1059void dsi_runtime_put(struct platform_device *dsidev)
1060{
1061 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1062 int r;
1063
1064 DSSDBG("dsi_runtime_put\n");
1065
1066 r = pm_runtime_put(&dsi->pdev->dev);
1067 WARN_ON(r < 0);
1049} 1068}
1050 1069
1051/* source clock for DSI PLL. this could also be PCLKFREE */ 1070/* source clock for DSI PLL. this could also be PCLKFREE */
@@ -1055,9 +1074,9 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1055 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1074 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1056 1075
1057 if (enable) 1076 if (enable)
1058 dss_clk_enable(DSS_CLK_SYSCK); 1077 clk_enable(dsi->sys_clk);
1059 else 1078 else
1060 dss_clk_disable(DSS_CLK_SYSCK); 1079 clk_disable(dsi->sys_clk);
1061 1080
1062 if (enable && dsi->pll_locked) { 1081 if (enable && dsi->pll_locked) {
1063 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) 1082 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
@@ -1150,10 +1169,11 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1150{ 1169{
1151 unsigned long r; 1170 unsigned long r;
1152 int dsi_module = dsi_get_dsidev_id(dsidev); 1171 int dsi_module = dsi_get_dsidev_id(dsidev);
1172 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1153 1173
1154 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { 1174 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) {
1155 /* DSI FCLK source is DSS_CLK_FCK */ 1175 /* DSI FCLK source is DSS_CLK_FCK */
1156 r = dss_clk_get_rate(DSS_CLK_FCK); 1176 r = clk_get_rate(dsi->dss_clk);
1157 } else { 1177 } else {
1158 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ 1178 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
1159 r = dsi_get_pll_hsdiv_dsi_rate(dsidev); 1179 r = dsi_get_pll_hsdiv_dsi_rate(dsidev);
@@ -1262,7 +1282,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1262 return -EINVAL; 1282 return -EINVAL;
1263 1283
1264 if (cinfo->use_sys_clk) { 1284 if (cinfo->use_sys_clk) {
1265 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); 1285 cinfo->clkin = clk_get_rate(dsi->sys_clk);
1266 /* XXX it is unclear if highfreq should be used 1286 /* XXX it is unclear if highfreq should be used
1267 * with DSS_SYS_CLK source also */ 1287 * with DSS_SYS_CLK source also */
1268 cinfo->highfreq = 0; 1288 cinfo->highfreq = 0;
@@ -1311,7 +1331,7 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
1311 int match = 0; 1331 int match = 0;
1312 unsigned long dss_sys_clk, max_dss_fck; 1332 unsigned long dss_sys_clk, max_dss_fck;
1313 1333
1314 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK); 1334 dss_sys_clk = clk_get_rate(dsi->sys_clk);
1315 1335
1316 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1336 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1317 1337
@@ -1601,7 +1621,6 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1601 dsi->vdds_dsi_reg = vdds_dsi; 1621 dsi->vdds_dsi_reg = vdds_dsi;
1602 } 1622 }
1603 1623
1604 enable_clocks(1);
1605 dsi_enable_pll_clock(dsidev, 1); 1624 dsi_enable_pll_clock(dsidev, 1);
1606 /* 1625 /*
1607 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. 1626 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
@@ -1653,7 +1672,6 @@ err1:
1653 } 1672 }
1654err0: 1673err0:
1655 dsi_disable_scp_clk(dsidev); 1674 dsi_disable_scp_clk(dsidev);
1656 enable_clocks(0);
1657 dsi_enable_pll_clock(dsidev, 0); 1675 dsi_enable_pll_clock(dsidev, 0);
1658 return r; 1676 return r;
1659} 1677}
@@ -1671,7 +1689,6 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1671 } 1689 }
1672 1690
1673 dsi_disable_scp_clk(dsidev); 1691 dsi_disable_scp_clk(dsidev);
1674 enable_clocks(0);
1675 dsi_enable_pll_clock(dsidev, 0); 1692 dsi_enable_pll_clock(dsidev, 0);
1676 1693
1677 DSSDBG("PLL uninit done\n"); 1694 DSSDBG("PLL uninit done\n");
@@ -1688,7 +1705,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1688 dispc_clk_src = dss_get_dispc_clk_source(); 1705 dispc_clk_src = dss_get_dispc_clk_source();
1689 dsi_clk_src = dss_get_dsi_clk_source(dsi_module); 1706 dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
1690 1707
1691 enable_clocks(1); 1708 if (dsi_runtime_get(dsidev))
1709 return;
1692 1710
1693 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); 1711 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
1694 1712
@@ -1731,7 +1749,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1731 1749
1732 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1750 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk);
1733 1751
1734 enable_clocks(0); 1752 dsi_runtime_put(dsidev);
1735} 1753}
1736 1754
1737void dsi_dump_clocks(struct seq_file *s) 1755void dsi_dump_clocks(struct seq_file *s)
@@ -1873,7 +1891,8 @@ static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1873{ 1891{
1874#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r)) 1892#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
1875 1893
1876 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1894 if (dsi_runtime_get(dsidev))
1895 return;
1877 dsi_enable_scp_clk(dsidev); 1896 dsi_enable_scp_clk(dsidev);
1878 1897
1879 DUMPREG(DSI_REVISION); 1898 DUMPREG(DSI_REVISION);
@@ -1947,7 +1966,7 @@ static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1947 DUMPREG(DSI_PLL_CONFIGURATION2); 1966 DUMPREG(DSI_PLL_CONFIGURATION2);
1948 1967
1949 dsi_disable_scp_clk(dsidev); 1968 dsi_disable_scp_clk(dsidev);
1950 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1969 dsi_runtime_put(dsidev);
1951#undef DUMPREG 1970#undef DUMPREG
1952} 1971}
1953 1972
@@ -2463,28 +2482,6 @@ static void dsi_cio_uninit(struct platform_device *dsidev)
2463 dsi->dsi_mux_pads(false); 2482 dsi->dsi_mux_pads(false);
2464} 2483}
2465 2484
2466static int _dsi_wait_reset(struct platform_device *dsidev)
2467{
2468 int t = 0;
2469
2470 while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
2471 if (++t > 5) {
2472 DSSERR("soft reset failed\n");
2473 return -ENODEV;
2474 }
2475 udelay(1);
2476 }
2477
2478 return 0;
2479}
2480
2481static int _dsi_reset(struct platform_device *dsidev)
2482{
2483 /* Soft reset */
2484 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
2485 return _dsi_wait_reset(dsidev);
2486}
2487
2488static void dsi_config_tx_fifo(struct platform_device *dsidev, 2485static void dsi_config_tx_fifo(struct platform_device *dsidev,
2489 enum fifo_size size1, enum fifo_size size2, 2486 enum fifo_size size1, enum fifo_size size2,
2490 enum fifo_size size3, enum fifo_size size4) 2487 enum fifo_size size3, enum fifo_size size4)
@@ -3386,6 +3383,10 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
3386 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion, 3383 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3387 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); 3384 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3388 3385
3386 /* Reset LANEx_ULPS_SIG2 */
3387 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
3388 7, 5);
3389
3389 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS); 3390 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
3390 3391
3391 dsi_if_enable(dsidev, false); 3392 dsi_if_enable(dsidev, false);
@@ -4198,22 +4199,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4198 dsi_pll_uninit(dsidev, disconnect_lanes); 4199 dsi_pll_uninit(dsidev, disconnect_lanes);
4199} 4200}
4200 4201
4201static int dsi_core_init(struct platform_device *dsidev)
4202{
4203 /* Autoidle */
4204 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0);
4205
4206 /* ENWAKEUP */
4207 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2);
4208
4209 /* SIDLEMODE smart-idle */
4210 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3);
4211
4212 _dsi_initialize_irq(dsidev);
4213
4214 return 0;
4215}
4216
4217int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) 4202int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4218{ 4203{
4219 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4204 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4229,37 +4214,37 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4229 r = omap_dss_start_device(dssdev); 4214 r = omap_dss_start_device(dssdev);
4230 if (r) { 4215 if (r) {
4231 DSSERR("failed to start device\n"); 4216 DSSERR("failed to start device\n");
4232 goto err0; 4217 goto err_start_dev;
4233 } 4218 }
4234 4219
4235 enable_clocks(1); 4220 r = dsi_runtime_get(dsidev);
4236 dsi_enable_pll_clock(dsidev, 1);
4237
4238 r = _dsi_reset(dsidev);
4239 if (r) 4221 if (r)
4240 goto err1; 4222 goto err_get_dsi;
4241 4223
4242 dsi_core_init(dsidev); 4224 dsi_enable_pll_clock(dsidev, 1);
4225
4226 _dsi_initialize_irq(dsidev);
4243 4227
4244 r = dsi_display_init_dispc(dssdev); 4228 r = dsi_display_init_dispc(dssdev);
4245 if (r) 4229 if (r)
4246 goto err1; 4230 goto err_init_dispc;
4247 4231
4248 r = dsi_display_init_dsi(dssdev); 4232 r = dsi_display_init_dsi(dssdev);
4249 if (r) 4233 if (r)
4250 goto err2; 4234 goto err_init_dsi;
4251 4235
4252 mutex_unlock(&dsi->lock); 4236 mutex_unlock(&dsi->lock);
4253 4237
4254 return 0; 4238 return 0;
4255 4239
4256err2: 4240err_init_dsi:
4257 dsi_display_uninit_dispc(dssdev); 4241 dsi_display_uninit_dispc(dssdev);
4258err1: 4242err_init_dispc:
4259 enable_clocks(0);
4260 dsi_enable_pll_clock(dsidev, 0); 4243 dsi_enable_pll_clock(dsidev, 0);
4244 dsi_runtime_put(dsidev);
4245err_get_dsi:
4261 omap_dss_stop_device(dssdev); 4246 omap_dss_stop_device(dssdev);
4262err0: 4247err_start_dev:
4263 mutex_unlock(&dsi->lock); 4248 mutex_unlock(&dsi->lock);
4264 DSSDBG("dsi_display_enable FAILED\n"); 4249 DSSDBG("dsi_display_enable FAILED\n");
4265 return r; 4250 return r;
@@ -4278,11 +4263,16 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4278 4263
4279 mutex_lock(&dsi->lock); 4264 mutex_lock(&dsi->lock);
4280 4265
4266 dsi_sync_vc(dsidev, 0);
4267 dsi_sync_vc(dsidev, 1);
4268 dsi_sync_vc(dsidev, 2);
4269 dsi_sync_vc(dsidev, 3);
4270
4281 dsi_display_uninit_dispc(dssdev); 4271 dsi_display_uninit_dispc(dssdev);
4282 4272
4283 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps); 4273 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
4284 4274
4285 enable_clocks(0); 4275 dsi_runtime_put(dsidev);
4286 dsi_enable_pll_clock(dsidev, 0); 4276 dsi_enable_pll_clock(dsidev, 0);
4287 4277
4288 omap_dss_stop_device(dssdev); 4278 omap_dss_stop_device(dssdev);
@@ -4302,16 +4292,11 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
4302EXPORT_SYMBOL(omapdss_dsi_enable_te); 4292EXPORT_SYMBOL(omapdss_dsi_enable_te);
4303 4293
4304void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 4294void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
4305 u32 fifo_size, enum omap_burst_size *burst_size, 4295 u32 fifo_size, u32 burst_size,
4306 u32 *fifo_low, u32 *fifo_high) 4296 u32 *fifo_low, u32 *fifo_high)
4307{ 4297{
4308 unsigned burst_size_bytes; 4298 *fifo_high = fifo_size - burst_size;
4309 4299 *fifo_low = fifo_size - burst_size * 2;
4310 *burst_size = OMAP_DSS_BURST_16x32;
4311 burst_size_bytes = 16 * 32 / 8;
4312
4313 *fifo_high = fifo_size - burst_size_bytes;
4314 *fifo_low = fifo_size - burst_size_bytes * 2;
4315} 4300}
4316 4301
4317int dsi_init_display(struct omap_dss_device *dssdev) 4302int dsi_init_display(struct omap_dss_device *dssdev)
@@ -4437,7 +4422,47 @@ static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
4437 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); 4422 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
4438} 4423}
4439 4424
4440static int dsi_init(struct platform_device *dsidev) 4425static int dsi_get_clocks(struct platform_device *dsidev)
4426{
4427 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4428 struct clk *clk;
4429
4430 clk = clk_get(&dsidev->dev, "fck");
4431 if (IS_ERR(clk)) {
4432 DSSERR("can't get fck\n");
4433 return PTR_ERR(clk);
4434 }
4435
4436 dsi->dss_clk = clk;
4437
4438 if (cpu_is_omap34xx() || cpu_is_omap3630())
4439 clk = clk_get(&dsidev->dev, "dss2_alwon_fck");
4440 else
4441 clk = clk_get(&dsidev->dev, "sys_clk");
4442 if (IS_ERR(clk)) {
4443 DSSERR("can't get sys_clk\n");
4444 clk_put(dsi->dss_clk);
4445 dsi->dss_clk = NULL;
4446 return PTR_ERR(clk);
4447 }
4448
4449 dsi->sys_clk = clk;
4450
4451 return 0;
4452}
4453
4454static void dsi_put_clocks(struct platform_device *dsidev)
4455{
4456 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4457
4458 if (dsi->dss_clk)
4459 clk_put(dsi->dss_clk);
4460 if (dsi->sys_clk)
4461 clk_put(dsi->sys_clk);
4462}
4463
4464/* DSI1 HW IP initialisation */
4465static int omap_dsi1hw_probe(struct platform_device *dsidev)
4441{ 4466{
4442 struct omap_display_platform_data *dss_plat_data; 4467 struct omap_display_platform_data *dss_plat_data;
4443 struct omap_dss_board_info *board_info; 4468 struct omap_dss_board_info *board_info;
@@ -4449,7 +4474,7 @@ static int dsi_init(struct platform_device *dsidev)
4449 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4474 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
4450 if (!dsi) { 4475 if (!dsi) {
4451 r = -ENOMEM; 4476 r = -ENOMEM;
4452 goto err0; 4477 goto err_alloc;
4453 } 4478 }
4454 4479
4455 dsi->pdev = dsidev; 4480 dsi->pdev = dsidev;
@@ -4472,6 +4497,12 @@ static int dsi_init(struct platform_device *dsidev)
4472 mutex_init(&dsi->lock); 4497 mutex_init(&dsi->lock);
4473 sema_init(&dsi->bus_lock, 1); 4498 sema_init(&dsi->bus_lock, 1);
4474 4499
4500 r = dsi_get_clocks(dsidev);
4501 if (r)
4502 goto err_get_clk;
4503
4504 pm_runtime_enable(&dsidev->dev);
4505
4475 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, 4506 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
4476 dsi_framedone_timeout_work_callback); 4507 dsi_framedone_timeout_work_callback);
4477 4508
@@ -4484,26 +4515,26 @@ static int dsi_init(struct platform_device *dsidev)
4484 if (!dsi_mem) { 4515 if (!dsi_mem) {
4485 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4516 DSSERR("can't get IORESOURCE_MEM DSI\n");
4486 r = -EINVAL; 4517 r = -EINVAL;
4487 goto err1; 4518 goto err_ioremap;
4488 } 4519 }
4489 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4520 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
4490 if (!dsi->base) { 4521 if (!dsi->base) {
4491 DSSERR("can't ioremap DSI\n"); 4522 DSSERR("can't ioremap DSI\n");
4492 r = -ENOMEM; 4523 r = -ENOMEM;
4493 goto err1; 4524 goto err_ioremap;
4494 } 4525 }
4495 dsi->irq = platform_get_irq(dsi->pdev, 0); 4526 dsi->irq = platform_get_irq(dsi->pdev, 0);
4496 if (dsi->irq < 0) { 4527 if (dsi->irq < 0) {
4497 DSSERR("platform_get_irq failed\n"); 4528 DSSERR("platform_get_irq failed\n");
4498 r = -ENODEV; 4529 r = -ENODEV;
4499 goto err2; 4530 goto err_get_irq;
4500 } 4531 }
4501 4532
4502 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, 4533 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
4503 dev_name(&dsidev->dev), dsi->pdev); 4534 dev_name(&dsidev->dev), dsi->pdev);
4504 if (r < 0) { 4535 if (r < 0) {
4505 DSSERR("request_irq failed\n"); 4536 DSSERR("request_irq failed\n");
4506 goto err2; 4537 goto err_get_irq;
4507 } 4538 }
4508 4539
4509 /* DSI VCs initialization */ 4540 /* DSI VCs initialization */
@@ -4515,7 +4546,9 @@ static int dsi_init(struct platform_device *dsidev)
4515 4546
4516 dsi_calc_clock_param_ranges(dsidev); 4547 dsi_calc_clock_param_ranges(dsidev);
4517 4548
4518 enable_clocks(1); 4549 r = dsi_runtime_get(dsidev);
4550 if (r)
4551 goto err_get_dsi;
4519 4552
4520 rev = dsi_read_reg(dsidev, DSI_REVISION); 4553 rev = dsi_read_reg(dsidev, DSI_REVISION);
4521 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", 4554 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
@@ -4523,21 +4556,32 @@ static int dsi_init(struct platform_device *dsidev)
4523 4556
4524 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev); 4557 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
4525 4558
4526 enable_clocks(0); 4559 dsi_runtime_put(dsidev);
4527 4560
4528 return 0; 4561 return 0;
4529err2: 4562
4563err_get_dsi:
4564 free_irq(dsi->irq, dsi->pdev);
4565err_get_irq:
4530 iounmap(dsi->base); 4566 iounmap(dsi->base);
4531err1: 4567err_ioremap:
4568 pm_runtime_disable(&dsidev->dev);
4569err_get_clk:
4532 kfree(dsi); 4570 kfree(dsi);
4533err0: 4571err_alloc:
4534 return r; 4572 return r;
4535} 4573}
4536 4574
4537static void dsi_exit(struct platform_device *dsidev) 4575static int omap_dsi1hw_remove(struct platform_device *dsidev)
4538{ 4576{
4539 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4577 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4540 4578
4579 WARN_ON(dsi->scp_clk_refcount > 0);
4580
4581 pm_runtime_disable(&dsidev->dev);
4582
4583 dsi_put_clocks(dsidev);
4584
4541 if (dsi->vdds_dsi_reg != NULL) { 4585 if (dsi->vdds_dsi_reg != NULL) {
4542 if (dsi->vdds_dsi_enabled) { 4586 if (dsi->vdds_dsi_enabled) {
4543 regulator_disable(dsi->vdds_dsi_reg); 4587 regulator_disable(dsi->vdds_dsi_reg);
@@ -4553,38 +4597,56 @@ static void dsi_exit(struct platform_device *dsidev)
4553 4597
4554 kfree(dsi); 4598 kfree(dsi);
4555 4599
4556 DSSDBG("omap_dsi_exit\n"); 4600 return 0;
4557} 4601}
4558 4602
4559/* DSI1 HW IP initialisation */ 4603static int dsi_runtime_suspend(struct device *dev)
4560static int omap_dsi1hw_probe(struct platform_device *dsidev)
4561{ 4604{
4562 int r; 4605 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4563 4606
4564 r = dsi_init(dsidev); 4607 clk_disable(dsi->dss_clk);
4565 if (r) { 4608
4566 DSSERR("Failed to initialize DSI\n"); 4609 dispc_runtime_put();
4567 goto err_dsi; 4610 dss_runtime_put();
4568 } 4611
4569err_dsi: 4612 return 0;
4570 return r;
4571} 4613}
4572 4614
4573static int omap_dsi1hw_remove(struct platform_device *dsidev) 4615static int dsi_runtime_resume(struct device *dev)
4574{ 4616{
4575 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4617 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4618 int r;
4619
4620 r = dss_runtime_get();
4621 if (r)
4622 goto err_get_dss;
4623
4624 r = dispc_runtime_get();
4625 if (r)
4626 goto err_get_dispc;
4627
4628 clk_enable(dsi->dss_clk);
4576 4629
4577 dsi_exit(dsidev);
4578 WARN_ON(dsi->scp_clk_refcount > 0);
4579 return 0; 4630 return 0;
4631
4632err_get_dispc:
4633 dss_runtime_put();
4634err_get_dss:
4635 return r;
4580} 4636}
4581 4637
4638static const struct dev_pm_ops dsi_pm_ops = {
4639 .runtime_suspend = dsi_runtime_suspend,
4640 .runtime_resume = dsi_runtime_resume,
4641};
4642
4582static struct platform_driver omap_dsi1hw_driver = { 4643static struct platform_driver omap_dsi1hw_driver = {
4583 .probe = omap_dsi1hw_probe, 4644 .probe = omap_dsi1hw_probe,
4584 .remove = omap_dsi1hw_remove, 4645 .remove = omap_dsi1hw_remove,
4585 .driver = { 4646 .driver = {
4586 .name = "omapdss_dsi1", 4647 .name = "omapdss_dsi1",
4587 .owner = THIS_MODULE, 4648 .owner = THIS_MODULE,
4649 .pm = &dsi_pm_ops,
4588 }, 4650 },
4589}; 4651};
4590 4652