static int msm_sata_vreg_init(struct device *dev)
{
	int ret = 0;
	struct msm_sata_hba *hba = dev_get_drvdata(dev);

	ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_ext_3p3v",
				&hba->clk_pwr, 3300000, 3300000, 850000);
	if (ret)
		goto out;

	
	msm_sata_delay_us(1000);

	
	if (readl_relaxed(hba->ahci_base +
				AHCI_HOST_CAP) & AHCI_HOST_CAP_PMP) {
		
		ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_pmp_pwr",
				&hba->pmp_pwr, 1800000, 1800000, 200000);
		if (ret) {
			msm_sata_vreg_put_disable(dev, hba->clk_pwr,
					"sata_ext_3p3v", 3300000);
			goto out;
		}

		
		msm_sata_delay_us(1000);
	}

out:
	return ret;
}
Beispiel #2
0
static int msm_sata_vreg_init(struct device *dev)
{
	int ret = 0;
	struct msm_sata_hba *hba = dev_get_drvdata(dev);

	if (hba->pdata && hba->pdata->xo_vote) {
		ret = msm_xo_mode_vote(hba->xo_sata_clk, MSM_XO_MODE_ON);
		if (ret < 0) {
			dev_err(dev, "%s: Failed to vote for XO ON (%d)\n",
					__func__, ret);
			goto out;
		}
	}

	/*
	 * The SATA clock generator needs 3.3V supply and can consume
	 * max. 850mA during functional mode.
	 */
	ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_ext_3p3v",
				&hba->clk_pwr, 3300000, 3300000, 850000);
	if (ret)
		goto out_disable_xo;

	/* Add 1ms regulator ramp-up delay */
	msm_sata_delay_us(1000);

	/* Read AHCI capability register to check if PMP is supported.*/
	if (readl_relaxed(hba->ahci_base +
				AHCI_HOST_CAP) & AHCI_HOST_CAP_PMP) {
		/* Power up port-multiplier */
		ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_pmp_pwr",
				&hba->pmp_pwr, 1800000, 1800000, 200000);
		if (ret)
			goto out_disable_3p3v;

		/* Add 1ms regulator ramp-up delay */
		msm_sata_delay_us(1000);
	}

	goto out;

out_disable_3p3v:
	msm_sata_vreg_put_disable(dev, hba->clk_pwr,
			"sata_ext_3p3v", 3300000);
out_disable_xo:
	if (hba->pdata && hba->pdata->xo_vote)
		msm_xo_mode_vote(hba->xo_sata_clk, MSM_XO_MODE_OFF);
out:
	return ret;
}
Beispiel #3
0
static int msm_sata_vreg_init(struct device *dev)
{
	int ret = 0;
	struct msm_sata_hba *hba = dev_get_drvdata(dev);

	/*
	 * The SATA clock generator needs 3.3V supply and can consume
	 * max. 850mA during functional mode.
	 */
	ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_ext_3p3v",
				&hba->clk_pwr, 3300000, 3300000, 850000);
	if (ret)
		goto out;

	/* Add 1ms regulator ramp-up delay */
	msm_sata_delay_us(1000);

	/* Read AHCI capability register to check if PMP is supported.*/
	if (readl_relaxed(hba->ahci_base +
				AHCI_HOST_CAP) & AHCI_HOST_CAP_PMP) {
		/* Power up port-multiplier */
		ret = msm_sata_vreg_get_enable_set_vdd(dev, "sata_pmp_pwr",
				&hba->pmp_pwr, 1800000, 1800000, 200000);
		if (ret) {
			msm_sata_vreg_put_disable(dev, hba->clk_pwr,
					"sata_ext_3p3v", 3300000);
			goto out;
		}

		/* Add 1ms regulator ramp-up delay */
		msm_sata_delay_us(1000);
	}

out:
	return ret;
}
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;
}
Beispiel #5
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;
}