Lines Matching +full:dual +full:- +full:lane

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4 * Author(s): Raphaël GALLAIS-POU <raphael.gallais-pou@foss.st.com> for STMicroelectronics.
16 #include <linux/clk-provider.h>
19 #include <linux/media-bus-format.h>
62 #define CR_LK1POL GENMASK(20, 16) /* Link-1 output Polarity */
63 #define CR_LK2POL GENMASK(25, 21) /* Link-2 output Polarity */
73 #define CDLCR_DISTR0 GENMASK(3, 0) /* Channel distribution for lane 0 */
74 #define CDLCR_DISTR1 GENMASK(7, 4) /* Channel distribution for lane 1 */
75 #define CDLCR_DISTR2 GENMASK(11, 8) /* Channel distribution for lane 2 */
76 #define CDLCR_DISTR3 GENMASK(15, 12) /* Channel distribution for lane 3 */
77 #define CDLCR_DISTR4 GENMASK(19, 16) /* Channel distribution for lane 4 */
94 #define PHY_CFGCR_EN_DIG_DL GENMASK(4, 0) /* LVDS PHY digital lane enable */
96 #define PHY_PLLCR1_EN_SD BIT(1) /* LVDS PHY PLL sigma-delta signal enable */
120 * ,--------. ,--------. ,--------. ,--------. ,---------.
123 * `--------' `--------' `--------' `--------' `---------'
127 * ,--------. ,--------. ,--------. ,--------. ,---------.
130 * `--------' `--------' `--------' `--------' `---------'
291 writel(val, lvds->base + reg);
296 return readl(lvds->base + reg);
310 * Expected JEIDA-RGB888 data to be sent in LSB format
327 * Expected VESA-RGB888 data to be sent in LSB format
348 struct drm_device *drm = lvds->lvds_bridge.dev;
354 * Adjusted value so that the masking window is opened at start-up
356 lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16);
359 lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN);
363 lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr);
366 lvds_set(lvds, phy->base + phy->ofs.PLLTESTCR, PHY_PLLTESTCR_EN);
367 lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_DIV_EN);
370 lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN);
373 lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_PLL_EN);
374 ret = readl_poll_timeout_atomic(lvds->base + phy->base + phy->ofs.PLLSR,
380 /* WCLKCR_SECND_CLKPIX_SEL is for dual link */
383 lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN);
416 return -EINVAL;
427 delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz;
429 delta = -delta;
456 * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by
457 * several post-dividers, each one with a specific application.
459 * ,------. ,-----. ,-----.
460 * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco
461 * `------' ,-> | | `-----' |
462 * | `-----' |
463 * | ,------. |
464 * `-------- | MDIV | <-----'
465 * `------'
469 * is passed through a programmable post-divider BDIV. Finally, the
472 * ,--------.
473 * ,-----> | DP div | ----------------> Fdp
474 * ,------. | `--------'
475 * Fvco --> | BDIV | ------------------------------------> Fbit
476 * | `------' ,------. |
477 * `-------------> | TDIV | --.---------------------> ClkObs
478 * '------' | ,--------.
479 * `--> | LS div | ------> Fls
480 * '--------'
484 * to a pixel clock per lane per clock sample (Fls). This is useful
489 hwclk = __clk_get_hw(lvds->pllref_clk);
495 if (lvds_is_dual_link(lvds->link_type))
501 lvds->pixel_clock_rate * 7 / 1000 / multiplier,
505 lvds_write(lvds, phy->base + phy->ofs.PLLCR2, ndiv << 16);
506 lvds_set(lvds, phy->base + phy->ofs.PLLCR2, bdiv);
507 lvds_write(lvds, phy->base + phy->ofs.PLLSDCR1, mdiv);
510 lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16);
517 * - PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO
518 * - EN_TWG = 0
519 * - EN_SD = 0
520 * - DOWN_SPREAD = 0
523 * - EN_TWG = 0
524 * - EN_SD = 1
525 * - DOWN_SPREAD = 0
528 * - EN_TWG = 1
529 * - EN_SD = 1
533 lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD);
536 lvds_set(lvds, phy->base + phy->ofs.DCR, PHY_DCR_POWER_OK);
537 lvds_set(lvds, phy->base + phy->ofs.CMCR1, PHY_CMCR_CM_EN_DL);
538 lvds_set(lvds, phy->base + phy->ofs.CMCR2, PHY_CMCR_CM_EN_DL4);
541 lvds_set(lvds, phy->base + phy->ofs.PLLCPCR, 0x1);
542 lvds_set(lvds, phy->base + phy->ofs.BCR3, PHY_BCR3_VM_EN_DL);
543 lvds_set(lvds, phy->base + phy->ofs.BCR1, PHY_BCR1_EN_BIAS_DL);
545 lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL);
551 struct drm_device *drm = lvds->lvds_bridge.dev;
555 ret = clk_prepare_enable(lvds->pclk);
561 ret = clk_prepare_enable(lvds->pllref_clk);
564 clk_disable_unprepare(lvds->pclk);
568 /* In case we are operating in dual link the second PHY is set before the primary PHY. */
569 if (lvds->secondary) {
570 phy = lvds->secondary;
573 lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
583 if (lvds->primary) {
584 phy = lvds->primary;
587 lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
611 if (lvds->primary) {
612 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
614 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1,
616 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
620 if (lvds->secondary) {
621 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
623 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1,
625 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
629 clk_disable_unprepare(lvds->pllref_clk);
630 clk_disable_unprepare(lvds->pclk);
637 struct drm_device *drm = lvds->lvds_bridge.dev;
642 ret = clk_prepare_enable(lvds->pclk);
648 if (lvds_is_dual_link(lvds->link_type))
653 val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2);
659 lvds->primary->base + lvds->primary->ofs.PLLSDCR1);
666 lvds->pixel_clock_rate * 7 / 1000 / multiplier,
675 * 1/7 because for each pixel in 1 lane there is 7 bits
678 lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7;
680 clk_disable_unprepare(lvds->pclk);
682 return (unsigned long)lvds->pixel_clock_rate;
694 connector = &lvds->connector;
696 return -EINVAL;
698 if (list_empty(&connector->modes)) {
699 drm_dbg(connector->dev, "connector: empty modes list\n");
700 return -EINVAL;
703 mode = list_first_entry(&connector->modes,
708 if (lvds_is_dual_link(lvds->link_type))
713 lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv);
716 * 1/7 because for each pixel in 1 lane there is 7 bits
719 lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv)
722 return lvds->pixel_clock_rate;
744 of_clk_del_provider(lvds->dev->of_node);
745 clk_hw_unregister(&lvds->lvds_ck_px);
750 struct device_node *node = lvds->dev->of_node;
753 lvds->lvds_ck_px.init = &clk_data;
756 lvds->pixel_clock_rate = 148500000;
758 ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px);
763 &lvds->lvds_ck_px);
765 clk_hw_unregister(&lvds->lvds_ck_px);
775 struct drm_device *drm = lvds->lvds_bridge.dev;
781 info = &(&lvds->connector)->display_info;
782 if (!info->num_bus_formats || !info->bus_formats) {
787 switch (info->bus_formats[0]) {
788 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */
791 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */
794 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */
798 drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]);
802 /* Set bitmap for each lane */
823 connector = &lvds->connector;
827 if (list_empty(&connector->modes)) {
828 drm_dbg(connector->dev, "connector: empty modes list\n");
832 bus_flags = connector->display_info.bus_flags;
833 mode = list_first_entry(&connector->modes,
843 if (lvds->primary)
846 if (lvds->secondary) {
855 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
858 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
861 switch (lvds->link_type) {
869 drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n");
884 return drm_panel_get_modes(lvds->panel, connector);
896 return -EINVAL;
898 if (list_empty(&connector->modes)) {
899 drm_dbg(connector->dev, "connector: empty modes list\n");
900 return -EINVAL;
903 if (!conn_state->crtc)
904 return -EINVAL;
906 panel_mode = list_first_entry(&connector->modes,
910 crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
914 if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
915 crtc_state->mode.vdisplay != panel_mode->vdisplay)
916 return -EINVAL;
919 drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
941 struct drm_connector *connector = &lvds->connector;
945 drm_err(bridge->dev, "Parent encoder object not found\n");
946 return -ENODEV;
950 encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
953 encoder->possible_clones = 0;
956 if (lvds->next_bridge)
957 return drm_bridge_attach(encoder, lvds->next_bridge,
961 drm_err(bridge->dev, "Fix bridge driver to make connector optional!");
962 return -EINVAL;
966 if (!lvds->panel)
969 ret = drm_connector_init(bridge->dev, connector,
989 ret = clk_prepare_enable(lvds->pclk);
991 drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n");
995 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
1011 if (lvds->panel) {
1012 drm_panel_prepare(lvds->panel);
1013 drm_panel_enable(lvds->panel);
1022 if (lvds->panel) {
1023 drm_panel_disable(lvds->panel);
1024 drm_panel_unprepare(lvds->panel);
1030 clk_disable_unprepare(lvds->pclk);
1045 struct device *dev = &pdev->dev;
1056 lvds->dev = dev;
1058 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,
1059 &lvds->panel, &lvds->next_bridge);
1065 lvds->base = devm_platform_ioremap_resource(pdev, 0);
1066 if (IS_ERR(lvds->base)) {
1067 ret = PTR_ERR(lvds->base);
1072 lvds->pclk = devm_clk_get(dev, "pclk");
1073 if (IS_ERR(lvds->pclk)) {
1074 ret = PTR_ERR(lvds->pclk);
1079 ret = clk_prepare_enable(lvds->pclk);
1096 port1 = of_graph_get_port_by_id(dev->of_node, 1);
1097 port2 = of_graph_get_port_by_id(dev->of_node, 2);
1102 lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
1103 lvds->primary = &lvds_phy_16ff_primary;
1104 lvds->secondary = &lvds_phy_16ff_secondary;
1107 lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
1108 lvds->primary = &lvds_phy_16ff_primary;
1109 lvds->secondary = &lvds_phy_16ff_secondary;
1111 case -EINVAL:
1124 lvds->link_type = LVDS_SINGLE_LINK_PRIMARY;
1125 lvds->primary = &lvds_phy_16ff_primary;
1126 lvds->secondary = NULL;
1128 ret = -EINVAL;
1137 lvds->link_type = LVDS_SINGLE_LINK_SECONDARY;
1138 lvds->primary = NULL;
1139 lvds->secondary = &lvds_phy_16ff_secondary;
1141 ret = (ret == -EINVAL) ? -EINVAL : 0;
1148 ret = -EINVAL;
1154 lvds->pllref_clk = devm_clk_get(dev, "ref");
1155 if (IS_ERR(lvds->pllref_clk)) {
1156 ret = PTR_ERR(lvds->pllref_clk);
1167 lvds->lvds_bridge.of_node = dev->of_node;
1168 lvds->hw_version = lvds_read(lvds, LVDS_VERR);
1170 dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version);
1172 drm_bridge_add(&lvds->lvds_bridge);
1176 clk_disable_unprepare(lvds->pclk);
1181 clk_disable_unprepare(lvds->pclk);
1192 drm_bridge_remove(&lvds->lvds_bridge);
1197 .compatible = "st,stm32mp25-lvds",
1209 .name = "stm32-display-lvds",
1216 MODULE_AUTHOR("Raphaël Gallais-Pou <raphael.gallais-pou@foss.st.com>");