diff options
author | Robert Chiras <robert.chiras@nxp.com> | 2018-04-12 16:32:39 +0300 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 4079fed429ec01a36b8d8faca2df4151459a2618 (patch) | |
tree | fc6de219dbcf7b8e5716d35d37573063c94e1c00 /drivers/phy | |
parent | e34bfd08b774c0ccac446ebec7e3b2aecb210d00 (diff) |
MLK-18178: phy: mixel-mipi: Update the PRG register settings
Update the register settings for PRG values to be more accurate,
depending on the timing used.
Also, update the init function to make sure the PHY is powered OFF in
this stage, and the power_on function to correctly power ON the PHY
according to the specification: assert PD_PLL, wait for LOCK, assert
PD_DPHY.
Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r-- | drivers/phy/phy-mixel-mipi-dsi.c | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/drivers/phy/phy-mixel-mipi-dsi.c b/drivers/phy/phy-mixel-mipi-dsi.c index 0b004002f9c0..26ce0cdd2138 100644 --- a/drivers/phy/phy-mixel-mipi-dsi.c +++ b/drivers/phy/phy-mixel-mipi-dsi.c @@ -41,6 +41,7 @@ #define DPHY_AUTO_PD_EN 0x3c #define DPHY_RXLPRP 0x40 #define DPHY_RXCDRP 0x44 +#define DPHY_M_PRG_RXHS_SETTLE 0x48 #define MBPS(x) ((x) * 1000000) @@ -204,36 +205,53 @@ static int mixel_mipi_phy_enable(struct phy *phy, u32 reset) static void mixel_phy_set_prg_regs(struct phy *phy) { struct mixel_mipi_phy_priv *priv = phy_get_drvdata(phy); - u32 step; - u32 step_num; - u32 step_max; /* MC_PRG_HS_PREPARE */ - if (priv->data_rate > MBPS(1000)) + if (priv->data_rate < MBPS(1000)) phy_write(phy, 0x01, DPHY_MC_PRG_HS_PREPARE); else phy_write(phy, 0x00, DPHY_MC_PRG_HS_PREPARE); /* M_PRG_HS_PREPARE */ - if (priv->data_rate > MBPS(250)) - phy_write(phy, 0x00, DPHY_M_PRG_HS_PREPARE); - else + if (priv->data_rate < MBPS(250)) + phy_write(phy, 0x03, DPHY_M_PRG_HS_PREPARE); + else if (priv->data_rate < MBPS(500)) + phy_write(phy, 0x02, DPHY_M_PRG_HS_PREPARE); + else if (priv->data_rate < MBPS(1000)) phy_write(phy, 0x01, DPHY_M_PRG_HS_PREPARE); + else + phy_write(phy, 0x00, DPHY_M_PRG_HS_PREPARE); /* MC_PRG_HS_ZERO */ - step_max = 48; - step = (DATA_RATE_MAX_SPEED - DATA_RATE_MIN_SPEED) / step_max; - step_num = ((priv->data_rate - DATA_RATE_MIN_SPEED) / step) + 1; - phy_write(phy, step_num, DPHY_MC_PRG_HS_ZERO); + if (priv->data_rate < MBPS(250)) + phy_write(phy, 0x01, DPHY_MC_PRG_HS_ZERO); + else if (priv->data_rate < MBPS(500)) + phy_write(phy, 0x06, DPHY_MC_PRG_HS_ZERO); + else if (priv->data_rate < MBPS(1000)) + phy_write(phy, 0x0F, DPHY_MC_PRG_HS_ZERO); + else if (priv->data_rate < MBPS(1500)) + phy_write(phy, 0x20, DPHY_MC_PRG_HS_ZERO); + else + phy_write(phy, 0x30, DPHY_MC_PRG_HS_ZERO); /* M_PRG_HS_ZERO */ - if (priv->data_rate < MBPS(1000)) + if (priv->data_rate < MBPS(500)) + phy_write(phy, 0x01, DPHY_M_PRG_HS_ZERO); + else if (priv->data_rate < MBPS(1000)) + phy_write(phy, 0x02, DPHY_M_PRG_HS_ZERO); + else if (priv->data_rate < MBPS(1500)) phy_write(phy, 0x09, DPHY_M_PRG_HS_ZERO); else phy_write(phy, 0x10, DPHY_M_PRG_HS_ZERO); /* MC_PRG_HS_TRAIL and M_PRG_HS_TRAIL */ - if (priv->data_rate < MBPS(1000)) { + if (priv->data_rate < MBPS(250)) { + phy_write(phy, 0x02, DPHY_MC_PRG_HS_TRAIL); + phy_write(phy, 0x02, DPHY_M_PRG_HS_TRAIL); + } else if (priv->data_rate < MBPS(500)) { + phy_write(phy, 0x04, DPHY_MC_PRG_HS_TRAIL); + phy_write(phy, 0x04, DPHY_M_PRG_HS_TRAIL); + } else if (priv->data_rate < MBPS(1000)) { phy_write(phy, 0x05, DPHY_MC_PRG_HS_TRAIL); phy_write(phy, 0x05, DPHY_M_PRG_HS_TRAIL); } else if (priv->data_rate < MBPS(1500)) { @@ -243,14 +261,26 @@ static void mixel_phy_set_prg_regs(struct phy *phy) phy_write(phy, 0x0F, DPHY_MC_PRG_HS_TRAIL); phy_write(phy, 0x0F, DPHY_M_PRG_HS_TRAIL); } + + /* M_PRG_HS_ZERO */ + if (priv->data_rate < MBPS(250)) + phy_write(phy, 0x0B, DPHY_M_PRG_RXHS_SETTLE); + else if (priv->data_rate < MBPS(500)) + phy_write(phy, 0x08, DPHY_M_PRG_RXHS_SETTLE); + else + phy_write(phy, 0x06, DPHY_M_PRG_RXHS_SETTLE); + } -int mixel_mipi_phy_init(struct phy *phy) +static int mixel_mipi_phy_init(struct phy *phy) { struct mixel_mipi_phy_priv *priv = dev_get_drvdata(phy->dev.parent); mutex_lock(&priv->lock); + phy_write(phy, PWR_OFF, DPHY_PD_PLL); + phy_write(phy, PWR_OFF, DPHY_PD_DPHY); + mixel_phy_set_prg_regs(phy); phy_write(phy, 0x00, DPHY_LOCK_BYP); @@ -280,7 +310,7 @@ int mixel_mipi_phy_init(struct phy *phy) return 0; } -int mixel_mipi_phy_exit(struct phy *phy) +static int mixel_mipi_phy_exit(struct phy *phy) { phy_write(phy, 0, DPHY_CM); phy_write(phy, 0, DPHY_CN); @@ -297,7 +327,6 @@ static int mixel_mipi_phy_power_on(struct phy *phy) mutex_lock(&priv->lock); - phy_write(phy, PWR_ON, DPHY_PD_DPHY); phy_write(phy, PWR_ON, DPHY_PD_PLL); timeout = 100; @@ -305,10 +334,15 @@ static int mixel_mipi_phy_power_on(struct phy *phy) udelay(10); if (--timeout == 0) { dev_err(&phy->dev, "Could not get DPHY lock!\n"); + phy_write(phy, PWR_OFF, DPHY_PD_PLL); mutex_unlock(&priv->lock); return -EINVAL; } } + dev_dbg(&phy->dev, "DPHY lock acquired after %d tries\n", + (100 - timeout)); + + phy_write(phy, PWR_ON, DPHY_PD_DPHY); if (priv->have_sc) ret = mixel_mipi_phy_enable(phy, 1); @@ -367,7 +401,7 @@ static int mixel_mipi_phy_probe(struct platform_device *pdev) struct mixel_mipi_phy_priv *priv; struct resource *res; struct phy *phy; - u32 phy_id = 0; + int phy_id = 0; if (!np) return -ENODEV; |