On 9/15/26 10:00 AM, Julien Stephan wrote:
> Add a new driver for the MIPI DSI PHY. The driver supports MT8183
> compatible SoCs. The driver is base on the corresponding kernel driver

s/base/based/

> commit 2ec9c210c1f9 ("phy: mediatek: Add support for MT8196 MIPI DSI PHY")
> 
> Few notes about the port from kernel:

s/Few/A few/

> - tested on Genio-350 which does not have nvmem-cells, so keep rt_code[]
>   zeroed and fallback to 0x210 has kernel does when no cell available.

s/has/as the/

>   Can be implemented later.
> - PLL is not registered as a clock provider:
>     - configure() = determine_rate+set_rate
>     - power_on() = clk_prepare_enable
>   configure() takes a struct phy_configure_opts_mipi_dphy and uses its
>   hs_clk_rate member, which carries the per-lane data rate the kernel
>   would have set on the "hs" clock.
> 

...

> +static int mtk_mipi_tx_pll_enable(struct mtk_mipi_tx *mipi_tx)
> +{
> +     void __iomem *base = mipi_tx->regs;
> +     unsigned int txdiv, txdiv0;
> +     u64 pcw;
> +
> +     dev_dbg(mipi_tx->dev, "enable: %llu bps\n", mipi_tx->data_rate);
> +
> +     if (mipi_tx->data_rate >= 2000000000) {
> +             txdiv = 1;
> +             txdiv0 = 0;
> +     } else if (mipi_tx->data_rate >= 1000000000) {
> +             txdiv = 2;
> +             txdiv0 = 1;
> +     } else if (mipi_tx->data_rate >= 500000000) {
> +             txdiv = 4;
> +             txdiv0 = 2;
> +     } else if (mipi_tx->data_rate > 250000000) {
> +             txdiv = 8;
> +             txdiv0 = 3;
> +     } else if (mipi_tx->data_rate >= 125000000) {
> +             txdiv = 16;
> +             txdiv0 = 4;
> +     } else {
> +             return -EINVAL;
> +     }
> +
> +     mtk_phy_clear_bits(base + MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS);
> +
> +     mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
> +     mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
> +     udelay(1);
> +     mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
> +     pcw = div_u64(mipi_tx->data_rate * txdiv << 24, MIPITX_PLL_REF_RATE);

(mipi_tx->data_rate * txdiv) << 24

For those of us that can't remember order of operations.

> +     writel(pcw, base + MIPITX_PLL_CON0);
> +     mtk_phy_update_field(base + MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, txdiv0);
> +     mtk_phy_set_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
> +
> +     return 0;
> +}
> +

...

> +static void mtk_mipi_tx_power_on_signal(struct mtk_mipi_tx *mipi_tx)
> +{
> +     void __iomem *base = mipi_tx->regs;
> +
> +     /* BG_LPF_EN / BG_CORE_EN */
> +     writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON);
> +     udelay(30);
> +     writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, base + MIPITX_LANE_CON);
> +
> +     /* Switch OFF each Lane */
> +     mtk_phy_clear_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
> +     mtk_phy_clear_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
> +     mtk_phy_clear_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
> +     mtk_phy_clear_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
> +     mtk_phy_clear_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
> +
> +     mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_HSTX_LDO_REF_SEL,
> +                          (mipi_tx->mipitx_drive - 3000) / 200);

Is this 3000 supposed to be MIPITX_DRIVE_MIN_UA?

> +
> +     mtk_mipi_tx_config_calibration_data(mipi_tx);
> +
> +     mtk_phy_set_bits(base + MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
> +}
> +

...

> +     /*
> +      * The kernel reads the per-lane impedance trim codes from the
> +      * "calibration-data" nvmem cell. No MediaTek board describes that cell

Technically, mipi_tx0: dsi-phy@11e50000 does in mt8183.dtsi

Not saying we need to implement it right now though. Just the comment isn't
100% accurate.

> +      * in its device tree yet, so rt_code[] is left zeroed here and the
> +      * SoC layer substitutes the same mid-scale default the kernel uses
> +      * when the cell is absent.
> +      */
> +
> +     return 0;
> +}
> +

Reply via email to