2019-08-07 16:46:44 +08:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright ( c ) 2019 MediaTek Inc .
* Author : jitao . shi < jitao . shi @ mediatek . com >
*/
2022-09-20 17:00:35 +08:00
# include "phy-mtk-io.h"
2020-10-06 07:37:07 +08:00
# include "phy-mtk-mipi-dsi.h"
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_CON 0x00
# define RG_DSI_LDOCORE_EN BIT(0)
# define RG_DSI_CKG_LDOOUT_EN BIT(1)
2022-09-20 17:00:33 +08:00
# define RG_DSI_BCLK_SEL GENMASK(3, 2)
# define RG_DSI_LD_IDX_SEL GENMASK(6, 4)
# define RG_DSI_PHYCLK_SEL GENMASK(9, 8)
2019-08-07 16:46:44 +08:00
# define RG_DSI_DSICLK_FREQ_SEL BIT(10)
# define RG_DSI_LPTX_CLMP_EN BIT(11)
# define MIPITX_DSI_CLOCK_LANE 0x04
# define MIPITX_DSI_DATA_LANE0 0x08
# define MIPITX_DSI_DATA_LANE1 0x0c
# define MIPITX_DSI_DATA_LANE2 0x10
# define MIPITX_DSI_DATA_LANE3 0x14
# define RG_DSI_LNTx_LDOOUT_EN BIT(0)
# define RG_DSI_LNTx_CKLANE_EN BIT(1)
# define RG_DSI_LNTx_LPTX_IPLUS1 BIT(2)
# define RG_DSI_LNTx_LPTX_IPLUS2 BIT(3)
# define RG_DSI_LNTx_LPTX_IMINUS BIT(4)
# define RG_DSI_LNTx_LPCD_IPLUS BIT(5)
# define RG_DSI_LNTx_LPCD_IMINUS BIT(6)
2022-09-20 17:00:33 +08:00
# define RG_DSI_LNTx_RT_CODE GENMASK(11, 8)
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_TOP_CON 0x40
# define RG_DSI_LNT_INTR_EN BIT(0)
# define RG_DSI_LNT_HS_BIAS_EN BIT(1)
# define RG_DSI_LNT_IMP_CAL_EN BIT(2)
# define RG_DSI_LNT_TESTMODE_EN BIT(3)
2022-09-20 17:00:33 +08:00
# define RG_DSI_LNT_IMP_CAL_CODE GENMASK(7, 4)
# define RG_DSI_LNT_AIO_SEL GENMASK(10, 8)
2019-08-07 16:46:44 +08:00
# define RG_DSI_PAD_TIE_LOW_EN BIT(11)
# define RG_DSI_DEBUG_INPUT_EN BIT(12)
2022-09-20 17:00:33 +08:00
# define RG_DSI_PRESERVE GENMASK(15, 13)
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_BG_CON 0x44
# define RG_DSI_BG_CORE_EN BIT(0)
# define RG_DSI_BG_CKEN BIT(1)
2022-09-20 17:00:33 +08:00
# define RG_DSI_BG_DIV GENMASK(3, 2)
2019-08-07 16:46:44 +08:00
# define RG_DSI_BG_FAST_CHARGE BIT(4)
2022-09-20 17:00:33 +08:00
# define RG_DSI_V12_SEL GENMASK(7, 5)
# define RG_DSI_V10_SEL GENMASK(10, 8)
# define RG_DSI_V072_SEL GENMASK(13, 11)
# define RG_DSI_V04_SEL GENMASK(16, 14)
# define RG_DSI_V032_SEL GENMASK(19, 17)
# define RG_DSI_V02_SEL GENMASK(22, 20)
# define RG_DSI_VOUT_MSK \
( RG_DSI_V12_SEL | RG_DSI_V10_SEL | RG_DSI_V072_SEL | \
RG_DSI_V04_SEL | RG_DSI_V032_SEL | RG_DSI_V02_SEL )
# define RG_DSI_BG_R1_TRIM GENMASK(27, 24)
# define RG_DSI_BG_R2_TRIM GENMASK(31, 28)
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_PLL_CON0 0x50
# define RG_DSI_MPPLL_PLL_EN BIT(0)
2022-09-20 17:00:33 +08:00
# define RG_DSI_MPPLL_PREDIV GENMASK(2, 1)
# define RG_DSI_MPPLL_TXDIV0 GENMASK(4, 3)
# define RG_DSI_MPPLL_TXDIV1 GENMASK(6, 5)
# define RG_DSI_MPPLL_POSDIV GENMASK(9, 7)
# define RG_DSI_MPPLL_DIV_MSK \
( RG_DSI_MPPLL_PREDIV | RG_DSI_MPPLL_TXDIV0 | \
RG_DSI_MPPLL_TXDIV1 | RG_DSI_MPPLL_POSDIV )
2019-08-07 16:46:44 +08:00
# define RG_DSI_MPPLL_MONVC_EN BIT(10)
# define RG_DSI_MPPLL_MONREF_EN BIT(11)
# define RG_DSI_MPPLL_VOD_EN BIT(12)
# define MIPITX_DSI_PLL_CON1 0x54
# define RG_DSI_MPPLL_SDM_FRA_EN BIT(0)
# define RG_DSI_MPPLL_SDM_SSC_PH_INIT BIT(1)
# define RG_DSI_MPPLL_SDM_SSC_EN BIT(2)
2022-09-20 17:00:33 +08:00
# define RG_DSI_MPPLL_SDM_SSC_PRD GENMASK(31, 16)
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_PLL_CON2 0x58
# define MIPITX_DSI_PLL_TOP 0x64
2022-09-20 17:00:33 +08:00
# define RG_DSI_MPPLL_PRESERVE GENMASK(15, 8)
2019-08-07 16:46:44 +08:00
# define MIPITX_DSI_PLL_PWR 0x68
# define RG_DSI_MPPLL_SDM_PWR_ON BIT(0)
# define RG_DSI_MPPLL_SDM_ISO_EN BIT(1)
# define RG_DSI_MPPLL_SDM_PWR_ACK BIT(8)
# define MIPITX_DSI_SW_CTRL 0x80
# define SW_CTRL_EN BIT(0)
# define MIPITX_DSI_SW_CTRL_CON0 0x84
# define SW_LNTC_LPTX_PRE_OE BIT(0)
# define SW_LNTC_LPTX_OE BIT(1)
# define SW_LNTC_LPTX_P BIT(2)
# define SW_LNTC_LPTX_N BIT(3)
# define SW_LNTC_HSTX_PRE_OE BIT(4)
# define SW_LNTC_HSTX_OE BIT(5)
# define SW_LNTC_HSTX_ZEROCLK BIT(6)
# define SW_LNT0_LPTX_PRE_OE BIT(7)
# define SW_LNT0_LPTX_OE BIT(8)
# define SW_LNT0_LPTX_P BIT(9)
# define SW_LNT0_LPTX_N BIT(10)
# define SW_LNT0_HSTX_PRE_OE BIT(11)
# define SW_LNT0_HSTX_OE BIT(12)
# define SW_LNT0_LPRX_EN BIT(13)
# define SW_LNT1_LPTX_PRE_OE BIT(14)
# define SW_LNT1_LPTX_OE BIT(15)
# define SW_LNT1_LPTX_P BIT(16)
# define SW_LNT1_LPTX_N BIT(17)
# define SW_LNT1_HSTX_PRE_OE BIT(18)
# define SW_LNT1_HSTX_OE BIT(19)
# define SW_LNT2_LPTX_PRE_OE BIT(20)
# define SW_LNT2_LPTX_OE BIT(21)
# define SW_LNT2_LPTX_P BIT(22)
# define SW_LNT2_LPTX_N BIT(23)
# define SW_LNT2_HSTX_PRE_OE BIT(24)
# define SW_LNT2_HSTX_OE BIT(25)
static int mtk_mipi_tx_pll_prepare ( struct clk_hw * hw )
{
struct mtk_mipi_tx * mipi_tx = mtk_mipi_tx_from_clk_hw ( hw ) ;
2022-09-20 17:00:35 +08:00
void __iomem * base = mipi_tx - > regs ;
2019-08-07 16:46:44 +08:00
u8 txdiv , txdiv0 , txdiv1 ;
u64 pcw ;
dev_dbg ( mipi_tx - > dev , " prepare: %u Hz \n " , mipi_tx - > data_rate ) ;
if ( mipi_tx - > data_rate > = 500000000 ) {
txdiv = 1 ;
txdiv0 = 0 ;
txdiv1 = 0 ;
} else if ( mipi_tx - > data_rate > = 250000000 ) {
txdiv = 2 ;
txdiv0 = 1 ;
txdiv1 = 0 ;
} else if ( mipi_tx - > data_rate > = 125000000 ) {
txdiv = 4 ;
txdiv0 = 2 ;
txdiv1 = 0 ;
} else if ( mipi_tx - > data_rate > 62000000 ) {
txdiv = 8 ;
txdiv0 = 2 ;
txdiv1 = 1 ;
} else if ( mipi_tx - > data_rate > = 50000000 ) {
txdiv = 16 ;
txdiv0 = 2 ;
txdiv1 = 2 ;
} else {
return - EINVAL ;
}
2022-09-20 17:00:35 +08:00
mtk_phy_update_bits ( base + MIPITX_DSI_BG_CON ,
RG_DSI_VOUT_MSK | RG_DSI_BG_CKEN |
RG_DSI_BG_CORE_EN ,
FIELD_PREP ( RG_DSI_V02_SEL , 4 ) |
FIELD_PREP ( RG_DSI_V032_SEL , 4 ) |
FIELD_PREP ( RG_DSI_V04_SEL , 4 ) |
FIELD_PREP ( RG_DSI_V072_SEL , 4 ) |
FIELD_PREP ( RG_DSI_V10_SEL , 4 ) |
FIELD_PREP ( RG_DSI_V12_SEL , 4 ) |
RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN ) ;
2019-08-07 16:46:44 +08:00
usleep_range ( 30 , 100 ) ;
2022-09-20 17:00:35 +08:00
mtk_phy_update_bits ( base + MIPITX_DSI_TOP_CON ,
RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN ,
FIELD_PREP ( RG_DSI_LNT_IMP_CAL_CODE , 8 ) |
RG_DSI_LNT_HS_BIAS_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_set_bits ( base + MIPITX_DSI_CON ,
RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_update_bits ( base + MIPITX_DSI_PLL_PWR ,
RG_DSI_MPPLL_SDM_PWR_ON | RG_DSI_MPPLL_SDM_ISO_EN ,
RG_DSI_MPPLL_SDM_PWR_ON ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_PLL_CON0 , RG_DSI_MPPLL_PLL_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_update_bits ( base + MIPITX_DSI_PLL_CON0 ,
RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 |
RG_DSI_MPPLL_PREDIV ,
FIELD_PREP ( RG_DSI_MPPLL_TXDIV0 , txdiv0 ) |
FIELD_PREP ( RG_DSI_MPPLL_TXDIV1 , txdiv1 ) ) ;
2019-08-07 16:46:44 +08:00
/*
* PLL PCW config
* PCW bit 24 ~ 30 = integer part of pcw
* PCW bit 0 ~ 23 = fractional part of pcw
* pcw = data_Rate * 4 * txdiv / ( Ref_clk * 2 ) ;
* Post DIV = 4 , so need data_Rate * 4
* Ref_clk is 26 MHz
*/
2022-09-20 17:00:35 +08:00
pcw = div_u64 ( ( ( u64 ) mipi_tx - > data_rate * 2 * txdiv ) < < 24 , 26000000 ) ;
writel ( pcw , base + MIPITX_DSI_PLL_CON2 ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_set_bits ( base + MIPITX_DSI_PLL_CON1 , RG_DSI_MPPLL_SDM_FRA_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_set_bits ( base + MIPITX_DSI_PLL_CON0 , RG_DSI_MPPLL_PLL_EN ) ;
2019-08-07 16:46:44 +08:00
usleep_range ( 20 , 100 ) ;
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_PLL_CON1 , RG_DSI_MPPLL_SDM_SSC_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_update_field ( base + MIPITX_DSI_PLL_TOP ,
RG_DSI_MPPLL_PRESERVE ,
mipi_tx - > driver_data - > mppll_preserve ) ;
2019-08-07 16:46:44 +08:00
return 0 ;
}
static void mtk_mipi_tx_pll_unprepare ( struct clk_hw * hw )
{
struct mtk_mipi_tx * mipi_tx = mtk_mipi_tx_from_clk_hw ( hw ) ;
2022-09-20 17:00:35 +08:00
void __iomem * base = mipi_tx - > regs ;
2019-08-07 16:46:44 +08:00
dev_dbg ( mipi_tx - > dev , " unprepare \n " ) ;
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_PLL_CON0 , RG_DSI_MPPLL_PLL_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_PLL_TOP , RG_DSI_MPPLL_PRESERVE ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_update_bits ( base + MIPITX_DSI_PLL_PWR ,
RG_DSI_MPPLL_SDM_ISO_EN | RG_DSI_MPPLL_SDM_PWR_ON ,
RG_DSI_MPPLL_SDM_ISO_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_TOP_CON , RG_DSI_LNT_HS_BIAS_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_CON ,
RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_BG_CON ,
RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( base + MIPITX_DSI_PLL_CON0 , RG_DSI_MPPLL_DIV_MSK ) ;
2019-08-07 16:46:44 +08:00
}
static long mtk_mipi_tx_pll_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
return clamp_val ( rate , 50000000 , 1250000000 ) ;
}
static const struct clk_ops mtk_mipi_tx_pll_ops = {
. prepare = mtk_mipi_tx_pll_prepare ,
. unprepare = mtk_mipi_tx_pll_unprepare ,
. round_rate = mtk_mipi_tx_pll_round_rate ,
. set_rate = mtk_mipi_tx_pll_set_rate ,
. recalc_rate = mtk_mipi_tx_pll_recalc_rate ,
} ;
static void mtk_mipi_tx_power_on_signal ( struct phy * phy )
{
struct mtk_mipi_tx * mipi_tx = phy_get_drvdata ( phy ) ;
u32 reg ;
for ( reg = MIPITX_DSI_CLOCK_LANE ;
reg < = MIPITX_DSI_DATA_LANE3 ; reg + = 4 )
2022-09-20 17:00:35 +08:00
mtk_phy_set_bits ( mipi_tx - > regs + reg , RG_DSI_LNTx_LDOOUT_EN ) ;
2019-08-07 16:46:44 +08:00
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( mipi_tx - > regs + MIPITX_DSI_TOP_CON ,
RG_DSI_PAD_TIE_LOW_EN ) ;
2019-08-07 16:46:44 +08:00
}
static void mtk_mipi_tx_power_off_signal ( struct phy * phy )
{
struct mtk_mipi_tx * mipi_tx = phy_get_drvdata ( phy ) ;
u32 reg ;
2022-09-20 17:00:35 +08:00
mtk_phy_set_bits ( mipi_tx - > regs + MIPITX_DSI_TOP_CON ,
RG_DSI_PAD_TIE_LOW_EN ) ;
2019-08-07 16:46:44 +08:00
for ( reg = MIPITX_DSI_CLOCK_LANE ;
reg < = MIPITX_DSI_DATA_LANE3 ; reg + = 4 )
2022-09-20 17:00:35 +08:00
mtk_phy_clear_bits ( mipi_tx - > regs + reg , RG_DSI_LNTx_LDOOUT_EN ) ;
2019-08-07 16:46:44 +08:00
}
const struct mtk_mipitx_data mt2701_mipitx_data = {
2022-09-20 17:00:35 +08:00
. mppll_preserve = 3 ,
2019-08-07 16:46:44 +08:00
. mipi_tx_clk_ops = & mtk_mipi_tx_pll_ops ,
. mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal ,
. mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal ,
} ;
const struct mtk_mipitx_data mt8173_mipitx_data = {
2022-09-20 17:00:35 +08:00
. mppll_preserve = 0 ,
2019-08-07 16:46:44 +08:00
. mipi_tx_clk_ops = & mtk_mipi_tx_pll_ops ,
. mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal ,
. mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal ,
} ;