phy: rockchip-emmc: add some setup configuration
authorShawn Lin <shawn.lin@rock-chips.com>
Mon, 25 Apr 2016 01:46:37 +0000 (09:46 +0800)
committerGerrit Code Review <gerrit@rock-chips.com>
Mon, 25 Apr 2016 09:56:45 +0000 (17:56 +0800)
Let's expose the freq-sel, dr-sel, opdalay to dt for user
to decide how to configure their phy.

Change-Id: Ib9ef40b263d3fd669c7bbda666d28c0c55ff6d8e
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
drivers/phy/phy-rockchip-emmc.c

index bd128d06496b417a680368767180f73bcd273edd..3162554d6c1641911891598893f4f214a40fca2d 100644 (file)
                ((val) << (shift) | (mask) << ((shift) + 16))
 
 /* Register definition */
-#define GRF_EMMCPHY_CON0       0x0
-#define GRF_EMMCPHY_CON1       0x4
-#define GRF_EMMCPHY_CON2       0x8
-#define GRF_EMMCPHY_CON3       0xc
-#define GRF_EMMCPHY_CON4       0x10
-#define GRF_EMMCPHY_CON5       0x14
-#define GRF_EMMCPHY_CON6       0x18
-#define GRF_EMMCPHY_STATUS     0x20
-
-#define PHYCTRL_PDB_MASK       0x1
-#define PHYCTRL_PDB_SHIFT      0x0
-#define PHYCTRL_PDB_PWR_ON     0x1
-#define PHYCTRL_PDB_PWR_OFF    0x0
-#define PHYCTRL_ENDLL_MASK     0x1
-#define PHYCTRL_ENDLL_SHIFT     0x1
-#define PHYCTRL_ENDLL_ENABLE   0x1
-#define PHYCTRL_ENDLL_DISABLE  0x0
-#define PHYCTRL_CALDONE_MASK   0x1
-#define PHYCTRL_CALDONE_SHIFT   0x6
-#define PHYCTRL_CALDONE_DONE   0x1
-#define PHYCTRL_CALDONE_GOING  0x0
-#define PHYCTRL_DLLRDY_MASK    0x1
-#define PHYCTRL_DLLRDY_SHIFT   0x5
-#define PHYCTRL_DLLRDY_DONE    0x1
-#define PHYCTRL_DLLRDY_GOING   0x0
-#define PHYCTRL_FREQSEL_200M   0x0
-#define PHYCTRL_FREQSEL_50M    0x1
-#define PHYCTRL_FREQSEL_100M   0x2
-#define PHYCTRL_FREQSEL_150M   0x3
-#define PHYCTRL_FREQSEL_MASK   0x3
-#define PHYCTRL_FREQSEL_SHIFT  0xc
-#define PHYCTRL_DR_MASK                0x7
-#define PHYCTRL_DR_SHIFT       0x4
-#define PHYCTRL_DR_50OHM       0x0
-#define PHYCTRL_DR_33OHM       0x1
-#define PHYCTRL_DR_66OHM       0x2
-#define PHYCTRL_DR_100OHM      0x3
-#define PHYCTRL_DR_40OHM       0x4
+#define GRF_EMMCPHY_CON0               0x0
+#define GRF_EMMCPHY_CON1               0x4
+#define GRF_EMMCPHY_CON2               0x8
+#define GRF_EMMCPHY_CON3               0xc
+#define GRF_EMMCPHY_CON4               0x10
+#define GRF_EMMCPHY_CON5               0x14
+#define GRF_EMMCPHY_CON6               0x18
+#define GRF_EMMCPHY_STATUS             0x20
+
+#define PHYCTRL_PDB_MASK               0x1
+#define PHYCTRL_PDB_SHIFT              0x0
+#define PHYCTRL_PDB_PWR_ON             0x1
+#define PHYCTRL_PDB_PWR_OFF            0x0
+#define PHYCTRL_ENDLL_MASK             0x1
+#define PHYCTRL_ENDLL_SHIFT            0x1
+#define PHYCTRL_ENDLL_ENABLE           0x1
+#define PHYCTRL_ENDLL_DISABLE          0x0
+#define PHYCTRL_CALDONE_MASK           0x1
+#define PHYCTRL_CALDONE_SHIFT          0x6
+#define PHYCTRL_CALDONE_DONE           0x1
+#define PHYCTRL_CALDONE_GOING          0x0
+#define PHYCTRL_DLLRDY_MASK            0x1
+#define PHYCTRL_DLLRDY_SHIFT           0x5
+#define PHYCTRL_DLLRDY_DONE            0x1
+#define PHYCTRL_DLLRDY_GOING           0x0
+#define PHYCTRL_FREQSEL_200M           0x0
+#define PHYCTRL_FREQSEL_50M            0x1
+#define PHYCTRL_FREQSEL_100M           0x2
+#define PHYCTRL_FREQSEL_150M           0x3
+#define PHYCTRL_FREQSEL_MASK           0x3
+#define PHYCTRL_FREQSEL_SHIFT          0xc
+#define PHYCTRL_DR_MASK                        0x7
+#define PHYCTRL_DR_SHIFT               0x4
+#define PHYCTRL_DR_50OHM               0x0
+#define PHYCTRL_DR_33OHM               0x1
+#define PHYCTRL_DR_66OHM               0x2
+#define PHYCTRL_DR_100OHM              0x3
+#define PHYCTRL_DR_40OHM               0x4
+#define PHYCTRL_OTAPDLYENA             0x1
+#define PHYCTRL_OTAPDLYENA_MASK                0x1
+#define PHYCTRL_OTAPDLYENA_SHIFT       11
+#define PHYCTRL_OTAPDLYSEL_MASK                0xf
+#define PHYCTRL_OTAPDLYSEL_SHIFT       7
 
 struct rockchip_emmc_phy {
        unsigned int    reg_offset;
        struct regmap   *reg_base;
+       u32     freq_sel;
+       u32     dr_sel;
+       u32     opdelay;
 };
 
 static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
