.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2009 Nokia Corporation |
---|
3 | 4 | * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
7 | | - * the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
---|
10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
12 | | - * more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License along with |
---|
15 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
---|
16 | 5 | */ |
---|
17 | 6 | |
---|
18 | 7 | #define DSS_SUBSYS_NAME "DSI" |
---|
.. | .. |
---|
403 | 392 | struct { |
---|
404 | 393 | struct dss_debugfs_entry *irqs; |
---|
405 | 394 | struct dss_debugfs_entry *regs; |
---|
| 395 | + struct dss_debugfs_entry *clks; |
---|
406 | 396 | } debugfs; |
---|
407 | 397 | |
---|
408 | 398 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
---|
.. | .. |
---|
440 | 430 | static inline struct dsi_data *to_dsi_data(struct omap_dss_device *dssdev) |
---|
441 | 431 | { |
---|
442 | 432 | return dev_get_drvdata(dssdev->dev); |
---|
443 | | -} |
---|
444 | | - |
---|
445 | | -static struct dsi_data *dsi_get_dsi_from_id(int module) |
---|
446 | | -{ |
---|
447 | | - struct omap_dss_device *out; |
---|
448 | | - enum omap_dss_output_id id; |
---|
449 | | - |
---|
450 | | - switch (module) { |
---|
451 | | - case 0: |
---|
452 | | - id = OMAP_DSS_OUTPUT_DSI1; |
---|
453 | | - break; |
---|
454 | | - case 1: |
---|
455 | | - id = OMAP_DSS_OUTPUT_DSI2; |
---|
456 | | - break; |
---|
457 | | - default: |
---|
458 | | - return NULL; |
---|
459 | | - } |
---|
460 | | - |
---|
461 | | - out = omap_dss_get_output(id); |
---|
462 | | - |
---|
463 | | - return out ? to_dsi_data(out) : NULL; |
---|
464 | 433 | } |
---|
465 | 434 | |
---|
466 | 435 | static inline void dsi_write_reg(struct dsi_data *dsi, |
---|
.. | .. |
---|
1157 | 1126 | WARN_ON(r < 0 && r != -ENOSYS); |
---|
1158 | 1127 | } |
---|
1159 | 1128 | |
---|
1160 | | -static int dsi_regulator_init(struct dsi_data *dsi) |
---|
1161 | | -{ |
---|
1162 | | - struct regulator *vdds_dsi; |
---|
1163 | | - |
---|
1164 | | - if (dsi->vdds_dsi_reg != NULL) |
---|
1165 | | - return 0; |
---|
1166 | | - |
---|
1167 | | - vdds_dsi = devm_regulator_get(dsi->dev, "vdd"); |
---|
1168 | | - |
---|
1169 | | - if (IS_ERR(vdds_dsi)) { |
---|
1170 | | - if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) |
---|
1171 | | - DSSERR("can't get DSI VDD regulator\n"); |
---|
1172 | | - return PTR_ERR(vdds_dsi); |
---|
1173 | | - } |
---|
1174 | | - |
---|
1175 | | - dsi->vdds_dsi_reg = vdds_dsi; |
---|
1176 | | - |
---|
1177 | | - return 0; |
---|
1178 | | -} |
---|
1179 | | - |
---|
1180 | 1129 | static void _dsi_print_reset_status(struct dsi_data *dsi) |
---|
1181 | 1130 | { |
---|
1182 | 1131 | u32 l; |
---|
.. | .. |
---|
1373 | 1322 | |
---|
1374 | 1323 | DSSDBG("PLL init\n"); |
---|
1375 | 1324 | |
---|
1376 | | - r = dsi_regulator_init(dsi); |
---|
1377 | | - if (r) |
---|
1378 | | - return r; |
---|
1379 | | - |
---|
1380 | 1325 | r = dsi_runtime_get(dsi); |
---|
1381 | 1326 | if (r) |
---|
1382 | 1327 | return r; |
---|
.. | .. |
---|
1434 | 1379 | DSSDBG("PLL disable done\n"); |
---|
1435 | 1380 | } |
---|
1436 | 1381 | |
---|
1437 | | -static void dsi_dump_dsi_clocks(struct dsi_data *dsi, struct seq_file *s) |
---|
| 1382 | +static int dsi_dump_dsi_clocks(struct seq_file *s, void *p) |
---|
1438 | 1383 | { |
---|
| 1384 | + struct dsi_data *dsi = s->private; |
---|
1439 | 1385 | struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; |
---|
1440 | 1386 | enum dss_clk_source dispc_clk_src, dsi_clk_src; |
---|
1441 | 1387 | int dsi_module = dsi->module_id; |
---|
.. | .. |
---|
1445 | 1391 | dsi_clk_src = dss_get_dsi_clk_source(dsi->dss, dsi_module); |
---|
1446 | 1392 | |
---|
1447 | 1393 | if (dsi_runtime_get(dsi)) |
---|
1448 | | - return; |
---|
| 1394 | + return 0; |
---|
1449 | 1395 | |
---|
1450 | 1396 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); |
---|
1451 | 1397 | |
---|
.. | .. |
---|
1489 | 1435 | seq_printf(s, "LP_CLK\t\t%lu\n", dsi->current_lp_cinfo.lp_clk); |
---|
1490 | 1436 | |
---|
1491 | 1437 | dsi_runtime_put(dsi); |
---|
1492 | | -} |
---|
1493 | 1438 | |
---|
1494 | | -void dsi_dump_clocks(struct seq_file *s) |
---|
1495 | | -{ |
---|
1496 | | - struct dsi_data *dsi; |
---|
1497 | | - int i; |
---|
1498 | | - |
---|
1499 | | - for (i = 0; i < MAX_NUM_DSI; i++) { |
---|
1500 | | - dsi = dsi_get_dsi_from_id(i); |
---|
1501 | | - if (dsi) |
---|
1502 | | - dsi_dump_dsi_clocks(dsi, s); |
---|
1503 | | - } |
---|
| 1439 | + return 0; |
---|
1504 | 1440 | } |
---|
1505 | 1441 | |
---|
1506 | 1442 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
---|
1507 | | -static void dsi_dump_dsi_irqs(struct dsi_data *dsi, struct seq_file *s) |
---|
| 1443 | +static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) |
---|
1508 | 1444 | { |
---|
| 1445 | + struct dsi_data *dsi = s->private; |
---|
1509 | 1446 | unsigned long flags; |
---|
1510 | 1447 | struct dsi_irq_stats stats; |
---|
1511 | 1448 | |
---|
.. | .. |
---|
1589 | 1526 | PIS(ULPSACTIVENOT_ALL0); |
---|
1590 | 1527 | PIS(ULPSACTIVENOT_ALL1); |
---|
1591 | 1528 | #undef PIS |
---|
1592 | | -} |
---|
1593 | 1529 | |
---|
1594 | | -static int dsi1_dump_irqs(struct seq_file *s, void *p) |
---|
1595 | | -{ |
---|
1596 | | - struct dsi_data *dsi = dsi_get_dsi_from_id(0); |
---|
1597 | | - |
---|
1598 | | - dsi_dump_dsi_irqs(dsi, s); |
---|
1599 | | - return 0; |
---|
1600 | | -} |
---|
1601 | | - |
---|
1602 | | -static int dsi2_dump_irqs(struct seq_file *s, void *p) |
---|
1603 | | -{ |
---|
1604 | | - struct dsi_data *dsi = dsi_get_dsi_from_id(1); |
---|
1605 | | - |
---|
1606 | | - dsi_dump_dsi_irqs(dsi, s); |
---|
1607 | 1530 | return 0; |
---|
1608 | 1531 | } |
---|
1609 | 1532 | #endif |
---|
1610 | 1533 | |
---|
1611 | | -static void dsi_dump_dsi_regs(struct dsi_data *dsi, struct seq_file *s) |
---|
| 1534 | +static int dsi_dump_dsi_regs(struct seq_file *s, void *p) |
---|
1612 | 1535 | { |
---|
1613 | | -#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsi, r)) |
---|
| 1536 | + struct dsi_data *dsi = s->private; |
---|
1614 | 1537 | |
---|
1615 | 1538 | if (dsi_runtime_get(dsi)) |
---|
1616 | | - return; |
---|
| 1539 | + return 0; |
---|
1617 | 1540 | dsi_enable_scp_clk(dsi); |
---|
1618 | 1541 | |
---|
| 1542 | +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsi, r)) |
---|
1619 | 1543 | DUMPREG(DSI_REVISION); |
---|
1620 | 1544 | DUMPREG(DSI_SYSCONFIG); |
---|
1621 | 1545 | DUMPREG(DSI_SYSSTATUS); |
---|
.. | .. |
---|
1685 | 1609 | DUMPREG(DSI_PLL_GO); |
---|
1686 | 1610 | DUMPREG(DSI_PLL_CONFIGURATION1); |
---|
1687 | 1611 | DUMPREG(DSI_PLL_CONFIGURATION2); |
---|
| 1612 | +#undef DUMPREG |
---|
1688 | 1613 | |
---|
1689 | 1614 | dsi_disable_scp_clk(dsi); |
---|
1690 | 1615 | dsi_runtime_put(dsi); |
---|
1691 | | -#undef DUMPREG |
---|
1692 | | -} |
---|
1693 | 1616 | |
---|
1694 | | -static int dsi1_dump_regs(struct seq_file *s, void *p) |
---|
1695 | | -{ |
---|
1696 | | - struct dsi_data *dsi = dsi_get_dsi_from_id(0); |
---|
1697 | | - |
---|
1698 | | - dsi_dump_dsi_regs(dsi, s); |
---|
1699 | | - return 0; |
---|
1700 | | -} |
---|
1701 | | - |
---|
1702 | | -static int dsi2_dump_regs(struct seq_file *s, void *p) |
---|
1703 | | -{ |
---|
1704 | | - struct dsi_data *dsi = dsi_get_dsi_from_id(1); |
---|
1705 | | - |
---|
1706 | | - dsi_dump_dsi_regs(dsi, s); |
---|
1707 | 1617 | return 0; |
---|
1708 | 1618 | } |
---|
1709 | 1619 | |
---|
.. | .. |
---|
3330 | 3240 | |
---|
3331 | 3241 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
---|
3332 | 3242 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
---|
3333 | | - struct videomode *vm = &dsi->vm; |
---|
| 3243 | + const struct videomode *vm = &dsi->vm; |
---|
3334 | 3244 | /* |
---|
3335 | 3245 | * Don't use line buffers if width is greater than the video |
---|
3336 | 3246 | * port's line buffer size |
---|
.. | .. |
---|
3459 | 3369 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; |
---|
3460 | 3370 | int tclk_trail, ths_exit, exiths_clk; |
---|
3461 | 3371 | bool ddr_alwon; |
---|
3462 | | - struct videomode *vm = &dsi->vm; |
---|
| 3372 | + const struct videomode *vm = &dsi->vm; |
---|
3463 | 3373 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
---|
3464 | 3374 | int ndl = dsi->num_lanes_used - 1; |
---|
3465 | 3375 | int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1; |
---|
.. | .. |
---|
3638 | 3548 | |
---|
3639 | 3549 | static void dsi_proto_timings(struct dsi_data *dsi) |
---|
3640 | 3550 | { |
---|
3641 | | - unsigned int tlpx, tclk_zero, tclk_prepare, tclk_trail; |
---|
| 3551 | + unsigned int tlpx, tclk_zero, tclk_prepare; |
---|
3642 | 3552 | unsigned int tclk_pre, tclk_post; |
---|
3643 | 3553 | unsigned int ths_prepare, ths_prepare_ths_zero, ths_zero; |
---|
3644 | 3554 | unsigned int ths_trail, ths_exit; |
---|
.. | .. |
---|
3657 | 3567 | |
---|
3658 | 3568 | r = dsi_read_reg(dsi, DSI_DSIPHY_CFG1); |
---|
3659 | 3569 | tlpx = FLD_GET(r, 20, 16) * 2; |
---|
3660 | | - tclk_trail = FLD_GET(r, 15, 8); |
---|
3661 | 3570 | tclk_zero = FLD_GET(r, 7, 0); |
---|
3662 | 3571 | |
---|
3663 | 3572 | r = dsi_read_reg(dsi, DSI_DSIPHY_CFG2); |
---|
.. | .. |
---|
3709 | 3618 | int vbp = dsi->vm_timings.vbp; |
---|
3710 | 3619 | int window_sync = dsi->vm_timings.window_sync; |
---|
3711 | 3620 | bool hsync_end; |
---|
3712 | | - struct videomode *vm = &dsi->vm; |
---|
| 3621 | + const struct videomode *vm = &dsi->vm; |
---|
3713 | 3622 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
---|
3714 | 3623 | int tl, t_he, width_bytes; |
---|
3715 | 3624 | |
---|
.. | .. |
---|
3818 | 3727 | { |
---|
3819 | 3728 | struct dsi_data *dsi = to_dsi_data(dssdev); |
---|
3820 | 3729 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
---|
3821 | | - struct omap_dss_device *out = &dsi->output; |
---|
3822 | 3730 | u8 data_type; |
---|
3823 | 3731 | u16 word_count; |
---|
3824 | 3732 | int r; |
---|
3825 | 3733 | |
---|
3826 | | - if (!out->dispc_channel_connected) { |
---|
3827 | | - DSSERR("failed to enable display: no output/manager\n"); |
---|
3828 | | - return -ENODEV; |
---|
3829 | | - } |
---|
3830 | | - |
---|
3831 | 3734 | r = dsi_display_init_dispc(dsi); |
---|
3832 | 3735 | if (r) |
---|
3833 | | - goto err_init_dispc; |
---|
| 3736 | + return r; |
---|
3834 | 3737 | |
---|
3835 | 3738 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
---|
3836 | 3739 | switch (dsi->pix_fmt) { |
---|
.. | .. |
---|
3879 | 3782 | } |
---|
3880 | 3783 | err_pix_fmt: |
---|
3881 | 3784 | dsi_display_uninit_dispc(dsi); |
---|
3882 | | -err_init_dispc: |
---|
3883 | 3785 | return r; |
---|
3884 | 3786 | } |
---|
3885 | 3787 | |
---|
.. | .. |
---|
3965 | 3867 | r = schedule_delayed_work(&dsi->framedone_timeout_work, |
---|
3966 | 3868 | msecs_to_jiffies(250)); |
---|
3967 | 3869 | BUG_ON(r == 0); |
---|
3968 | | - |
---|
3969 | | - dss_mgr_set_timings(&dsi->output, &dsi->vm); |
---|
3970 | 3870 | |
---|
3971 | 3871 | dss_mgr_start_update(&dsi->output); |
---|
3972 | 3872 | |
---|
.. | .. |
---|
4109 | 4009 | dsi->mgr_config.fifohandcheck = false; |
---|
4110 | 4010 | } |
---|
4111 | 4011 | |
---|
4112 | | - /* |
---|
4113 | | - * override interlace, logic level and edge related parameters in |
---|
4114 | | - * videomode with default values |
---|
4115 | | - */ |
---|
4116 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_INTERLACED; |
---|
4117 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_HSYNC_LOW; |
---|
4118 | | - dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH; |
---|
4119 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW; |
---|
4120 | | - dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH; |
---|
4121 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE; |
---|
4122 | | - dsi->vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE; |
---|
4123 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_DE_LOW; |
---|
4124 | | - dsi->vm.flags |= DISPLAY_FLAGS_DE_HIGH; |
---|
4125 | | - dsi->vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE; |
---|
4126 | | - dsi->vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE; |
---|
4127 | | - |
---|
4128 | | - dss_mgr_set_timings(&dsi->output, &dsi->vm); |
---|
4129 | | - |
---|
4130 | 4012 | r = dsi_configure_dispc_clocks(dsi); |
---|
4131 | 4013 | if (r) |
---|
4132 | 4014 | goto err1; |
---|
.. | .. |
---|
4262 | 4144 | } |
---|
4263 | 4145 | } |
---|
4264 | 4146 | |
---|
4265 | | -static int dsi_display_enable(struct omap_dss_device *dssdev) |
---|
| 4147 | +static void dsi_display_enable(struct omap_dss_device *dssdev) |
---|
4266 | 4148 | { |
---|
4267 | 4149 | struct dsi_data *dsi = to_dsi_data(dssdev); |
---|
4268 | | - int r = 0; |
---|
| 4150 | + int r; |
---|
4269 | 4151 | |
---|
4270 | 4152 | DSSDBG("dsi_display_enable\n"); |
---|
4271 | 4153 | |
---|
.. | .. |
---|
4285 | 4167 | |
---|
4286 | 4168 | mutex_unlock(&dsi->lock); |
---|
4287 | 4169 | |
---|
4288 | | - return 0; |
---|
| 4170 | + return; |
---|
4289 | 4171 | |
---|
4290 | 4172 | err_init_dsi: |
---|
4291 | 4173 | dsi_runtime_put(dsi); |
---|
4292 | 4174 | err_get_dsi: |
---|
4293 | 4175 | mutex_unlock(&dsi->lock); |
---|
4294 | 4176 | DSSDBG("dsi_display_enable FAILED\n"); |
---|
4295 | | - return r; |
---|
4296 | 4177 | } |
---|
4297 | 4178 | |
---|
4298 | 4179 | static void dsi_display_disable(struct omap_dss_device *dssdev, |
---|
.. | .. |
---|
4842 | 4723 | dsi->user_dispc_cinfo = ctx.dispc_cinfo; |
---|
4843 | 4724 | |
---|
4844 | 4725 | dsi->vm = ctx.vm; |
---|
| 4726 | + |
---|
| 4727 | + /* |
---|
| 4728 | + * override interlace, logic level and edge related parameters in |
---|
| 4729 | + * videomode with default values |
---|
| 4730 | + */ |
---|
| 4731 | + dsi->vm.flags &= ~DISPLAY_FLAGS_INTERLACED; |
---|
| 4732 | + dsi->vm.flags &= ~DISPLAY_FLAGS_HSYNC_LOW; |
---|
| 4733 | + dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH; |
---|
| 4734 | + dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW; |
---|
| 4735 | + dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH; |
---|
| 4736 | + /* |
---|
| 4737 | + * HACK: These flags should be handled through the omap_dss_device bus |
---|
| 4738 | + * flags, but this will only be possible when the DSI encoder will be |
---|
| 4739 | + * converted to the omapdrm-managed encoder model. |
---|
| 4740 | + */ |
---|
| 4741 | + dsi->vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE; |
---|
| 4742 | + dsi->vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE; |
---|
| 4743 | + dsi->vm.flags &= ~DISPLAY_FLAGS_DE_LOW; |
---|
| 4744 | + dsi->vm.flags |= DISPLAY_FLAGS_DE_HIGH; |
---|
| 4745 | + dsi->vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE; |
---|
| 4746 | + dsi->vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE; |
---|
| 4747 | + |
---|
| 4748 | + dss_mgr_set_timings(&dsi->output, &dsi->vm); |
---|
| 4749 | + |
---|
4845 | 4750 | dsi->vm_timings = ctx.dsi_vm; |
---|
4846 | 4751 | |
---|
4847 | 4752 | mutex_unlock(&dsi->lock); |
---|
.. | .. |
---|
4962 | 4867 | return 0; |
---|
4963 | 4868 | } |
---|
4964 | 4869 | |
---|
4965 | | -static int dsi_connect(struct omap_dss_device *dssdev, |
---|
4966 | | - struct omap_dss_device *dst) |
---|
| 4870 | +static int dsi_connect(struct omap_dss_device *src, |
---|
| 4871 | + struct omap_dss_device *dst) |
---|
4967 | 4872 | { |
---|
4968 | | - struct dsi_data *dsi = to_dsi_data(dssdev); |
---|
4969 | | - int r; |
---|
4970 | | - |
---|
4971 | | - r = dsi_regulator_init(dsi); |
---|
4972 | | - if (r) |
---|
4973 | | - return r; |
---|
4974 | | - |
---|
4975 | | - r = dss_mgr_connect(&dsi->output, dssdev); |
---|
4976 | | - if (r) |
---|
4977 | | - return r; |
---|
4978 | | - |
---|
4979 | | - r = omapdss_output_set_device(dssdev, dst); |
---|
4980 | | - if (r) { |
---|
4981 | | - DSSERR("failed to connect output to new device: %s\n", |
---|
4982 | | - dssdev->name); |
---|
4983 | | - dss_mgr_disconnect(&dsi->output, dssdev); |
---|
4984 | | - return r; |
---|
4985 | | - } |
---|
4986 | | - |
---|
4987 | | - return 0; |
---|
| 4873 | + return omapdss_device_connect(dst->dss, dst, dst->next); |
---|
4988 | 4874 | } |
---|
4989 | 4875 | |
---|
4990 | | -static void dsi_disconnect(struct omap_dss_device *dssdev, |
---|
4991 | | - struct omap_dss_device *dst) |
---|
| 4876 | +static void dsi_disconnect(struct omap_dss_device *src, |
---|
| 4877 | + struct omap_dss_device *dst) |
---|
4992 | 4878 | { |
---|
4993 | | - struct dsi_data *dsi = to_dsi_data(dssdev); |
---|
4994 | | - |
---|
4995 | | - WARN_ON(dst != dssdev->dst); |
---|
4996 | | - |
---|
4997 | | - if (dst != dssdev->dst) |
---|
4998 | | - return; |
---|
4999 | | - |
---|
5000 | | - omapdss_output_unset_device(dssdev); |
---|
5001 | | - |
---|
5002 | | - dss_mgr_disconnect(&dsi->output, dssdev); |
---|
| 4879 | + omapdss_device_disconnect(dst, dst->next); |
---|
5003 | 4880 | } |
---|
5004 | 4881 | |
---|
5005 | | -static const struct omapdss_dsi_ops dsi_ops = { |
---|
| 4882 | +static const struct omap_dss_device_ops dsi_ops = { |
---|
5006 | 4883 | .connect = dsi_connect, |
---|
5007 | 4884 | .disconnect = dsi_disconnect, |
---|
5008 | | - |
---|
5009 | | - .bus_lock = dsi_bus_lock, |
---|
5010 | | - .bus_unlock = dsi_bus_unlock, |
---|
5011 | | - |
---|
5012 | 4885 | .enable = dsi_display_enable, |
---|
5013 | | - .disable = dsi_display_disable, |
---|
5014 | 4886 | |
---|
5015 | | - .enable_hs = dsi_vc_enable_hs, |
---|
| 4887 | + .dsi = { |
---|
| 4888 | + .bus_lock = dsi_bus_lock, |
---|
| 4889 | + .bus_unlock = dsi_bus_unlock, |
---|
5016 | 4890 | |
---|
5017 | | - .configure_pins = dsi_configure_pins, |
---|
5018 | | - .set_config = dsi_set_config, |
---|
| 4891 | + .disable = dsi_display_disable, |
---|
5019 | 4892 | |
---|
5020 | | - .enable_video_output = dsi_enable_video_output, |
---|
5021 | | - .disable_video_output = dsi_disable_video_output, |
---|
| 4893 | + .enable_hs = dsi_vc_enable_hs, |
---|
5022 | 4894 | |
---|
5023 | | - .update = dsi_update, |
---|
| 4895 | + .configure_pins = dsi_configure_pins, |
---|
| 4896 | + .set_config = dsi_set_config, |
---|
5024 | 4897 | |
---|
5025 | | - .enable_te = dsi_enable_te, |
---|
| 4898 | + .enable_video_output = dsi_enable_video_output, |
---|
| 4899 | + .disable_video_output = dsi_disable_video_output, |
---|
5026 | 4900 | |
---|
5027 | | - .request_vc = dsi_request_vc, |
---|
5028 | | - .set_vc_id = dsi_set_vc_id, |
---|
5029 | | - .release_vc = dsi_release_vc, |
---|
| 4901 | + .update = dsi_update, |
---|
5030 | 4902 | |
---|
5031 | | - .dcs_write = dsi_vc_dcs_write, |
---|
5032 | | - .dcs_write_nosync = dsi_vc_dcs_write_nosync, |
---|
5033 | | - .dcs_read = dsi_vc_dcs_read, |
---|
| 4903 | + .enable_te = dsi_enable_te, |
---|
5034 | 4904 | |
---|
5035 | | - .gen_write = dsi_vc_generic_write, |
---|
5036 | | - .gen_write_nosync = dsi_vc_generic_write_nosync, |
---|
5037 | | - .gen_read = dsi_vc_generic_read, |
---|
| 4905 | + .request_vc = dsi_request_vc, |
---|
| 4906 | + .set_vc_id = dsi_set_vc_id, |
---|
| 4907 | + .release_vc = dsi_release_vc, |
---|
5038 | 4908 | |
---|
5039 | | - .bta_sync = dsi_vc_send_bta_sync, |
---|
| 4909 | + .dcs_write = dsi_vc_dcs_write, |
---|
| 4910 | + .dcs_write_nosync = dsi_vc_dcs_write_nosync, |
---|
| 4911 | + .dcs_read = dsi_vc_dcs_read, |
---|
5040 | 4912 | |
---|
5041 | | - .set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size, |
---|
| 4913 | + .gen_write = dsi_vc_generic_write, |
---|
| 4914 | + .gen_write_nosync = dsi_vc_generic_write_nosync, |
---|
| 4915 | + .gen_read = dsi_vc_generic_read, |
---|
| 4916 | + |
---|
| 4917 | + .bta_sync = dsi_vc_send_bta_sync, |
---|
| 4918 | + |
---|
| 4919 | + .set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size, |
---|
| 4920 | + }, |
---|
5042 | 4921 | }; |
---|
5043 | 4922 | |
---|
5044 | | -static void dsi_init_output(struct dsi_data *dsi) |
---|
5045 | | -{ |
---|
5046 | | - struct omap_dss_device *out = &dsi->output; |
---|
5047 | | - |
---|
5048 | | - out->dev = dsi->dev; |
---|
5049 | | - out->id = dsi->module_id == 0 ? |
---|
5050 | | - OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; |
---|
5051 | | - |
---|
5052 | | - out->output_type = OMAP_DISPLAY_TYPE_DSI; |
---|
5053 | | - out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1"; |
---|
5054 | | - out->dispc_channel = dsi_get_channel(dsi); |
---|
5055 | | - out->ops.dsi = &dsi_ops; |
---|
5056 | | - out->owner = THIS_MODULE; |
---|
5057 | | - |
---|
5058 | | - omapdss_register_output(out); |
---|
5059 | | -} |
---|
5060 | | - |
---|
5061 | | -static void dsi_uninit_output(struct dsi_data *dsi) |
---|
5062 | | -{ |
---|
5063 | | - struct omap_dss_device *out = &dsi->output; |
---|
5064 | | - |
---|
5065 | | - omapdss_unregister_output(out); |
---|
5066 | | -} |
---|
5067 | | - |
---|
5068 | | -static int dsi_probe_of(struct dsi_data *dsi) |
---|
5069 | | -{ |
---|
5070 | | - struct device_node *node = dsi->dev->of_node; |
---|
5071 | | - struct property *prop; |
---|
5072 | | - u32 lane_arr[10]; |
---|
5073 | | - int len, num_pins; |
---|
5074 | | - int r, i; |
---|
5075 | | - struct device_node *ep; |
---|
5076 | | - struct omap_dsi_pin_config pin_cfg; |
---|
5077 | | - |
---|
5078 | | - ep = of_graph_get_endpoint_by_regs(node, 0, 0); |
---|
5079 | | - if (!ep) |
---|
5080 | | - return 0; |
---|
5081 | | - |
---|
5082 | | - prop = of_find_property(ep, "lanes", &len); |
---|
5083 | | - if (prop == NULL) { |
---|
5084 | | - dev_err(dsi->dev, "failed to find lane data\n"); |
---|
5085 | | - r = -EINVAL; |
---|
5086 | | - goto err; |
---|
5087 | | - } |
---|
5088 | | - |
---|
5089 | | - num_pins = len / sizeof(u32); |
---|
5090 | | - |
---|
5091 | | - if (num_pins < 4 || num_pins % 2 != 0 || |
---|
5092 | | - num_pins > dsi->num_lanes_supported * 2) { |
---|
5093 | | - dev_err(dsi->dev, "bad number of lanes\n"); |
---|
5094 | | - r = -EINVAL; |
---|
5095 | | - goto err; |
---|
5096 | | - } |
---|
5097 | | - |
---|
5098 | | - r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins); |
---|
5099 | | - if (r) { |
---|
5100 | | - dev_err(dsi->dev, "failed to read lane data\n"); |
---|
5101 | | - goto err; |
---|
5102 | | - } |
---|
5103 | | - |
---|
5104 | | - pin_cfg.num_pins = num_pins; |
---|
5105 | | - for (i = 0; i < num_pins; ++i) |
---|
5106 | | - pin_cfg.pins[i] = (int)lane_arr[i]; |
---|
5107 | | - |
---|
5108 | | - r = dsi_configure_pins(&dsi->output, &pin_cfg); |
---|
5109 | | - if (r) { |
---|
5110 | | - dev_err(dsi->dev, "failed to configure pins"); |
---|
5111 | | - goto err; |
---|
5112 | | - } |
---|
5113 | | - |
---|
5114 | | - of_node_put(ep); |
---|
5115 | | - |
---|
5116 | | - return 0; |
---|
5117 | | - |
---|
5118 | | -err: |
---|
5119 | | - of_node_put(ep); |
---|
5120 | | - return r; |
---|
5121 | | -} |
---|
| 4923 | +/* ----------------------------------------------------------------------------- |
---|
| 4924 | + * PLL |
---|
| 4925 | + */ |
---|
5122 | 4926 | |
---|
5123 | 4927 | static const struct dss_pll_ops dsi_pll_ops = { |
---|
5124 | 4928 | .enable = dsi_pll_enable, |
---|
.. | .. |
---|
5233 | 5037 | return 0; |
---|
5234 | 5038 | } |
---|
5235 | 5039 | |
---|
5236 | | -/* DSI1 HW IP initialisation */ |
---|
| 5040 | +/* ----------------------------------------------------------------------------- |
---|
| 5041 | + * Component Bind & Unbind |
---|
| 5042 | + */ |
---|
| 5043 | + |
---|
| 5044 | +static int dsi_bind(struct device *dev, struct device *master, void *data) |
---|
| 5045 | +{ |
---|
| 5046 | + struct dss_device *dss = dss_get_device(master); |
---|
| 5047 | + struct dsi_data *dsi = dev_get_drvdata(dev); |
---|
| 5048 | + char name[10]; |
---|
| 5049 | + u32 rev; |
---|
| 5050 | + int r; |
---|
| 5051 | + |
---|
| 5052 | + dsi->dss = dss; |
---|
| 5053 | + |
---|
| 5054 | + dsi_init_pll_data(dss, dsi); |
---|
| 5055 | + |
---|
| 5056 | + r = dsi_runtime_get(dsi); |
---|
| 5057 | + if (r) |
---|
| 5058 | + return r; |
---|
| 5059 | + |
---|
| 5060 | + rev = dsi_read_reg(dsi, DSI_REVISION); |
---|
| 5061 | + dev_dbg(dev, "OMAP DSI rev %d.%d\n", |
---|
| 5062 | + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); |
---|
| 5063 | + |
---|
| 5064 | + dsi->line_buffer_size = dsi_get_line_buf_size(dsi); |
---|
| 5065 | + |
---|
| 5066 | + dsi_runtime_put(dsi); |
---|
| 5067 | + |
---|
| 5068 | + snprintf(name, sizeof(name), "dsi%u_regs", dsi->module_id + 1); |
---|
| 5069 | + dsi->debugfs.regs = dss_debugfs_create_file(dss, name, |
---|
| 5070 | + dsi_dump_dsi_regs, dsi); |
---|
| 5071 | +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
---|
| 5072 | + snprintf(name, sizeof(name), "dsi%u_irqs", dsi->module_id + 1); |
---|
| 5073 | + dsi->debugfs.irqs = dss_debugfs_create_file(dss, name, |
---|
| 5074 | + dsi_dump_dsi_irqs, dsi); |
---|
| 5075 | +#endif |
---|
| 5076 | + snprintf(name, sizeof(name), "dsi%u_clks", dsi->module_id + 1); |
---|
| 5077 | + dsi->debugfs.clks = dss_debugfs_create_file(dss, name, |
---|
| 5078 | + dsi_dump_dsi_clocks, dsi); |
---|
| 5079 | + |
---|
| 5080 | + return 0; |
---|
| 5081 | +} |
---|
| 5082 | + |
---|
| 5083 | +static void dsi_unbind(struct device *dev, struct device *master, void *data) |
---|
| 5084 | +{ |
---|
| 5085 | + struct dsi_data *dsi = dev_get_drvdata(dev); |
---|
| 5086 | + |
---|
| 5087 | + dss_debugfs_remove_file(dsi->debugfs.clks); |
---|
| 5088 | + dss_debugfs_remove_file(dsi->debugfs.irqs); |
---|
| 5089 | + dss_debugfs_remove_file(dsi->debugfs.regs); |
---|
| 5090 | + |
---|
| 5091 | + WARN_ON(dsi->scp_clk_refcount > 0); |
---|
| 5092 | + |
---|
| 5093 | + dss_pll_unregister(&dsi->pll); |
---|
| 5094 | +} |
---|
| 5095 | + |
---|
| 5096 | +static const struct component_ops dsi_component_ops = { |
---|
| 5097 | + .bind = dsi_bind, |
---|
| 5098 | + .unbind = dsi_unbind, |
---|
| 5099 | +}; |
---|
| 5100 | + |
---|
| 5101 | +/* ----------------------------------------------------------------------------- |
---|
| 5102 | + * Probe & Remove, Suspend & Resume |
---|
| 5103 | + */ |
---|
| 5104 | + |
---|
| 5105 | +static int dsi_init_output(struct dsi_data *dsi) |
---|
| 5106 | +{ |
---|
| 5107 | + struct omap_dss_device *out = &dsi->output; |
---|
| 5108 | + int r; |
---|
| 5109 | + |
---|
| 5110 | + out->dev = dsi->dev; |
---|
| 5111 | + out->id = dsi->module_id == 0 ? |
---|
| 5112 | + OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; |
---|
| 5113 | + |
---|
| 5114 | + out->type = OMAP_DISPLAY_TYPE_DSI; |
---|
| 5115 | + out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1"; |
---|
| 5116 | + out->dispc_channel = dsi_get_channel(dsi); |
---|
| 5117 | + out->ops = &dsi_ops; |
---|
| 5118 | + out->owner = THIS_MODULE; |
---|
| 5119 | + out->of_port = 0; |
---|
| 5120 | + out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE |
---|
| 5121 | + | DRM_BUS_FLAG_DE_HIGH |
---|
| 5122 | + | DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE; |
---|
| 5123 | + |
---|
| 5124 | + r = omapdss_device_init_output(out, NULL); |
---|
| 5125 | + if (r < 0) |
---|
| 5126 | + return r; |
---|
| 5127 | + |
---|
| 5128 | + omapdss_device_register(out); |
---|
| 5129 | + |
---|
| 5130 | + return 0; |
---|
| 5131 | +} |
---|
| 5132 | + |
---|
| 5133 | +static void dsi_uninit_output(struct dsi_data *dsi) |
---|
| 5134 | +{ |
---|
| 5135 | + struct omap_dss_device *out = &dsi->output; |
---|
| 5136 | + |
---|
| 5137 | + omapdss_device_unregister(out); |
---|
| 5138 | + omapdss_device_cleanup_output(out); |
---|
| 5139 | +} |
---|
| 5140 | + |
---|
| 5141 | +static int dsi_probe_of(struct dsi_data *dsi) |
---|
| 5142 | +{ |
---|
| 5143 | + struct device_node *node = dsi->dev->of_node; |
---|
| 5144 | + struct property *prop; |
---|
| 5145 | + u32 lane_arr[10]; |
---|
| 5146 | + int len, num_pins; |
---|
| 5147 | + int r, i; |
---|
| 5148 | + struct device_node *ep; |
---|
| 5149 | + struct omap_dsi_pin_config pin_cfg; |
---|
| 5150 | + |
---|
| 5151 | + ep = of_graph_get_endpoint_by_regs(node, 0, 0); |
---|
| 5152 | + if (!ep) |
---|
| 5153 | + return 0; |
---|
| 5154 | + |
---|
| 5155 | + prop = of_find_property(ep, "lanes", &len); |
---|
| 5156 | + if (prop == NULL) { |
---|
| 5157 | + dev_err(dsi->dev, "failed to find lane data\n"); |
---|
| 5158 | + r = -EINVAL; |
---|
| 5159 | + goto err; |
---|
| 5160 | + } |
---|
| 5161 | + |
---|
| 5162 | + num_pins = len / sizeof(u32); |
---|
| 5163 | + |
---|
| 5164 | + if (num_pins < 4 || num_pins % 2 != 0 || |
---|
| 5165 | + num_pins > dsi->num_lanes_supported * 2) { |
---|
| 5166 | + dev_err(dsi->dev, "bad number of lanes\n"); |
---|
| 5167 | + r = -EINVAL; |
---|
| 5168 | + goto err; |
---|
| 5169 | + } |
---|
| 5170 | + |
---|
| 5171 | + r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins); |
---|
| 5172 | + if (r) { |
---|
| 5173 | + dev_err(dsi->dev, "failed to read lane data\n"); |
---|
| 5174 | + goto err; |
---|
| 5175 | + } |
---|
| 5176 | + |
---|
| 5177 | + pin_cfg.num_pins = num_pins; |
---|
| 5178 | + for (i = 0; i < num_pins; ++i) |
---|
| 5179 | + pin_cfg.pins[i] = (int)lane_arr[i]; |
---|
| 5180 | + |
---|
| 5181 | + r = dsi_configure_pins(&dsi->output, &pin_cfg); |
---|
| 5182 | + if (r) { |
---|
| 5183 | + dev_err(dsi->dev, "failed to configure pins"); |
---|
| 5184 | + goto err; |
---|
| 5185 | + } |
---|
| 5186 | + |
---|
| 5187 | + of_node_put(ep); |
---|
| 5188 | + |
---|
| 5189 | + return 0; |
---|
| 5190 | + |
---|
| 5191 | +err: |
---|
| 5192 | + of_node_put(ep); |
---|
| 5193 | + return r; |
---|
| 5194 | +} |
---|
| 5195 | + |
---|
5237 | 5196 | static const struct dsi_of_data dsi_of_data_omap34xx = { |
---|
5238 | 5197 | .model = DSI_MODEL_OMAP3, |
---|
5239 | 5198 | .pll_hw = &dss_omap3_dsi_pll_hw, |
---|
.. | .. |
---|
5299 | 5258 | { /* sentinel */ } |
---|
5300 | 5259 | }; |
---|
5301 | 5260 | |
---|
5302 | | -static int dsi_bind(struct device *dev, struct device *master, void *data) |
---|
| 5261 | +static int dsi_probe(struct platform_device *pdev) |
---|
5303 | 5262 | { |
---|
5304 | | - struct platform_device *pdev = to_platform_device(dev); |
---|
5305 | | - struct dss_device *dss = dss_get_device(master); |
---|
5306 | 5263 | const struct soc_device_attribute *soc; |
---|
5307 | 5264 | const struct dsi_module_id_data *d; |
---|
5308 | | - u32 rev; |
---|
5309 | | - int r, i; |
---|
| 5265 | + struct device *dev = &pdev->dev; |
---|
5310 | 5266 | struct dsi_data *dsi; |
---|
5311 | 5267 | struct resource *dsi_mem; |
---|
5312 | 5268 | struct resource *res; |
---|
| 5269 | + unsigned int i; |
---|
| 5270 | + int r; |
---|
5313 | 5271 | |
---|
5314 | 5272 | dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); |
---|
5315 | 5273 | if (!dsi) |
---|
5316 | 5274 | return -ENOMEM; |
---|
5317 | 5275 | |
---|
5318 | | - dsi->dss = dss; |
---|
5319 | 5276 | dsi->dev = dev; |
---|
5320 | 5277 | dev_set_drvdata(dev, dsi); |
---|
5321 | 5278 | |
---|
.. | .. |
---|
5366 | 5323 | return r; |
---|
5367 | 5324 | } |
---|
5368 | 5325 | |
---|
| 5326 | + dsi->vdds_dsi_reg = devm_regulator_get(dev, "vdd"); |
---|
| 5327 | + if (IS_ERR(dsi->vdds_dsi_reg)) { |
---|
| 5328 | + if (PTR_ERR(dsi->vdds_dsi_reg) != -EPROBE_DEFER) |
---|
| 5329 | + DSSERR("can't get DSI VDD regulator\n"); |
---|
| 5330 | + return PTR_ERR(dsi->vdds_dsi_reg); |
---|
| 5331 | + } |
---|
| 5332 | + |
---|
5369 | 5333 | soc = soc_device_match(dsi_soc_devices); |
---|
5370 | 5334 | if (soc) |
---|
5371 | 5335 | dsi->data = soc->data; |
---|
.. | .. |
---|
5412 | 5376 | if (r) |
---|
5413 | 5377 | return r; |
---|
5414 | 5378 | |
---|
5415 | | - dsi_init_pll_data(dss, dsi); |
---|
5416 | | - |
---|
5417 | 5379 | pm_runtime_enable(dev); |
---|
5418 | | - |
---|
5419 | | - r = dsi_runtime_get(dsi); |
---|
5420 | | - if (r) |
---|
5421 | | - goto err_runtime_get; |
---|
5422 | | - |
---|
5423 | | - rev = dsi_read_reg(dsi, DSI_REVISION); |
---|
5424 | | - dev_dbg(dev, "OMAP DSI rev %d.%d\n", |
---|
5425 | | - FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); |
---|
5426 | 5380 | |
---|
5427 | 5381 | /* DSI on OMAP3 doesn't have register DSI_GNQ, set number |
---|
5428 | 5382 | * of data to 3 by default */ |
---|
5429 | | - if (dsi->data->quirks & DSI_QUIRK_GNQ) |
---|
| 5383 | + if (dsi->data->quirks & DSI_QUIRK_GNQ) { |
---|
| 5384 | + dsi_runtime_get(dsi); |
---|
5430 | 5385 | /* NB_DATA_LANES */ |
---|
5431 | 5386 | dsi->num_lanes_supported = 1 + REG_GET(dsi, DSI_GNQ, 11, 9); |
---|
5432 | | - else |
---|
| 5387 | + dsi_runtime_put(dsi); |
---|
| 5388 | + } else { |
---|
5433 | 5389 | dsi->num_lanes_supported = 3; |
---|
| 5390 | + } |
---|
5434 | 5391 | |
---|
5435 | | - dsi->line_buffer_size = dsi_get_line_buf_size(dsi); |
---|
| 5392 | + r = of_platform_populate(dev->of_node, NULL, NULL, dev); |
---|
| 5393 | + if (r) { |
---|
| 5394 | + DSSERR("Failed to populate DSI child devices: %d\n", r); |
---|
| 5395 | + goto err_pm_disable; |
---|
| 5396 | + } |
---|
5436 | 5397 | |
---|
5437 | | - dsi_init_output(dsi); |
---|
| 5398 | + r = dsi_init_output(dsi); |
---|
| 5399 | + if (r) |
---|
| 5400 | + goto err_of_depopulate; |
---|
5438 | 5401 | |
---|
5439 | 5402 | r = dsi_probe_of(dsi); |
---|
5440 | 5403 | if (r) { |
---|
5441 | 5404 | DSSERR("Invalid DSI DT data\n"); |
---|
5442 | | - goto err_probe_of; |
---|
| 5405 | + goto err_uninit_output; |
---|
5443 | 5406 | } |
---|
5444 | 5407 | |
---|
5445 | | - r = of_platform_populate(dev->of_node, NULL, NULL, dev); |
---|
| 5408 | + r = component_add(&pdev->dev, &dsi_component_ops); |
---|
5446 | 5409 | if (r) |
---|
5447 | | - DSSERR("Failed to populate DSI child devices: %d\n", r); |
---|
5448 | | - |
---|
5449 | | - dsi_runtime_put(dsi); |
---|
5450 | | - |
---|
5451 | | - if (dsi->module_id == 0) |
---|
5452 | | - dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi1_regs", |
---|
5453 | | - dsi1_dump_regs, |
---|
5454 | | - &dsi); |
---|
5455 | | - else |
---|
5456 | | - dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi2_regs", |
---|
5457 | | - dsi2_dump_regs, |
---|
5458 | | - &dsi); |
---|
5459 | | -#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
---|
5460 | | - if (dsi->module_id == 0) |
---|
5461 | | - dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi1_irqs", |
---|
5462 | | - dsi1_dump_irqs, |
---|
5463 | | - &dsi); |
---|
5464 | | - else |
---|
5465 | | - dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi2_irqs", |
---|
5466 | | - dsi2_dump_irqs, |
---|
5467 | | - &dsi); |
---|
5468 | | -#endif |
---|
| 5410 | + goto err_uninit_output; |
---|
5469 | 5411 | |
---|
5470 | 5412 | return 0; |
---|
5471 | 5413 | |
---|
5472 | | -err_probe_of: |
---|
| 5414 | +err_uninit_output: |
---|
5473 | 5415 | dsi_uninit_output(dsi); |
---|
5474 | | - dsi_runtime_put(dsi); |
---|
5475 | | - |
---|
5476 | | -err_runtime_get: |
---|
| 5416 | +err_of_depopulate: |
---|
| 5417 | + of_platform_depopulate(dev); |
---|
| 5418 | +err_pm_disable: |
---|
5477 | 5419 | pm_runtime_disable(dev); |
---|
5478 | 5420 | return r; |
---|
5479 | 5421 | } |
---|
5480 | 5422 | |
---|
5481 | | -static void dsi_unbind(struct device *dev, struct device *master, void *data) |
---|
| 5423 | +static int dsi_remove(struct platform_device *pdev) |
---|
5482 | 5424 | { |
---|
5483 | | - struct dsi_data *dsi = dev_get_drvdata(dev); |
---|
| 5425 | + struct dsi_data *dsi = platform_get_drvdata(pdev); |
---|
5484 | 5426 | |
---|
5485 | | - dss_debugfs_remove_file(dsi->debugfs.irqs); |
---|
5486 | | - dss_debugfs_remove_file(dsi->debugfs.regs); |
---|
5487 | | - |
---|
5488 | | - of_platform_depopulate(dev); |
---|
5489 | | - |
---|
5490 | | - WARN_ON(dsi->scp_clk_refcount > 0); |
---|
5491 | | - |
---|
5492 | | - dss_pll_unregister(&dsi->pll); |
---|
| 5427 | + component_del(&pdev->dev, &dsi_component_ops); |
---|
5493 | 5428 | |
---|
5494 | 5429 | dsi_uninit_output(dsi); |
---|
5495 | 5430 | |
---|
5496 | | - pm_runtime_disable(dev); |
---|
| 5431 | + of_platform_depopulate(&pdev->dev); |
---|
| 5432 | + |
---|
| 5433 | + pm_runtime_disable(&pdev->dev); |
---|
5497 | 5434 | |
---|
5498 | 5435 | if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) { |
---|
5499 | 5436 | regulator_disable(dsi->vdds_dsi_reg); |
---|
5500 | 5437 | dsi->vdds_dsi_enabled = false; |
---|
5501 | 5438 | } |
---|
5502 | | -} |
---|
5503 | 5439 | |
---|
5504 | | -static const struct component_ops dsi_component_ops = { |
---|
5505 | | - .bind = dsi_bind, |
---|
5506 | | - .unbind = dsi_unbind, |
---|
5507 | | -}; |
---|
5508 | | - |
---|
5509 | | -static int dsi_probe(struct platform_device *pdev) |
---|
5510 | | -{ |
---|
5511 | | - return component_add(&pdev->dev, &dsi_component_ops); |
---|
5512 | | -} |
---|
5513 | | - |
---|
5514 | | -static int dsi_remove(struct platform_device *pdev) |
---|
5515 | | -{ |
---|
5516 | | - component_del(&pdev->dev, &dsi_component_ops); |
---|
5517 | 5440 | return 0; |
---|
5518 | 5441 | } |
---|
5519 | 5442 | |
---|
.. | .. |
---|
5527 | 5450 | /* wait for current handler to finish before turning the DSI off */ |
---|
5528 | 5451 | synchronize_irq(dsi->irq); |
---|
5529 | 5452 | |
---|
5530 | | - dispc_runtime_put(dsi->dss->dispc); |
---|
5531 | | - |
---|
5532 | 5453 | return 0; |
---|
5533 | 5454 | } |
---|
5534 | 5455 | |
---|
5535 | 5456 | static int dsi_runtime_resume(struct device *dev) |
---|
5536 | 5457 | { |
---|
5537 | 5458 | struct dsi_data *dsi = dev_get_drvdata(dev); |
---|
5538 | | - int r; |
---|
5539 | | - |
---|
5540 | | - r = dispc_runtime_get(dsi->dss->dispc); |
---|
5541 | | - if (r) |
---|
5542 | | - return r; |
---|
5543 | 5459 | |
---|
5544 | 5460 | dsi->is_enabled = true; |
---|
5545 | 5461 | /* ensure the irq handler sees the is_enabled value */ |
---|
.. | .. |
---|
5551 | 5467 | static const struct dev_pm_ops dsi_pm_ops = { |
---|
5552 | 5468 | .runtime_suspend = dsi_runtime_suspend, |
---|
5553 | 5469 | .runtime_resume = dsi_runtime_resume, |
---|
| 5470 | + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) |
---|
5554 | 5471 | }; |
---|
5555 | 5472 | |
---|
5556 | 5473 | struct platform_driver omap_dsihw_driver = { |
---|