diff options
Diffstat (limited to 'arch/arm/mach-imx/clock-imx6q.c')
-rw-r--r-- | arch/arm/mach-imx/clock-imx6q.c | 105 |
1 files changed, 96 insertions, 9 deletions
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c index 1029a3b2f6a..a54f8c9ad14 100644 --- a/arch/arm/mach-imx/clock-imx6q.c +++ b/arch/arm/mach-imx/clock-imx6q.c @@ -24,6 +24,23 @@ #include <mach/common.h> #include <mach/hardware.h> +/* IOMUXC */ +#define MXC_IOMUXC_BASE IMX_IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR) +#define IOMUXC_GPR0 (MXC_IOMUXC_BASE + 0x00) +#define IOMUXC_GPR1 (MXC_IOMUXC_BASE + 0x04) +#define IOMUXC_GPR2 (MXC_IOMUXC_BASE + 0x08) +#define IOMUXC_GPR3 (MXC_IOMUXC_BASE + 0x0C) +#define IOMUXC_GPR4 (MXC_IOMUXC_BASE + 0x10) +#define IOMUXC_GPR5 (MXC_IOMUXC_BASE + 0x14) +#define IOMUXC_GPR6 (MXC_IOMUXC_BASE + 0x18) +#define IOMUXC_GPR7 (MXC_IOMUXC_BASE + 0x1C) +#define IOMUXC_GPR8 (MXC_IOMUXC_BASE + 0x20) +#define IOMUXC_GPR9 (MXC_IOMUXC_BASE + 0x24) +#define IOMUXC_GPR10 (MXC_IOMUXC_BASE + 0x28) +#define IOMUXC_GPR11 (MXC_IOMUXC_BASE + 0x2C) +#define IOMUXC_GPR12 (MXC_IOMUXC_BASE + 0x30) +#define IOMUXC_GPR13 (MXC_IOMUXC_BASE + 0x34) + #define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR) #define PLL1_SYS (PLL_BASE + 0x000) #define PLL2_BUS (PLL_BASE + 0x030) @@ -1856,8 +1873,27 @@ static struct clk pcie_clk = { static int sata_clk_enable(struct clk *clk) { + int timeout = 0x100000; u32 val; + /* Clear Power Down and Enable PLLs */ + val = readl_relaxed(PLL8_ENET); + val &= ~BM_PLL_POWER_DOWN; + writel_relaxed(val, PLL8_ENET); + + val = readl_relaxed(PLL8_ENET); + val |= BM_PLL_ENABLE; + writel_relaxed(val, PLL8_ENET); + + /* Wait for PLL to lock */ + while (!(readl_relaxed(PLL8_ENET) & BM_PLL_LOCK) && --timeout) + cpu_relax(); + + /* Disable the bypass */ + val = readl_relaxed(PLL8_ENET); + val &= ~BM_PLL_BYPASS; + writel_relaxed(val, PLL8_ENET); + val = readl_relaxed(PLL8_ENET); val |= BM_PLL_ENET_EN_SATA; writel_relaxed(val, PLL8_ENET); @@ -1876,14 +1912,62 @@ static void sata_clk_disable(struct clk *clk) writel_relaxed(val, PLL8_ENET); } -static struct clk sata_clk = { - __INIT_CLK_DEBUG(sata_clk) - .enable_reg = CCGR5, - .enable_shift = CG2, - .enable = sata_clk_enable, - .disable = sata_clk_disable, - .parent = &ipg_clk, - .secondary = &pll8_enet, +static struct clk sata_clk[] = { + { + __INIT_CLK_DEBUG(sata_clk) + .enable_reg = CCGR5, + .enable_shift = CG2, + .enable = sata_clk_enable, + .disable = sata_clk_disable, + .parent = &ipg_clk, + .secondary = &sata_clk[1], + }, + { + .parent = &mmdc_ch0_axi_clk, + }, +}; + +static int ahci_phy_clk_enable(struct clk *clk) +{ + u32 val; + + /* Set PHY Paremeters, two steps to configure the GPR13, + * one write for rest of parameters, mask of first write is 0x07FFFFFD, + * and the other one write for setting the mpll_clk_off_b + *.rx_eq_val_0(iomuxc_gpr13[26:24]), + *.los_lvl(iomuxc_gpr13[23:19]), + *.rx_dpll_mode_0(iomuxc_gpr13[18:16]), + *.mpll_ss_en(iomuxc_gpr13[14]), + *.tx_atten_0(iomuxc_gpr13[13:11]), + *.tx_boost_0(iomuxc_gpr13[10:7]), + *.tx_lvl(iomuxc_gpr13[6:2]), + *.mpll_ck_off(iomuxc_gpr13[1]), + *.tx_edgerate_0(iomuxc_gpr13[0]), + */ + val = readl_relaxed(IOMUXC_GPR13); + writel_relaxed(((val & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13); + + /* enable SATA_PHY PLL */ + val = readl_relaxed(IOMUXC_GPR13); + writel_relaxed(((val & ~0x2) | 0x2), IOMUXC_GPR13); + + + return 0; +} + +static void ahci_phy_clk_disable(struct clk *clk) +{ + /* disable SATA_PHY PLL */ + writel_relaxed((readl_relaxed(IOMUXC_GPR13) & ~0x2), IOMUXC_GPR13); +} + +static struct clk ahci_phy_clk = { + .enable = ahci_phy_clk_enable, + .disable = ahci_phy_clk_disable, +}; + +static struct clk ahci_dma_clk = { + .parent = &ahb_clk, }; #define _REGISTER_CLOCK(d, n, c) \ @@ -1931,7 +2015,10 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("208c000.pwm", NULL, pwm4_clk), _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk), _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk), - _REGISTER_CLOCK(NULL, "sata_clk", sata_clk), + _REGISTER_CLOCK("imx6q-ahci", "ahci", sata_clk[0]), + _REGISTER_CLOCK("imx6q-ahci", "ahci_phy", ahci_phy_clk), + _REGISTER_CLOCK("imx6q-ahci", "ahci_dma", ahci_dma_clk), + _REGISTER_CLOCK(NULL, "cpu", arm_clk), _REGISTER_CLOCK(NULL, "ipu1_clk", ipu1_clk), _REGISTER_CLOCK(NULL, "ipu2_clk", ipu2_clk), _REGISTER_CLOCK(NULL, "ipu1_di0_clk", ipu1_di0_clk), |