void msm_sata_deinit(struct device *ahci_dev)
{
	struct device *dev = ahci_dev->parent;

	msm_sata_phy_deinit(dev);
	msm_sata_vreg_deinit(dev);
	msm_sata_clk_deinit(dev);
}
Пример #2
0
void msm_sata_deinit(struct device *ahci_dev)
{
	struct device *dev = ahci_dev->parent;

	msm_sata_phy_deinit(dev);
#ifndef CONFIG_SATA_SNPS_PHY
	msm_sata_vreg_deinit(dev);
#endif
	msm_sata_clk_deinit(dev);
}
static int msm_sata_phy_init(struct device *dev)
{
	int ret = 0;
	u32 reg = 0;
	struct platform_device *pdev = to_platform_device(dev);
	struct msm_sata_hba *hba = dev_get_drvdata(dev);
	struct resource *mem;

	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem");
	if (!mem) {
		dev_err(dev, "no mmio space\n");
		return -EINVAL;
	}

	hba->phy_base = devm_ioremap(dev, mem->start, resource_size(mem));
	if (!hba->phy_base) {
		dev_err(dev, "failed to allocate memory for SATA PHY\n");
		return -ENOMEM;
	}

	

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_SER_CTRL);

	writel_relaxed(0xB1, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
	mb();
	msm_sata_delay_us(10);

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);
	writel_relaxed(0x02, hba->phy_base + SATA_PHY_TX_IMCAL2);

	
	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_REFCLK_CFG);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_PWRGEN_CFG);

	writel_relaxed(0x0A, hba->phy_base + UNIPHY_PLL_CAL_CFG0);
	writel_relaxed(0xF3, hba->phy_base + UNIPHY_PLL_CAL_CFG8);
	writel_relaxed(0x01, hba->phy_base + UNIPHY_PLL_CAL_CFG9);
	writel_relaxed(0xED, hba->phy_base + UNIPHY_PLL_CAL_CFG10);
	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_CAL_CFG11);

	writel_relaxed(0x36, hba->phy_base + UNIPHY_PLL_SDM_CFG0);
	writel_relaxed(0x0D, hba->phy_base + UNIPHY_PLL_SDM_CFG1);
	writel_relaxed(0xA3, hba->phy_base + UNIPHY_PLL_SDM_CFG2);
	writel_relaxed(0xF0, hba->phy_base + UNIPHY_PLL_SDM_CFG3);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SDM_CFG4);

	writel_relaxed(0x19, hba->phy_base + UNIPHY_PLL_SSC_CFG0);
	writel_relaxed(0xE1, hba->phy_base + UNIPHY_PLL_SSC_CFG1);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SSC_CFG2);
	writel_relaxed(0x11, hba->phy_base + UNIPHY_PLL_SSC_CFG3);

	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_LKDET_CFG0);
	writel_relaxed(0xFF, hba->phy_base + UNIPHY_PLL_LKDET_CFG1);

	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_GLB_CFG);
	mb();
	msm_sata_delay_us(40);

	writel_relaxed(0x03, hba->phy_base + UNIPHY_PLL_GLB_CFG);
	mb();
	msm_sata_delay_us(400);

	writel_relaxed(0x05, hba->phy_base + UNIPHY_PLL_LKDET_CFG2);
	mb();

	
	ret = readl_poll_timeout(hba->phy_base + UNIPHY_PLL_STATUS, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout UNIPHY_PLL_STATUS\n");
		goto out;
	}

	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_TX_IMCAL_STAT, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n");
		goto out;
	}

	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_RX_IMCAL_STAT, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n");
		goto out;
	}

	
	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);

	writel_relaxed(0x00, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x59, hba->phy_base + SATA_PHY_CDR_CTRL0);
	writel_relaxed(0x04, hba->phy_base + SATA_PHY_CDR_CTRL1);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL2);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_PI_CTRL0);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL3);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);

	writel_relaxed(0x11, hba->phy_base + SATA_PHY_TX_DATA_CTRL);
	writel_relaxed(0x43, hba->phy_base + SATA_PHY_ALIGNP);
	writel_relaxed(0x04, hba->phy_base + SATA_PHY_OOB_TERM);

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_EQUAL);
	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL0);
	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL1);
	mb();

	dev_dbg(dev, "SATA PHY powered up in functional mode\n");

out:
	
	if (ret)
		msm_sata_phy_deinit(dev);

	return ret;
}
Пример #4
0
static int msm_sata_phy_init(struct device *dev)
{
	/* Synopsys PHY specific Power Up Sequence */

	u32 reg = 0;
	struct platform_device *pdev = to_platform_device(dev);
	struct msm_sata_hba *hba = dev_get_drvdata(dev);
	struct resource *mem;

	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem");
	if (!mem) {
		dev_err(dev, "no mmio space\n");
		return -EINVAL;
	}

	hba->phy_base = devm_ioremap(dev, mem->start, resource_size(mem));
	if (!hba->phy_base) {
		dev_err(dev, "failed to allocate memory for SATA PHY\n");
		return -ENOMEM;
	}


	/* Setting SSC_EN to 1 */

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM3);
	reg = reg | 0x08;
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM3);

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM0) &
			~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
	reg |=
	SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(hba->tx_preemph_gen3);
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM0);

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM1) &
			~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
	reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM1);

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM2) &
		~SATA_PHY_P0_PARAM2_RX_EQ_MASK;

	reg |= SATA_PHY_P0_PARAM2_RX_EQ(hba->rx_eq);

	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM2);

	/* Setting PHY_RESET to 1 */

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM4);
	reg = reg | 0x01;
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM4);

	/* Setting REF_SSP_EN to 1 */

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM4);
	reg = reg | 0x03;
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM4);
	mb();
	msm_sata_delay_us(20);

	/* Clearing PHY_RESET to 0 */

	reg = readl_relaxed(hba->phy_base + SATA_PHY_P0_PARAM4);
	reg = reg & 0xfffffffe;
	writel_relaxed(reg, hba->phy_base + SATA_PHY_P0_PARAM4);

	reg = readl_poll_timeout(hba->ahci_base + SATA_CNT_P0_PHYSR, reg,
			(reg & 1), POLL_PERIOD_US, TIMEOUT_PERIOD_US);
	if (reg) {
		dev_err(dev, "poll timeout SATA_CNT_P0_PHYSR\n");
		/* power down PHY in case of failure */
		msm_sata_phy_deinit(dev);
		return reg;
	}

	/* MPLL setting */
	if (hba->mpll)
		writel_relaxed(hba->mpll, hba->phy_base + SATA_PHY_MPLL);

        /* Term Offset */
        if (hba->term_off)
                writel_relaxed(hba->term_off, hba->phy_base + SATA_PHY_TX_DRIV_CTRL2);

	return 0;
}