diff options
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r-- | arch/arm/mach-davinci/board-da850-evm.c | 35 | ||||
-rw-r--r-- | arch/arm/mach-davinci/clock.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-davinci/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/da850.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-davinci/devices-da8xx.c | 126 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/clkdev.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/da8xx.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/psc.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-davinci/psc.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-davinci/sleep.S | 6 |
10 files changed, 198 insertions, 24 deletions
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 29671ef0715..008d51407cd 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -115,6 +115,32 @@ static struct spi_board_info da850evm_spi_info[] = { }, }; +#ifdef CONFIG_MTD +static void da850_evm_m25p80_notify_add(struct mtd_info *mtd) +{ + char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; + size_t retlen; + + if (!strcmp(mtd->name, "MAC-Address")) { + mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr); + if (retlen == ETH_ALEN) + pr_info("Read MAC addr from SPI Flash: %pM\n", + mac_addr); + } +} + +static struct mtd_notifier da850evm_spi_notifier = { + .add = da850_evm_m25p80_notify_add, +}; + +static void da850_evm_setup_mac_addr(void) +{ + register_mtd_user(&da850evm_spi_notifier); +} +#else +static void da850_evm_setup_mac_addr(void) { } +#endif + static struct mtd_partition da850_evm_norflash_partition[] = { { .name = "bootloaders + env", @@ -1117,6 +1143,8 @@ static __init int da850_evm_init_cpufreq(void) static __init int da850_evm_init_cpufreq(void) { return 0; } #endif +#define DA850EVM_SATA_REFCLKPN_RATE (100 * 1000 * 1000) + static __init void da850_evm_init(void) { int ret; @@ -1237,6 +1265,13 @@ static __init void da850_evm_init(void) if (ret) pr_warning("da850_evm_init: spi 1 registration failed: %d\n", ret); + + ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE); + if (ret) + pr_warning("da850_evm_init: sata registration failed: %d\n", + ret); + + da850_evm_setup_mac_addr(); } #ifdef CONFIG_SERIAL_8250_CONSOLE diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index ae653194b64..00861139101 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, - PSC_STATE_ENABLE); + true, clk->flags); } static void __clk_disable(struct clk *clk) @@ -54,8 +54,7 @@ static void __clk_disable(struct clk *clk) if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, - (clk->flags & PSC_SWRSTDISABLE) ? - PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); + false, clk->flags); if (clk->parent) __clk_disable(clk->parent); } @@ -239,8 +238,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, - (ck->flags & PSC_SWRSTDISABLE) ? - PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); + false, ck->flags); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 50b2482e0ba..a705f367a84 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -111,6 +111,7 @@ struct clk { #define CLK_PLL BIT(4) /* PLL-derived clock */ #define PRE_PLL BIT(5) /* source is before PLL mult/div */ #define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(7) /* Force module state transtition */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 133aac40585..935dbed5c54 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -58,6 +58,7 @@ static struct pll_data pll0_data = { static struct clk ref_clk = { .name = "ref_clk", .rate = DA850_REF_FREQ, + .set_rate = davinci_simple_set_rate, }; static struct clk pll0_clk = { @@ -373,6 +374,14 @@ static struct clk spi1_clk = { .flags = DA850_CLK_ASYNC3, }; +static struct clk sata_clk = { + .name = "sata", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_SATA, + .gpsc = 1, + .flags = PSC_FORCE, +}; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -419,6 +428,7 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "usb20", &usb20_clk), CLK("spi_davinci.0", NULL, &spi0_clk), CLK("spi_davinci.1", NULL, &spi1_clk), + CLK("ahci", NULL, &sata_clk), CLK(NULL, NULL, NULL), }; diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index fc4e98ea754..2f7e719636f 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -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 diff --git a/arch/arm/mach-davinci/include/mach/clkdev.h b/arch/arm/mach-davinci/include/mach/clkdev.h deleted file mode 100644 index 14a50488718..00000000000 --- a/arch/arm/mach-davinci/include/mach/clkdev.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -struct clk; - -static inline int __clk_get(struct clk *clk) -{ - return 1; -} - -static inline void __clk_put(struct clk *clk) -{ -} - -#endif diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index ad64da713fc..eaca7d8b9d6 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -57,6 +57,7 @@ extern unsigned int da850_max_speed; #define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000) #define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x)) #define DA8XX_DEEPSLEEP_REG 0x8 +#define DA8XX_PWRDN_REG 0x18 #define DA8XX_PSC0_BASE 0x01c10000 #define DA8XX_PLL0_BASE 0x01c11000 @@ -89,6 +90,7 @@ int da850_register_cpufreq(char *async_clk); int da8xx_register_cpuidle(void); void __iomem * __init da8xx_get_mem_ctlr(void); int da850_register_pm(struct platform_device *pdev); +int __init da850_register_sata(unsigned long refclkpn); extern struct platform_device da8xx_serial_device; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 1110fdd77ba..fa59c097223 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -243,13 +243,14 @@ #define PSC_STATE_DISABLE 2 #define PSC_STATE_ENABLE 3 -#define MDSTAT_STATE_MASK 0x1f +#define MDSTAT_STATE_MASK 0x3f +#define MDCTL_FORCE BIT(31) #ifndef __ASSEMBLER__ extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, u32 next_state); + unsigned int id, bool enable, u32 flags); #endif diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index a4158040070..1fb6bdff38c 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -25,6 +25,8 @@ #include <mach/cputype.h> #include <mach/psc.h> +#include "clock.h" + /* Return nonzero iff the domain's clock is active */ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) { @@ -48,11 +50,12 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) /* Enable or disable a PSC domain */ void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, u32 next_state) + unsigned int id, bool enable, u32 flags) { u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; + u32 next_state = PSC_STATE_ENABLE; if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { pr_warning("PSC: Bad psc data: 0x%x[%d]\n", @@ -62,9 +65,18 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); + if (!enable) { + if (flags & PSC_SWRSTDISABLE) + next_state = PSC_STATE_SWRSTDISABLE; + else + next_state = PSC_STATE_DISABLE; + } + mdctl = __raw_readl(psc_base + MDCTL + 4 * id); mdctl &= ~MDSTAT_STATE_MASK; mdctl |= next_state; + if (flags & PSC_FORCE) + mdctl |= MDCTL_FORCE; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); pdstat = __raw_readl(psc_base + PDSTAT); diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index fb5e72b532b..5f1e045a3ad 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -217,7 +217,11 @@ ddr2clk_stop_done: ENDPROC(davinci_ddr_psc_config) CACHE_FLUSH: - .word arm926_flush_kern_cache_all +#ifdef CONFIG_CPU_V6 + .word v6_flush_kern_cache_all +#else + .word arm926_flush_kern_cache_all +#endif ENTRY(davinci_cpu_suspend_sz) .word . - davinci_cpu_suspend |