@@ -148,22 +156,34 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
        return 0;
 }
 
-static int rockchip_emmc_phy_init(struct phy*phy)
+static int rockchip_emmc_phy_init(struct phy *phy)
 {
        struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
 
        regmap_write(rk_phy->reg_base,
                     rk_phy->reg_offset + GRF_EMMCPHY_CON0,
-                    HIWORD_UPDATE(PHYCTRL_FREQSEL_200M,
+                    HIWORD_UPDATE(rk_phy->freq_sel,
                                   PHYCTRL_FREQSEL_MASK,
                                   PHYCTRL_FREQSEL_SHIFT));
 
        regmap_write(rk_phy->reg_base,
                     rk_phy->reg_offset + GRF_EMMCPHY_CON6,
-                    HIWORD_UPDATE(PHYCTRL_DR_100OHM,
+                    HIWORD_UPDATE(rk_phy->dr_sel,
                                   PHYCTRL_DR_MASK,
                                   PHYCTRL_DR_SHIFT));
 
+       regmap_write(rk_phy->reg_base,
+                    rk_phy->reg_offset + GRF_EMMCPHY_CON0,
+                    HIWORD_UPDATE(PHYCTRL_OTAPDLYENA,
+                                  PHYCTRL_OTAPDLYENA_MASK,
+                                  PHYCTRL_OTAPDLYENA_SHIFT));
+
+       regmap_write(rk_phy->reg_base,
+                    rk_phy->reg_offset + GRF_EMMCPHY_CON0,
+                    HIWORD_UPDATE(rk_phy->opdelay,
+                                  PHYCTRL_OTAPDLYSEL_MASK,
+                                  PHYCTRL_OTAPDLYSEL_SHIFT));
+
        return 0;
 }
 
@@ -208,6 +228,9 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev)
        struct phy_provider *phy_provider;
        struct regmap *grf;
        unsigned int reg_offset;
+       u32 freq_sel;
+       u32 dr_sel;
+       u32 opdelay;
 
        grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
        if (IS_ERR(grf)) {
@@ -225,6 +248,59 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       rk_phy->freq_sel = 0x0;
+       if (!of_property_read_u32(dev->of_node, "freq-sel", &freq_sel)) {
+               switch (freq_sel) {
+               case 50000000:
+                       rk_phy->freq_sel = PHYCTRL_FREQSEL_50M;
+                       break;
+               case 100000000:
+                       rk_phy->freq_sel = PHYCTRL_FREQSEL_100M;
+                       break;
+               case 150000000:
+                       rk_phy->freq_sel = PHYCTRL_FREQSEL_150M;
+                       break;
+               case 200000000:
+                       rk_phy->freq_sel = PHYCTRL_FREQSEL_200M;
+                       break;
+               default:
+                       dev_info(dev, "Not support freq_sel, default 200M\n");
+                       break;
+               }
+       }
+
+       rk_phy->dr_sel = 0x0;
+       if (!of_property_read_u32(dev->of_node, "dr-sel", &dr_sel)) {
+               switch (dr_sel) {
+               case 50:
+                       rk_phy->dr_sel = PHYCTRL_DR_50OHM;
+                       break;
+               case 33:
+                       rk_phy->dr_sel = PHYCTRL_DR_33OHM;
+                       break;
+               case 66:
+                       rk_phy->dr_sel = PHYCTRL_DR_66OHM;
+                       break;
+               case 100:
+                       rk_phy->dr_sel = PHYCTRL_DR_100OHM;
+                       break;
+               case 40:
+                       rk_phy->dr_sel = PHYCTRL_DR_40OHM;
+                       break;
+               default:
+                       dev_info(dev, "Not support dr_sel, default 50OHM\n");
+                       break;
+               }
+       }
+
+       rk_phy->opdelay = 0x4;
+       if (!of_property_read_u32(dev->of_node, "opdelay", &opdelay)) {
+               if (opdelay > 15)
+                       dev_info(dev, "opdelay shouldn't larger than 15\n");
+               else
+                       rk_phy->opdelay = opdelay;
+       }
+
        rk_phy->reg_offset = reg_offset;
        rk_phy->reg_base = grf;