static int exynos5_ahci_init(void __iomem *mmio) { int val, ret; __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, EXYNOS5_SATA_PHY_CONTROL); val = 0; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= 0x3D; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= LINK_RESET; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM); val &= ~PHCTRLM_REF_RATE; __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM); /* High speed enable for Gen3 */ val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM); val |= PHCTRLM_HIGH_SPEED; __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM); /* Port0 is available */ __raw_writel(0x1, mmio + HOST_PORTS_IMPL); ret = ahci_phy_init(mmio); val = __raw_readl(phy_ctrl + SATA_CTRL0); val |= CTRL0_P0_PHY_CALIBRATED_SEL|CTRL0_P0_PHY_CALIBRATED; __raw_writel(val, phy_ctrl + SATA_CTRL0); sata_set_gen(SATA_GENERATION3); /* release cmu reset */ val = __raw_readl(phy_ctrl + SATA_RESET); val &= ~RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); if (wait_for_reg_status(phy_ctrl, SATA_PHSATA_STATM, PHSTATM_PLL_LOCKED, 1)) { return ret; } return 0; }
static int exynos4_ahci_init(struct device *dev, void __iomem *mmio) { struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata; int val, ret; phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K); if (!phy_base) { dev_err(dev, "failed to allocate memory for SATA PHY\n"); return -ENOMEM; } phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16); if (!phy_ctrl) { dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n"); ret = -ENOMEM; goto err1; } clk_sata = clk_get(dev, "sata"); if (IS_ERR(clk_sata)) { dev_err(dev, "failed to get sata clock\n"); ret = PTR_ERR(clk_sata); clk_sata = NULL; goto err2; } clk_enable(clk_sata); clk_sataphy = clk_get(dev, "sataphy"); if (IS_ERR(clk_sataphy)) { dev_err(dev, "failed to get sataphy clock\n"); ret = PTR_ERR(clk_sataphy); clk_sataphy = NULL; goto err3; } clk_enable(clk_sataphy); clk_sclk_sata = clk_get(dev, "sclk_sata"); if (IS_ERR(clk_sclk_sata)) { dev_err(dev, "failed to get sclk_sata\n"); ret = PTR_ERR(clk_sclk_sata); clk_sclk_sata = NULL; goto err4; } clk_enable(clk_sclk_sata); clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ); __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL); /* Enable PHY link control */ val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N | SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N; __raw_writel(val, phy_ctrl + SATA_CTRL1); /* Set communication speed as 3Gbps and enable PHY power */ val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE | SATA_CTRL0_PHY_POR_N; __raw_writel(val, phy_ctrl + SATA_CTRL0); /* Port0 is available */ __raw_writel(0x1, mmio + HOST_PORTS_IMPL); return ahci_phy_init(mmio); err4: clk_disable(clk_sataphy); clk_put(clk_sataphy); err3: clk_disable(clk_sata); clk_put(clk_sata); err2: iounmap(phy_ctrl); err1: iounmap(phy_base); return ret; }
static int exynos5_ahci_init(struct device *dev, void __iomem *mmio) { struct clk *clk_sata, *clk_sataphy, *clk_sata_i2c, *clk_sclk_sata; int val, ret; phy_i2c_base = ioremap(EXYNOS5_PA_SATA_PHY_I2C, SZ_4K); if (!phy_i2c_base) { dev_err(dev, "failed to allocate memory for SATA PHY\n"); return -ENOMEM; } phy_ctrl = ioremap(EXYNOS5_PA_SATA_PHY_CTRL, SZ_64K); if (!phy_ctrl) { dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n"); ret = -ENOMEM; goto err1; } __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, EXYNOS5_SATA_PHY_CONTROL); val = 0; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= 0x3D; __raw_writel(val, phy_ctrl + SATA_RESET); clk_sata = clk_get(dev, "sata"); if (IS_ERR(clk_sata)) { dev_err(dev, "failed to get sata clock\n"); ret = PTR_ERR(clk_sata); clk_sata = NULL; goto err2; } clk_enable(clk_sata); clk_sataphy = clk_get(dev, "sata_phy"); if (IS_ERR(clk_sataphy)) { dev_err(dev, "failed to get sataphy clock\n"); ret = PTR_ERR(clk_sataphy); clk_sataphy = NULL; goto err3; } clk_enable(clk_sataphy); clk_sata_i2c = clk_get(dev, "sata_phy_i2c"); if (IS_ERR(clk_sata_i2c)) { dev_err(dev, "failed to get sclk_sata\n"); ret = PTR_ERR(clk_sata_i2c); clk_sata_i2c = NULL; goto err4; } clk_enable(clk_sata_i2c); clk_sclk_sata = clk_get(dev, "sclk_sata"); clk_enable(clk_sclk_sata); if (IS_ERR(clk_sclk_sata)) { dev_err(dev, "failed to get sclk_sata\n"); ret = PTR_ERR(clk_sclk_sata); clk_sclk_sata = NULL; goto err5; } clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ); val = __raw_readl(phy_ctrl + SATA_RESET); val |= LINK_RESET; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM); val &= ~PHCTRLM_REF_RATE; __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM); /* High speed enable for Gen3 */ val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM); val |= PHCTRLM_HIGH_SPEED; __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM); /* Port0 is available */ __raw_writel(0x1, mmio + HOST_PORTS_IMPL); ret = ahci_phy_init(mmio); val = __raw_readl(phy_ctrl + SATA_CTRL0); val |= CTRL0_P0_PHY_CALIBRATED_SEL|CTRL0_P0_PHY_CALIBRATED; __raw_writel(val, phy_ctrl + SATA_CTRL0); sata_set_gen(GEN3); /* release cmu reset */ val = __raw_readl(phy_ctrl + SATA_RESET); val &= ~RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); val = __raw_readl(phy_ctrl + SATA_RESET); val |= RESET_CMN_RST_N; __raw_writel(val, phy_ctrl + SATA_RESET); if (wait_for_reg_status(phy_ctrl, SATA_PHSATA_STATM, PHSTATM_PLL_LOCKED, 1)) { return ret; } dev_err(dev, " ahci_phy_init FAIL\n"); err5: clk_disable(clk_sata_i2c); clk_put(clk_sata_i2c); err4: clk_disable(clk_sataphy); clk_put(clk_sataphy); err3: clk_disable(clk_sata); clk_put(clk_sata); err2: iounmap(phy_ctrl); err1: iounmap(phy_i2c_base); return false; }