diff options
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r-- | arch/arm/mach-imx/clock-imx6q.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-imx/devices-imx6q.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 2 |
3 files changed, 122 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), diff --git a/arch/arm/mach-imx/devices-imx6q.h b/arch/arm/mach-imx/devices-imx6q.h new file mode 100644 index 00000000000..e41268d650e --- /dev/null +++ b/arch/arm/mach-imx/devices-imx6q.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/ahci_platform.h> + +extern struct ahci_platform_data imx_sata_pdata; + diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3f46730ac06..b33b9f2807e 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -31,6 +31,7 @@ #include <mach/iomux-mx6q.h> #include <mach/ipu-v3.h> #include <mach/mxc_vpu.h> +#include "devices-imx6q.h" static iomux_v3_cfg_t imx6q_sabrelite_pads[] = { /* DISPLAY */ @@ -122,6 +123,7 @@ static const struct of_dev_auxdata imx6q_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("fsl,ipuv3", MX6Q_IPU1_BASE_ADDR, "imx-ipuv3.0", &ipuv3_pdata), OF_DEV_AUXDATA("fsl,ipuv3", MX6Q_IPU2_BASE_ADDR, "imx-ipuv3.1", &ipuv3_pdata), OF_DEV_AUXDATA("fsl,vpu", MX6Q_VPU_BASE_ADDR, "mxc_vpu.0", &vpu_pdata), + OF_DEV_AUXDATA("fsl,imx6q-ahci", MX6Q_SATA_BASE_ADDR, "imx6q-ahci", &imx_sata_pdata), }; static void __init imx6q_init_machine(void) |