1224 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved4 * Author(s): Raphaël GALLAIS-POU <raphael.gallais-pou@foss.st.com> for STMicroelectronics.5 */6 7#include <drm/drm_atomic_helper.h>8#include <drm/drm_bridge.h>9#include <drm/drm_device.h>10#include <drm/drm_of.h>11#include <drm/drm_panel.h>12#include <drm/drm_print.h>13#include <drm/drm_probe_helper.h>14 15#include <linux/clk.h>16#include <linux/clk-provider.h>17#include <linux/io.h>18#include <linux/iopoll.h>19#include <linux/media-bus-format.h>20#include <linux/module.h>21#include <linux/of_device.h>22#include <linux/platform_device.h>23#include <linux/reset.h>24 25/* LVDS Host registers */26#define LVDS_CR 0x0000 /* configuration register */27#define LVDS_DMLCR0 0x0004 /* data mapping lsb configuration register 0 */28#define LVDS_DMMCR0 0x0008 /* data mapping msb configuration register 0 */29#define LVDS_DMLCR1 0x000C /* data mapping lsb configuration register 1 */30#define LVDS_DMMCR1 0x0010 /* data mapping msb configuration register 1 */31#define LVDS_DMLCR2 0x0014 /* data mapping lsb configuration register 2 */32#define LVDS_DMMCR2 0x0018 /* data mapping msb configuration register 2 */33#define LVDS_DMLCR3 0x001C /* data mapping lsb configuration register 3 */34#define LVDS_DMMCR3 0x0020 /* data mapping msb configuration register 3 */35#define LVDS_DMLCR4 0x0024 /* data mapping lsb configuration register 4 */36#define LVDS_DMMCR4 0x0028 /* data mapping msb configuration register 4 */37#define LVDS_CDL1CR 0x002C /* channel distrib link 1 configuration register */38#define LVDS_CDL2CR 0x0030 /* channel distrib link 2 configuration register */39 40#define CDL1CR_DEFAULT 0x04321 /* Default value for CDL1CR */41#define CDL2CR_DEFAULT 0x59876 /* Default value for CDL2CR */42 43#define LVDS_DMLCR(bit) (LVDS_DMLCR0 + 0x8 * (bit))44#define LVDS_DMMCR(bit) (LVDS_DMMCR0 + 0x8 * (bit))45 46/* LVDS Wrapper registers */47#define LVDS_WCLKCR 0x11B0 /* Wrapper clock control register */48 49#define LVDS_HWCFGR 0x1FF0 /* HW configuration register */50#define LVDS_VERR 0x1FF4 /* Version register */51#define LVDS_IPIDR 0x1FF8 /* Identification register */52#define LVDS_SIDR 0x1FFC /* Size Identification register */53 54/* Bitfield description */55#define CR_LVDSEN BIT(0) /* LVDS PHY Enable */56#define CR_HSPOL BIT(1) /* Horizontal Synchronization Polarity */57#define CR_VSPOL BIT(2) /* Vertical Synchronization Polarity */58#define CR_DEPOL BIT(3) /* Data Enable Polarity */59#define CR_CI BIT(4) /* Control Internal (software controlled bit) */60#define CR_LKMOD BIT(5) /* Link Mode, for both Links */61#define CR_LKPHA BIT(6) /* Link Phase, for both Links */62#define CR_LK1POL GENMASK(20, 16) /* Link-1 output Polarity */63#define CR_LK2POL GENMASK(25, 21) /* Link-2 output Polarity */64 65#define DMMCR_MAP0 GENMASK(4, 0) /* Mapping for bit 0 of datalane x */66#define DMMCR_MAP1 GENMASK(9, 5) /* Mapping for bit 1 of datalane x */67#define DMMCR_MAP2 GENMASK(14, 10) /* Mapping for bit 2 of datalane x */68#define DMMCR_MAP3 GENMASK(19, 15) /* Mapping for bit 3 of datalane x */69#define DMLCR_MAP4 GENMASK(4, 0) /* Mapping for bit 4 of datalane x */70#define DMLCR_MAP5 GENMASK(9, 5) /* Mapping for bit 5 of datalane x */71#define DMLCR_MAP6 GENMASK(14, 10) /* Mapping for bit 6 of datalane x */72 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 */78 79#define PHY_GCR_BIT_CLK_OUT BIT(0) /* BIT clock enable */80#define PHY_GCR_LS_CLK_OUT BIT(4) /* LS clock enable */81#define PHY_GCR_DP_CLK_OUT BIT(8) /* DP clock enable */82#define PHY_GCR_RSTZ BIT(24) /* LVDS PHY digital reset */83#define PHY_GCR_DIV_RSTN BIT(25) /* Output divider reset */84#define PHY_SCR_TX_EN BIT(16) /* Transmission mode enable */85/* Current mode driver enable */86#define PHY_CMCR_CM_EN_DL (BIT(28) | BIT(20) | BIT(12) | BIT(4))87#define PHY_CMCR_CM_EN_DL4 BIT(4)88/* Bias enable */89#define PHY_BCR1_EN_BIAS_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))90#define PHY_BCR2_BIAS_EN BIT(28)91/* Voltage mode driver enable */92#define PHY_BCR3_VM_EN_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))93#define PHY_DCR_POWER_OK BIT(12)94#define PHY_CFGCR_EN_DIG_DL GENMASK(4, 0) /* LVDS PHY digital lane enable */95#define PHY_PLLCR1_PLL_EN BIT(0) /* LVDS PHY PLL enable */96#define PHY_PLLCR1_EN_SD BIT(1) /* LVDS PHY PLL sigma-delta signal enable */97#define PHY_PLLCR1_EN_TWG BIT(2) /* LVDS PHY PLL triangular wave generator enable */98#define PHY_PLLCR1_DIV_EN BIT(8) /* LVDS PHY PLL dividers enable */99#define PHY_PLLCR2_NDIV GENMASK(25, 16) /* NDIV mask value */100#define PHY_PLLCR2_BDIV GENMASK(9, 0) /* BDIV mask value */101#define PHY_PLLSR_PLL_LOCK BIT(0) /* LVDS PHY PLL lock status */102#define PHY_PLLSDCR1_MDIV GENMASK(9, 0) /* MDIV mask value */103#define PHY_PLLTESTCR_TDIV GENMASK(25, 16) /* TDIV mask value */104#define PHY_PLLTESTCR_CLK_EN BIT(0) /* Test clock enable */105#define PHY_PLLTESTCR_EN BIT(8) /* Test divider output enable */106 107#define WCLKCR_SECND_CLKPIX_SEL BIT(0) /* Pixel clock selection */108#define WCLKCR_SRCSEL BIT(8) /* Source selection for the pixel clock */109 110/* Sleep & timeout for pll lock/unlock */111#define SLEEP_US 1000112#define TIMEOUT_US 200000113 114/*115 * The link phase defines whether an ODD pixel is carried over together with116 * the next EVEN pixel or together with the previous EVEN pixel.117 *118 * LVDS_DUAL_LINK_EVEN_ODD_PIXELS (LKPHA = 0)119 *120 * ,--------. ,--------. ,--------. ,--------. ,---------.121 * | ODD LK \/ PIXEL 3 \/ PIXEL 1 \/ PIXEL' 1 \/ PIXEL' 3 |122 * | EVEN LK /\ PIXEL 2 /\ PIXEL' 0 /\ PIXEL' 2 /\ PIXEL' 4 |123 * `--------' `--------' `--------' `--------' `---------'124 *125 * LVDS_DUAL_LINK_ODD_EVEN_PIXELS (LKPHA = 1)126 *127 * ,--------. ,--------. ,--------. ,--------. ,---------.128 * | ODD LK \/ PIXEL 3 \/ PIXEL 1 \/ PIXEL' 1 \/ PIXEL' 3 |129 * | EVEN LK /\ PIXEL 4 /\ PIXEL 2 /\ PIXEL' 0 /\ PIXEL' 2 |130 * `--------' `--------' `--------' `--------' `---------'131 *132 */133enum lvds_link_type {134 LVDS_SINGLE_LINK_PRIMARY = 0,135 LVDS_SINGLE_LINK_SECONDARY,136 LVDS_DUAL_LINK_EVEN_ODD_PIXELS,137 LVDS_DUAL_LINK_ODD_EVEN_PIXELS,138};139 140enum lvds_pixel {141 PIX_R_0 = 0,142 PIX_R_1,143 PIX_R_2,144 PIX_R_3,145 PIX_R_4,146 PIX_R_5,147 PIX_R_6,148 PIX_R_7,149 PIX_G_0,150 PIX_G_1,151 PIX_G_2,152 PIX_G_3,153 PIX_G_4,154 PIX_G_5,155 PIX_G_6,156 PIX_G_7,157 PIX_B_0,158 PIX_B_1,159 PIX_B_2,160 PIX_B_3,161 PIX_B_4,162 PIX_B_5,163 PIX_B_6,164 PIX_B_7,165 PIX_H_S,166 PIX_V_S,167 PIX_D_E,168 PIX_C_E,169 PIX_C_I,170 PIX_TOG,171 PIX_ONE,172 PIX_ZER,173};174 175struct phy_reg_offsets {176 u32 GCR; /* Global Control Register */177 u32 CMCR1; /* Current Mode Control Register 1 */178 u32 CMCR2; /* Current Mode Control Register 2 */179 u32 SCR; /* Serial Control Register */180 u32 BCR1; /* Bias Control Register 1 */181 u32 BCR2; /* Bias Control Register 2 */182 u32 BCR3; /* Bias Control Register 3 */183 u32 MPLCR; /* Monitor PLL Lock Control Register */184 u32 DCR; /* Debug Control Register */185 u32 SSR1; /* Spare Status Register 1 */186 u32 CFGCR; /* Configuration Control Register */187 u32 PLLCR1; /* PLL_MODE 1 Control Register */188 u32 PLLCR2; /* PLL_MODE 2 Control Register */189 u32 PLLSR; /* PLL Status Register */190 u32 PLLSDCR1; /* PLL_SD_1 Control Register */191 u32 PLLSDCR2; /* PLL_SD_2 Control Register */192 u32 PLLTWGCR1;/* PLL_TWG_1 Control Register */193 u32 PLLTWGCR2;/* PLL_TWG_2 Control Register */194 u32 PLLCPCR; /* PLL_CP Control Register */195 u32 PLLTESTCR;/* PLL_TEST Control Register */196};197 198struct lvds_phy_info {199 u32 base;200 struct phy_reg_offsets ofs;201};202 203static struct lvds_phy_info lvds_phy_16ff_primary = {204 .base = 0x1000,205 .ofs = {206 .GCR = 0x0,207 .CMCR1 = 0xC,208 .CMCR2 = 0x10,209 .SCR = 0x20,210 .BCR1 = 0x2C,211 .BCR2 = 0x30,212 .BCR3 = 0x34,213 .MPLCR = 0x64,214 .DCR = 0x84,215 .SSR1 = 0x88,216 .CFGCR = 0xA0,217 .PLLCR1 = 0xC0,218 .PLLCR2 = 0xC4,219 .PLLSR = 0xC8,220 .PLLSDCR1 = 0xCC,221 .PLLSDCR2 = 0xD0,222 .PLLTWGCR1 = 0xD4,223 .PLLTWGCR2 = 0xD8,224 .PLLCPCR = 0xE0,225 .PLLTESTCR = 0xE8,226 }227};228 229static struct lvds_phy_info lvds_phy_16ff_secondary = {230 .base = 0x1100,231 .ofs = {232 .GCR = 0x0,233 .CMCR1 = 0xC,234 .CMCR2 = 0x10,235 .SCR = 0x20,236 .BCR1 = 0x2C,237 .BCR2 = 0x30,238 .BCR3 = 0x34,239 .MPLCR = 0x64,240 .DCR = 0x84,241 .SSR1 = 0x88,242 .CFGCR = 0xA0,243 .PLLCR1 = 0xC0,244 .PLLCR2 = 0xC4,245 .PLLSR = 0xC8,246 .PLLSDCR1 = 0xCC,247 .PLLSDCR2 = 0xD0,248 .PLLTWGCR1 = 0xD4,249 .PLLTWGCR2 = 0xD8,250 .PLLCPCR = 0xE0,251 .PLLTESTCR = 0xE8,252 }253};254 255struct stm_lvds {256 void __iomem *base;257 struct device *dev;258 struct clk *pclk; /* APB peripheral clock */259 struct clk *pllref_clk; /* Reference clock for the internal PLL */260 struct clk_hw lvds_ck_px; /* Pixel clock */261 u32 pixel_clock_rate; /* Pixel clock rate */262 263 struct lvds_phy_info *primary;264 struct lvds_phy_info *secondary;265 266 struct drm_bridge lvds_bridge;267 struct drm_bridge *next_bridge;268 struct drm_connector connector;269 struct drm_encoder *encoder;270 struct drm_panel *panel;271 272 u32 hw_version;273 u32 link_type;274};275 276#define bridge_to_stm_lvds(b) \277 container_of(b, struct stm_lvds, lvds_bridge)278 279#define connector_to_stm_lvds(c) \280 container_of(c, struct stm_lvds, connector)281 282#define lvds_is_dual_link(lvds) \283 ({ \284 typeof(lvds) __lvds = (lvds); \285 __lvds == LVDS_DUAL_LINK_EVEN_ODD_PIXELS || \286 __lvds == LVDS_DUAL_LINK_ODD_EVEN_PIXELS; \287 })288 289static inline void lvds_write(struct stm_lvds *lvds, u32 reg, u32 val)290{291 writel(val, lvds->base + reg);292}293 294static inline u32 lvds_read(struct stm_lvds *lvds, u32 reg)295{296 return readl(lvds->base + reg);297}298 299static inline void lvds_set(struct stm_lvds *lvds, u32 reg, u32 mask)300{301 lvds_write(lvds, reg, lvds_read(lvds, reg) | mask);302}303 304static inline void lvds_clear(struct stm_lvds *lvds, u32 reg, u32 mask)305{306 lvds_write(lvds, reg, lvds_read(lvds, reg) & ~mask);307}308 309/*310 * Expected JEIDA-RGB888 data to be sent in LSB format311 * bit6 ............................bit0312 * CHAN0 {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}313 * CHAN1 {G2, R7, R6, R5, R4, R3, R2}314 * CHAN2 {B3, B2, G7, G6, G5, G4, G3}315 * CHAN3 {DE, VS, HS, B7, B6, B5, B4}316 * CHAN4 {CE, B1, B0, G1, G0, R1, R0}317 */318static enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = {319 { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },320 { PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 },321 { PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 },322 { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 },323 { PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 }324};325 326/*327 * Expected VESA-RGB888 data to be sent in LSB format328 * bit6 ............................bit0329 * CHAN0 {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}330 * CHAN1 {G0, R5, R4, R3, R2, R1, R0}331 * CHAN2 {B1, B0, G5, G4, G3, G2, G1}332 * CHAN3 {DE, VS, HS, B5, B4, B3, B2}333 * CHAN4 {CE, B7, B6, G7, G6, R7, R6}334 */335static enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = {336 { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },337 { PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 },338 { PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 },339 { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 },340 { PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 }341};342 343/*344 * Clocks and PHY related functions345 */346static int lvds_pll_enable(struct stm_lvds *lvds, struct lvds_phy_info *phy)347{348 struct drm_device *drm = lvds->lvds_bridge.dev;349 u32 lvds_gcr;350 int val, ret;351 352 /*353 * PLL lock timing control for the monitor unmask after startup (pll_en)354 * Adjusted value so that the masking window is opened at start-up355 */356 lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16);357 358 /* Enable bias */359 lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN);360 361 /* Enable DP, LS, BIT clock output */362 lvds_gcr = PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT;363 lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr);364 365 /* Power up all output dividers */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);368 369 /* Set PHY in serial transmission mode */370 lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN);371 372 /* Enable the LVDS PLL & wait for its lock */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,375 val, val & PHY_PLLSR_PLL_LOCK,376 SLEEP_US, TIMEOUT_US);377 if (ret)378 drm_err(drm, "!TIMEOUT! waiting PLL, let's continue\n");379 380 /* WCLKCR_SECND_CLKPIX_SEL is for dual link */381 lvds_write(lvds, LVDS_WCLKCR, WCLKCR_SECND_CLKPIX_SEL);382 383 lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN);384 385 return ret;386}387 388static int pll_get_clkout_khz(int clkin_khz, int bdiv, int mdiv, int ndiv)389{390 int divisor = ndiv * bdiv;391 392 /* Prevents from division by 0 */393 if (!divisor)394 return 0;395 396 return clkin_khz * mdiv / divisor;397}398 399#define TDIV 70400#define NDIV_MIN 2401#define NDIV_MAX 6402#define BDIV_MIN 2403#define BDIV_MAX 6404#define MDIV_MIN 1405#define MDIV_MAX 1023406 407static int lvds_pll_get_params(struct stm_lvds *lvds,408 unsigned int clkin_khz, unsigned int clkout_khz,409 unsigned int *bdiv, unsigned int *mdiv, unsigned int *ndiv)410{411 int delta, best_delta; /* all in khz */412 int i, o, n;413 414 /* Early checks preventing division by 0 & odd results */415 if (clkin_khz <= 0 || clkout_khz <= 0)416 return -EINVAL;417 418 best_delta = 1000000; /* big started value (1000000khz) */419 420 for (i = NDIV_MIN; i <= NDIV_MAX; i++) {421 for (o = BDIV_MIN; o <= BDIV_MAX; o++) {422 n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);423 /* Check ndiv according to vco range */424 if (n < MDIV_MIN || n > MDIV_MAX)425 continue;426 /* Check if new delta is better & saves parameters */427 delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz;428 if (delta < 0)429 delta = -delta;430 if (delta < best_delta) {431 *ndiv = i;432 *mdiv = n;433 *bdiv = o;434 best_delta = delta;435 }436 /* fast return in case of "perfect result" */437 if (!delta)438 return 0;439 }440 }441 442 return 0;443}444 445static void lvds_pll_config(struct stm_lvds *lvds, struct lvds_phy_info *phy)446{447 unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;448 struct clk_hw *hwclk;449 int multiplier;450 451 /*452 * The LVDS PHY includes a low power low jitter high performance and453 * highly configuration Phase Locked Loop supporting integer and454 * fractional multiplication ratios and Spread Spectrum Clocking. In455 * integer mode, the only software supported feature for now, the PLL is456 * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by457 * several post-dividers, each one with a specific application.458 *459 * ,------. ,-----. ,-----.460 * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco461 * `------' ,-> | | `-----' |462 * | `-----' |463 * | ,------. |464 * `-------- | MDIV | <-----'465 * `------'466 *467 * From the output of the VCO, the clock can be optionally extracted on468 * the RCC clock observer, with a divider TDIV, for testing purpose, or469 * is passed through a programmable post-divider BDIV. Finally, the470 * frequency can be divided further with two fixed dividers.471 *472 * ,--------.473 * ,-----> | DP div | ----------------> Fdp474 * ,------. | `--------'475 * Fvco --> | BDIV | ------------------------------------> Fbit476 * | `------' ,------. |477 * `-------------> | TDIV | --.---------------------> ClkObs478 * '------' | ,--------.479 * `--> | LS div | ------> Fls480 * '--------'481 *482 * The LS and DP clock dividers operate at a fixed ratio of 7 and 3.5483 * respectively with regards to fbit. LS divider converts the bit clock484 * to a pixel clock per lane per clock sample (Fls). This is useful485 * when used to generate a dot clock for the display unit RGB output,486 * and DP divider is.487 */488 489 hwclk = __clk_get_hw(lvds->pllref_clk);490 if (!hwclk)491 return;492 493 pll_in_khz = clk_hw_get_rate(hwclk) / 1000;494 495 if (lvds_is_dual_link(lvds->link_type))496 multiplier = 2;497 else498 multiplier = 1;499 500 lvds_pll_get_params(lvds, pll_in_khz,501 lvds->pixel_clock_rate * 7 / 1000 / multiplier,502 &bdiv, &mdiv, &ndiv);503 504 /* Set BDIV, MDIV and NDIV */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);508 509 /* Hardcode TDIV as dynamic values are not yet implemented */510 lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16);511 512 /*513 * For now, PLL just needs to be in integer mode514 * Fractional and spread spectrum clocking are not yet implemented515 *516 * PLL integer mode:517 * - PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO518 * - EN_TWG = 0519 * - EN_SD = 0520 * - DOWN_SPREAD = 0521 *522 * PLL fractional mode:523 * - EN_TWG = 0524 * - EN_SD = 1525 * - DOWN_SPREAD = 0526 *527 * Spread Spectrum Clocking528 * - EN_TWG = 1529 * - EN_SD = 1530 */531 532 /* Disable TWG and SD */533 lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD);534 535 /* Power up bias and PLL dividers */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);539 540 /* Set up voltage mode */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);544 /* Enable digital datalanes */545 lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL);546}547 548static int lvds_pixel_clk_enable(struct clk_hw *hw)549{550 struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);551 struct drm_device *drm = lvds->lvds_bridge.dev;552 struct lvds_phy_info *phy;553 int ret;554 555 ret = clk_prepare_enable(lvds->pclk);556 if (ret) {557 drm_err(drm, "Failed to enable lvds peripheral clk\n");558 return ret;559 }560 561 ret = clk_prepare_enable(lvds->pllref_clk);562 if (ret) {563 drm_err(drm, "Failed to enable lvds reference clk\n");564 clk_disable_unprepare(lvds->pclk);565 return ret;566 }567 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;571 572 /* Release LVDS PHY from reset mode */573 lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);574 lvds_pll_config(lvds, phy);575 576 ret = lvds_pll_enable(lvds, phy);577 if (ret) {578 drm_err(drm, "Failed to enable secondary PHY PLL: %d\n", ret);579 return ret;580 }581 }582 583 if (lvds->primary) {584 phy = lvds->primary;585 586 /* Release LVDS PHY from reset mode */587 lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);588 lvds_pll_config(lvds, phy);589 590 ret = lvds_pll_enable(lvds, phy);591 if (ret) {592 drm_err(drm, "Failed to enable primary PHY PLL: %d\n", ret);593 return ret;594 }595 }596 597 return 0;598}599 600static void lvds_pixel_clk_disable(struct clk_hw *hw)601{602 struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);603 604 /*605 * For each PHY:606 * Disable DP, LS, BIT clock outputs607 * Shutdown the PLL608 * Assert LVDS PHY in reset mode609 */610 611 if (lvds->primary) {612 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,613 (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));614 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1,615 PHY_PLLCR1_PLL_EN);616 lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,617 PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);618 }619 620 if (lvds->secondary) {621 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,622 (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));623 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1,624 PHY_PLLCR1_PLL_EN);625 lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,626 PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);627 }628 629 clk_disable_unprepare(lvds->pllref_clk);630 clk_disable_unprepare(lvds->pclk);631}632 633static unsigned long lvds_pixel_clk_recalc_rate(struct clk_hw *hw,634 unsigned long parent_rate)635{636 struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);637 struct drm_device *drm = lvds->lvds_bridge.dev;638 unsigned int pll_in_khz, bdiv, mdiv, ndiv;639 int ret, multiplier, pll_out_khz;640 u32 val;641 642 ret = clk_prepare_enable(lvds->pclk);643 if (ret) {644 drm_err(drm, "Failed to enable lvds peripheral clk\n");645 return 0;646 }647 648 if (lvds_is_dual_link(lvds->link_type))649 multiplier = 2;650 else651 multiplier = 1;652 653 val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2);654 655 ndiv = (val & PHY_PLLCR2_NDIV) >> 16;656 bdiv = (val & PHY_PLLCR2_BDIV) >> 0;657 658 mdiv = (unsigned int)lvds_read(lvds,659 lvds->primary->base + lvds->primary->ofs.PLLSDCR1);660 661 pll_in_khz = (unsigned int)(parent_rate / 1000);662 663 /* Compute values if not yet accessible */664 if (val == 0 || mdiv == 0) {665 lvds_pll_get_params(lvds, pll_in_khz,666 lvds->pixel_clock_rate * 7 / 1000 / multiplier,667 &bdiv, &mdiv, &ndiv);668 }669 670 pll_out_khz = pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv);671 drm_dbg(drm, "ndiv %d , bdiv %d, mdiv %d, pll_out_khz %d\n",672 ndiv, bdiv, mdiv, pll_out_khz);673 674 /*675 * 1/7 because for each pixel in 1 lane there is 7 bits676 * We want pixclk, not bitclk677 */678 lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7;679 680 clk_disable_unprepare(lvds->pclk);681 682 return (unsigned long)lvds->pixel_clock_rate;683}684 685static long lvds_pixel_clk_round_rate(struct clk_hw *hw, unsigned long rate,686 unsigned long *parent_rate)687{688 struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);689 unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;690 const struct drm_connector *connector;691 const struct drm_display_mode *mode;692 int multiplier;693 694 connector = &lvds->connector;695 if (!connector)696 return -EINVAL;697 698 if (list_empty(&connector->modes)) {699 drm_dbg(connector->dev, "connector: empty modes list\n");700 return -EINVAL;701 }702 703 mode = list_first_entry(&connector->modes,704 struct drm_display_mode, head);705 706 pll_in_khz = (unsigned int)(*parent_rate / 1000);707 708 if (lvds_is_dual_link(lvds->link_type))709 multiplier = 2;710 else711 multiplier = 1;712 713 lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv);714 715 /*716 * 1/7 because for each pixel in 1 lane there is 7 bits717 * We want pixclk, not bitclk718 */719 lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv)720 * 1000 * multiplier / 7;721 722 return lvds->pixel_clock_rate;723}724 725static const struct clk_ops lvds_pixel_clk_ops = {726 .enable = lvds_pixel_clk_enable,727 .disable = lvds_pixel_clk_disable,728 .recalc_rate = lvds_pixel_clk_recalc_rate,729 .round_rate = lvds_pixel_clk_round_rate,730};731 732static const struct clk_init_data clk_data = {733 .name = "clk_pix_lvds",734 .ops = &lvds_pixel_clk_ops,735 .parent_names = (const char * []) {"ck_ker_lvdsphy"},736 .num_parents = 1,737 .flags = CLK_IGNORE_UNUSED,738};739 740static void lvds_pixel_clk_unregister(void *data)741{742 struct stm_lvds *lvds = data;743 744 of_clk_del_provider(lvds->dev->of_node);745 clk_hw_unregister(&lvds->lvds_ck_px);746}747 748static int lvds_pixel_clk_register(struct stm_lvds *lvds)749{750 struct device_node *node = lvds->dev->of_node;751 int ret;752 753 lvds->lvds_ck_px.init = &clk_data;754 755 /* set the rate by default at 148500000 */756 lvds->pixel_clock_rate = 148500000;757 758 ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px);759 if (ret)760 return ret;761 762 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get,763 &lvds->lvds_ck_px);764 if (ret)765 clk_hw_unregister(&lvds->lvds_ck_px);766 767 return ret;768}769 770/*771 * Host configuration related772 */773static void lvds_config_data_mapping(struct stm_lvds *lvds)774{775 struct drm_device *drm = lvds->lvds_bridge.dev;776 const struct drm_display_info *info;777 enum lvds_pixel (*bitmap)[7];778 u32 lvds_dmlcr, lvds_dmmcr;779 int i;780 781 info = &(&lvds->connector)->display_info;782 if (!info->num_bus_formats || !info->bus_formats) {783 drm_warn(drm, "No LVDS bus format reported\n");784 return;785 }786 787 switch (info->bus_formats[0]) {788 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */789 drm_warn(drm, "Pixel format with data mapping not yet supported.\n");790 return;791 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */792 bitmap = lvds_bitmap_vesa_rgb888;793 break;794 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */795 bitmap = lvds_bitmap_jeida_rgb888;796 break;797 default:798 drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]);799 return;800 }801 802 /* Set bitmap for each lane */803 for (i = 0; i < 5; i++) {804 lvds_dmlcr = ((bitmap[i][0])805 + (bitmap[i][1] << 5)806 + (bitmap[i][2] << 10)807 + (bitmap[i][3] << 15));808 lvds_dmmcr = ((bitmap[i][4])809 + (bitmap[i][5] << 5)810 + (bitmap[i][6] << 10));811 812 lvds_write(lvds, LVDS_DMLCR(i), lvds_dmlcr);813 lvds_write(lvds, LVDS_DMMCR(i), lvds_dmmcr);814 }815}816 817static void lvds_config_mode(struct stm_lvds *lvds)818{819 u32 bus_flags, lvds_cr = 0, lvds_cdl1cr = 0, lvds_cdl2cr = 0;820 const struct drm_display_mode *mode;821 const struct drm_connector *connector;822 823 connector = &lvds->connector;824 if (!connector)825 return;826 827 if (list_empty(&connector->modes)) {828 drm_dbg(connector->dev, "connector: empty modes list\n");829 return;830 }831 832 bus_flags = connector->display_info.bus_flags;833 mode = list_first_entry(&connector->modes,834 struct drm_display_mode, head);835 836 lvds_clear(lvds, LVDS_CR, CR_LKMOD);837 lvds_clear(lvds, LVDS_CDL1CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |838 CDLCR_DISTR3 | CDLCR_DISTR4);839 lvds_clear(lvds, LVDS_CDL2CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |840 CDLCR_DISTR3 | CDLCR_DISTR4);841 842 /* Set channel distribution */843 if (lvds->primary)844 lvds_cdl1cr = CDL1CR_DEFAULT;845 846 if (lvds->secondary) {847 lvds_cr |= CR_LKMOD;848 lvds_cdl2cr = CDL2CR_DEFAULT;849 }850 851 /* Set signal polarity */852 if (bus_flags & DRM_BUS_FLAG_DE_LOW)853 lvds_cr |= CR_DEPOL;854 855 if (mode->flags & DRM_MODE_FLAG_NHSYNC)856 lvds_cr |= CR_HSPOL;857 858 if (mode->flags & DRM_MODE_FLAG_NVSYNC)859 lvds_cr |= CR_VSPOL;860 861 switch (lvds->link_type) {862 case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */863 lvds_cr &= ~CR_LKPHA;864 break;865 case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */866 lvds_cr |= CR_LKPHA;867 break;868 default:869 drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n");870 lvds_cr &= ~CR_LKPHA;871 break;872 }873 874 /* Write config to registers */875 lvds_set(lvds, LVDS_CR, lvds_cr);876 lvds_write(lvds, LVDS_CDL1CR, lvds_cdl1cr);877 lvds_write(lvds, LVDS_CDL2CR, lvds_cdl2cr);878}879 880static int lvds_connector_get_modes(struct drm_connector *connector)881{882 struct stm_lvds *lvds = connector_to_stm_lvds(connector);883 884 return drm_panel_get_modes(lvds->panel, connector);885}886 887static int lvds_connector_atomic_check(struct drm_connector *connector,888 struct drm_atomic_state *state)889{890 const struct drm_display_mode *panel_mode;891 struct drm_connector_state *conn_state;892 struct drm_crtc_state *crtc_state;893 894 conn_state = drm_atomic_get_new_connector_state(state, connector);895 if (!conn_state)896 return -EINVAL;897 898 if (list_empty(&connector->modes)) {899 drm_dbg(connector->dev, "connector: empty modes list\n");900 return -EINVAL;901 }902 903 if (!conn_state->crtc)904 return -EINVAL;905 906 panel_mode = list_first_entry(&connector->modes,907 struct drm_display_mode, head);908 909 /* We're not allowed to modify the resolution. */910 crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);911 if (IS_ERR(crtc_state))912 return PTR_ERR(crtc_state);913 914 if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||915 crtc_state->mode.vdisplay != panel_mode->vdisplay)916 return -EINVAL;917 918 /* The flat panel mode is fixed, just copy it to the adjusted mode. */919 drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);920 921 return 0;922}923 924static const struct drm_connector_helper_funcs lvds_conn_helper_funcs = {925 .get_modes = lvds_connector_get_modes,926 .atomic_check = lvds_connector_atomic_check,927};928 929static const struct drm_connector_funcs lvds_conn_funcs = {930 .reset = drm_atomic_helper_connector_reset,931 .fill_modes = drm_helper_probe_single_connector_modes,932 .destroy = drm_connector_cleanup,933 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,934 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,935};936 937static int lvds_attach(struct drm_bridge *bridge,938 enum drm_bridge_attach_flags flags)939{940 struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);941 struct drm_connector *connector = &lvds->connector;942 struct drm_encoder *encoder = bridge->encoder;943 int ret;944 945 if (!bridge->encoder) {946 drm_err(bridge->dev, "Parent encoder object not found\n");947 return -ENODEV;948 }949 950 /* Set the encoder type as caller does not know it */951 bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;952 953 /* No cloning support */954 bridge->encoder->possible_clones = 0;955 956 /* If we have a next bridge just attach it. */957 if (lvds->next_bridge)958 return drm_bridge_attach(bridge->encoder, lvds->next_bridge,959 bridge, flags);960 961 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {962 drm_err(bridge->dev, "Fix bridge driver to make connector optional!");963 return -EINVAL;964 }965 966 /* Otherwise if we have a panel, create a connector. */967 if (!lvds->panel)968 return 0;969 970 ret = drm_connector_init(bridge->dev, connector,971 &lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS);972 if (ret < 0)973 return ret;974 975 drm_connector_helper_add(connector, &lvds_conn_helper_funcs);976 977 ret = drm_connector_attach_encoder(connector, encoder);978 979 return ret;980}981 982static void lvds_atomic_enable(struct drm_bridge *bridge,983 struct drm_bridge_state *old_bridge_state)984{985 struct drm_atomic_state *state = old_bridge_state->base.state;986 struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);987 struct drm_connector_state *conn_state;988 struct drm_connector *connector;989 int ret;990 991 ret = clk_prepare_enable(lvds->pclk);992 if (ret) {993 drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n");994 return;995 }996 997 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);998 if (!connector)999 return;1000 1001 conn_state = drm_atomic_get_new_connector_state(state, connector);1002 if (!conn_state)1003 return;1004 1005 lvds_config_mode(lvds);1006 1007 /* Set Data Mapping */1008 lvds_config_data_mapping(lvds);1009 1010 /* Turn the output on. */1011 lvds_set(lvds, LVDS_CR, CR_LVDSEN);1012 1013 if (lvds->panel) {1014 drm_panel_prepare(lvds->panel);1015 drm_panel_enable(lvds->panel);1016 }1017}1018 1019static void lvds_atomic_disable(struct drm_bridge *bridge,1020 struct drm_bridge_state *old_bridge_state)1021{1022 struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);1023 1024 if (lvds->panel) {1025 drm_panel_disable(lvds->panel);1026 drm_panel_unprepare(lvds->panel);1027 }1028 1029 /* Disable LVDS module */1030 lvds_clear(lvds, LVDS_CR, CR_LVDSEN);1031 1032 clk_disable_unprepare(lvds->pclk);1033}1034 1035static const struct drm_bridge_funcs lvds_bridge_funcs = {1036 .attach = lvds_attach,1037 .atomic_enable = lvds_atomic_enable,1038 .atomic_disable = lvds_atomic_disable,1039 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,1040 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,1041 .atomic_reset = drm_atomic_helper_bridge_reset,1042};1043 1044static int lvds_probe(struct platform_device *pdev)1045{1046 struct device_node *port1, *port2, *remote;1047 struct device *dev = &pdev->dev;1048 struct reset_control *rstc;1049 struct stm_lvds *lvds;1050 int ret, dual_link;1051 1052 dev_dbg(dev, "Probing LVDS driver...\n");1053 1054 lvds = devm_kzalloc(dev, sizeof(*lvds), GFP_KERNEL);1055 if (!lvds)1056 return -ENOMEM;1057 1058 lvds->dev = dev;1059 1060 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,1061 &lvds->panel, &lvds->next_bridge);1062 if (ret) {1063 dev_err_probe(dev, ret, "Panel not found\n");1064 return ret;1065 }1066 1067 lvds->base = devm_platform_ioremap_resource(pdev, 0);1068 if (IS_ERR(lvds->base)) {1069 ret = PTR_ERR(lvds->base);1070 dev_err(dev, "Unable to get regs %d\n", ret);1071 return ret;1072 }1073 1074 lvds->pclk = devm_clk_get(dev, "pclk");1075 if (IS_ERR(lvds->pclk)) {1076 ret = PTR_ERR(lvds->pclk);1077 dev_err(dev, "Unable to get peripheral clock: %d\n", ret);1078 return ret;1079 }1080 1081 ret = clk_prepare_enable(lvds->pclk);1082 if (ret) {1083 dev_err(dev, "%s: Failed to enable peripheral clk\n", __func__);1084 return ret;1085 }1086 1087 rstc = devm_reset_control_get_exclusive(dev, NULL);1088 1089 if (IS_ERR(rstc)) {1090 ret = PTR_ERR(rstc);1091 goto err_lvds_probe;1092 }1093 1094 reset_control_assert(rstc);1095 usleep_range(10, 20);1096 reset_control_deassert(rstc);1097 1098 port1 = of_graph_get_port_by_id(dev->of_node, 1);1099 port2 = of_graph_get_port_by_id(dev->of_node, 2);1100 dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);1101 1102 switch (dual_link) {1103 case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:1104 lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS;1105 lvds->primary = &lvds_phy_16ff_primary;1106 lvds->secondary = &lvds_phy_16ff_secondary;1107 break;1108 case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:1109 lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS;1110 lvds->primary = &lvds_phy_16ff_primary;1111 lvds->secondary = &lvds_phy_16ff_secondary;1112 break;1113 case -EINVAL:1114 /*1115 * drm_of_lvds_get_dual_pixel_order returns 4 possible values.1116 * In the case where the returned value is an error, it can be1117 * either ENODEV or EINVAL. Seeing the structure of this1118 * function, EINVAL means that either port1 or port2 is not1119 * present in the device tree.1120 * In that case, the lvds panel can be a single link panel, or1121 * there is a semantical error in the device tree code.1122 */1123 remote = of_get_next_available_child(port1, NULL);1124 if (remote) {1125 if (of_graph_get_remote_endpoint(remote)) {1126 lvds->link_type = LVDS_SINGLE_LINK_PRIMARY;1127 lvds->primary = &lvds_phy_16ff_primary;1128 lvds->secondary = NULL;1129 } else {1130 ret = -EINVAL;1131 }1132 1133 of_node_put(remote);1134 }1135 1136 remote = of_get_next_available_child(port2, NULL);1137 if (remote) {1138 if (of_graph_get_remote_endpoint(remote)) {1139 lvds->link_type = LVDS_SINGLE_LINK_SECONDARY;1140 lvds->primary = NULL;1141 lvds->secondary = &lvds_phy_16ff_secondary;1142 } else {1143 ret = (ret == -EINVAL) ? -EINVAL : 0;1144 }1145 1146 of_node_put(remote);1147 }1148 break;1149 default:1150 ret = -EINVAL;1151 goto err_lvds_probe;1152 }1153 of_node_put(port1);1154 of_node_put(port2);1155 1156 lvds->pllref_clk = devm_clk_get(dev, "ref");1157 if (IS_ERR(lvds->pllref_clk)) {1158 ret = PTR_ERR(lvds->pllref_clk);1159 dev_err(dev, "Unable to get reference clock: %d\n", ret);1160 goto err_lvds_probe;1161 }1162 1163 ret = lvds_pixel_clk_register(lvds);1164 if (ret) {1165 dev_err(dev, "Failed to register LVDS pixel clock: %d\n", ret);1166 goto err_lvds_probe;1167 }1168 1169 lvds->lvds_bridge.funcs = &lvds_bridge_funcs;1170 lvds->lvds_bridge.of_node = dev->of_node;1171 lvds->hw_version = lvds_read(lvds, LVDS_VERR);1172 1173 dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version);1174 1175 drm_bridge_add(&lvds->lvds_bridge);1176 1177 platform_set_drvdata(pdev, lvds);1178 1179 clk_disable_unprepare(lvds->pclk);1180 1181 return 0;1182 1183err_lvds_probe:1184 clk_disable_unprepare(lvds->pclk);1185 1186 return ret;1187}1188 1189static void lvds_remove(struct platform_device *pdev)1190{1191 struct stm_lvds *lvds = platform_get_drvdata(pdev);1192 1193 lvds_pixel_clk_unregister(lvds);1194 1195 drm_bridge_remove(&lvds->lvds_bridge);1196}1197 1198static const struct of_device_id lvds_dt_ids[] = {1199 {1200 .compatible = "st,stm32mp25-lvds",1201 .data = NULL1202 },1203 { /* sentinel */ }1204};1205 1206MODULE_DEVICE_TABLE(of, lvds_dt_ids);1207 1208static struct platform_driver lvds_platform_driver = {1209 .probe = lvds_probe,1210 .remove = lvds_remove,1211 .driver = {1212 .name = "stm32-display-lvds",1213 .of_match_table = lvds_dt_ids,1214 },1215};1216 1217module_platform_driver(lvds_platform_driver);1218 1219MODULE_AUTHOR("Raphaël Gallais-Pou <raphael.gallais-pou@foss.st.com>");1220MODULE_AUTHOR("Philippe Cornu <philippe.cornu@foss.st.com>");1221MODULE_AUTHOR("Yannick Fertre <yannick.fertre@foss.st.com>");1222MODULE_DESCRIPTION("STMicroelectronics LVDS Display Interface Transmitter DRM driver");1223MODULE_LICENSE("GPL");1224