Lines Matching +full:panel +full:- +full:lvds

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Mark Yao <mark.yao@rock-chips.com>
6 * Sandy Huang <hjc@rock-chips.com>
40 * rockchip_lvds_soc_data - rockchip lvds Soc private data
41 * @ch1_offset: lvds channel 1 registe offset
42 * grf_soc_con6: general registe offset for LVDS contrl
43 * grf_soc_con7: general registe offset for LVDS contrl
59 int output; /* rgb lvds or dual lvds output */
62 struct drm_panel *panel; member
69 static inline void lvds_writel(struct rockchip_lvds *lvds, u32 offset, u32 val) in lvds_writel() argument
71 writel_relaxed(val, lvds->regs + offset); in lvds_writel()
72 if (lvds->output == DISPLAY_OUTPUT_LVDS) in lvds_writel()
74 writel_relaxed(val, lvds->regs + offset + lvds->soc_data->ch1_offset); in lvds_writel()
79 if (strncmp(s, "jeida-18", 8) == 0) in lvds_name_to_format()
81 else if (strncmp(s, "jeida-24", 8) == 0) in lvds_name_to_format()
83 else if (strncmp(s, "vesa-24", 7) == 0) in lvds_name_to_format()
86 return -EINVAL; in lvds_name_to_format()
93 else if (strncmp(s, "lvds", 4) == 0) in lvds_name_to_output()
98 return -EINVAL; in lvds_name_to_output()
101 static int rockchip_lvds_poweron(struct rockchip_lvds *lvds) in rockchip_lvds_poweron() argument
106 ret = clk_enable(lvds->pclk); in rockchip_lvds_poweron()
108 DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); in rockchip_lvds_poweron()
111 ret = pm_runtime_get_sync(lvds->dev); in rockchip_lvds_poweron()
113 DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); in rockchip_lvds_poweron()
114 clk_disable(lvds->pclk); in rockchip_lvds_poweron()
120 if (lvds->output == DISPLAY_OUTPUT_RGB) { in rockchip_lvds_poweron()
123 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); in rockchip_lvds_poweron()
124 lvds_writel(lvds, RK3288_LVDS_CH0_REG2, in rockchip_lvds_poweron()
126 lvds_writel(lvds, RK3288_LVDS_CH0_REG4, in rockchip_lvds_poweron()
133 lvds_writel(lvds, RK3288_LVDS_CH0_REG5, in rockchip_lvds_poweron()
143 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); in rockchip_lvds_poweron()
144 lvds_writel(lvds, RK3288_LVDS_CH0_REG1, in rockchip_lvds_poweron()
151 lvds_writel(lvds, RK3288_LVDS_CH0_REG2, in rockchip_lvds_poweron()
160 lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); in rockchip_lvds_poweron()
161 lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); in rockchip_lvds_poweron()
163 lvds_writel(lvds, RK3288_LVDS_CH0_REG3, RK3288_LVDS_PLL_FBDIV_REG3(0x46)); in rockchip_lvds_poweron()
164 lvds_writel(lvds, RK3288_LVDS_CH0_REGD, RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); in rockchip_lvds_poweron()
165 lvds_writel(lvds, RK3288_LVDS_CH0_REG20, RK3288_LVDS_CH0_REG20_LSB); in rockchip_lvds_poweron()
167 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); in rockchip_lvds_poweron()
168 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); in rockchip_lvds_poweron()
173 static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds) in rockchip_lvds_poweroff() argument
178 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); in rockchip_lvds_poweroff()
179 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); in rockchip_lvds_poweroff()
182 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); in rockchip_lvds_poweroff()
184 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); in rockchip_lvds_poweroff()
186 pm_runtime_put(lvds->dev); in rockchip_lvds_poweroff()
187 clk_disable(lvds->pclk); in rockchip_lvds_poweroff()
200 struct rockchip_lvds *lvds = connector_to_lvds(connector); in rockchip_lvds_connector_get_modes() local
201 struct drm_panel *panel = lvds->panel; in rockchip_lvds_connector_get_modes() local
203 return drm_panel_get_modes(panel); in rockchip_lvds_connector_get_modes()
214 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); in rockchip_lvds_grf_config() local
215 u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0; in rockchip_lvds_grf_config()
216 u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0; in rockchip_lvds_grf_config()
221 if (lvds->output == DISPLAY_OUTPUT_RGB) in rockchip_lvds_grf_config()
222 if (lvds->pins && !IS_ERR(lvds->pins->default_state)) in rockchip_lvds_grf_config()
223 pinctrl_select_state(lvds->pins->p, in rockchip_lvds_grf_config()
224 lvds->pins->default_state); in rockchip_lvds_grf_config()
225 val = lvds->format | LVDS_CH0_EN; in rockchip_lvds_grf_config()
226 if (lvds->output == DISPLAY_OUTPUT_RGB) in rockchip_lvds_grf_config()
228 else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS) in rockchip_lvds_grf_config()
231 if ((mode->htotal - mode->hsync_start) & 0x01) in rockchip_lvds_grf_config()
236 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); in rockchip_lvds_grf_config()
238 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); in rockchip_lvds_grf_config()
243 static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds, in rockchip_lvds_set_vop_source() argument
249 if (!lvds->soc_data->has_vop_sel) in rockchip_lvds_set_vop_source()
252 ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); in rockchip_lvds_set_vop_source()
260 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val); in rockchip_lvds_set_vop_source()
274 s->output_mode = ROCKCHIP_OUT_MODE_P888; in rockchip_lvds_encoder_atomic_check()
275 s->output_type = DRM_MODE_CONNECTOR_LVDS; in rockchip_lvds_encoder_atomic_check()
282 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); in rockchip_lvds_encoder_enable() local
283 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; in rockchip_lvds_encoder_enable()
286 drm_panel_prepare(lvds->panel); in rockchip_lvds_encoder_enable()
287 ret = rockchip_lvds_poweron(lvds); in rockchip_lvds_encoder_enable()
289 DRM_DEV_ERROR(lvds->dev, "failed to power on lvds: %d\n", ret); in rockchip_lvds_encoder_enable()
290 drm_panel_unprepare(lvds->panel); in rockchip_lvds_encoder_enable()
293 rockchip_lvds_set_vop_source(lvds, encoder); in rockchip_lvds_encoder_enable()
294 drm_panel_enable(lvds->panel); in rockchip_lvds_encoder_enable()
299 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); in rockchip_lvds_encoder_disable() local
301 drm_panel_disable(lvds->panel); in rockchip_lvds_encoder_disable()
302 rockchip_lvds_poweroff(lvds); in rockchip_lvds_encoder_disable()
303 drm_panel_unprepare(lvds->panel); in rockchip_lvds_encoder_disable()
326 .compatible = "rockchip,rk3288-lvds",
336 struct rockchip_lvds *lvds = dev_get_drvdata(dev); in rockchip_lvds_bind() local
346 lvds->drm_dev = drm_dev; in rockchip_lvds_bind()
347 port = of_graph_get_port_by_id(dev->of_node, 1); in rockchip_lvds_bind()
350 "can't found port point, please init lvds panel port!\n"); in rockchip_lvds_bind()
351 return -EINVAL; in rockchip_lvds_bind()
356 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id, in rockchip_lvds_bind()
357 &lvds->panel, &lvds->bridge); in rockchip_lvds_bind()
364 DRM_DEV_ERROR(dev, "lvds port does not have any children\n"); in rockchip_lvds_bind()
365 ret = -EINVAL; in rockchip_lvds_bind()
368 DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); in rockchip_lvds_bind()
369 ret = -EPROBE_DEFER; in rockchip_lvds_bind()
372 if (lvds->panel) in rockchip_lvds_bind()
373 remote = lvds->panel->dev->of_node; in rockchip_lvds_bind()
375 remote = lvds->bridge->of_node; in rockchip_lvds_bind()
376 if (of_property_read_string(dev->of_node, "rockchip,output", &name)) in rockchip_lvds_bind()
378 lvds->output = DISPLAY_OUTPUT_RGB; in rockchip_lvds_bind()
380 lvds->output = lvds_name_to_output(name); in rockchip_lvds_bind()
382 if (lvds->output < 0) { in rockchip_lvds_bind()
384 ret = lvds->output; in rockchip_lvds_bind()
388 if (of_property_read_string(remote, "data-mapping", &name)) in rockchip_lvds_bind()
390 lvds->format = LVDS_VESA_18; in rockchip_lvds_bind()
392 lvds->format = lvds_name_to_format(name); in rockchip_lvds_bind()
394 if (lvds->format < 0) { in rockchip_lvds_bind()
395 DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name); in rockchip_lvds_bind()
396 ret = lvds->format; in rockchip_lvds_bind()
400 encoder = &lvds->encoder; in rockchip_lvds_bind()
401 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, in rockchip_lvds_bind()
402 dev->of_node); in rockchip_lvds_bind()
407 DRM_DEV_ERROR(drm_dev->dev, in rockchip_lvds_bind()
414 if (lvds->panel) { in rockchip_lvds_bind()
415 connector = &lvds->connector; in rockchip_lvds_bind()
416 connector->dpms = DRM_MODE_DPMS_OFF; in rockchip_lvds_bind()
421 DRM_DEV_ERROR(drm_dev->dev, in rockchip_lvds_bind()
431 DRM_DEV_ERROR(drm_dev->dev, in rockchip_lvds_bind()
436 ret = drm_panel_attach(lvds->panel, connector); in rockchip_lvds_bind()
438 DRM_DEV_ERROR(drm_dev->dev, in rockchip_lvds_bind()
439 "failed to attach panel: %d\n", ret); in rockchip_lvds_bind()
443 ret = drm_bridge_attach(encoder, lvds->bridge, NULL); in rockchip_lvds_bind()
445 DRM_DEV_ERROR(drm_dev->dev, in rockchip_lvds_bind()
472 struct rockchip_lvds *lvds = dev_get_drvdata(dev); in rockchip_lvds_unbind() local
474 rockchip_lvds_encoder_disable(&lvds->encoder); in rockchip_lvds_unbind()
475 if (lvds->panel) in rockchip_lvds_unbind()
476 drm_panel_detach(lvds->panel); in rockchip_lvds_unbind()
478 drm_connector_cleanup(&lvds->connector); in rockchip_lvds_unbind()
479 drm_encoder_cleanup(&lvds->encoder); in rockchip_lvds_unbind()
489 struct device *dev = &pdev->dev; in rockchip_lvds_probe()
490 struct rockchip_lvds *lvds; in rockchip_lvds_probe() local
495 if (!dev->of_node) in rockchip_lvds_probe()
496 return -ENODEV; in rockchip_lvds_probe()
498 lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); in rockchip_lvds_probe()
499 if (!lvds) in rockchip_lvds_probe()
500 return -ENOMEM; in rockchip_lvds_probe()
502 lvds->dev = dev; in rockchip_lvds_probe()
503 match = of_match_node(rockchip_lvds_dt_ids, dev->of_node); in rockchip_lvds_probe()
505 return -ENODEV; in rockchip_lvds_probe()
506 lvds->soc_data = match->data; in rockchip_lvds_probe()
509 lvds->regs = devm_ioremap_resource(&pdev->dev, res); in rockchip_lvds_probe()
510 if (IS_ERR(lvds->regs)) in rockchip_lvds_probe()
511 return PTR_ERR(lvds->regs); in rockchip_lvds_probe()
513 lvds->pclk = devm_clk_get(&pdev->dev, "pclk_lvds"); in rockchip_lvds_probe()
514 if (IS_ERR(lvds->pclk)) { in rockchip_lvds_probe()
516 return PTR_ERR(lvds->pclk); in rockchip_lvds_probe()
519 lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), in rockchip_lvds_probe()
521 if (!lvds->pins) in rockchip_lvds_probe()
522 return -ENOMEM; in rockchip_lvds_probe()
524 lvds->pins->p = devm_pinctrl_get(lvds->dev); in rockchip_lvds_probe()
525 if (IS_ERR(lvds->pins->p)) { in rockchip_lvds_probe()
527 devm_kfree(lvds->dev, lvds->pins); in rockchip_lvds_probe()
528 lvds->pins = NULL; in rockchip_lvds_probe()
530 lvds->pins->default_state = in rockchip_lvds_probe()
531 pinctrl_lookup_state(lvds->pins->p, "lcdc"); in rockchip_lvds_probe()
532 if (IS_ERR(lvds->pins->default_state)) { in rockchip_lvds_probe()
534 devm_kfree(lvds->dev, lvds->pins); in rockchip_lvds_probe()
535 lvds->pins = NULL; in rockchip_lvds_probe()
539 lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node, in rockchip_lvds_probe()
541 if (IS_ERR(lvds->grf)) { in rockchip_lvds_probe()
543 return PTR_ERR(lvds->grf); in rockchip_lvds_probe()
546 dev_set_drvdata(dev, lvds); in rockchip_lvds_probe()
548 ret = clk_prepare(lvds->pclk); in rockchip_lvds_probe()
553 ret = component_add(&pdev->dev, &rockchip_lvds_component_ops); in rockchip_lvds_probe()
556 clk_unprepare(lvds->pclk); in rockchip_lvds_probe()
564 struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev); in rockchip_lvds_remove() local
566 component_del(&pdev->dev, &rockchip_lvds_component_ops); in rockchip_lvds_remove()
567 clk_unprepare(lvds->pclk); in rockchip_lvds_remove()
576 .name = "rockchip-lvds",