|
@@ -14,6 +14,8 @@
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
#include <linux/serial_8250.h>
|
|
|
+#include <linux/ahci_platform.h>
|
|
|
+#include <linux/clk.h>
|
|
|
|
|
|
#include <mach/cputype.h>
|
|
|
#include <mach/common.h>
|
|
@@ -33,6 +35,7 @@
|
|
|
#define DA8XX_SPI0_BASE 0x01c41000
|
|
|
#define DA830_SPI1_BASE 0x01e12000
|
|
|
#define DA8XX_LCD_CNTRL_BASE 0x01e13000
|
|
|
+#define DA850_SATA_BASE 0x01e18000
|
|
|
#define DA850_MMCSD1_BASE 0x01e1b000
|
|
|
#define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000
|
|
|
#define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000
|
|
@@ -842,3 +845,126 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info,
|
|
|
|
|
|
return platform_device_register(&da8xx_spi_device[instance]);
|
|
|
}
|
|
|
+
|
|
|
+#ifdef CONFIG_ARCH_DAVINCI_DA850
|
|
|
+
|
|
|
+static struct resource da850_sata_resources[] = {
|
|
|
+ {
|
|
|
+ .start = DA850_SATA_BASE,
|
|
|
+ .end = DA850_SATA_BASE + 0x1fff,
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .start = IRQ_DA850_SATAINT,
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+/* SATA PHY Control Register offset from AHCI base */
|
|
|
+#define SATA_P0PHYCR_REG 0x178
|
|
|
+
|
|
|
+#define SATA_PHY_MPY(x) ((x) << 0)
|
|
|
+#define SATA_PHY_LOS(x) ((x) << 6)
|
|
|
+#define SATA_PHY_RXCDR(x) ((x) << 10)
|
|
|
+#define SATA_PHY_RXEQ(x) ((x) << 13)
|
|
|
+#define SATA_PHY_TXSWING(x) ((x) << 19)
|
|
|
+#define SATA_PHY_ENPLL(x) ((x) << 31)
|
|
|
+
|
|
|
+static struct clk *da850_sata_clk;
|
|
|
+static unsigned long da850_sata_refclkpn;
|
|
|
+
|
|
|
+/* Supported DA850 SATA crystal frequencies */
|
|
|
+#define KHZ_TO_HZ(freq) ((freq) * 1000)
|
|
|
+static unsigned long da850_sata_xtal[] = {
|
|
|
+ KHZ_TO_HZ(300000),
|
|
|
+ KHZ_TO_HZ(250000),
|
|
|
+ 0, /* Reserved */
|
|
|
+ KHZ_TO_HZ(187500),
|
|
|
+ KHZ_TO_HZ(150000),
|
|
|
+ KHZ_TO_HZ(125000),
|
|
|
+ KHZ_TO_HZ(120000),
|
|
|
+ KHZ_TO_HZ(100000),
|
|
|
+ KHZ_TO_HZ(75000),
|
|
|
+ KHZ_TO_HZ(60000),
|
|
|
+};
|
|
|
+
|
|
|
+static int da850_sata_init(struct device *dev, void __iomem *addr)
|
|
|
+{
|
|
|
+ int i, ret;
|
|
|
+ unsigned int val;
|
|
|
+
|
|
|
+ da850_sata_clk = clk_get(dev, NULL);
|
|
|
+ if (IS_ERR(da850_sata_clk))
|
|
|
+ return PTR_ERR(da850_sata_clk);
|
|
|
+
|
|
|
+ ret = clk_enable(da850_sata_clk);
|
|
|
+ if (ret)
|
|
|
+ goto err0;
|
|
|
+
|
|
|
+ /* Enable SATA clock receiver */
|
|
|
+ val = __raw_readl(DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG));
|
|
|
+ val &= ~BIT(0);
|
|
|
+ __raw_writel(val, DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG));
|
|
|
+
|
|
|
+ /* Get the multiplier needed for 1.5GHz PLL output */
|
|
|
+ for (i = 0; i < ARRAY_SIZE(da850_sata_xtal); i++)
|
|
|
+ if (da850_sata_xtal[i] == da850_sata_refclkpn)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (i == ARRAY_SIZE(da850_sata_xtal)) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto err1;
|
|
|
+ }
|
|
|
+
|
|
|
+ val = SATA_PHY_MPY(i + 1) |
|
|
|
+ SATA_PHY_LOS(1) |
|
|
|
+ SATA_PHY_RXCDR(4) |
|
|
|
+ SATA_PHY_RXEQ(1) |
|
|
|
+ SATA_PHY_TXSWING(3) |
|
|
|
+ SATA_PHY_ENPLL(1);
|
|
|
+
|
|
|
+ __raw_writel(val, addr + SATA_P0PHYCR_REG);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err1:
|
|
|
+ clk_disable(da850_sata_clk);
|
|
|
+err0:
|
|
|
+ clk_put(da850_sata_clk);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void da850_sata_exit(struct device *dev)
|
|
|
+{
|
|
|
+ clk_disable(da850_sata_clk);
|
|
|
+ clk_put(da850_sata_clk);
|
|
|
+}
|
|
|
+
|
|
|
+static struct ahci_platform_data da850_sata_pdata = {
|
|
|
+ .init = da850_sata_init,
|
|
|
+ .exit = da850_sata_exit,
|
|
|
+};
|
|
|
+
|
|
|
+static u64 da850_sata_dmamask = DMA_BIT_MASK(32);
|
|
|
+
|
|
|
+static struct platform_device da850_sata_device = {
|
|
|
+ .name = "ahci",
|
|
|
+ .id = -1,
|
|
|
+ .dev = {
|
|
|
+ .platform_data = &da850_sata_pdata,
|
|
|
+ .dma_mask = &da850_sata_dmamask,
|
|
|
+ .coherent_dma_mask = DMA_BIT_MASK(32),
|
|
|
+ },
|
|
|
+ .num_resources = ARRAY_SIZE(da850_sata_resources),
|
|
|
+ .resource = da850_sata_resources,
|
|
|
+};
|
|
|
+
|
|
|
+int __init da850_register_sata(unsigned long refclkpn)
|
|
|
+{
|
|
|
+ da850_sata_refclkpn = refclkpn;
|
|
|
+ if (!da850_sata_refclkpn)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return platform_device_register(&da850_sata_device);
|
|
|
+}
|
|
|
+#endif
|