Lines Matching +full:dphy +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0
66 #define DATA_LANE_EN(x) BIT((x) - 1)
425 /* DPHY registers */
494 int (*probe)(struct cdns_dphy *dphy);
495 void (*remove)(struct cdns_dphy *dphy);
496 void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
497 void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
498 enum cdns_dphy_clk_lane_cfg cfg);
499 void (*set_pll_cfg)(struct cdns_dphy *dphy,
500 const struct cdns_dphy_cfg *cfg);
501 unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy);
505 struct cdns_dphy_cfg cfg; member
529 struct cdns_dphy *dphy; member
548 static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, in cdns_dsi_get_dphy_pll_cfg() argument
549 struct cdns_dphy_cfg *cfg, in cdns_dsi_get_dphy_pll_cfg() argument
558 unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); in cdns_dsi_get_dphy_pll_cfg()
560 memset(cfg, 0, sizeof(*cfg)); in cdns_dsi_get_dphy_pll_cfg()
562 cfg->nlanes = dsi_nlanes; in cdns_dsi_get_dphy_pll_cfg()
565 return -EINVAL; in cdns_dsi_get_dphy_pll_cfg()
567 cfg->pll_ipdiv = 1; in cdns_dsi_get_dphy_pll_cfg()
569 cfg->pll_ipdiv = 2; in cdns_dsi_get_dphy_pll_cfg()
571 cfg->pll_ipdiv = 4; in cdns_dsi_get_dphy_pll_cfg()
573 cfg->pll_ipdiv = 8; in cdns_dsi_get_dphy_pll_cfg()
582 adj_dsi_htotal += dsi_nlanes - (dsi_htotal % dsi_nlanes); in cdns_dsi_get_dphy_pll_cfg()
588 return -EINVAL; in cdns_dsi_get_dphy_pll_cfg()
594 return -EINVAL; in cdns_dsi_get_dphy_pll_cfg()
596 cfg->pll_opdiv = 1; in cdns_dsi_get_dphy_pll_cfg()
598 cfg->pll_opdiv = 2; in cdns_dsi_get_dphy_pll_cfg()
600 cfg->pll_opdiv = 4; in cdns_dsi_get_dphy_pll_cfg()
602 cfg->pll_opdiv = 8; in cdns_dsi_get_dphy_pll_cfg()
605 * Allow a deviation of 0.2% on the per-lane data rate to try to in cdns_dsi_get_dphy_pll_cfg()
610 cfg->pll_opdiv * cfg->pll_ipdiv, in cdns_dsi_get_dphy_pll_cfg()
612 fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * in cdns_dsi_get_dphy_pll_cfg()
613 cfg->pll_ipdiv, in cdns_dsi_get_dphy_pll_cfg()
663 cfg->pll_opdiv * cfg->pll_ipdiv * 2 * 8); in cdns_dsi_get_dphy_pll_cfg()
667 cfg->pll_fbdiv = fbdiv; in cdns_dsi_get_dphy_pll_cfg()
668 *dsi_hfp_ext = adj_dsi_htotal - dsi_htotal; in cdns_dsi_get_dphy_pll_cfg()
673 if (!cfg->pll_fbdiv) in cdns_dsi_get_dphy_pll_cfg()
674 return -EINVAL; in cdns_dsi_get_dphy_pll_cfg()
678 cfg->lane_bps = dlane_bps; in cdns_dsi_get_dphy_pll_cfg()
683 static int cdns_dphy_setup_psm(struct cdns_dphy *dphy) in cdns_dphy_setup_psm() argument
685 unsigned long psm_clk_hz = clk_get_rate(dphy->psm_clk); in cdns_dphy_setup_psm()
689 return -EINVAL; in cdns_dphy_setup_psm()
692 if (dphy->ops->set_psm_div) in cdns_dphy_setup_psm()
693 dphy->ops->set_psm_div(dphy, psm_div); in cdns_dphy_setup_psm()
698 static void cdns_dphy_set_clk_lane_cfg(struct cdns_dphy *dphy, in cdns_dphy_set_clk_lane_cfg() argument
699 enum cdns_dphy_clk_lane_cfg cfg) in cdns_dphy_set_clk_lane_cfg() argument
701 if (dphy->ops->set_clk_lane_cfg) in cdns_dphy_set_clk_lane_cfg()
702 dphy->ops->set_clk_lane_cfg(dphy, cfg); in cdns_dphy_set_clk_lane_cfg()
705 static void cdns_dphy_set_pll_cfg(struct cdns_dphy *dphy, in cdns_dphy_set_pll_cfg() argument
706 const struct cdns_dphy_cfg *cfg) in cdns_dphy_set_pll_cfg() argument
708 if (dphy->ops->set_pll_cfg) in cdns_dphy_set_pll_cfg()
709 dphy->ops->set_pll_cfg(dphy, cfg); in cdns_dphy_set_pll_cfg()
712 static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) in cdns_dphy_get_wakeup_time_ns() argument
714 return dphy->ops->get_wakeup_time_ns(dphy); in cdns_dphy_get_wakeup_time_ns()
726 dsi_timing -= dsi_pkt_overhead; in dpi_to_dsi_timing()
738 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_mode2cfg()
745 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in cdns_dsi_mode2cfg()
748 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); in cdns_dsi_mode2cfg()
749 nlanes = output->dev->lanes; in cdns_dsi_mode2cfg()
752 tmp = mode->htotal - in cdns_dsi_mode2cfg()
753 (sync_pulse ? mode->hsync_end : mode->hsync_start); in cdns_dsi_mode2cfg()
755 tmp = mode->crtc_htotal - in cdns_dsi_mode2cfg()
757 mode->crtc_hsync_end : mode->crtc_hsync_start); in cdns_dsi_mode2cfg()
759 dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD); in cdns_dsi_mode2cfg()
760 dsi_htotal += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; in cdns_dsi_mode2cfg()
761 dsi_hss_hsa_hse_hbp += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; in cdns_dsi_mode2cfg()
765 tmp = mode->hsync_end - mode->hsync_start; in cdns_dsi_mode2cfg()
767 tmp = mode->crtc_hsync_end - mode->crtc_hsync_start; in cdns_dsi_mode2cfg()
769 dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp, in cdns_dsi_mode2cfg()
771 dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; in cdns_dsi_mode2cfg()
772 dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; in cdns_dsi_mode2cfg()
775 dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ? in cdns_dsi_mode2cfg()
776 mode->hdisplay : mode->crtc_hdisplay, in cdns_dsi_mode2cfg()
778 dsi_htotal += dsi_cfg->hact; in cdns_dsi_mode2cfg()
781 dpi_hfp = mode->hsync_start - mode->hdisplay; in cdns_dsi_mode2cfg()
783 dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; in cdns_dsi_mode2cfg()
785 dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); in cdns_dsi_mode2cfg()
786 dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; in cdns_dsi_mode2cfg()
789 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, in cdns_dsi_mode2cfg()
790 mode->htotal, bpp, in cdns_dsi_mode2cfg()
791 mode->clock * 1000, in cdns_dsi_mode2cfg()
795 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, in cdns_dsi_mode2cfg()
796 mode->crtc_htotal, bpp, in cdns_dsi_mode2cfg()
797 mode->crtc_clock * 1000, in cdns_dsi_mode2cfg()
804 dsi_cfg->hfp += dsi_hfp_ext; in cdns_dsi_mode2cfg()
806 dsi_cfg->htotal = dsi_htotal; in cdns_dsi_mode2cfg()
813 if ((u64)dphy_cfg->lane_bps * dpi_hfp * nlanes < in cdns_dsi_mode2cfg()
815 (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000) in cdns_dsi_mode2cfg()
816 return -EINVAL; in cdns_dsi_mode2cfg()
825 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_bridge_attach()
827 if (!drm_core_check_feature(bridge->dev, DRIVER_ATOMIC)) { in cdns_dsi_bridge_attach()
828 dev_err(dsi->base.dev, in cdns_dsi_bridge_attach()
829 "cdns-dsi driver is only compatible with DRM devices supporting atomic updates"); in cdns_dsi_bridge_attach()
830 return -ENOTSUPP; in cdns_dsi_bridge_attach()
833 return drm_bridge_attach(bridge->encoder, output->bridge, bridge); in cdns_dsi_bridge_attach()
842 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_bridge_mode_valid()
851 if (mode->vtotal - mode->vsync_end < 2) in cdns_dsi_bridge_mode_valid()
855 if (mode->vsync_end - mode->vsync_start < 2) in cdns_dsi_bridge_mode_valid()
858 /* HACT must be 32-bits aligned. */ in cdns_dsi_bridge_mode_valid()
859 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); in cdns_dsi_bridge_mode_valid()
860 if ((mode->hdisplay * bpp) % 32) in cdns_dsi_bridge_mode_valid()
863 nlanes = output->dev->lanes; in cdns_dsi_bridge_mode_valid()
878 val = readl(dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_bridge_disable()
881 writel(val, dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_bridge_disable()
883 val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id); in cdns_dsi_bridge_disable()
884 writel(val, dsi->regs + MCTL_MAIN_EN); in cdns_dsi_bridge_disable()
885 pm_runtime_put(dsi->base.dev); in cdns_dsi_bridge_disable()
894 * Power all internal DPHY blocks down and maintain their reset line in cdns_dsi_hs_init()
895 * asserted before changing the DPHY config. in cdns_dsi_hs_init()
899 dsi->regs + MCTL_DPHY_CFG0); in cdns_dsi_hs_init()
902 * Configure the internal PSM clk divider so that the DPHY has a in cdns_dsi_hs_init()
905 WARN_ON_ONCE(cdns_dphy_setup_psm(dsi->dphy)); in cdns_dsi_hs_init()
908 * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes in cdns_dsi_hs_init()
914 cdns_dphy_set_clk_lane_cfg(dsi->dphy, DPHY_CLK_CFG_LEFT_DRIVES_LEFT); in cdns_dsi_hs_init()
917 * Configure the DPHY PLL that will be used to generate the TX byte in cdns_dsi_hs_init()
920 cdns_dphy_set_pll_cfg(dsi->dphy, dphy_cfg); in cdns_dsi_hs_init()
924 dsi->dphy->regs + DPHY_CMN_SSM); in cdns_dsi_hs_init()
927 writel(PLL_LOCKED, dsi->regs + MCTL_MAIN_STS_CLR); in cdns_dsi_hs_init()
929 dsi->regs + MCTL_DPHY_CFG0); in cdns_dsi_hs_init()
930 WARN_ON_ONCE(readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status, in cdns_dsi_hs_init()
932 /* De-assert data and clock reset lines. */ in cdns_dsi_hs_init()
934 DPHY_D_RSTB(dphy_cfg->nlanes) | DPHY_C_RSTB, in cdns_dsi_hs_init()
935 dsi->regs + MCTL_DPHY_CFG0); in cdns_dsi_hs_init()
940 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_init_link()
945 if (dsi->link_initialized) in cdns_dsi_init_link()
949 for (i = 1; i < output->dev->lanes; i++) in cdns_dsi_init_link()
952 if (!(output->dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) in cdns_dsi_init_link()
955 writel(val, dsi->regs + MCTL_MAIN_PHY_CTL); in cdns_dsi_init_link()
958 sysclk_period = NSEC_PER_SEC / clk_get_rate(dsi->dsi_sys_clk); in cdns_dsi_init_link()
961 dsi->regs + MCTL_ULPOUT_TIME); in cdns_dsi_init_link()
963 writel(LINK_EN, dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_init_link()
966 for (i = 0; i < output->dev->lanes; i++) in cdns_dsi_init_link()
969 writel(val, dsi->regs + MCTL_MAIN_EN); in cdns_dsi_init_link()
971 dsi->link_initialized = true; in cdns_dsi_init_link()
978 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_bridge_enable()
986 if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) in cdns_dsi_bridge_enable()
989 mode = &bridge->encoder->crtc->state->adjusted_mode; in cdns_dsi_bridge_enable()
990 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); in cdns_dsi_bridge_enable()
991 nlanes = output->dev->lanes; in cdns_dsi_bridge_enable()
999 dsi->regs + VID_HSIZE1); in cdns_dsi_bridge_enable()
1001 dsi->regs + VID_HSIZE2); in cdns_dsi_bridge_enable()
1003 writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) | in cdns_dsi_bridge_enable()
1004 VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) | in cdns_dsi_bridge_enable()
1005 VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1), in cdns_dsi_bridge_enable()
1006 dsi->regs + VID_VSIZE1); in cdns_dsi_bridge_enable()
1007 writel(mode->crtc_vdisplay, dsi->regs + VID_VSIZE2); in cdns_dsi_bridge_enable()
1009 tmp = dsi_cfg.htotal - in cdns_dsi_bridge_enable()
1012 writel(BLK_LINE_PULSE_PKT_LEN(tmp), dsi->regs + VID_BLKSIZE2); in cdns_dsi_bridge_enable()
1013 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in cdns_dsi_bridge_enable()
1014 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD), in cdns_dsi_bridge_enable()
1015 dsi->regs + VID_VCA_SETTING2); in cdns_dsi_bridge_enable()
1017 tmp = dsi_cfg.htotal - in cdns_dsi_bridge_enable()
1019 writel(BLK_LINE_EVENT_PKT_LEN(tmp), dsi->regs + VID_BLKSIZE1); in cdns_dsi_bridge_enable()
1020 if (!(output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)) in cdns_dsi_bridge_enable()
1021 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD), in cdns_dsi_bridge_enable()
1022 dsi->regs + VID_VCA_SETTING2); in cdns_dsi_bridge_enable()
1024 tmp = DIV_ROUND_UP(dsi_cfg.htotal, nlanes) - in cdns_dsi_bridge_enable()
1027 if (!(output->dev->mode_flags & MIPI_DSI_MODE_EOT_PACKET)) in cdns_dsi_bridge_enable()
1028 tmp -= DIV_ROUND_UP(DSI_EOT_PKT_SIZE, nlanes); in cdns_dsi_bridge_enable()
1032 reg_wakeup = cdns_dphy_get_wakeup_time_ns(dsi->dphy) / in cdns_dsi_bridge_enable()
1035 dsi->regs + VID_DPHY_TIME); in cdns_dsi_bridge_enable()
1056 dsi->regs + MCTL_DPHY_TIMEOUT1); in cdns_dsi_bridge_enable()
1058 writel(LPRX_TIMEOUT(tmp), dsi->regs + MCTL_DPHY_TIMEOUT2); in cdns_dsi_bridge_enable()
1060 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO) { in cdns_dsi_bridge_enable()
1061 switch (output->dev->format) { in cdns_dsi_bridge_enable()
1083 dev_err(dsi->base.dev, "Unsupported DSI format\n"); in cdns_dsi_bridge_enable()
1087 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in cdns_dsi_bridge_enable()
1095 writel(tmp, dsi->regs + VID_MAIN_CTL); in cdns_dsi_bridge_enable()
1098 tmp = readl(dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_bridge_enable()
1101 if (!(output->dev->mode_flags & MIPI_DSI_MODE_EOT_PACKET)) in cdns_dsi_bridge_enable()
1104 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO) in cdns_dsi_bridge_enable()
1105 tmp |= IF_VID_MODE | IF_VID_SELECT(input->id) | VID_EN; in cdns_dsi_bridge_enable()
1107 writel(tmp, dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_bridge_enable()
1109 tmp = readl(dsi->regs + MCTL_MAIN_EN) | IF_EN(input->id); in cdns_dsi_bridge_enable()
1110 writel(tmp, dsi->regs + MCTL_MAIN_EN); in cdns_dsi_bridge_enable()
1124 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_attach()
1125 struct cdns_dsi_input *input = &dsi->input; in cdns_dsi_attach()
1136 if (output->dev) in cdns_dsi_attach()
1137 return -EBUSY; in cdns_dsi_attach()
1140 if (dev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) in cdns_dsi_attach()
1141 return -ENOTSUPP; in cdns_dsi_attach()
1144 * The host <-> device link might be described using an OF-graph in cdns_dsi_attach()
1146 * this representation, otherwise we use dsidev->dev.of_node which in cdns_dsi_attach()
1149 np = of_graph_get_remote_node(dsi->base.dev->of_node, DSI_OUTPUT_PORT, in cdns_dsi_attach()
1150 dev->channel); in cdns_dsi_attach()
1152 np = of_node_get(dev->dev.of_node); in cdns_dsi_attach()
1158 bridge = of_drm_find_bridge(dev->dev.of_node); in cdns_dsi_attach()
1160 bridge = ERR_PTR(-EINVAL); in cdns_dsi_attach()
1167 dev_err(host->dev, "failed to add DSI device %s (err = %d)", in cdns_dsi_attach()
1168 dev->name, ret); in cdns_dsi_attach()
1172 output->dev = dev; in cdns_dsi_attach()
1173 output->bridge = bridge; in cdns_dsi_attach()
1174 output->panel = panel; in cdns_dsi_attach()
1181 drm_bridge_add(&input->bridge); in cdns_dsi_attach()
1190 struct cdns_dsi_output *output = &dsi->output; in cdns_dsi_detach()
1191 struct cdns_dsi_input *input = &dsi->input; in cdns_dsi_detach()
1193 drm_bridge_remove(&input->bridge); in cdns_dsi_detach()
1194 if (output->panel) in cdns_dsi_detach()
1195 drm_panel_bridge_remove(output->bridge); in cdns_dsi_detach()
1206 flag = readl(dsi->regs + DIRECT_CMD_STS_FLAG); in cdns_dsi_interrupt()
1208 ctl = readl(dsi->regs + DIRECT_CMD_STS_CTL); in cdns_dsi_interrupt()
1210 writel(ctl, dsi->regs + DIRECT_CMD_STS_CTL); in cdns_dsi_interrupt()
1211 complete(&dsi->direct_cmd_comp); in cdns_dsi_interrupt()
1226 ret = pm_runtime_get_sync(host->dev); in cdns_dsi_transfer()
1236 tx_len = msg->tx_buf ? msg->tx_len : 0; in cdns_dsi_transfer()
1237 rx_len = msg->rx_buf ? msg->rx_len : 0; in cdns_dsi_transfer()
1241 ret = -ENOTSUPP; in cdns_dsi_transfer()
1246 if (tx_len > dsi->direct_cmd_fifo_depth) { in cdns_dsi_transfer()
1247 ret = -ENOTSUPP; in cdns_dsi_transfer()
1252 if (rx_len > dsi->rx_fifo_depth) { in cdns_dsi_transfer()
1253 ret = -ENOTSUPP; in cdns_dsi_transfer()
1257 cmd = CMD_SIZE(tx_len) | CMD_VCHAN_ID(msg->channel) | in cdns_dsi_transfer()
1258 CMD_DATATYPE(msg->type); in cdns_dsi_transfer()
1260 if (msg->flags & MIPI_DSI_MSG_USE_LPM) in cdns_dsi_transfer()
1263 if (mipi_dsi_packet_format_is_long(msg->type)) in cdns_dsi_transfer()
1270 } else if (msg->flags & MIPI_DSI_MSG_REQ_ACK) { in cdns_dsi_transfer()
1276 writel(readl(dsi->regs + MCTL_MAIN_DATA_CTL) | ctl, in cdns_dsi_transfer()
1277 dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_transfer()
1279 writel(cmd, dsi->regs + DIRECT_CMD_MAIN_SETTINGS); in cdns_dsi_transfer()
1282 const u8 *buf = msg->tx_buf; in cdns_dsi_transfer()
1289 writel(val, dsi->regs + DIRECT_CMD_WRDATA); in cdns_dsi_transfer()
1293 writel(wait, dsi->regs + DIRECT_CMD_STS_CLR); in cdns_dsi_transfer()
1294 writel(wait, dsi->regs + DIRECT_CMD_STS_CTL); in cdns_dsi_transfer()
1295 reinit_completion(&dsi->direct_cmd_comp); in cdns_dsi_transfer()
1296 writel(0, dsi->regs + DIRECT_CMD_SEND); in cdns_dsi_transfer()
1298 wait_for_completion_timeout(&dsi->direct_cmd_comp, in cdns_dsi_transfer()
1301 sts = readl(dsi->regs + DIRECT_CMD_STS); in cdns_dsi_transfer()
1302 writel(wait, dsi->regs + DIRECT_CMD_STS_CLR); in cdns_dsi_transfer()
1303 writel(0, dsi->regs + DIRECT_CMD_STS_CTL); in cdns_dsi_transfer()
1305 writel(readl(dsi->regs + MCTL_MAIN_DATA_CTL) & ~ctl, in cdns_dsi_transfer()
1306 dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_transfer()
1310 ret = -ETIMEDOUT; in cdns_dsi_transfer()
1316 ret = -EIO; in cdns_dsi_transfer()
1321 u8 *buf = msg->rx_buf; in cdns_dsi_transfer()
1324 val = readl(dsi->regs + DIRECT_CMD_RDDATA); in cdns_dsi_transfer()
1330 pm_runtime_put(host->dev); in cdns_dsi_transfer()
1344 reset_control_deassert(dsi->dsi_p_rst); in cdns_dsi_resume()
1345 clk_prepare_enable(dsi->dsi_p_clk); in cdns_dsi_resume()
1346 clk_prepare_enable(dsi->dsi_sys_clk); in cdns_dsi_resume()
1347 clk_prepare_enable(dsi->dphy->psm_clk); in cdns_dsi_resume()
1348 clk_prepare_enable(dsi->dphy->pll_ref_clk); in cdns_dsi_resume()
1357 clk_disable_unprepare(dsi->dphy->pll_ref_clk); in cdns_dsi_suspend()
1358 clk_disable_unprepare(dsi->dphy->psm_clk); in cdns_dsi_suspend()
1359 clk_disable_unprepare(dsi->dsi_sys_clk); in cdns_dsi_suspend()
1360 clk_disable_unprepare(dsi->dsi_p_clk); in cdns_dsi_suspend()
1361 reset_control_assert(dsi->dsi_p_rst); in cdns_dsi_suspend()
1362 dsi->link_initialized = false; in cdns_dsi_suspend()
1369 static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) in cdns_dphy_ref_get_wakeup_time_ns() argument
1375 static void cdns_dphy_ref_set_pll_cfg(struct cdns_dphy *dphy, in cdns_dphy_ref_set_pll_cfg() argument
1376 const struct cdns_dphy_cfg *cfg) in cdns_dphy_ref_set_pll_cfg() argument
1380 fbdiv_low = (cfg->pll_fbdiv / 4) - 2; in cdns_dphy_ref_set_pll_cfg()
1381 fbdiv_high = cfg->pll_fbdiv - fbdiv_low - 2; in cdns_dphy_ref_set_pll_cfg()
1384 DPHY_CMN_IPDIV(cfg->pll_ipdiv) | in cdns_dphy_ref_set_pll_cfg()
1385 DPHY_CMN_OPDIV(cfg->pll_opdiv), in cdns_dphy_ref_set_pll_cfg()
1386 dphy->regs + DPHY_CMN_OPIPDIV); in cdns_dphy_ref_set_pll_cfg()
1389 dphy->regs + DPHY_CMN_FBDIV); in cdns_dphy_ref_set_pll_cfg()
1392 dphy->regs + DPHY_CMN_PWM); in cdns_dphy_ref_set_pll_cfg()
1395 static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div) in cdns_dphy_ref_set_psm_div() argument
1398 dphy->regs + DPHY_PSM_CFG); in cdns_dphy_ref_set_psm_div()
1402 * This is the reference implementation of DPHY hooks. Specific integration of
1403 * this IP may have to re-implement some of them depending on how they decided
1413 { .compatible = "cdns,dphy", .data = &ref_dphy_ops },
1420 struct cdns_dphy *dphy; in cdns_dphy_probe() local
1425 ret = of_parse_phandle_with_args(pdev->dev.of_node, "phys", in cdns_dphy_probe()
1426 "#phy-cells", 0, &args); in cdns_dphy_probe()
1428 return ERR_PTR(-ENOENT); in cdns_dphy_probe()
1431 if (!match || !match->data) in cdns_dphy_probe()
1432 return ERR_PTR(-EINVAL); in cdns_dphy_probe()
1434 dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); in cdns_dphy_probe()
1435 if (!dphy) in cdns_dphy_probe()
1436 return ERR_PTR(-ENOMEM); in cdns_dphy_probe()
1438 dphy->ops = match->data; in cdns_dphy_probe()
1444 dphy->regs = devm_ioremap_resource(&pdev->dev, &res); in cdns_dphy_probe()
1445 if (IS_ERR(dphy->regs)) in cdns_dphy_probe()
1446 return ERR_CAST(dphy->regs); in cdns_dphy_probe()
1448 dphy->psm_clk = of_clk_get_by_name(args.np, "psm"); in cdns_dphy_probe()
1449 if (IS_ERR(dphy->psm_clk)) in cdns_dphy_probe()
1450 return ERR_CAST(dphy->psm_clk); in cdns_dphy_probe()
1452 dphy->pll_ref_clk = of_clk_get_by_name(args.np, "pll_ref"); in cdns_dphy_probe()
1453 if (IS_ERR(dphy->pll_ref_clk)) { in cdns_dphy_probe()
1454 ret = PTR_ERR(dphy->pll_ref_clk); in cdns_dphy_probe()
1458 if (dphy->ops->probe) { in cdns_dphy_probe()
1459 ret = dphy->ops->probe(dphy); in cdns_dphy_probe()
1464 return dphy; in cdns_dphy_probe()
1467 clk_put(dphy->pll_ref_clk); in cdns_dphy_probe()
1470 clk_put(dphy->psm_clk); in cdns_dphy_probe()
1475 static void cdns_dphy_remove(struct cdns_dphy *dphy) in cdns_dphy_remove() argument
1477 if (dphy->ops->remove) in cdns_dphy_remove()
1478 dphy->ops->remove(dphy); in cdns_dphy_remove()
1480 clk_put(dphy->pll_ref_clk); in cdns_dphy_remove()
1481 clk_put(dphy->psm_clk); in cdns_dphy_remove()
1492 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); in cdns_dsi_drm_probe()
1494 return -ENOMEM; in cdns_dsi_drm_probe()
1498 input = &dsi->input; in cdns_dsi_drm_probe()
1501 dsi->regs = devm_ioremap_resource(&pdev->dev, res); in cdns_dsi_drm_probe()
1502 if (IS_ERR(dsi->regs)) in cdns_dsi_drm_probe()
1503 return PTR_ERR(dsi->regs); in cdns_dsi_drm_probe()
1505 dsi->dsi_p_clk = devm_clk_get(&pdev->dev, "dsi_p_clk"); in cdns_dsi_drm_probe()
1506 if (IS_ERR(dsi->dsi_p_clk)) in cdns_dsi_drm_probe()
1507 return PTR_ERR(dsi->dsi_p_clk); in cdns_dsi_drm_probe()
1509 dsi->dsi_p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev, in cdns_dsi_drm_probe()
1511 if (IS_ERR(dsi->dsi_p_rst)) in cdns_dsi_drm_probe()
1512 return PTR_ERR(dsi->dsi_p_rst); in cdns_dsi_drm_probe()
1514 dsi->dsi_sys_clk = devm_clk_get(&pdev->dev, "dsi_sys_clk"); in cdns_dsi_drm_probe()
1515 if (IS_ERR(dsi->dsi_sys_clk)) in cdns_dsi_drm_probe()
1516 return PTR_ERR(dsi->dsi_sys_clk); in cdns_dsi_drm_probe()
1522 dsi->dphy = cdns_dphy_probe(pdev); in cdns_dsi_drm_probe()
1523 if (IS_ERR(dsi->dphy)) in cdns_dsi_drm_probe()
1524 return PTR_ERR(dsi->dphy); in cdns_dsi_drm_probe()
1526 ret = clk_prepare_enable(dsi->dsi_p_clk); in cdns_dsi_drm_probe()
1530 val = readl(dsi->regs + ID_REG); in cdns_dsi_drm_probe()
1532 dev_err(&pdev->dev, "invalid vendor id\n"); in cdns_dsi_drm_probe()
1533 ret = -EINVAL; in cdns_dsi_drm_probe()
1537 val = readl(dsi->regs + IP_CONF); in cdns_dsi_drm_probe()
1538 dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2); in cdns_dsi_drm_probe()
1539 dsi->rx_fifo_depth = RX_FIFO_DEPTH(val); in cdns_dsi_drm_probe()
1540 init_completion(&dsi->direct_cmd_comp); in cdns_dsi_drm_probe()
1542 writel(0, dsi->regs + MCTL_MAIN_DATA_CTL); in cdns_dsi_drm_probe()
1543 writel(0, dsi->regs + MCTL_MAIN_EN); in cdns_dsi_drm_probe()
1544 writel(0, dsi->regs + MCTL_MAIN_PHY_CTL); in cdns_dsi_drm_probe()
1547 * We only support the DPI input, so force input->id to in cdns_dsi_drm_probe()
1550 input->id = CDNS_DPI_INPUT; in cdns_dsi_drm_probe()
1551 input->bridge.funcs = &cdns_dsi_bridge_funcs; in cdns_dsi_drm_probe()
1552 input->bridge.of_node = pdev->dev.of_node; in cdns_dsi_drm_probe()
1555 writel(0, dsi->regs + MCTL_MAIN_STS_CTL); in cdns_dsi_drm_probe()
1556 writel(0, dsi->regs + MCTL_DPHY_ERR_CTL1); in cdns_dsi_drm_probe()
1557 writel(0, dsi->regs + CMD_MODE_STS_CTL); in cdns_dsi_drm_probe()
1558 writel(0, dsi->regs + DIRECT_CMD_STS_CTL); in cdns_dsi_drm_probe()
1559 writel(0, dsi->regs + DIRECT_CMD_RD_STS_CTL); in cdns_dsi_drm_probe()
1560 writel(0, dsi->regs + VID_MODE_STS_CTL); in cdns_dsi_drm_probe()
1561 writel(0, dsi->regs + TVG_STS_CTL); in cdns_dsi_drm_probe()
1562 writel(0, dsi->regs + DPI_IRQ_EN); in cdns_dsi_drm_probe()
1563 ret = devm_request_irq(&pdev->dev, irq, cdns_dsi_interrupt, 0, in cdns_dsi_drm_probe()
1564 dev_name(&pdev->dev), dsi); in cdns_dsi_drm_probe()
1568 pm_runtime_enable(&pdev->dev); in cdns_dsi_drm_probe()
1569 dsi->base.dev = &pdev->dev; in cdns_dsi_drm_probe()
1570 dsi->base.ops = &cdns_dsi_ops; in cdns_dsi_drm_probe()
1572 ret = mipi_dsi_host_register(&dsi->base); in cdns_dsi_drm_probe()
1576 clk_disable_unprepare(dsi->dsi_p_clk); in cdns_dsi_drm_probe()
1581 pm_runtime_disable(&pdev->dev); in cdns_dsi_drm_probe()
1584 clk_disable_unprepare(dsi->dsi_p_clk); in cdns_dsi_drm_probe()
1587 cdns_dphy_remove(dsi->dphy); in cdns_dsi_drm_probe()
1596 mipi_dsi_host_unregister(&dsi->base); in cdns_dsi_drm_remove()
1597 pm_runtime_disable(&pdev->dev); in cdns_dsi_drm_remove()
1598 cdns_dphy_remove(dsi->dphy); in cdns_dsi_drm_remove()
1612 .name = "cdns-dsi",
1622 MODULE_ALIAS("platform:cdns-dsi");