1*90f80d95SChun-Kuang Hu // SPDX-License-Identifier: GPL-2.0 2*90f80d95SChun-Kuang Hu /* 3*90f80d95SChun-Kuang Hu * Copyright (c) 2019 MediaTek Inc. 4*90f80d95SChun-Kuang Hu * Author: jitao.shi <jitao.shi@mediatek.com> 5*90f80d95SChun-Kuang Hu */ 6*90f80d95SChun-Kuang Hu 7*90f80d95SChun-Kuang Hu #include "phy-mtk-mipi-dsi.h" 8*90f80d95SChun-Kuang Hu 9*90f80d95SChun-Kuang Hu #define MIPITX_LANE_CON 0x000c 10*90f80d95SChun-Kuang Hu #define RG_DSI_CPHY_T1DRV_EN BIT(0) 11*90f80d95SChun-Kuang Hu #define RG_DSI_ANA_CK_SEL BIT(1) 12*90f80d95SChun-Kuang Hu #define RG_DSI_PHY_CK_SEL BIT(2) 13*90f80d95SChun-Kuang Hu #define RG_DSI_CPHY_EN BIT(3) 14*90f80d95SChun-Kuang Hu #define RG_DSI_PHYCK_INV_EN BIT(4) 15*90f80d95SChun-Kuang Hu #define RG_DSI_PWR04_EN BIT(5) 16*90f80d95SChun-Kuang Hu #define RG_DSI_BG_LPF_EN BIT(6) 17*90f80d95SChun-Kuang Hu #define RG_DSI_BG_CORE_EN BIT(7) 18*90f80d95SChun-Kuang Hu #define RG_DSI_PAD_TIEL_SEL BIT(8) 19*90f80d95SChun-Kuang Hu 20*90f80d95SChun-Kuang Hu #define MIPITX_VOLTAGE_SEL 0x0010 21*90f80d95SChun-Kuang Hu #define RG_DSI_HSTX_LDO_REF_SEL (0xf << 6) 22*90f80d95SChun-Kuang Hu 23*90f80d95SChun-Kuang Hu #define MIPITX_PLL_PWR 0x0028 24*90f80d95SChun-Kuang Hu #define MIPITX_PLL_CON0 0x002c 25*90f80d95SChun-Kuang Hu #define MIPITX_PLL_CON1 0x0030 26*90f80d95SChun-Kuang Hu #define MIPITX_PLL_CON2 0x0034 27*90f80d95SChun-Kuang Hu #define MIPITX_PLL_CON3 0x0038 28*90f80d95SChun-Kuang Hu #define MIPITX_PLL_CON4 0x003c 29*90f80d95SChun-Kuang Hu #define RG_DSI_PLL_IBIAS (3 << 10) 30*90f80d95SChun-Kuang Hu 31*90f80d95SChun-Kuang Hu #define MIPITX_D2P_RTCODE 0x0100 32*90f80d95SChun-Kuang Hu #define MIPITX_D2_SW_CTL_EN 0x0144 33*90f80d95SChun-Kuang Hu #define MIPITX_D0_SW_CTL_EN 0x0244 34*90f80d95SChun-Kuang Hu #define MIPITX_CK_CKMODE_EN 0x0328 35*90f80d95SChun-Kuang Hu #define DSI_CK_CKMODE_EN BIT(0) 36*90f80d95SChun-Kuang Hu #define MIPITX_CK_SW_CTL_EN 0x0344 37*90f80d95SChun-Kuang Hu #define MIPITX_D1_SW_CTL_EN 0x0444 38*90f80d95SChun-Kuang Hu #define MIPITX_D3_SW_CTL_EN 0x0544 39*90f80d95SChun-Kuang Hu #define DSI_SW_CTL_EN BIT(0) 40*90f80d95SChun-Kuang Hu #define AD_DSI_PLL_SDM_PWR_ON BIT(0) 41*90f80d95SChun-Kuang Hu #define AD_DSI_PLL_SDM_ISO_EN BIT(1) 42*90f80d95SChun-Kuang Hu 43*90f80d95SChun-Kuang Hu #define RG_DSI_PLL_EN BIT(4) 44*90f80d95SChun-Kuang Hu #define RG_DSI_PLL_POSDIV (0x7 << 8) 45*90f80d95SChun-Kuang Hu 46*90f80d95SChun-Kuang Hu static int mtk_mipi_tx_pll_enable(struct clk_hw *hw) 47*90f80d95SChun-Kuang Hu { 48*90f80d95SChun-Kuang Hu struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 49*90f80d95SChun-Kuang Hu unsigned int txdiv, txdiv0; 50*90f80d95SChun-Kuang Hu u64 pcw; 51*90f80d95SChun-Kuang Hu 52*90f80d95SChun-Kuang Hu dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate); 53*90f80d95SChun-Kuang Hu 54*90f80d95SChun-Kuang Hu if (mipi_tx->data_rate >= 2000000000) { 55*90f80d95SChun-Kuang Hu txdiv = 1; 56*90f80d95SChun-Kuang Hu txdiv0 = 0; 57*90f80d95SChun-Kuang Hu } else if (mipi_tx->data_rate >= 1000000000) { 58*90f80d95SChun-Kuang Hu txdiv = 2; 59*90f80d95SChun-Kuang Hu txdiv0 = 1; 60*90f80d95SChun-Kuang Hu } else if (mipi_tx->data_rate >= 500000000) { 61*90f80d95SChun-Kuang Hu txdiv = 4; 62*90f80d95SChun-Kuang Hu txdiv0 = 2; 63*90f80d95SChun-Kuang Hu } else if (mipi_tx->data_rate > 250000000) { 64*90f80d95SChun-Kuang Hu txdiv = 8; 65*90f80d95SChun-Kuang Hu txdiv0 = 3; 66*90f80d95SChun-Kuang Hu } else if (mipi_tx->data_rate >= 125000000) { 67*90f80d95SChun-Kuang Hu txdiv = 16; 68*90f80d95SChun-Kuang Hu txdiv0 = 4; 69*90f80d95SChun-Kuang Hu } else { 70*90f80d95SChun-Kuang Hu return -EINVAL; 71*90f80d95SChun-Kuang Hu } 72*90f80d95SChun-Kuang Hu 73*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); 74*90f80d95SChun-Kuang Hu 75*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); 76*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 77*90f80d95SChun-Kuang Hu udelay(1); 78*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); 79*90f80d95SChun-Kuang Hu pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); 80*90f80d95SChun-Kuang Hu writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); 81*90f80d95SChun-Kuang Hu mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, 82*90f80d95SChun-Kuang Hu txdiv0 << 8); 83*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 84*90f80d95SChun-Kuang Hu 85*90f80d95SChun-Kuang Hu return 0; 86*90f80d95SChun-Kuang Hu } 87*90f80d95SChun-Kuang Hu 88*90f80d95SChun-Kuang Hu static void mtk_mipi_tx_pll_disable(struct clk_hw *hw) 89*90f80d95SChun-Kuang Hu { 90*90f80d95SChun-Kuang Hu struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 91*90f80d95SChun-Kuang Hu 92*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 93*90f80d95SChun-Kuang Hu 94*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); 95*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); 96*90f80d95SChun-Kuang Hu } 97*90f80d95SChun-Kuang Hu 98*90f80d95SChun-Kuang Hu static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 99*90f80d95SChun-Kuang Hu unsigned long *prate) 100*90f80d95SChun-Kuang Hu { 101*90f80d95SChun-Kuang Hu return clamp_val(rate, 50000000, 1600000000); 102*90f80d95SChun-Kuang Hu } 103*90f80d95SChun-Kuang Hu 104*90f80d95SChun-Kuang Hu static const struct clk_ops mtk_mipi_tx_pll_ops = { 105*90f80d95SChun-Kuang Hu .enable = mtk_mipi_tx_pll_enable, 106*90f80d95SChun-Kuang Hu .disable = mtk_mipi_tx_pll_disable, 107*90f80d95SChun-Kuang Hu .round_rate = mtk_mipi_tx_pll_round_rate, 108*90f80d95SChun-Kuang Hu .set_rate = mtk_mipi_tx_pll_set_rate, 109*90f80d95SChun-Kuang Hu .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 110*90f80d95SChun-Kuang Hu }; 111*90f80d95SChun-Kuang Hu 112*90f80d95SChun-Kuang Hu static void mtk_mipi_tx_config_calibration_data(struct mtk_mipi_tx *mipi_tx) 113*90f80d95SChun-Kuang Hu { 114*90f80d95SChun-Kuang Hu int i, j; 115*90f80d95SChun-Kuang Hu 116*90f80d95SChun-Kuang Hu for (i = 0; i < 5; i++) { 117*90f80d95SChun-Kuang Hu if ((mipi_tx->rt_code[i] & 0x1f) == 0) 118*90f80d95SChun-Kuang Hu mipi_tx->rt_code[i] |= 0x10; 119*90f80d95SChun-Kuang Hu 120*90f80d95SChun-Kuang Hu if ((mipi_tx->rt_code[i] >> 5 & 0x1f) == 0) 121*90f80d95SChun-Kuang Hu mipi_tx->rt_code[i] |= 0x10 << 5; 122*90f80d95SChun-Kuang Hu 123*90f80d95SChun-Kuang Hu for (j = 0; j < 10; j++) 124*90f80d95SChun-Kuang Hu mtk_mipi_tx_update_bits(mipi_tx, 125*90f80d95SChun-Kuang Hu MIPITX_D2P_RTCODE * (i + 1) + j * 4, 126*90f80d95SChun-Kuang Hu 1, mipi_tx->rt_code[i] >> j & 1); 127*90f80d95SChun-Kuang Hu } 128*90f80d95SChun-Kuang Hu } 129*90f80d95SChun-Kuang Hu 130*90f80d95SChun-Kuang Hu static void mtk_mipi_tx_power_on_signal(struct phy *phy) 131*90f80d95SChun-Kuang Hu { 132*90f80d95SChun-Kuang Hu struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 133*90f80d95SChun-Kuang Hu 134*90f80d95SChun-Kuang Hu /* BG_LPF_EN / BG_CORE_EN */ 135*90f80d95SChun-Kuang Hu writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, 136*90f80d95SChun-Kuang Hu mipi_tx->regs + MIPITX_LANE_CON); 137*90f80d95SChun-Kuang Hu usleep_range(30, 100); 138*90f80d95SChun-Kuang Hu writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, 139*90f80d95SChun-Kuang Hu mipi_tx->regs + MIPITX_LANE_CON); 140*90f80d95SChun-Kuang Hu 141*90f80d95SChun-Kuang Hu /* Switch OFF each Lane */ 142*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); 143*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); 144*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); 145*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); 146*90f80d95SChun-Kuang Hu mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); 147*90f80d95SChun-Kuang Hu 148*90f80d95SChun-Kuang Hu mtk_mipi_tx_update_bits(mipi_tx, MIPITX_VOLTAGE_SEL, 149*90f80d95SChun-Kuang Hu RG_DSI_HSTX_LDO_REF_SEL, 150*90f80d95SChun-Kuang Hu (mipi_tx->mipitx_drive - 3000) / 200 << 6); 151*90f80d95SChun-Kuang Hu 152*90f80d95SChun-Kuang Hu mtk_mipi_tx_config_calibration_data(mipi_tx); 153*90f80d95SChun-Kuang Hu 154*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN); 155*90f80d95SChun-Kuang Hu } 156*90f80d95SChun-Kuang Hu 157*90f80d95SChun-Kuang Hu static void mtk_mipi_tx_power_off_signal(struct phy *phy) 158*90f80d95SChun-Kuang Hu { 159*90f80d95SChun-Kuang Hu struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 160*90f80d95SChun-Kuang Hu 161*90f80d95SChun-Kuang Hu /* Switch ON each Lane */ 162*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); 163*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); 164*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); 165*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); 166*90f80d95SChun-Kuang Hu mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); 167*90f80d95SChun-Kuang Hu 168*90f80d95SChun-Kuang Hu writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, 169*90f80d95SChun-Kuang Hu mipi_tx->regs + MIPITX_LANE_CON); 170*90f80d95SChun-Kuang Hu writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON); 171*90f80d95SChun-Kuang Hu } 172*90f80d95SChun-Kuang Hu 173*90f80d95SChun-Kuang Hu const struct mtk_mipitx_data mt8183_mipitx_data = { 174*90f80d95SChun-Kuang Hu .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, 175*90f80d95SChun-Kuang Hu .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, 176*90f80d95SChun-Kuang Hu .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, 177*90f80d95SChun-Kuang Hu }; 178