From f3a43650387114b8c4644c06367d067325295bb4 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 9 May 2016 16:11:25 +0800 Subject: [PATCH] phy: rockchip-emmc: enable ctrl-base before waiting pll Need to control phy's digital block before enabling pll and waiting for it into locked state. Change-Id: I04037f5496fd5c1ef4e24853eb32b43ce326ff01 Signed-off-by: Shawn Lin --- drivers/phy/phy-rockchip-emmc.c | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c index 3a2bbb703253..b0763d38dae8 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/phy-rockchip-emmc.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -39,7 +40,11 @@ #define GRF_EMMCPHY_CON5 0x14 #define GRF_EMMCPHY_CON6 0x18 #define GRF_EMMCPHY_STATUS 0x20 +#define CTRL_OFFSET 0x2c +#define CTRL_INTER_CLKEN 0x1 +#define CTRL_INTER_CLKRDY 0x1 +#define CTRL_INTER_CLKOUT 0x1 #define PHYCTRL_PDB_MASK 0x1 #define PHYCTRL_PDB_SHIFT 0x0 #define PHYCTRL_PDB_PWR_ON 0x1 @@ -78,6 +83,7 @@ struct rockchip_emmc_phy { unsigned int reg_offset; struct regmap *reg_base; + void __iomem *ctrl_base; u32 freq_sel; u32 dr_sel; u32 opdelay; @@ -88,6 +94,8 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, { unsigned int caldone; unsigned int dllrdy; + u16 ctrl_val; + unsigned long timeout; /* * Keep phyctrl_pdb and phyctrl_endll low to allow @@ -108,6 +116,22 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, if (on_off == PHYCTRL_PDB_PWR_OFF) return 0; + ctrl_val = readw(rk_phy->ctrl_base + CTRL_OFFSET); + ctrl_val |= CTRL_INTER_CLKEN; + writew(ctrl_val, rk_phy->ctrl_base + CTRL_OFFSET); + /* Wait max 20 ms */ + while (!((ctrl_val = readw(rk_phy->ctrl_base + CTRL_OFFSET)) + & CTRL_INTER_CLKRDY)) { + if (timeout == 0) { + pr_err("rockchip_emmc_phy_power_on: inter_clk not rdy\n"); + return -EINVAL; + } + timeout--; + mdelay(1); + } + ctrl_val |= CTRL_INTER_CLKOUT; + writew(ctrl_val, rk_phy->ctrl_base + CTRL_OFFSET); + /* * According to the user manual, calpad calibration * cycle takes more than 2us without the minimal recommended @@ -232,6 +256,7 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) u32 freq_sel; u32 dr_sel; u32 opdelay; + u32 ctrl_base; grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); if (IS_ERR(grf)) { @@ -249,6 +274,18 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) return -EINVAL; } + if (of_property_read_u32(dev->of_node, "ctrl-base", &ctrl_base)) { + dev_err(dev, "missing ctrl-base property in node %s\n", + dev->of_node->name); + return -EINVAL; + } + + rk_phy->ctrl_base = ioremap(ctrl_base, SZ_1K); + if (!rk_phy->ctrl_base) { + dev_err(dev, "failed to remap ctrl_base!\n"); + return -ENOMEM; + } + rk_phy->freq_sel = 0x0; if (!of_property_read_u32(dev->of_node, "freq-sel", &freq_sel)) { switch (freq_sel) { @@ -308,6 +345,7 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) generic_phy = devm_phy_create(dev, dev->of_node, &ops); if (IS_ERR(generic_phy)) { dev_err(dev, "failed to create PHY\n"); + iounmap(rk_phy->ctrl_base); return PTR_ERR(generic_phy); } -- 2.34.1