diff options
| author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-10-14 03:37:27 -0400 |
|---|---|---|
| committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-10-14 03:37:27 -0400 |
| commit | d546029043202ab306630fd2a10221feaed029e3 (patch) | |
| tree | 538d0f8cd61ac971190994d7c00226d894d0683f | |
| parent | 976d167615b64e14bc1491ca51d424e2ba9a5e84 (diff) | |
| parent | d870ea1d6bc5057f2599416655b42ab192dae6d0 (diff) | |
Merge branch 'features/ahci' into for-arnd-features
| -rw-r--r-- | arch/arm/mach-mx5/board-mx53_ard.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-mx5/board-mx53_loco.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-mx5/board-mx53_smd.c | 16 | ||||
| -rw-r--r-- | arch/arm/mach-mx5/clock-mx51-mx53.c | 19 | ||||
| -rw-r--r-- | arch/arm/mach-mx5/devices-imx53.h | 2 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/devices/Kconfig | 4 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/devices/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/devices/platform-ahci-imx.c | 156 | ||||
| -rw-r--r-- | arch/arm/plat-mxc/include/mach/devices-common.h | 10 |
9 files changed, 210 insertions, 0 deletions
diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c index 76a67c4a2a0b..ef2039eff74c 100644 --- a/arch/arm/mach-mx5/board-mx53_ard.c +++ b/arch/arm/mach-mx5/board-mx53_ard.c | |||
| @@ -234,6 +234,7 @@ static void __init mx53_ard_board_init(void) | |||
| 234 | imx53_add_imx_i2c(1, &mx53_ard_i2c2_data); | 234 | imx53_add_imx_i2c(1, &mx53_ard_i2c2_data); |
| 235 | imx53_add_imx_i2c(2, &mx53_ard_i2c3_data); | 235 | imx53_add_imx_i2c(2, &mx53_ard_i2c3_data); |
| 236 | imx_add_gpio_keys(&ard_button_data); | 236 | imx_add_gpio_keys(&ard_button_data); |
| 237 | imx53_add_ahci_imx(); | ||
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | static void __init mx53_ard_timer_init(void) | 240 | static void __init mx53_ard_timer_init(void) |
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index 4e1d51d252dc..940aac932fa3 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c | |||
| @@ -273,6 +273,7 @@ static void __init mx53_loco_board_init(void) | |||
| 273 | imx53_add_sdhci_esdhc_imx(2, &mx53_loco_sd3_data); | 273 | imx53_add_sdhci_esdhc_imx(2, &mx53_loco_sd3_data); |
| 274 | imx_add_gpio_keys(&loco_button_data); | 274 | imx_add_gpio_keys(&loco_button_data); |
| 275 | gpio_led_register_device(-1, &mx53loco_leds_data); | 275 | gpio_led_register_device(-1, &mx53loco_leds_data); |
| 276 | imx53_add_ahci_imx(); | ||
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | static void __init mx53_loco_timer_init(void) | 279 | static void __init mx53_loco_timer_init(void) |
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c index bc02894eafef..efcab68840ae 100644 --- a/arch/arm/mach-mx5/board-mx53_smd.c +++ b/arch/arm/mach-mx5/board-mx53_smd.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "devices-imx53.h" | 35 | #include "devices-imx53.h" |
| 36 | 36 | ||
| 37 | #define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6) | 37 | #define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6) |
| 38 | #define MX53_SMD_SATA_PWR_EN IMX_GPIO_NR(3, 3) | ||
| 38 | 39 | ||
| 39 | static iomux_v3_cfg_t mx53_smd_pads[] = { | 40 | static iomux_v3_cfg_t mx53_smd_pads[] = { |
| 40 | MX53_PAD_CSI0_DAT10__UART1_TXD_MUX, | 41 | MX53_PAD_CSI0_DAT10__UART1_TXD_MUX, |
| @@ -111,6 +112,19 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = { | |||
| 111 | .bitrate = 100000, | 112 | .bitrate = 100000, |
| 112 | }; | 113 | }; |
| 113 | 114 | ||
| 115 | static inline void mx53_smd_ahci_pwr_on(void) | ||
| 116 | { | ||
| 117 | int ret; | ||
| 118 | |||
| 119 | /* Enable SATA PWR */ | ||
| 120 | ret = gpio_request_one(MX53_SMD_SATA_PWR_EN, | ||
| 121 | GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "ahci-sata-pwr"); | ||
| 122 | if (ret) { | ||
| 123 | pr_err("failed to enable SATA_PWR_EN: %d\n", ret); | ||
| 124 | return; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 114 | static void __init mx53_smd_board_init(void) | 128 | static void __init mx53_smd_board_init(void) |
| 115 | { | 129 | { |
| 116 | imx53_soc_init(); | 130 | imx53_soc_init(); |
| @@ -125,6 +139,8 @@ static void __init mx53_smd_board_init(void) | |||
| 125 | imx53_add_sdhci_esdhc_imx(0, NULL); | 139 | imx53_add_sdhci_esdhc_imx(0, NULL); |
| 126 | imx53_add_sdhci_esdhc_imx(1, NULL); | 140 | imx53_add_sdhci_esdhc_imx(1, NULL); |
| 127 | imx53_add_sdhci_esdhc_imx(2, NULL); | 141 | imx53_add_sdhci_esdhc_imx(2, NULL); |
| 142 | mx53_smd_ahci_pwr_on(); | ||
| 143 | imx53_add_ahci_imx(); | ||
| 128 | } | 144 | } |
| 129 | 145 | ||
| 130 | static void __init mx53_smd_timer_init(void) | 146 | static void __init mx53_smd_timer_init(void) |
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index f7bf996f463b..1ef7e97e0015 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c | |||
| @@ -1401,6 +1401,22 @@ static struct clk esdhc4_mx53_clk = { | |||
| 1401 | .secondary = &esdhc4_ipg_clk, | 1401 | .secondary = &esdhc4_ipg_clk, |
| 1402 | }; | 1402 | }; |
| 1403 | 1403 | ||
| 1404 | static struct clk sata_clk = { | ||
| 1405 | .parent = &ipg_clk, | ||
| 1406 | .enable = _clk_max_enable, | ||
| 1407 | .enable_reg = MXC_CCM_CCGR4, | ||
| 1408 | .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, | ||
| 1409 | .disable = _clk_max_disable, | ||
| 1410 | }; | ||
| 1411 | |||
| 1412 | static struct clk ahci_phy_clk = { | ||
| 1413 | .parent = &usb_phy1_clk, | ||
| 1414 | }; | ||
| 1415 | |||
| 1416 | static struct clk ahci_dma_clk = { | ||
| 1417 | .parent = &ahb_clk, | ||
| 1418 | }; | ||
| 1419 | |||
| 1404 | DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); | 1420 | DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); |
| 1405 | DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); | 1421 | DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); |
| 1406 | DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); | 1422 | DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); |
| @@ -1507,6 +1523,9 @@ static struct clk_lookup mx53_lookups[] = { | |||
| 1507 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | 1523 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) |
| 1508 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) | 1524 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) |
| 1509 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) | 1525 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) |
| 1526 | _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk) | ||
| 1527 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk) | ||
| 1528 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk) | ||
| 1510 | }; | 1529 | }; |
| 1511 | 1530 | ||
| 1512 | static void clk_tree_init(void) | 1531 | static void clk_tree_init(void) |
diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h index c27fe8bb4762..1ab399e73caa 100644 --- a/arch/arm/mach-mx5/devices-imx53.h +++ b/arch/arm/mach-mx5/devices-imx53.h | |||
| @@ -40,3 +40,5 @@ extern const struct imx_imx_ssi_data imx53_imx_ssi_data[]; | |||
| 40 | extern const struct imx_imx_keypad_data imx53_imx_keypad_data; | 40 | extern const struct imx_imx_keypad_data imx53_imx_keypad_data; |
| 41 | #define imx53_add_imx_keypad(pdata) \ | 41 | #define imx53_add_imx_keypad(pdata) \ |
| 42 | imx_add_imx_keypad(&imx53_imx_keypad_data, pdata) | 42 | imx_add_imx_keypad(&imx53_imx_keypad_data, pdata) |
| 43 | |||
| 44 | extern struct platform_device *__init imx53_add_ahci_imx(void); | ||
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig index bd294add932c..f63887ba88b4 100644 --- a/arch/arm/plat-mxc/devices/Kconfig +++ b/arch/arm/plat-mxc/devices/Kconfig | |||
| @@ -76,3 +76,7 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | |||
| 76 | 76 | ||
| 77 | config IMX_HAVE_PLATFORM_SPI_IMX | 77 | config IMX_HAVE_PLATFORM_SPI_IMX |
| 78 | bool | 78 | bool |
| 79 | |||
| 80 | config IMX_HAVE_PLATFORM_AHCI | ||
| 81 | bool | ||
| 82 | default y if ARCH_MX53 | ||
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile index b41bf972b54b..e858ad92c3ec 100644 --- a/arch/arm/plat-mxc/devices/Makefile +++ b/arch/arm/plat-mxc/devices/Makefile | |||
| @@ -25,3 +25,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o | |||
| 25 | obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o | 25 | obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o |
| 26 | obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o | 26 | obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o |
| 27 | obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o | 27 | obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o |
| 28 | obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o | ||
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c new file mode 100644 index 000000000000..d8a56aee521b --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | */ | ||
| 4 | |||
| 5 | /* | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | |||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | |||
| 16 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/device.h> | ||
| 25 | #include <linux/dma-mapping.h> | ||
| 26 | #include <asm/sizes.h> | ||
| 27 | #include <mach/hardware.h> | ||
| 28 | #include <mach/devices-common.h> | ||
| 29 | |||
| 30 | #define imx_ahci_imx_data_entry_single(soc, _devid) \ | ||
| 31 | { \ | ||
| 32 | .devid = _devid, \ | ||
| 33 | .iobase = soc ## _SATA_BASE_ADDR, \ | ||
| 34 | .irq = soc ## _INT_SATA, \ | ||
| 35 | } | ||
| 36 | |||
| 37 | #ifdef CONFIG_SOC_IMX53 | ||
| 38 | const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst = | ||
| 39 | imx_ahci_imx_data_entry_single(MX53, "imx53-ahci"); | ||
| 40 | #endif | ||
| 41 | |||
| 42 | enum { | ||
| 43 | HOST_CAP = 0x00, | ||
| 44 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ | ||
| 45 | HOST_PORTS_IMPL = 0x0c, | ||
| 46 | HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ | ||
| 47 | }; | ||
| 48 | |||
| 49 | static struct clk *sata_clk, *sata_ref_clk; | ||
| 50 | |||
| 51 | /* AHCI module Initialization, if return 0, initialization is successful. */ | ||
| 52 | static int imx_sata_init(struct device *dev, void __iomem *addr) | ||
| 53 | { | ||
| 54 | u32 tmpdata; | ||
| 55 | int ret = 0; | ||
| 56 | struct clk *clk; | ||
| 57 | |||
| 58 | sata_clk = clk_get(dev, "ahci"); | ||
| 59 | if (IS_ERR(sata_clk)) { | ||
| 60 | dev_err(dev, "no sata clock.\n"); | ||
| 61 | return PTR_ERR(sata_clk); | ||
| 62 | } | ||
| 63 | ret = clk_enable(sata_clk); | ||
| 64 | if (ret) { | ||
| 65 | dev_err(dev, "can't enable sata clock.\n"); | ||
| 66 | goto put_sata_clk; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* Get the AHCI SATA PHY CLK */ | ||
| 70 | sata_ref_clk = clk_get(dev, "ahci_phy"); | ||
| 71 | if (IS_ERR(sata_ref_clk)) { | ||
| 72 | dev_err(dev, "no sata ref clock.\n"); | ||
| 73 | ret = PTR_ERR(sata_ref_clk); | ||
| 74 | goto release_sata_clk; | ||
| 75 | } | ||
| 76 | ret = clk_enable(sata_ref_clk); | ||
| 77 | if (ret) { | ||
| 78 | dev_err(dev, "can't enable sata ref clock.\n"); | ||
| 79 | goto put_sata_ref_clk; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* Get the AHB clock rate, and configure the TIMER1MS reg later */ | ||
| 83 | clk = clk_get(dev, "ahci_dma"); | ||
| 84 | if (IS_ERR(clk)) { | ||
| 85 | dev_err(dev, "no dma clock.\n"); | ||
| 86 | ret = PTR_ERR(clk); | ||
| 87 | goto release_sata_ref_clk; | ||
| 88 | } | ||
| 89 | tmpdata = clk_get_rate(clk) / 1000; | ||
| 90 | clk_put(clk); | ||
| 91 | |||
| 92 | writel(tmpdata, addr + HOST_TIMER1MS); | ||
| 93 | |||
| 94 | tmpdata = readl(addr + HOST_CAP); | ||
| 95 | if (!(tmpdata & HOST_CAP_SSS)) { | ||
| 96 | tmpdata |= HOST_CAP_SSS; | ||
| 97 | writel(tmpdata, addr + HOST_CAP); | ||
| 98 | } | ||
| 99 | |||
| 100 | if (!(readl(addr + HOST_PORTS_IMPL) & 0x1)) | ||
| 101 | writel((readl(addr + HOST_PORTS_IMPL) | 0x1), | ||
| 102 | addr + HOST_PORTS_IMPL); | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | |||
| 106 | release_sata_ref_clk: | ||
| 107 | clk_disable(sata_ref_clk); | ||
| 108 | put_sata_ref_clk: | ||
| 109 | clk_put(sata_ref_clk); | ||
| 110 | release_sata_clk: | ||
| 111 | clk_disable(sata_clk); | ||
| 112 | put_sata_clk: | ||
| 113 | clk_put(sata_clk); | ||
| 114 | |||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | static void imx_sata_exit(struct device *dev) | ||
| 119 | { | ||
| 120 | clk_disable(sata_ref_clk); | ||
| 121 | clk_put(sata_ref_clk); | ||
| 122 | |||
| 123 | clk_disable(sata_clk); | ||
| 124 | clk_put(sata_clk); | ||
| 125 | |||
| 126 | } | ||
| 127 | struct platform_device *__init imx_add_ahci_imx( | ||
| 128 | const struct imx_ahci_imx_data *data, | ||
| 129 | const struct ahci_platform_data *pdata) | ||
| 130 | { | ||
| 131 | struct resource res[] = { | ||
| 132 | { | ||
| 133 | .start = data->iobase, | ||
| 134 | .end = data->iobase + SZ_4K - 1, | ||
| 135 | .flags = IORESOURCE_MEM, | ||
| 136 | }, { | ||
| 137 | .start = data->irq, | ||
| 138 | .end = data->irq, | ||
| 139 | .flags = IORESOURCE_IRQ, | ||
| 140 | }, | ||
| 141 | }; | ||
| 142 | |||
| 143 | return imx_add_platform_device_dmamask(data->devid, 0, | ||
| 144 | res, ARRAY_SIZE(res), | ||
| 145 | pdata, sizeof(*pdata), DMA_BIT_MASK(32)); | ||
| 146 | } | ||
| 147 | |||
| 148 | struct platform_device *__init imx53_add_ahci_imx(void) | ||
| 149 | { | ||
| 150 | struct ahci_platform_data pdata = { | ||
| 151 | .init = imx_sata_init, | ||
| 152 | .exit = imx_sata_exit, | ||
| 153 | }; | ||
| 154 | |||
| 155 | return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata); | ||
| 156 | } | ||
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index 524538aabc4b..f04e063f355d 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h | |||
| @@ -301,3 +301,13 @@ struct platform_device *__init imx_add_spi_imx( | |||
| 301 | struct platform_device *imx_add_imx_dma(void); | 301 | struct platform_device *imx_add_imx_dma(void); |
| 302 | struct platform_device *imx_add_imx_sdma(char *name, | 302 | struct platform_device *imx_add_imx_sdma(char *name, |
| 303 | resource_size_t iobase, int irq, struct sdma_platform_data *pdata); | 303 | resource_size_t iobase, int irq, struct sdma_platform_data *pdata); |
| 304 | |||
| 305 | #include <linux/ahci_platform.h> | ||
| 306 | struct imx_ahci_imx_data { | ||
| 307 | const char *devid; | ||
| 308 | resource_size_t iobase; | ||
| 309 | resource_size_t irq; | ||
| 310 | }; | ||
| 311 | struct platform_device *__init imx_add_ahci_imx( | ||
| 312 | const struct imx_ahci_imx_data *data, | ||
| 313 | const struct ahci_platform_data *pdata); | ||
