]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00139241-2 mx6 sata: enable ahci sata module on mx6q
authorRichard Zhu <r65037@freescale.com>
Tue, 5 Jul 2011 07:03:16 +0000 (15:03 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:09:13 +0000 (14:09 +0200)
Eanble ahci sata on mx6q

Signed-off-by: Richard Zhu <r65037@freescale.com>
arch/arm/mach-mx6/Kconfig
arch/arm/mach-mx6/board-mx6q_sabreauto.c
arch/arm/mach-mx6/clock.c
arch/arm/mach-mx6/crm_regs.h
arch/arm/mach-mx6/devices-imx6q.h
arch/arm/plat-mxc/include/mach/mx6.h

index a1cd8dfca158a3851772f0fd7405737260316646..f07f22bd0c6edc390d018a7c490cf25f885b7485 100644 (file)
@@ -31,6 +31,7 @@ config MACH_MX6Q_SABREAUTO
        select IMX_HAVE_PLATFORM_MXC_EHCI
        select IMX_HAVE_PLATFORM_FSL_OTG
        select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+       select IMX_HAVE_PLATFORM_AHCI
        help
          Include support for i.MX 6Quad SABRE Automotive Infotainment platform. This includes specific
          configurations for the board and its peripherals.
index abdc28dd626954f45ed0f49c78ba2316ac50e79d..2aeaf52d6b12729c5f7af7e4fbc0d2ae8243befa 100644 (file)
 #include <mach/iomux-mx6q.h>
 #include <mach/imx-uart.h>
 #include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
 #include <linux/gpio.h>
 #include <linux/etherdevice.h>
 
 #include "usb.h"
 #include "devices-imx6q.h"
 #include "regs-anadig.h"
+#include "crm_regs.h"
 
 #define MX6Q_SABREAUTO_ECSPI1_CS0      IMX_GPIO_NR(2, 30)
 #define MX6Q_SABREAUTO_ECSPI1_CS1      IMX_GPIO_NR(3, 19)
@@ -74,6 +76,7 @@
 #define MX6Q_SABREAUTO_CAP_TCH_INT     IMX_GPIO_NR(3, 31)
 
 void __init early_console_setup(unsigned long base, struct clk *clk);
+static struct clk *sata_clk;
 
 static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
 
@@ -312,6 +315,86 @@ static struct viv_gpu_platform_data imx6q_gc2000_pdata __initdata = {
        .reserved_mem_size = SZ_128M,
 };
 
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6q_sabreauto_sata_init(struct device *dev, void __iomem *addr)
+{
+       u32 tmpdata;
+       int ret = 0;
+       struct clk *clk;
+
+       /* Enable SATA PWR CTRL_0 of MAX7310 */
+       gpio_request(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+       gpio_direction_output(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, 1);
+
+       sata_clk = clk_get(dev, "imx_sata_clk");
+       if (IS_ERR(sata_clk)) {
+               dev_err(dev, "no sata clock.\n");
+               return PTR_ERR(sata_clk);
+       }
+       ret = clk_enable(sata_clk);
+       if (ret) {
+               dev_err(dev, "can't enable sata clock.\n");
+               goto put_sata_clk;
+       }
+
+       /* Set PHY Paremeters, two steps to configure the GPR13,
+        * one write for rest of parameters, mask of first write is 0x07FF7FFD,
+        * 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]),
+        */
+       tmpdata = readl(IOMUXC_GPR13);
+       writel(((tmpdata & ~0x07FF7FFD) | 0x05932044), IOMUXC_GPR13);
+
+       /* enable SATA_PHY PLL */
+       tmpdata = readl(IOMUXC_GPR13);
+       writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+       /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+       clk = clk_get(NULL, "ahb");
+       if (IS_ERR(clk)) {
+               dev_err(dev, "no ahb clock.\n");
+               ret = PTR_ERR(clk);
+               goto release_sata_clk;
+       }
+       tmpdata = clk_get_rate(clk) / 1000;
+       clk_put(clk);
+
+       sata_init(addr, tmpdata);
+
+       return ret;
+
+release_sata_clk:
+       clk_disable(sata_clk);
+put_sata_clk:
+       clk_put(sata_clk);
+
+       return ret;
+}
+
+static void mx6q_sabreauto_sata_exit(struct device *dev)
+{
+       clk_disable(sata_clk);
+       clk_put(sata_clk);
+
+       /* Disable SATA PWR CTRL_0 of MAX7310 */
+       gpio_request(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+       gpio_direction_output(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, 0);
+
+}
+
+static struct ahci_platform_data mx6q_sabreauto_sata_data = {
+       .init = mx6q_sabreauto_sata_init,
+       .exit = mx6q_sabreauto_sata_exit,
+};
+
 /*!
  * Board specific initialization.
  */
@@ -332,6 +415,7 @@ static void __init mx6_board_init(void)
        imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabreauto_sd4_data);
        imx_add_viv_gpu("gc2000", &imx6_gc2000_data, &imx6q_gc2000_pdata);
        imx6q_sabreauto_init_usb();
+       imx6q_add_ahci(0, &mx6q_sabreauto_sata_data);
 }
 
 extern void __iomem *twd_base;
index db20143d7e212352b5cdf9ae6dd60dcfdfc517ad..394bf2bb414006873135c0137ab497ae096e03a5 100644 (file)
@@ -3824,6 +3824,26 @@ static struct clk pcie_clk = {
 static int _clk_sata_enable(struct clk *clk)
 {
        unsigned int reg;
+       unsigned int cyclecount;
+
+       /* Clear Power Down and Enable PLLs */
+       reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+       reg &= ~ANADIG_PLL_ENET_POWER_DOWN;
+       __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+       reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+       reg |= ANADIG_PLL_ENET_EN;
+       __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+       /* Waiting for the PLL is locked */
+       if (!WAIT(ANADIG_PLL_ENET_LOCK & __raw_readl(PLL8_ENET_BASE_ADDR),
+                               SPIN_DELAY))
+               panic("pll8 lock failed\n");
+
+       /* Disable the bypass */
+       reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+       reg &= ~ANADIG_PLL_ENET_BYPASS;
+       __raw_writel(reg, PLL8_ENET_BASE_ADDR);
 
        /* Enable SATA ref clock */
        reg = __raw_readl(PLL8_ENET_BASE_ADDR);
index a0a6fc896a56ff42de3b40e8237a61f353f6a418..e436ccfc8baa8cfbd7189db4201dbb5635a0e235 100644 (file)
 #ifndef __ARCH_ARM_MACH_MX6_CRM_REGS_H__
 #define __ARCH_ARM_MACH_MX6_CRM_REGS_H__
 
+/* IOMUXC */
+#define MXC_IOMUXC_BASE                        MX6_IO_ADDRESS(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)
+
 /* PLLs */
 #define MXC_PLL_BASE                   MX6_IO_ADDRESS(ANATOP_BASE_ADDR)
 #define PLL1_SYS_BASE_ADDR             (MXC_PLL_BASE + 0x0)
 #define ANADIG_PLL_MLB_VDDA_DELAY_CFG_OFFSET   (17)
 
 /* PLL8_ENET defines. */
+#define ANADIG_PLL_ENET_LOCK                   (1 << 31)
 #define ANADIG_PLL_ENET_EN_SATA                        (1 << 20)
 #define ANADIG_PLL_ENET_EN_PCIE                        (1 << 19)
+#define ANADIG_PLL_ENET_BYPASS                 (1 << 16)
+#define ANADIG_PLL_ENET_EN                     (1 << 13)
+#define ANADIG_PLL_ENET_POWER_DOWN             (1 << 12)
 #define ANADIG_PLL_ENET_DIV_SELECT_MASK                (0x3)
 #define ANADIG_PLL_ENET_DIV_SELECT_OFFSET      (0)
 
index ed8298ba9db71109a2134163cada5416bcecd608..ca2fbb59b312b373d37805f729f572cd31a9a5e6 100644 (file)
@@ -72,3 +72,7 @@ extern const struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] __initco
 extern const struct imx_viv_gpu_data imx6_gc2000_data __initconst;
 extern const struct imx_viv_gpu_data imx6_gc320_data __initconst;
 extern const struct imx_viv_gpu_data imx6_gc355_data __initconst;
+
+extern const struct imx_ahci_data imx6q_ahci_data __initconst;
+#define imx6q_add_ahci(id, pdata)   \
+       imx_add_ahci(&imx6q_ahci_data, pdata)
index 451fc7f093a31138b16fc6052e5d78e0fe774a8d..fe95cc0d2ccbccd7ab690fec5110f65953224e71 100644 (file)
@@ -99,7 +99,7 @@
 #define AIPS1_ARB_END_ADDR              0x020FFFFF
 #define AIPS2_ARB_BASE_ADDR             0x02100000
 #define AIPS2_ARB_END_ADDR              0x021FFFFF
-#define SATA_ARB_BASE_ADDR              0x02200000
+#define MX6Q_SATA_BASE_ADDR              0x02200000
 #define SATA_ARB_END_ADDR               0x02203FFF
 #define OPENVG_ARB_BASE_ADDR            0x02204000
 #define OPENVG_ARB_END_ADDR             0x02207FFF
 #define MX6Q_INT_I2C1                               68
 #define MX6Q_INT_I2C2                               69
 #define MX6Q_INT_I2C3                               70
-#define MXC_INT_SATA                               71
+#define MX6Q_INT_SATA                               71
 #define MX6Q_INT_USB_HS1                                       72
 #define MX6Q_INT_USB_HS2                                       73
 #define MX6Q_INT_USB_HS3                                       74