ARM: 32-bit SoC platform updates
Most of the SoC updates in this cycle are cleanups and moves to more modern infrastructure: - Davinci was moved to common clock framework - OMAP1-based Amstrad E3 "Superphone" saw a bunch of cleanups to the keyboard interface (bitbanged AT keyboard via GPIO). - Removal of some stale code for Renesas platforms - Power management improvements for i.MX6LL -----BEGIN PGP SIGNATURE----- iQJDBAABCAAtFiEElf+HevZ4QCAJmMQ+jBrnPN6EHHcFAlt+Lh0PHG9sb2ZAbGl4 b20ubmV0AAoJEIwa5zzehBx3Y+YP/2QVT1T1/Fz3WsuLg7BYa6r51BDxvr/pSQKh eqLhZCcI5RpOlW4noWgJXWqnX2AlR1vX6xe0W0ebj177ttUHmidUQUJCpwP39AGE LrVC2+mlFb3uPx0HlpHsx3zFZdNFfrhl5mN3JbZfnLv0fUibVEhR+K8ii7MV1/Fk Lbo9sVPT8GIJuU6uyTTUnsCufwCkARMhrYbO6cbtS0FCO77a5aHp7btvHZ2ykxwh hG9CI3FhfAP3Tkpm+IbHkC5jYQNRewQoqthzJ4WJbRrcdA/vaArBTOUoZG4NFMOM M3B4jd1x26llmQhUqH4kGeOZiQ714GPrKcGS+8w7Twj5sIRGDxpif2Ac0kKL2B8X Ps6UTM0cb63W9I+TphjLysKSarNjR2lVVhNVoJ8P47MSyDGIRpSR7+IWvlJ7U8vz 1yMWCguwrwZH3DnQb8UINTfI1Y1RstmtO5v8paSqfJyFX5r64x6VfYso1fRzxyFE 4r2TS0HRv117aKkHwY8smjielZ0CpGnyEDQgq9Z72V4FueIqsJQrA3oGYXgTArFl mLL+fJUdwPv00nWuAZ8q0wIj1NvJvksJy+cObZXL6HK9m3cSdYwOHipdG86k20S5 6/KMPmgrMbV9YO3lVtfJZjdu2QTBiYVBPGfsiSo5lVL5Q5rDYV9QBijnE+9W9/yT tJ038MhK =ACVk -----END PGP SIGNATURE----- Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull ARM 32-bit SoC platform updates from Olof Johansson: "Most of the SoC updates in this cycle are cleanups and moves to more modern infrastructure: - Davinci was moved to common clock framework - OMAP1-based Amstrad E3 "Superphone" saw a bunch of cleanups to the keyboard interface (bitbanged AT keyboard via GPIO). - Removal of some stale code for Renesas platforms - Power management improvements for i.MX6LL" * tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (112 commits) ARM: uniphier: select RESET_CONTROLLER arm64: uniphier: select RESET_CONTROLLER ARM: uniphier: remove empty Makefile ARM: exynos: Clear global variable on init error path ARM: exynos: Remove outdated maintainer information ARM: shmobile: Always enable ARCH_TIMER on SoCs with A7 and/or A15 ARM: shmobile: r8a7779: hide unused r8a7779_platform_cpu_kill soc: r9a06g032: don't build SMP files for non-SMP config ARM: shmobile: Add the R9A06G032 SMP enabler driver ARM: at91: pm: configure wakeup sources for ULP1 mode ARM: at91: pm: add PMC fast startup registers defines ARM: at91: pm: Add ULP1 mode support ARM: at91: pm: Use ULP0 naming instead of slow clock ARM: hisi: handle of_iomap and fix missing of_node_put ARM: hisi: check of_iomap and fix missing of_node_put ARM: hisi: fix error handling and missing of_node_put ARM: mx5: Set the DBGEN bit in ARM_GPC register ARM: imx51: Configure M4IF to avoid visual artifacts ARM: imx: call imx6sx_cpuidle_init() conditionally for 6sll ARM: imx: fix i.MX6SLL build ...hifive-unleashed-5.1
commit
9e259f9352
16
MAINTAINERS
16
MAINTAINERS
|
@ -1295,11 +1295,6 @@ F: arch/arm/mach-aspeed/
|
||||||
F: arch/arm/boot/dts/aspeed-*
|
F: arch/arm/boot/dts/aspeed-*
|
||||||
N: aspeed
|
N: aspeed
|
||||||
|
|
||||||
ARM/ATMEL AT91 Clock Support
|
|
||||||
M: Boris Brezillon <boris.brezillon@bootlin.com>
|
|
||||||
S: Maintained
|
|
||||||
F: drivers/clk/at91
|
|
||||||
|
|
||||||
ARM/CALXEDA HIGHBANK ARCHITECTURE
|
ARM/CALXEDA HIGHBANK ARCHITECTURE
|
||||||
M: Rob Herring <robh@kernel.org>
|
M: Rob Herring <robh@kernel.org>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
@ -1481,6 +1476,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
|
||||||
F: arch/arm/mach-imx/*vf610*
|
F: arch/arm/mach-imx/*vf610*
|
||||||
F: arch/arm/boot/dts/vf*
|
F: arch/arm/boot/dts/vf*
|
||||||
|
|
||||||
|
ARM/FREESCALE LAYERSCAPE ARM ARCHITECTURE
|
||||||
|
M: Shawn Guo <shawnguo@kernel.org>
|
||||||
|
M: Li Yang <leoyang.li@nxp.com>
|
||||||
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
S: Maintained
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
|
||||||
|
F: arch/arm/boot/dts/ls1021a*
|
||||||
|
F: arch/arm64/boot/dts/freescale/fsl-*
|
||||||
|
F: arch/arm64/boot/dts/freescale/qoriq-*
|
||||||
|
|
||||||
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
|
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
|
||||||
M: Lennert Buytenhek <kernel@wantstofly.org>
|
M: Lennert Buytenhek <kernel@wantstofly.org>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
@ -10571,6 +10576,7 @@ F: arch/arm/plat-omap/
|
||||||
F: arch/arm/configs/omap1_defconfig
|
F: arch/arm/configs/omap1_defconfig
|
||||||
F: drivers/i2c/busses/i2c-omap.c
|
F: drivers/i2c/busses/i2c-omap.c
|
||||||
F: include/linux/platform_data/i2c-omap.h
|
F: include/linux/platform_data/i2c-omap.h
|
||||||
|
F: include/linux/platform_data/ams-delta-fiq.h
|
||||||
|
|
||||||
OMAP2+ SUPPORT
|
OMAP2+ SUPPORT
|
||||||
M: Tony Lindgren <tony@atomide.com>
|
M: Tony Lindgren <tony@atomide.com>
|
||||||
|
|
|
@ -603,13 +603,16 @@ config ARCH_S3C24XX
|
||||||
config ARCH_DAVINCI
|
config ARCH_DAVINCI
|
||||||
bool "TI DaVinci"
|
bool "TI DaVinci"
|
||||||
select ARCH_HAS_HOLES_MEMORYMODEL
|
select ARCH_HAS_HOLES_MEMORYMODEL
|
||||||
select CLKDEV_LOOKUP
|
select COMMON_CLK
|
||||||
select CPU_ARM926T
|
select CPU_ARM926T
|
||||||
select GENERIC_ALLOCATOR
|
select GENERIC_ALLOCATOR
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
select GENERIC_IRQ_CHIP
|
select GENERIC_IRQ_CHIP
|
||||||
select GPIOLIB
|
select GPIOLIB
|
||||||
select HAVE_IDE
|
select HAVE_IDE
|
||||||
|
select PM_GENERIC_DOMAINS if PM
|
||||||
|
select PM_GENERIC_DOMAINS_OF if PM && OF
|
||||||
|
select RESET_CONTROLLER
|
||||||
select USE_OF
|
select USE_OF
|
||||||
select ZONE_DMA
|
select ZONE_DMA
|
||||||
help
|
help
|
||||||
|
|
|
@ -204,6 +204,14 @@ choice
|
||||||
depends on ARCH_BCM_HR2
|
depends on ARCH_BCM_HR2
|
||||||
select DEBUG_UART_8250
|
select DEBUG_UART_8250
|
||||||
|
|
||||||
|
config DEBUG_BCM_IPROC_UART3
|
||||||
|
bool "Kernel low-level debugging on BCM IPROC UART3"
|
||||||
|
depends on ARCH_BCM_CYGNUS
|
||||||
|
select DEBUG_UART_8250
|
||||||
|
help
|
||||||
|
Say Y here if you want the debug print routines to direct
|
||||||
|
their output to the third serial port on these devices.
|
||||||
|
|
||||||
config DEBUG_BCM_KONA_UART
|
config DEBUG_BCM_KONA_UART
|
||||||
bool "Kernel low-level debugging messages via BCM KONA UART"
|
bool "Kernel low-level debugging messages via BCM KONA UART"
|
||||||
depends on ARCH_BCM_MOBILE
|
depends on ARCH_BCM_MOBILE
|
||||||
|
@ -1562,14 +1570,15 @@ config DEBUG_UART_PHYS
|
||||||
default 0x18000400 if DEBUG_BCM_HR2
|
default 0x18000400 if DEBUG_BCM_HR2
|
||||||
default 0x18010000 if DEBUG_SIRFATLAS7_UART0
|
default 0x18010000 if DEBUG_SIRFATLAS7_UART0
|
||||||
default 0x18020000 if DEBUG_SIRFATLAS7_UART1
|
default 0x18020000 if DEBUG_SIRFATLAS7_UART1
|
||||||
|
default 0x18023000 if DEBUG_BCM_IPROC_UART3
|
||||||
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
|
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
|
||||||
default 0x20001000 if DEBUG_HIP01_UART
|
default 0x20001000 if DEBUG_HIP01_UART
|
||||||
default 0x20060000 if DEBUG_RK29_UART0
|
default 0x20060000 if DEBUG_RK29_UART0
|
||||||
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
|
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
|
||||||
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
|
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
|
||||||
default 0x20201000 if DEBUG_BCM2835
|
default 0x20201000 if DEBUG_BCM2835
|
||||||
default 0x3f201000 if DEBUG_BCM2836
|
|
||||||
default 0x3e000000 if DEBUG_BCM_KONA_UART
|
default 0x3e000000 if DEBUG_BCM_KONA_UART
|
||||||
|
default 0x3f201000 if DEBUG_BCM2836
|
||||||
default 0x4000e400 if DEBUG_LL_UART_EFM32
|
default 0x4000e400 if DEBUG_LL_UART_EFM32
|
||||||
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
|
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
|
||||||
default 0x40081000 if DEBUG_LPC18XX_UART0
|
default 0x40081000 if DEBUG_LPC18XX_UART0
|
||||||
|
@ -1682,6 +1691,7 @@ config DEBUG_UART_VIRT
|
||||||
default 0xf1002000 if DEBUG_MT8127_UART0
|
default 0xf1002000 if DEBUG_MT8127_UART0
|
||||||
default 0xf1006000 if DEBUG_MT6589_UART0
|
default 0xf1006000 if DEBUG_MT6589_UART0
|
||||||
default 0xf1009000 if DEBUG_MT8135_UART3
|
default 0xf1009000 if DEBUG_MT8135_UART3
|
||||||
|
default 0xf1023000 if DEBUG_BCM_IPROC_UART3
|
||||||
default 0xf11f1000 if DEBUG_VERSATILE
|
default 0xf11f1000 if DEBUG_VERSATILE
|
||||||
default 0xf1600000 if DEBUG_INTEGRATOR
|
default 0xf1600000 if DEBUG_INTEGRATOR
|
||||||
default 0xf1c28000 if DEBUG_SUNXI_UART0
|
default 0xf1c28000 if DEBUG_SUNXI_UART0
|
||||||
|
@ -1797,7 +1807,7 @@ config DEBUG_UART_8250_WORD
|
||||||
DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
|
DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
|
||||||
DEBUG_ALPINE_UART0 || \
|
DEBUG_ALPINE_UART0 || \
|
||||||
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
|
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
|
||||||
DEBUG_DAVINCI_DA8XX_UART2 || \
|
DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_BCM_IPROC_UART3 || \
|
||||||
DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
|
DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
|
||||||
|
|
||||||
config DEBUG_UART_8250_PALMCHIP
|
config DEBUG_UART_8250_PALMCHIP
|
||||||
|
|
|
@ -219,7 +219,6 @@ machine-$(CONFIG_ARCH_TANGO) += tango
|
||||||
machine-$(CONFIG_ARCH_TEGRA) += tegra
|
machine-$(CONFIG_ARCH_TEGRA) += tegra
|
||||||
machine-$(CONFIG_ARCH_U300) += u300
|
machine-$(CONFIG_ARCH_U300) += u300
|
||||||
machine-$(CONFIG_ARCH_U8500) += ux500
|
machine-$(CONFIG_ARCH_U8500) += ux500
|
||||||
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
|
|
||||||
machine-$(CONFIG_ARCH_VERSATILE) += versatile
|
machine-$(CONFIG_ARCH_VERSATILE) += versatile
|
||||||
machine-$(CONFIG_ARCH_VEXPRESS) += vexpress
|
machine-$(CONFIG_ARCH_VEXPRESS) += vexpress
|
||||||
machine-$(CONFIG_ARCH_VT8500) += vt8500
|
machine-$(CONFIG_ARCH_VT8500) += vt8500
|
||||||
|
|
|
@ -31,21 +31,25 @@
|
||||||
|
|
||||||
static unsigned long cpu_boot_addr;
|
static unsigned long cpu_boot_addr;
|
||||||
|
|
||||||
static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
|
static void tf_generic_smc(u32 type, u32 arg1, u32 arg2)
|
||||||
{
|
{
|
||||||
|
register u32 r0 asm("r0") = type;
|
||||||
|
register u32 r1 asm("r1") = arg1;
|
||||||
|
register u32 r2 asm("r2") = arg2;
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
".arch_extension sec\n\t"
|
".arch_extension sec\n\t"
|
||||||
"stmfd sp!, {r4 - r11, lr}\n\t"
|
"stmfd sp!, {r4 - r11}\n\t"
|
||||||
__asmeq("%0", "r0")
|
__asmeq("%0", "r0")
|
||||||
__asmeq("%1", "r1")
|
__asmeq("%1", "r1")
|
||||||
__asmeq("%2", "r2")
|
__asmeq("%2", "r2")
|
||||||
"mov r3, #0\n\t"
|
"mov r3, #0\n\t"
|
||||||
"mov r4, #0\n\t"
|
"mov r4, #0\n\t"
|
||||||
"smc #0\n\t"
|
"smc #0\n\t"
|
||||||
"ldmfd sp!, {r4 - r11, pc}"
|
"ldmfd sp!, {r4 - r11}\n\t"
|
||||||
:
|
:
|
||||||
: "r" (type), "r" (arg1), "r" (arg2)
|
: "r" (r0), "r" (r1), "r" (r2)
|
||||||
: "memory");
|
: "memory", "r3", "r12", "lr");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
|
static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Renesas SCIF(A) debugging macro include header
|
* Renesas SCIF(A) debugging macro include header
|
||||||
*
|
*
|
||||||
|
@ -5,10 +6,6 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2013 Renesas Electronics Corporation
|
* Copyright (C) 2012-2013 Renesas Electronics Corporation
|
||||||
* Copyright (C) 1994-1999 Russell King
|
* Copyright (C) 1994-1999 Russell King
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SCIF_PHYS CONFIG_DEBUG_UART_PHYS
|
#define SCIF_PHYS CONFIG_DEBUG_UART_PHYS
|
||||||
|
|
|
@ -40,15 +40,16 @@ extern void at91_pinctrl_gpio_resume(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const match_table_t pm_modes __initconst = {
|
static const match_table_t pm_modes __initconst = {
|
||||||
{ 0, "standby" },
|
{ AT91_PM_STANDBY, "standby" },
|
||||||
{ AT91_PM_SLOW_CLOCK, "ulp0" },
|
{ AT91_PM_ULP0, "ulp0" },
|
||||||
|
{ AT91_PM_ULP1, "ulp1" },
|
||||||
{ AT91_PM_BACKUP, "backup" },
|
{ AT91_PM_BACKUP, "backup" },
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct at91_pm_data pm_data = {
|
static struct at91_pm_data pm_data = {
|
||||||
.standby_mode = 0,
|
.standby_mode = AT91_PM_STANDBY,
|
||||||
.suspend_mode = AT91_PM_SLOW_CLOCK,
|
.suspend_mode = AT91_PM_ULP0,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define at91_ramc_read(id, field) \
|
#define at91_ramc_read(id, field) \
|
||||||
|
@ -79,6 +80,90 @@ static struct at91_pm_bu {
|
||||||
phys_addr_t resume;
|
phys_addr_t resume;
|
||||||
} *pm_bu;
|
} *pm_bu;
|
||||||
|
|
||||||
|
struct wakeup_source_info {
|
||||||
|
unsigned int pmc_fsmr_bit;
|
||||||
|
unsigned int shdwc_mr_bit;
|
||||||
|
bool set_polarity;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wakeup_source_info ws_info[] = {
|
||||||
|
{ .pmc_fsmr_bit = AT91_PMC_FSTT(10), .set_polarity = true },
|
||||||
|
{ .pmc_fsmr_bit = AT91_PMC_RTCAL, .shdwc_mr_bit = BIT(17) },
|
||||||
|
{ .pmc_fsmr_bit = AT91_PMC_USBAL },
|
||||||
|
{ .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id sama5d2_ws_ids[] = {
|
||||||
|
{ .compatible = "atmel,sama5d2-gem", .data = &ws_info[0] },
|
||||||
|
{ .compatible = "atmel,at91rm9200-rtc", .data = &ws_info[1] },
|
||||||
|
{ .compatible = "atmel,sama5d3-udc", .data = &ws_info[2] },
|
||||||
|
{ .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] },
|
||||||
|
{ .compatible = "usb-ohci", .data = &ws_info[2] },
|
||||||
|
{ .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] },
|
||||||
|
{ .compatible = "usb-ehci", .data = &ws_info[2] },
|
||||||
|
{ .compatible = "atmel,sama5d2-sdhci", .data = &ws_info[3] },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int at91_pm_config_ws(unsigned int pm_mode, bool set)
|
||||||
|
{
|
||||||
|
const struct wakeup_source_info *wsi;
|
||||||
|
const struct of_device_id *match;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
struct device_node *np;
|
||||||
|
unsigned int mode = 0, polarity = 0, val = 0;
|
||||||
|
|
||||||
|
if (pm_mode != AT91_PM_ULP1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!pm_data.pmc || !pm_data.shdwc)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (!set) {
|
||||||
|
writel(mode, pm_data.pmc + AT91_PMC_FSMR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SHDWC.WUIR */
|
||||||
|
val = readl(pm_data.shdwc + 0x0c);
|
||||||
|
mode |= (val & 0x3ff);
|
||||||
|
polarity |= ((val >> 16) & 0x3ff);
|
||||||
|
|
||||||
|
/* SHDWC.MR */
|
||||||
|
val = readl(pm_data.shdwc + 0x04);
|
||||||
|
|
||||||
|
/* Loop through defined wakeup sources. */
|
||||||
|
for_each_matching_node_and_match(np, sama5d2_ws_ids, &match) {
|
||||||
|
pdev = of_find_device_by_node(np);
|
||||||
|
if (!pdev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (device_may_wakeup(&pdev->dev)) {
|
||||||
|
wsi = match->data;
|
||||||
|
|
||||||
|
/* Check if enabled on SHDWC. */
|
||||||
|
if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit))
|
||||||
|
goto put_node;
|
||||||
|
|
||||||
|
mode |= wsi->pmc_fsmr_bit;
|
||||||
|
if (wsi->set_polarity)
|
||||||
|
polarity |= wsi->pmc_fsmr_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
put_node:
|
||||||
|
of_node_put(np);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
writel(mode, pm_data.pmc + AT91_PMC_FSMR);
|
||||||
|
writel(polarity, pm_data.pmc + AT91_PMC_FSPR);
|
||||||
|
} else {
|
||||||
|
pr_err("AT91: PM: no ULP1 wakeup sources found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode ? 0 : -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after processes are frozen, but before we shutdown devices.
|
* Called after processes are frozen, but before we shutdown devices.
|
||||||
*/
|
*/
|
||||||
|
@ -97,7 +182,7 @@ static int at91_pm_begin(suspend_state_t state)
|
||||||
pm_data.mode = -1;
|
pm_data.mode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return at91_pm_config_ws(pm_data.mode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -145,7 +230,7 @@ static int at91_pm_verify_clocks(void)
|
||||||
*/
|
*/
|
||||||
int at91_suspend_entering_slow_clock(void)
|
int at91_suspend_entering_slow_clock(void)
|
||||||
{
|
{
|
||||||
return (pm_data.mode >= AT91_PM_SLOW_CLOCK);
|
return (pm_data.mode >= AT91_PM_ULP0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
|
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
|
||||||
|
|
||||||
|
@ -186,7 +271,7 @@ static void at91_pm_suspend(suspend_state_t state)
|
||||||
* event sources; and reduces DRAM power. But otherwise it's identical to
|
* event sources; and reduces DRAM power. But otherwise it's identical to
|
||||||
* PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks.
|
* PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks.
|
||||||
*
|
*
|
||||||
* AT91_PM_SLOW_CLOCK is like STANDBY plus slow clock mode, so drivers must
|
* AT91_PM_ULP0 is like STANDBY plus slow clock mode, so drivers must
|
||||||
* suspend more deeply, the master clock switches to the clk32k and turns off
|
* suspend more deeply, the master clock switches to the clk32k and turns off
|
||||||
* the main oscillator
|
* the main oscillator
|
||||||
*
|
*
|
||||||
|
@ -204,7 +289,7 @@ static int at91_pm_enter(suspend_state_t state)
|
||||||
/*
|
/*
|
||||||
* Ensure that clocks are in a valid state.
|
* Ensure that clocks are in a valid state.
|
||||||
*/
|
*/
|
||||||
if ((pm_data.mode >= AT91_PM_SLOW_CLOCK) &&
|
if (pm_data.mode >= AT91_PM_ULP0 &&
|
||||||
!at91_pm_verify_clocks())
|
!at91_pm_verify_clocks())
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -233,6 +318,7 @@ error:
|
||||||
*/
|
*/
|
||||||
static void at91_pm_end(void)
|
static void at91_pm_end(void)
|
||||||
{
|
{
|
||||||
|
at91_pm_config_ws(pm_data.mode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -478,31 +564,28 @@ static void __init at91_pm_sram_init(void)
|
||||||
&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
|
&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init at91_pm_backup_init(void)
|
static bool __init at91_is_pm_mode_active(int pm_mode)
|
||||||
|
{
|
||||||
|
return (pm_data.standby_mode == pm_mode ||
|
||||||
|
pm_data.suspend_mode == pm_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init at91_pm_backup_init(void)
|
||||||
{
|
{
|
||||||
struct gen_pool *sram_pool;
|
struct gen_pool *sram_pool;
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
struct platform_device *pdev = NULL;
|
struct platform_device *pdev = NULL;
|
||||||
|
int ret = -ENODEV;
|
||||||
|
|
||||||
if ((pm_data.standby_mode != AT91_PM_BACKUP) &&
|
if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
|
||||||
(pm_data.suspend_mode != AT91_PM_BACKUP))
|
return 0;
|
||||||
return;
|
|
||||||
|
|
||||||
pm_bu = NULL;
|
pm_bu = NULL;
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
|
|
||||||
if (!np) {
|
|
||||||
pr_warn("%s: failed to find shdwc!\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_data.shdwc = of_iomap(np, 0);
|
|
||||||
of_node_put(np);
|
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
|
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
|
||||||
if (!np) {
|
if (!np) {
|
||||||
pr_warn("%s: failed to find sfrbu!\n", __func__);
|
pr_warn("%s: failed to find sfrbu!\n", __func__);
|
||||||
goto sfrbu_fail;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_data.sfrbu = of_iomap(np, 0);
|
pm_data.sfrbu = of_iomap(np, 0);
|
||||||
|
@ -529,6 +612,7 @@ static void __init at91_pm_backup_init(void)
|
||||||
pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
|
pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
|
||||||
if (!pm_bu) {
|
if (!pm_bu) {
|
||||||
pr_warn("%s: unable to alloc securam!\n", __func__);
|
pr_warn("%s: unable to alloc securam!\n", __func__);
|
||||||
|
ret = -ENOMEM;
|
||||||
goto securam_fail;
|
goto securam_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,19 +620,60 @@ static void __init at91_pm_backup_init(void)
|
||||||
pm_bu->canary = __pa_symbol(&canary);
|
pm_bu->canary = __pa_symbol(&canary);
|
||||||
pm_bu->resume = __pa_symbol(cpu_resume);
|
pm_bu->resume = __pa_symbol(cpu_resume);
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
sfrbu_fail:
|
|
||||||
iounmap(pm_data.shdwc);
|
|
||||||
pm_data.shdwc = NULL;
|
|
||||||
securam_fail:
|
securam_fail:
|
||||||
iounmap(pm_data.sfrbu);
|
iounmap(pm_data.sfrbu);
|
||||||
pm_data.sfrbu = NULL;
|
pm_data.sfrbu = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (pm_data.standby_mode == AT91_PM_BACKUP)
|
static void __init at91_pm_use_default_mode(int pm_mode)
|
||||||
pm_data.standby_mode = AT91_PM_SLOW_CLOCK;
|
{
|
||||||
if (pm_data.suspend_mode == AT91_PM_BACKUP)
|
if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
|
||||||
pm_data.suspend_mode = AT91_PM_SLOW_CLOCK;
|
return;
|
||||||
|
|
||||||
|
if (pm_data.standby_mode == pm_mode)
|
||||||
|
pm_data.standby_mode = AT91_PM_ULP0;
|
||||||
|
if (pm_data.suspend_mode == pm_mode)
|
||||||
|
pm_data.suspend_mode = AT91_PM_ULP0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init at91_pm_modes_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!at91_is_pm_mode_active(AT91_PM_BACKUP) &&
|
||||||
|
!at91_is_pm_mode_active(AT91_PM_ULP1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
|
||||||
|
if (!np) {
|
||||||
|
pr_warn("%s: failed to find shdwc!\n", __func__);
|
||||||
|
goto ulp1_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_data.shdwc = of_iomap(np, 0);
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
ret = at91_pm_backup_init();
|
||||||
|
if (ret) {
|
||||||
|
if (!at91_is_pm_mode_active(AT91_PM_ULP1))
|
||||||
|
goto unmap;
|
||||||
|
else
|
||||||
|
goto backup_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
unmap:
|
||||||
|
iounmap(pm_data.shdwc);
|
||||||
|
pm_data.shdwc = NULL;
|
||||||
|
ulp1_default:
|
||||||
|
at91_pm_use_default_mode(AT91_PM_ULP1);
|
||||||
|
backup_default:
|
||||||
|
at91_pm_use_default_mode(AT91_PM_BACKUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pmc_info {
|
struct pmc_info {
|
||||||
|
@ -644,7 +769,7 @@ void __init sama5d2_pm_init(void)
|
||||||
if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
|
if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
at91_pm_backup_init();
|
at91_pm_modes_init();
|
||||||
sama5_pm_init();
|
sama5_pm_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,10 @@
|
||||||
#define AT91_MEMCTRL_SDRAMC 1
|
#define AT91_MEMCTRL_SDRAMC 1
|
||||||
#define AT91_MEMCTRL_DDRSDR 2
|
#define AT91_MEMCTRL_DDRSDR 2
|
||||||
|
|
||||||
#define AT91_PM_SLOW_CLOCK 0x01
|
#define AT91_PM_STANDBY 0x00
|
||||||
#define AT91_PM_BACKUP 0x02
|
#define AT91_PM_ULP0 0x01
|
||||||
|
#define AT91_PM_ULP1 0x02
|
||||||
|
#define AT91_PM_BACKUP 0x03
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
struct at91_pm_data {
|
struct at91_pm_data {
|
||||||
|
|
|
@ -41,6 +41,15 @@ tmp2 .req r5
|
||||||
beq 1b
|
beq 1b
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for main oscillator selection is done
|
||||||
|
*/
|
||||||
|
.macro wait_moscsels
|
||||||
|
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||||
|
tst tmp1, #AT91_PMC_MOSCSELS
|
||||||
|
beq 1b
|
||||||
|
.endm
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until PLLA has locked.
|
* Wait until PLLA has locked.
|
||||||
*/
|
*/
|
||||||
|
@ -112,19 +121,20 @@ ENTRY(at91_pm_suspend_in_sram)
|
||||||
bl at91_sramc_self_refresh
|
bl at91_sramc_self_refresh
|
||||||
|
|
||||||
ldr r0, .pm_mode
|
ldr r0, .pm_mode
|
||||||
cmp r0, #AT91_PM_SLOW_CLOCK
|
cmp r0, #AT91_PM_STANDBY
|
||||||
beq slow_clock
|
beq standby
|
||||||
cmp r0, #AT91_PM_BACKUP
|
cmp r0, #AT91_PM_BACKUP
|
||||||
beq backup_mode
|
beq backup_mode
|
||||||
|
|
||||||
|
bl at91_ulp_mode
|
||||||
|
b exit_suspend
|
||||||
|
|
||||||
|
standby:
|
||||||
/* Wait for interrupt */
|
/* Wait for interrupt */
|
||||||
ldr pmc, .pmc_base
|
ldr pmc, .pmc_base
|
||||||
at91_cpu_idle
|
at91_cpu_idle
|
||||||
b exit_suspend
|
b exit_suspend
|
||||||
|
|
||||||
slow_clock:
|
|
||||||
bl at91_slowck_mode
|
|
||||||
b exit_suspend
|
|
||||||
backup_mode:
|
backup_mode:
|
||||||
bl at91_backup_mode
|
bl at91_backup_mode
|
||||||
b exit_suspend
|
b exit_suspend
|
||||||
|
@ -151,7 +161,102 @@ ENTRY(at91_backup_mode)
|
||||||
str tmp1, [r0, #0]
|
str tmp1, [r0, #0]
|
||||||
ENDPROC(at91_backup_mode)
|
ENDPROC(at91_backup_mode)
|
||||||
|
|
||||||
ENTRY(at91_slowck_mode)
|
.macro at91_pm_ulp0_mode
|
||||||
|
ldr pmc, .pmc_base
|
||||||
|
|
||||||
|
/* Turn off the crystal oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
/* Wait for interrupt */
|
||||||
|
at91_cpu_idle
|
||||||
|
|
||||||
|
/* Turn on the crystal oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
wait_moscrdy
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: This procedure only applies on the platform which uses
|
||||||
|
* the external crystal oscillator as a main clock source.
|
||||||
|
*/
|
||||||
|
.macro at91_pm_ulp1_mode
|
||||||
|
ldr pmc, .pmc_base
|
||||||
|
|
||||||
|
/* Switch the main clock source to 12-MHz RC oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_MOSCSEL
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
wait_moscsels
|
||||||
|
|
||||||
|
/* Disable the crystal oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
/* Switch the master clock source to main clock */
|
||||||
|
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||||
|
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
|
||||||
|
wait_mckrdy
|
||||||
|
|
||||||
|
/* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_WAITMODE
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
wait_mckrdy
|
||||||
|
|
||||||
|
/* Enable the crystal oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
wait_moscrdy
|
||||||
|
|
||||||
|
/* Switch the master clock source to slow clock */
|
||||||
|
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||||
|
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
|
||||||
|
wait_mckrdy
|
||||||
|
|
||||||
|
/* Switch main clock source to crystal oscillator */
|
||||||
|
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_MOSCSEL
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||||
|
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||||
|
|
||||||
|
wait_moscsels
|
||||||
|
|
||||||
|
/* Switch the master clock source to main clock */
|
||||||
|
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||||
|
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||||
|
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||||
|
|
||||||
|
wait_mckrdy
|
||||||
|
.endm
|
||||||
|
|
||||||
|
ENTRY(at91_ulp_mode)
|
||||||
ldr pmc, .pmc_base
|
ldr pmc, .pmc_base
|
||||||
|
|
||||||
/* Save Master clock setting */
|
/* Save Master clock setting */
|
||||||
|
@ -174,22 +279,19 @@ ENTRY(at91_slowck_mode)
|
||||||
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
||||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||||
|
|
||||||
/* Turn off the main oscillator */
|
ldr r0, .pm_mode
|
||||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
cmp r0, #AT91_PM_ULP1
|
||||||
bic tmp1, tmp1, #AT91_PMC_MOSCEN
|
beq ulp1_mode
|
||||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
|
||||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
|
||||||
|
|
||||||
/* Wait for interrupt */
|
at91_pm_ulp0_mode
|
||||||
at91_cpu_idle
|
b ulp_exit
|
||||||
|
|
||||||
/* Turn on the main oscillator */
|
ulp1_mode:
|
||||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
at91_pm_ulp1_mode
|
||||||
orr tmp1, tmp1, #AT91_PMC_MOSCEN
|
b ulp_exit
|
||||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
|
||||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
|
||||||
|
|
||||||
wait_moscrdy
|
ulp_exit:
|
||||||
|
ldr pmc, .pmc_base
|
||||||
|
|
||||||
/* Restore PLLA setting */
|
/* Restore PLLA setting */
|
||||||
ldr tmp1, .saved_pllar
|
ldr tmp1, .saved_pllar
|
||||||
|
@ -212,7 +314,7 @@ ENTRY(at91_slowck_mode)
|
||||||
wait_mckrdy
|
wait_mckrdy
|
||||||
|
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
ENDPROC(at91_slowck_mode)
|
ENDPROC(at91_ulp_mode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void at91_sramc_self_refresh(unsigned int is_active)
|
* void at91_sramc_self_refresh(unsigned int is_active)
|
||||||
|
|
|
@ -59,6 +59,7 @@ config MACH_DA8XX_DT
|
||||||
default y
|
default y
|
||||||
depends on ARCH_DAVINCI_DA850
|
depends on ARCH_DAVINCI_DA850
|
||||||
select PINCTRL
|
select PINCTRL
|
||||||
|
select TIMER_OF
|
||||||
help
|
help
|
||||||
Say y here to include support for TI DaVinci DA850 based using
|
Say y here to include support for TI DaVinci DA850 based using
|
||||||
Flattened Device Tree. More information at Documentation/devicetree
|
Flattened Device Tree. More information at Documentation/devicetree
|
||||||
|
@ -231,18 +232,6 @@ config DAVINCI_MUX_WARNINGS
|
||||||
to change the pin multiplexing setup. When there are no warnings
|
to change the pin multiplexing setup. When there are no warnings
|
||||||
printed, it's safe to deselect DAVINCI_MUX for your product.
|
printed, it's safe to deselect DAVINCI_MUX for your product.
|
||||||
|
|
||||||
config DAVINCI_RESET_CLOCKS
|
|
||||||
bool "Reset unused clocks during boot"
|
|
||||||
depends on ARCH_DAVINCI
|
|
||||||
help
|
|
||||||
Say Y if you want to reset unused clocks during boot.
|
|
||||||
This option saves power, but assumes all drivers are
|
|
||||||
using the clock framework. Broken drivers that do not
|
|
||||||
yet use clock framework may not work with this option.
|
|
||||||
If you are booting from another operating system, you
|
|
||||||
probably do not want this option enabled until your
|
|
||||||
device drivers work properly.
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# Common objects
|
# Common objects
|
||||||
obj-y := time.o clock.o serial.o psc.o \
|
obj-y := time.o serial.o usb.o \
|
||||||
usb.o common.o sram.o aemif.o
|
common.o sram.o
|
||||||
|
|
||||||
obj-$(CONFIG_DAVINCI_MUX) += mux.o
|
obj-$(CONFIG_DAVINCI_MUX) += mux.o
|
||||||
|
|
||||||
|
|
|
@ -1,218 +0,0 @@
|
||||||
/*
|
|
||||||
* AEMIF support for DaVinci SoCs
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
|
|
||||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
|
||||||
#include <linux/platform_data/mtd-davinci.h>
|
|
||||||
|
|
||||||
/* Timing value configuration */
|
|
||||||
|
|
||||||
#define TA(x) ((x) << 2)
|
|
||||||
#define RHOLD(x) ((x) << 4)
|
|
||||||
#define RSTROBE(x) ((x) << 7)
|
|
||||||
#define RSETUP(x) ((x) << 13)
|
|
||||||
#define WHOLD(x) ((x) << 17)
|
|
||||||
#define WSTROBE(x) ((x) << 20)
|
|
||||||
#define WSETUP(x) ((x) << 26)
|
|
||||||
|
|
||||||
#define TA_MAX 0x3
|
|
||||||
#define RHOLD_MAX 0x7
|
|
||||||
#define RSTROBE_MAX 0x3f
|
|
||||||
#define RSETUP_MAX 0xf
|
|
||||||
#define WHOLD_MAX 0x7
|
|
||||||
#define WSTROBE_MAX 0x3f
|
|
||||||
#define WSETUP_MAX 0xf
|
|
||||||
|
|
||||||
#define TIMING_MASK (TA(TA_MAX) | \
|
|
||||||
RHOLD(RHOLD_MAX) | \
|
|
||||||
RSTROBE(RSTROBE_MAX) | \
|
|
||||||
RSETUP(RSETUP_MAX) | \
|
|
||||||
WHOLD(WHOLD_MAX) | \
|
|
||||||
WSTROBE(WSTROBE_MAX) | \
|
|
||||||
WSETUP(WSETUP_MAX))
|
|
||||||
|
|
||||||
static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset)
|
|
||||||
{
|
|
||||||
return readl_relaxed(base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void davinci_aemif_writel(void __iomem *base,
|
|
||||||
int offset, unsigned long value)
|
|
||||||
{
|
|
||||||
writel_relaxed(value, base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* aemif_calc_rate - calculate timing data.
|
|
||||||
* @wanted: The cycle time needed in nanoseconds.
|
|
||||||
* @clk: The input clock rate in kHz.
|
|
||||||
* @max: The maximum divider value that can be programmed.
|
|
||||||
*
|
|
||||||
* On success, returns the calculated timing value minus 1 for easy
|
|
||||||
* programming into AEMIF timing registers, else negative errno.
|
|
||||||
*/
|
|
||||||
static int aemif_calc_rate(int wanted, unsigned long clk, int max)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
|
|
||||||
|
|
||||||
pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
|
|
||||||
|
|
||||||
/* It is generally OK to have a more relaxed timing than requested... */
|
|
||||||
if (result < 0)
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
/* ... But configuring tighter timings is not an option. */
|
|
||||||
else if (result > max)
|
|
||||||
result = -EINVAL;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
|
|
||||||
* @t: timing values to be progammed
|
|
||||||
* @base: The virtual base address of the AEMIF interface
|
|
||||||
* @cs: chip-select to program the timing values for
|
|
||||||
* @clkrate: the AEMIF clkrate
|
|
||||||
*
|
|
||||||
* This function programs the given timing values (in real clock) into the
|
|
||||||
* AEMIF registers taking the AEMIF clock into account.
|
|
||||||
*
|
|
||||||
* This function does not use any locking while programming the AEMIF
|
|
||||||
* because it is expected that there is only one user of a given
|
|
||||||
* chip-select.
|
|
||||||
*
|
|
||||||
* Returns 0 on success, else negative errno.
|
|
||||||
*/
|
|
||||||
static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
|
|
||||||
void __iomem *base, unsigned cs,
|
|
||||||
unsigned long clkrate)
|
|
||||||
{
|
|
||||||
unsigned set, val;
|
|
||||||
int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
|
|
||||||
unsigned offset = A1CR_OFFSET + cs * 4;
|
|
||||||
|
|
||||||
if (!t)
|
|
||||||
return 0; /* Nothing to do */
|
|
||||||
|
|
||||||
clkrate /= 1000; /* turn clock into kHz for ease of use */
|
|
||||||
|
|
||||||
ta = aemif_calc_rate(t->ta, clkrate, TA_MAX);
|
|
||||||
rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
|
|
||||||
rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
|
|
||||||
rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
|
|
||||||
whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
|
|
||||||
wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
|
|
||||||
wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
|
|
||||||
|
|
||||||
if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
|
|
||||||
whold < 0 || wstrobe < 0 || wsetup < 0) {
|
|
||||||
pr_err("%s: cannot get suitable timings\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
|
|
||||||
WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
|
|
||||||
|
|
||||||
val = __raw_readl(base + offset);
|
|
||||||
val &= ~TIMING_MASK;
|
|
||||||
val |= set;
|
|
||||||
__raw_writel(val, base + offset);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata
|
|
||||||
* @pdev - link to platform device to setup settings for
|
|
||||||
*
|
|
||||||
* This function does not use any locking while programming the AEMIF
|
|
||||||
* because it is expected that there is only one user of a given
|
|
||||||
* chip-select.
|
|
||||||
*
|
|
||||||
* Returns 0 on success, else negative errno.
|
|
||||||
*/
|
|
||||||
int davinci_aemif_setup(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev);
|
|
||||||
uint32_t val;
|
|
||||||
unsigned long clkrate;
|
|
||||||
struct resource *res;
|
|
||||||
void __iomem *base;
|
|
||||||
struct clk *clk;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
clk = clk_get(&pdev->dev, "aemif");
|
|
||||||
if (IS_ERR(clk)) {
|
|
||||||
ret = PTR_ERR(clk);
|
|
||||||
dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(clk);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
|
|
||||||
ret);
|
|
||||||
goto err_put;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = ioremap(res->start, resource_size(res));
|
|
||||||
if (!base) {
|
|
||||||
dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res);
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup Async configuration register in case we did not boot
|
|
||||||
* from NAND and so bootloader did not bother to set it up.
|
|
||||||
*/
|
|
||||||
val = davinci_aemif_readl(base, A1CR_OFFSET + pdata->core_chipsel * 4);
|
|
||||||
/*
|
|
||||||
* Extended Wait is not valid and Select Strobe mode is not
|
|
||||||
* used
|
|
||||||
*/
|
|
||||||
val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
|
|
||||||
if (pdata->options & NAND_BUSWIDTH_16)
|
|
||||||
val |= 0x1;
|
|
||||||
|
|
||||||
davinci_aemif_writel(base, A1CR_OFFSET + pdata->core_chipsel * 4, val);
|
|
||||||
|
|
||||||
clkrate = clk_get_rate(clk);
|
|
||||||
|
|
||||||
if (pdata->timing)
|
|
||||||
ret = davinci_aemif_setup_timing(pdata->timing, base,
|
|
||||||
pdata->core_chipsel, clkrate);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
|
|
||||||
|
|
||||||
iounmap(base);
|
|
||||||
err:
|
|
||||||
clk_disable_unprepare(clk);
|
|
||||||
err_put:
|
|
||||||
clk_put(clk);
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||||
#include <linux/platform_data/spi-davinci.h>
|
#include <linux/platform_data/spi-davinci.h>
|
||||||
#include <linux/platform_data/usb-davinci.h>
|
#include <linux/platform_data/usb-davinci.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
@ -110,15 +111,9 @@ static __init void da830_evm_usb_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* USB_REFCLKIN is not used. */
|
ret = da8xx_register_usb_phy_clocks();
|
||||||
ret = da8xx_register_usb20_phy_clk(false);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
|
pr_warn("%s: USB PHY CLK registration failed: %d\n",
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
ret = da8xx_register_usb11_phy_clk(false);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
|
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
|
|
||||||
ret = da8xx_register_usb_phy();
|
ret = da8xx_register_usb_phy();
|
||||||
|
@ -339,14 +334,48 @@ static struct resource da830_evm_nand_resources[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device da830_evm_nand_device = {
|
static struct platform_device da830_evm_aemif_devices[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 1,
|
.name = "davinci_nand",
|
||||||
.dev = {
|
.id = 1,
|
||||||
.platform_data = &da830_evm_nand_pdata,
|
.dev = {
|
||||||
|
.platform_data = &da830_evm_nand_pdata,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(da830_evm_nand_resources),
|
||||||
|
.resource = da830_evm_nand_resources,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(da830_evm_nand_resources),
|
};
|
||||||
.resource = da830_evm_nand_resources,
|
|
||||||
|
static struct resource da830_evm_aemif_resource[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_AEMIF_CTL_BASE,
|
||||||
|
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data da830_evm_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data da830_evm_aemif_pdata = {
|
||||||
|
.abus_data = da830_evm_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(da830_evm_aemif_abus_data),
|
||||||
|
.sub_devices = da830_evm_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(da830_evm_aemif_devices),
|
||||||
|
.cs_offset = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da830_evm_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da830_evm_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = da830_evm_aemif_resource,
|
||||||
|
.num_resources = ARRAY_SIZE(da830_evm_aemif_resource),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -377,12 +406,9 @@ static inline void da830_evm_init_nand(int mux_mode)
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: emif25 mux setup failed: %d\n", __func__, ret);
|
pr_warn("%s: emif25 mux setup failed: %d\n", __func__, ret);
|
||||||
|
|
||||||
ret = platform_device_register(&da830_evm_nand_device);
|
ret = platform_device_register(&da830_evm_aemif_device);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: NAND device not registered\n", __func__);
|
pr_warn("%s: AEMIF device not registered\n", __func__);
|
||||||
|
|
||||||
if (davinci_aemif_setup(&da830_evm_nand_device))
|
|
||||||
pr_warn("%s: Cannot configure AEMIF\n", __func__);
|
|
||||||
|
|
||||||
gpio_direction_output(mux_mode, 1);
|
gpio_direction_output(mux_mode, 1);
|
||||||
}
|
}
|
||||||
|
@ -557,6 +583,8 @@ static __init void da830_evm_init(void)
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
da830_register_clocks();
|
||||||
|
|
||||||
ret = da830_register_gpio();
|
ret = da830_register_gpio();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
#include <linux/platform_data/mtd-davinci.h>
|
#include <linux/platform_data/mtd-davinci.h>
|
||||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
#include <linux/platform_data/spi-davinci.h>
|
#include <linux/platform_data/spi-davinci.h>
|
||||||
#include <linux/platform_data/uio_pruss.h>
|
#include <linux/platform_data/uio_pruss.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
|
@ -185,16 +186,6 @@ static struct resource da850_evm_norflash_resource[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device da850_evm_norflash_device = {
|
|
||||||
.name = "physmap-flash",
|
|
||||||
.id = 0,
|
|
||||||
.dev = {
|
|
||||||
.platform_data = &da850_evm_norflash_data,
|
|
||||||
},
|
|
||||||
.num_resources = 1,
|
|
||||||
.resource = da850_evm_norflash_resource,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
|
/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
|
||||||
* (128K blocks). It may be used instead of the (default) SPI flash
|
* (128K blocks). It may be used instead of the (default) SPI flash
|
||||||
* to boot, using TI's tools to install the secondary boot loader
|
* to boot, using TI's tools to install the secondary boot loader
|
||||||
|
@ -266,37 +257,58 @@ static struct resource da850_evm_nandflash_resource[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device da850_evm_nandflash_device = {
|
static struct resource da850_evm_aemif_resource[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 1,
|
.start = DA8XX_AEMIF_CTL_BASE,
|
||||||
.dev = {
|
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
|
||||||
.platform_data = &da850_evm_nandflash_data,
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data da850_evm_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 3,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da850_evm_aemif_devices[] = {
|
||||||
|
{
|
||||||
|
.name = "davinci_nand",
|
||||||
|
.id = 1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_evm_nandflash_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(da850_evm_nandflash_resource),
|
||||||
|
.resource = da850_evm_nandflash_resource,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(da850_evm_nandflash_resource),
|
{
|
||||||
.resource = da850_evm_nandflash_resource,
|
.name = "physmap-flash",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_evm_norflash_data,
|
||||||
|
},
|
||||||
|
.num_resources = 1,
|
||||||
|
.resource = da850_evm_norflash_resource,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device *da850_evm_devices[] = {
|
static struct aemif_platform_data da850_evm_aemif_pdata = {
|
||||||
&da850_evm_nandflash_device,
|
.cs_offset = 2,
|
||||||
&da850_evm_norflash_device,
|
.abus_data = da850_evm_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(da850_evm_aemif_abus_data),
|
||||||
|
.sub_devices = da850_evm_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(da850_evm_aemif_devices),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DA8XX_AEMIF_CE2CFG_OFFSET 0x10
|
static struct platform_device da850_evm_aemif_device = {
|
||||||
#define DA8XX_AEMIF_ASIZE_16BIT 0x1
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
static void __init da850_evm_init_nor(void)
|
.dev = {
|
||||||
{
|
.platform_data = &da850_evm_aemif_pdata,
|
||||||
void __iomem *aemif_addr;
|
},
|
||||||
|
.resource = da850_evm_aemif_resource,
|
||||||
aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
|
.num_resources = ARRAY_SIZE(da850_evm_aemif_resource),
|
||||||
|
};
|
||||||
/* Configure data bus width of CS2 to 16 bit */
|
|
||||||
writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
|
|
||||||
DA8XX_AEMIF_ASIZE_16BIT,
|
|
||||||
aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
|
|
||||||
|
|
||||||
iounmap(aemif_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const short da850_evm_nand_pins[] = {
|
static const short da850_evm_nand_pins[] = {
|
||||||
DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
|
DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
|
||||||
|
@ -339,13 +351,10 @@ static inline void da850_evm_setup_nor_nand(void)
|
||||||
pr_warn("%s: NOR mux setup failed: %d\n",
|
pr_warn("%s: NOR mux setup failed: %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
|
|
||||||
da850_evm_init_nor();
|
ret = platform_device_register(&da850_evm_aemif_device);
|
||||||
|
if (ret)
|
||||||
platform_add_devices(da850_evm_devices,
|
pr_warn("%s: registering aemif failed: %d\n",
|
||||||
ARRAY_SIZE(da850_evm_devices));
|
__func__, ret);
|
||||||
|
|
||||||
if (davinci_aemif_setup(&da850_evm_nandflash_device))
|
|
||||||
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,6 +1349,8 @@ static __init void da850_evm_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
da850_register_clocks();
|
||||||
|
|
||||||
ret = da850_register_gpio();
|
ret = da850_register_gpio();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
|
|
@ -394,6 +394,8 @@ static __init void dm355_evm_init(void)
|
||||||
struct clk *aemif;
|
struct clk *aemif;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dm355_register_clocks();
|
||||||
|
|
||||||
ret = dm355_gpio_register();
|
ret = dm355_gpio_register();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
|
|
@ -234,6 +234,8 @@ static __init void dm355_leopard_init(void)
|
||||||
struct clk *aemif;
|
struct clk *aemif;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dm355_register_clocks();
|
||||||
|
|
||||||
ret = dm355_gpio_register();
|
ret = dm355_gpio_register();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
#include <linux/spi/eeprom.h>
|
#include <linux/spi/eeprom.h>
|
||||||
#include <linux/v4l2-dv-timings.h>
|
#include <linux/v4l2-dv-timings.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
|
@ -159,16 +160,49 @@ static struct resource davinci_nand_resources[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device davinci_nand_device = {
|
static struct platform_device davinci_aemif_devices[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 0,
|
.name = "davinci_nand",
|
||||||
.num_resources = ARRAY_SIZE(davinci_nand_resources),
|
.id = 0,
|
||||||
.resource = davinci_nand_resources,
|
.num_resources = ARRAY_SIZE(davinci_nand_resources),
|
||||||
.dev = {
|
.resource = davinci_nand_resources,
|
||||||
.platform_data = &davinci_nand_data,
|
.dev = {
|
||||||
|
.platform_data = &davinci_nand_data,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource davinci_aemif_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DM365_ASYNC_EMIF_CONTROL_BASE,
|
||||||
|
.end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data da850_evm_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data davinci_aemif_pdata = {
|
||||||
|
.abus_data = da850_evm_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(da850_evm_aemif_abus_data),
|
||||||
|
.sub_devices = davinci_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(davinci_aemif_devices),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device davinci_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &davinci_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = davinci_aemif_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(davinci_aemif_resources),
|
||||||
|
};
|
||||||
|
|
||||||
static struct at24_platform_data eeprom_info = {
|
static struct at24_platform_data eeprom_info = {
|
||||||
.byte_len = (256*1024) / 8,
|
.byte_len = (256*1024) / 8,
|
||||||
.page_size = 64,
|
.page_size = 64,
|
||||||
|
@ -537,10 +571,6 @@ static void __init evm_init_i2c(void)
|
||||||
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
|
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_device *dm365_evm_nand_devices[] __initdata = {
|
|
||||||
&davinci_nand_device,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int have_leds(void)
|
static inline int have_leds(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LEDS_CLASS
|
#ifdef CONFIG_LEDS_CLASS
|
||||||
|
@ -628,6 +658,7 @@ static void __init evm_init_cpld(void)
|
||||||
u8 mux, resets;
|
u8 mux, resets;
|
||||||
const char *label;
|
const char *label;
|
||||||
struct clk *aemif_clk;
|
struct clk *aemif_clk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Make sure we can configure the CPLD through CS1. Then
|
/* Make sure we can configure the CPLD through CS1. Then
|
||||||
* leave it on for later access to MMC and LED registers.
|
* leave it on for later access to MMC and LED registers.
|
||||||
|
@ -660,8 +691,10 @@ fail:
|
||||||
/* external keypad mux */
|
/* external keypad mux */
|
||||||
mux |= BIT(7);
|
mux |= BIT(7);
|
||||||
|
|
||||||
platform_add_devices(dm365_evm_nand_devices,
|
rc = platform_device_register(&davinci_aemif_device);
|
||||||
ARRAY_SIZE(dm365_evm_nand_devices));
|
if (rc)
|
||||||
|
pr_warn("%s(): error registering the aemif device: %d\n",
|
||||||
|
__func__, rc);
|
||||||
} else {
|
} else {
|
||||||
/* no OneNAND support yet */
|
/* no OneNAND support yet */
|
||||||
}
|
}
|
||||||
|
@ -742,6 +775,8 @@ static __init void dm365_evm_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dm365_register_clocks();
|
||||||
|
|
||||||
ret = dm365_gpio_register();
|
ret = dm365_gpio_register();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/platform_data/mmc-davinci.h>
|
#include <linux/platform_data/mmc-davinci.h>
|
||||||
#include <linux/platform_data/usb-davinci.h>
|
#include <linux/platform_data/usb-davinci.h>
|
||||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
|
|
||||||
#include "davinci.h"
|
#include "davinci.h"
|
||||||
|
|
||||||
|
@ -174,14 +175,47 @@ static struct resource davinci_evm_nandflash_resource[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device davinci_evm_nandflash_device = {
|
static struct resource davinci_evm_aemif_resource[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 0,
|
.start = DM644X_ASYNC_EMIF_CONTROL_BASE,
|
||||||
.dev = {
|
.end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
|
||||||
.platform_data = &davinci_evm_nandflash_data,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
|
};
|
||||||
.resource = davinci_evm_nandflash_resource,
|
|
||||||
|
static struct aemif_abus_data davinci_evm_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device davinci_evm_nandflash_devices[] = {
|
||||||
|
{
|
||||||
|
.name = "davinci_nand",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &davinci_evm_nandflash_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
|
||||||
|
.resource = davinci_evm_nandflash_resource,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data davinci_evm_aemif_pdata = {
|
||||||
|
.abus_data = davinci_evm_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(davinci_evm_aemif_abus_data),
|
||||||
|
.sub_devices = davinci_evm_nandflash_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(davinci_evm_nandflash_devices),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device davinci_evm_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &davinci_evm_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = davinci_evm_aemif_resource,
|
||||||
|
.num_resources = ARRAY_SIZE(davinci_evm_aemif_resource),
|
||||||
};
|
};
|
||||||
|
|
||||||
static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
|
static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
@ -773,6 +807,8 @@ static __init void davinci_evm_init(void)
|
||||||
struct clk *aemif_clk;
|
struct clk *aemif_clk;
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
|
|
||||||
|
dm644x_register_clocks();
|
||||||
|
|
||||||
dm644x_init_devices();
|
dm644x_init_devices();
|
||||||
|
|
||||||
ret = dm644x_gpio_register();
|
ret = dm644x_gpio_register();
|
||||||
|
@ -793,12 +829,7 @@ static __init void davinci_evm_init(void)
|
||||||
|
|
||||||
/* only one device will be jumpered and detected */
|
/* only one device will be jumpered and detected */
|
||||||
if (HAS_NAND) {
|
if (HAS_NAND) {
|
||||||
platform_device_register(&davinci_evm_nandflash_device);
|
platform_device_register(&davinci_evm_aemif_device);
|
||||||
|
|
||||||
if (davinci_aemif_setup(&davinci_evm_nandflash_device))
|
|
||||||
pr_warn("%s: Cannot configure AEMIF\n",
|
|
||||||
__func__);
|
|
||||||
|
|
||||||
#ifdef CONFIG_I2C
|
#ifdef CONFIG_I2C
|
||||||
evm_leds[7].default_trigger = "nand-disk";
|
evm_leds[7].default_trigger = "nand-disk";
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/platform_data/at24.h>
|
#include <linux/platform_data/at24.h>
|
||||||
#include <linux/platform_data/pcf857x.h>
|
#include <linux/platform_data/pcf857x.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
|
|
||||||
#include <media/i2c/tvp514x.h>
|
#include <media/i2c/tvp514x.h>
|
||||||
#include <media/i2c/adv7343.h>
|
#include <media/i2c/adv7343.h>
|
||||||
|
@ -106,18 +107,49 @@ static struct resource davinci_nand_resources[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device davinci_nand_device = {
|
static struct platform_device davinci_aemif_devices[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 0,
|
.name = "davinci_nand",
|
||||||
|
.id = 0,
|
||||||
.num_resources = ARRAY_SIZE(davinci_nand_resources),
|
.num_resources = ARRAY_SIZE(davinci_nand_resources),
|
||||||
.resource = davinci_nand_resources,
|
.resource = davinci_nand_resources,
|
||||||
|
.dev = {
|
||||||
.dev = {
|
.platform_data = &davinci_nand_data,
|
||||||
.platform_data = &davinci_nand_data,
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource davinci_aemif_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DM646X_ASYNC_EMIF_CONTROL_BASE,
|
||||||
|
.end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data davinci_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data davinci_aemif_pdata = {
|
||||||
|
.abus_data = davinci_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(davinci_aemif_abus_data),
|
||||||
|
.sub_devices = davinci_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(davinci_aemif_devices),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device davinci_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &davinci_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = davinci_aemif_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(davinci_aemif_resources),
|
||||||
|
};
|
||||||
|
|
||||||
#define HAS_ATA (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
|
#define HAS_ATA (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
|
||||||
IS_ENABLED(CONFIG_PATA_BK3710))
|
IS_ENABLED(CONFIG_PATA_BK3710))
|
||||||
|
|
||||||
|
@ -776,6 +808,8 @@ static __init void evm_init(void)
|
||||||
int ret;
|
int ret;
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
|
|
||||||
|
dm646x_register_clocks();
|
||||||
|
|
||||||
ret = dm646x_gpio_register();
|
ret = dm646x_gpio_register();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
@ -791,10 +825,8 @@ static __init void evm_init(void)
|
||||||
if (machine_is_davinci_dm6467tevm())
|
if (machine_is_davinci_dm6467tevm())
|
||||||
davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
|
davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
|
||||||
|
|
||||||
platform_device_register(&davinci_nand_device);
|
if (platform_device_register(&davinci_aemif_device))
|
||||||
|
pr_warn("%s: Cannot register AEMIF device.\n", __func__);
|
||||||
if (davinci_aemif_setup(&davinci_nand_device))
|
|
||||||
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
|
|
||||||
|
|
||||||
dm646x_init_edma(dm646x_edma_rsv);
|
dm646x_init_edma(dm646x_edma_rsv);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <mach/da8xx.h>
|
#include <mach/da8xx.h>
|
||||||
#include <linux/platform_data/mtd-davinci.h>
|
#include <linux/platform_data/mtd-davinci.h>
|
||||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
#include <mach/mux.h>
|
#include <mach/mux.h>
|
||||||
#include <linux/platform_data/spi-davinci.h>
|
#include <linux/platform_data/spi-davinci.h>
|
||||||
|
|
||||||
|
@ -422,27 +423,53 @@ static struct resource mityomapl138_nandflash_resource[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device mityomapl138_nandflash_device = {
|
static struct platform_device mityomapl138_aemif_devices[] = {
|
||||||
.name = "davinci_nand",
|
{
|
||||||
.id = 1,
|
.name = "davinci_nand",
|
||||||
.dev = {
|
.id = 1,
|
||||||
.platform_data = &mityomapl138_nandflash_data,
|
.dev = {
|
||||||
|
.platform_data = &mityomapl138_nandflash_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource),
|
||||||
|
.resource = mityomapl138_nandflash_resource,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource),
|
|
||||||
.resource = mityomapl138_nandflash_resource,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device *mityomapl138_devices[] __initdata = {
|
static struct resource mityomapl138_aemif_resources[] = {
|
||||||
&mityomapl138_nandflash_device,
|
{
|
||||||
|
.start = DA8XX_AEMIF_CTL_BASE,
|
||||||
|
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data mityomapl138_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data mityomapl138_aemif_pdata = {
|
||||||
|
.abus_data = mityomapl138_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(mityomapl138_aemif_abus_data),
|
||||||
|
.sub_devices = mityomapl138_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(mityomapl138_aemif_devices),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mityomapl138_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &mityomapl138_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = mityomapl138_aemif_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(mityomapl138_aemif_resources),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __init mityomapl138_setup_nand(void)
|
static void __init mityomapl138_setup_nand(void)
|
||||||
{
|
{
|
||||||
platform_add_devices(mityomapl138_devices,
|
if (platform_device_register(&mityomapl138_aemif_device))
|
||||||
ARRAY_SIZE(mityomapl138_devices));
|
pr_warn("%s: Cannot register AEMIF device\n", __func__);
|
||||||
|
|
||||||
if (davinci_aemif_setup(&mityomapl138_nandflash_device))
|
|
||||||
pr_warn("%s: Cannot configure AEMIF\n", __func__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const short mityomap_mii_pins[] = {
|
static const short mityomap_mii_pins[] = {
|
||||||
|
@ -503,6 +530,8 @@ static void __init mityomapl138_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
da850_register_clocks();
|
||||||
|
|
||||||
/* for now, no special EDMA channels are reserved */
|
/* for now, no special EDMA channels are reserved */
|
||||||
ret = da850_register_edma(NULL);
|
ret = da850_register_edma(NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -175,6 +175,8 @@ static __init void davinci_ntosd2_init(void)
|
||||||
struct clk *aemif_clk;
|
struct clk *aemif_clk;
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
|
|
||||||
|
dm644x_register_clocks();
|
||||||
|
|
||||||
dm644x_init_devices();
|
dm644x_init_devices();
|
||||||
|
|
||||||
ret = dm644x_gpio_register();
|
ret = dm644x_gpio_register();
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/gpio/machine.h>
|
#include <linux/gpio/machine.h>
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/mtd/rawnand.h>
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
|
#include <linux/platform_data/mtd-davinci.h>
|
||||||
|
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||||
|
#include <linux/platform_data/ti-aemif.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
@ -166,6 +171,129 @@ mmc_setup_mmcsd_fail:
|
||||||
gpiod_remove_lookup_table(&mmc_gpios_table);
|
gpiod_remove_lookup_table(&mmc_gpios_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mtd_partition omapl138_hawk_nandflash_partition[] = {
|
||||||
|
{
|
||||||
|
.name = "u-boot env",
|
||||||
|
.offset = 0,
|
||||||
|
.size = SZ_128K,
|
||||||
|
.mask_flags = MTD_WRITEABLE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "u-boot",
|
||||||
|
.offset = MTDPART_OFS_APPEND,
|
||||||
|
.size = SZ_512K,
|
||||||
|
.mask_flags = MTD_WRITEABLE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "free space",
|
||||||
|
.offset = MTDPART_OFS_APPEND,
|
||||||
|
.size = MTDPART_SIZ_FULL,
|
||||||
|
.mask_flags = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct davinci_aemif_timing omapl138_hawk_nandflash_timing = {
|
||||||
|
.wsetup = 24,
|
||||||
|
.wstrobe = 21,
|
||||||
|
.whold = 14,
|
||||||
|
.rsetup = 19,
|
||||||
|
.rstrobe = 50,
|
||||||
|
.rhold = 0,
|
||||||
|
.ta = 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct davinci_nand_pdata omapl138_hawk_nandflash_data = {
|
||||||
|
.core_chipsel = 1,
|
||||||
|
.parts = omapl138_hawk_nandflash_partition,
|
||||||
|
.nr_parts = ARRAY_SIZE(omapl138_hawk_nandflash_partition),
|
||||||
|
.ecc_mode = NAND_ECC_HW,
|
||||||
|
.ecc_bits = 4,
|
||||||
|
.bbt_options = NAND_BBT_USE_FLASH,
|
||||||
|
.options = NAND_BUSWIDTH_16,
|
||||||
|
.timing = &omapl138_hawk_nandflash_timing,
|
||||||
|
.mask_chipsel = 0,
|
||||||
|
.mask_ale = 0,
|
||||||
|
.mask_cle = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource omapl138_hawk_nandflash_resource[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_AEMIF_CS3_BASE,
|
||||||
|
.end = DA8XX_AEMIF_CS3_BASE + SZ_32M,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = DA8XX_AEMIF_CTL_BASE,
|
||||||
|
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource omapl138_hawk_aemif_resource[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_AEMIF_CTL_BASE,
|
||||||
|
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_abus_data omapl138_hawk_aemif_abus_data[] = {
|
||||||
|
{
|
||||||
|
.cs = 3,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device omapl138_hawk_aemif_devices[] = {
|
||||||
|
{
|
||||||
|
.name = "davinci_nand",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &omapl138_hawk_nandflash_data,
|
||||||
|
},
|
||||||
|
.resource = omapl138_hawk_nandflash_resource,
|
||||||
|
.num_resources = ARRAY_SIZE(omapl138_hawk_nandflash_resource),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct aemif_platform_data omapl138_hawk_aemif_pdata = {
|
||||||
|
.cs_offset = 2,
|
||||||
|
.abus_data = omapl138_hawk_aemif_abus_data,
|
||||||
|
.num_abus_data = ARRAY_SIZE(omapl138_hawk_aemif_abus_data),
|
||||||
|
.sub_devices = omapl138_hawk_aemif_devices,
|
||||||
|
.num_sub_devices = ARRAY_SIZE(omapl138_hawk_aemif_devices),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device omapl138_hawk_aemif_device = {
|
||||||
|
.name = "ti-aemif",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &omapl138_hawk_aemif_pdata,
|
||||||
|
},
|
||||||
|
.resource = omapl138_hawk_aemif_resource,
|
||||||
|
.num_resources = ARRAY_SIZE(omapl138_hawk_aemif_resource),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const short omapl138_hawk_nand_pins[] = {
|
||||||
|
DA850_EMA_WAIT_1, DA850_NEMA_OE, DA850_NEMA_WE, DA850_NEMA_CS_3,
|
||||||
|
DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
|
||||||
|
DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
|
||||||
|
DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11,
|
||||||
|
DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15,
|
||||||
|
DA850_EMA_A_1, DA850_EMA_A_2,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
static int omapl138_hawk_register_aemif(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = davinci_cfg_reg_list(omapl138_hawk_nand_pins);
|
||||||
|
if (ret)
|
||||||
|
pr_warn("%s: NAND mux setup failed: %d\n", __func__, ret);
|
||||||
|
|
||||||
|
return platform_device_register(&omapl138_hawk_aemif_device);
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
|
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
|
||||||
static da8xx_ocic_handler_t hawk_usb_ocic_handler;
|
static da8xx_ocic_handler_t hawk_usb_ocic_handler;
|
||||||
|
|
||||||
|
@ -236,14 +364,9 @@ static __init void omapl138_hawk_usb_init(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = da8xx_register_usb20_phy_clk(false);
|
ret = da8xx_register_usb_phy_clocks();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
|
pr_warn("%s: USB PHY CLK registration failed: %d\n",
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
ret = da8xx_register_usb11_phy_clk(false);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
|
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
|
|
||||||
ret = da8xx_register_usb_phy();
|
ret = da8xx_register_usb_phy();
|
||||||
|
@ -285,6 +408,8 @@ static __init void omapl138_hawk_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
da850_register_clocks();
|
||||||
|
|
||||||
ret = da850_register_gpio();
|
ret = da850_register_gpio();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||||
|
@ -301,6 +426,10 @@ static __init void omapl138_hawk_init(void)
|
||||||
|
|
||||||
omapl138_hawk_usb_init();
|
omapl138_hawk_usb_init();
|
||||||
|
|
||||||
|
ret = omapl138_hawk_register_aemif();
|
||||||
|
if (ret)
|
||||||
|
pr_warn("%s: aemif registration failed: %d\n", __func__, ret);
|
||||||
|
|
||||||
ret = da8xx_register_watchdog();
|
ret = da8xx_register_watchdog();
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("%s: watchdog registration failed: %d\n",
|
pr_warn("%s: watchdog registration failed: %d\n",
|
||||||
|
|
|
@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
|
||||||
{
|
{
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
|
|
||||||
|
dm644x_register_clocks();
|
||||||
|
|
||||||
dm644x_init_devices();
|
dm644x_init_devices();
|
||||||
|
|
||||||
platform_add_devices(davinci_sffsdr_devices,
|
platform_add_devices(davinci_sffsdr_devices,
|
||||||
|
|
|
@ -1,745 +0,0 @@
|
||||||
/*
|
|
||||||
* Clock and PLL control for DaVinci devices
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006-2007 Texas Instruments.
|
|
||||||
* Copyright (C) 2008-2009 Deep Root Systems, LLC
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
|
||||||
|
|
||||||
#include <mach/clock.h>
|
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
static LIST_HEAD(clocks);
|
|
||||||
static DEFINE_MUTEX(clocks_mutex);
|
|
||||||
static DEFINE_SPINLOCK(clockfw_lock);
|
|
||||||
|
|
||||||
void davinci_clk_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk->parent)
|
|
||||||
davinci_clk_enable(clk->parent);
|
|
||||||
if (clk->usecount++ == 0) {
|
|
||||||
if (clk->flags & CLK_PSC)
|
|
||||||
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
|
|
||||||
true, clk->flags);
|
|
||||||
else if (clk->clk_enable)
|
|
||||||
clk->clk_enable(clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void davinci_clk_disable(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (WARN_ON(clk->usecount == 0))
|
|
||||||
return;
|
|
||||||
if (--clk->usecount == 0) {
|
|
||||||
if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
|
|
||||||
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
|
|
||||||
false, clk->flags);
|
|
||||||
else if (clk->clk_disable)
|
|
||||||
clk->clk_disable(clk);
|
|
||||||
}
|
|
||||||
if (clk->parent)
|
|
||||||
davinci_clk_disable(clk->parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
int davinci_clk_reset(struct clk *clk, bool reset)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
if (clk->flags & CLK_PSC)
|
|
||||||
davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(davinci_clk_reset);
|
|
||||||
|
|
||||||
int davinci_clk_reset_assert(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk) || !clk->reset)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return clk->reset(clk, true);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(davinci_clk_reset_assert);
|
|
||||||
|
|
||||||
int davinci_clk_reset_deassert(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk) || !clk->reset)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return clk->reset(clk, false);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(davinci_clk_reset_deassert);
|
|
||||||
|
|
||||||
int clk_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!clk)
|
|
||||||
return 0;
|
|
||||||
else if (IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
davinci_clk_enable(clk);
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_enable);
|
|
||||||
|
|
||||||
void clk_disable(struct clk *clk)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
davinci_clk_disable(clk);
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_disable);
|
|
||||||
|
|
||||||
unsigned long clk_get_rate(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return clk->rate;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_get_rate);
|
|
||||||
|
|
||||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (clk->round_rate)
|
|
||||||
return clk->round_rate(clk, rate);
|
|
||||||
|
|
||||||
return clk->rate;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_round_rate);
|
|
||||||
|
|
||||||
/* Propagate rate to children */
|
|
||||||
static void propagate_rate(struct clk *root)
|
|
||||||
{
|
|
||||||
struct clk *clk;
|
|
||||||
|
|
||||||
list_for_each_entry(clk, &root->children, childnode) {
|
|
||||||
if (clk->recalc)
|
|
||||||
clk->rate = clk->recalc(clk);
|
|
||||||
propagate_rate(clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
int ret = -EINVAL;
|
|
||||||
|
|
||||||
if (!clk)
|
|
||||||
return 0;
|
|
||||||
else if (IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (clk->set_rate)
|
|
||||||
ret = clk->set_rate(clk, rate);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
if (ret == 0) {
|
|
||||||
if (clk->recalc)
|
|
||||||
clk->rate = clk->recalc(clk);
|
|
||||||
propagate_rate(clk);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_set_rate);
|
|
||||||
|
|
||||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!clk)
|
|
||||||
return 0;
|
|
||||||
else if (IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Cannot change parent on enabled clock */
|
|
||||||
if (WARN_ON(clk->usecount))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
if (clk->set_parent) {
|
|
||||||
int ret = clk->set_parent(clk, parent);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clk->parent = parent;
|
|
||||||
list_del_init(&clk->childnode);
|
|
||||||
list_add(&clk->childnode, &clk->parent->children);
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
if (clk->recalc)
|
|
||||||
clk->rate = clk->recalc(clk);
|
|
||||||
propagate_rate(clk);
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_set_parent);
|
|
||||||
|
|
||||||
struct clk *clk_get_parent(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (!clk)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return clk->parent;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_get_parent);
|
|
||||||
|
|
||||||
int clk_register(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (WARN(clk->parent && !clk->parent->rate,
|
|
||||||
"CLK: %s parent %s has no rate!\n",
|
|
||||||
clk->name, clk->parent->name))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&clk->children);
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
list_add_tail(&clk->node, &clocks);
|
|
||||||
if (clk->parent) {
|
|
||||||
if (clk->set_parent) {
|
|
||||||
int ret = clk->set_parent(clk, clk->parent);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list_add_tail(&clk->childnode, &clk->parent->children);
|
|
||||||
}
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
/* If rate is already set, use it */
|
|
||||||
if (clk->rate)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Else, see if there is a way to calculate it */
|
|
||||||
if (clk->recalc)
|
|
||||||
clk->rate = clk->recalc(clk);
|
|
||||||
|
|
||||||
/* Otherwise, default to parent rate */
|
|
||||||
else if (clk->parent)
|
|
||||||
clk->rate = clk->parent->rate;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_register);
|
|
||||||
|
|
||||||
void clk_unregister(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (clk == NULL || IS_ERR(clk))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
list_del(&clk->node);
|
|
||||||
list_del(&clk->childnode);
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(clk_unregister);
|
|
||||||
|
|
||||||
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
|
|
||||||
/*
|
|
||||||
* Disable any unused clocks left on by the bootloader
|
|
||||||
*/
|
|
||||||
int __init davinci_clk_disable_unused(void)
|
|
||||||
{
|
|
||||||
struct clk *ck;
|
|
||||||
|
|
||||||
spin_lock_irq(&clockfw_lock);
|
|
||||||
list_for_each_entry(ck, &clocks, node) {
|
|
||||||
if (ck->usecount > 0)
|
|
||||||
continue;
|
|
||||||
if (!(ck->flags & CLK_PSC))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore if in Disabled or SwRstDisable states */
|
|
||||||
if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pr_debug("Clocks: disable unused %s\n", ck->name);
|
|
||||||
|
|
||||||
davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
|
|
||||||
false, ck->flags);
|
|
||||||
}
|
|
||||||
spin_unlock_irq(&clockfw_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned long clk_sysclk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 v, plldiv;
|
|
||||||
struct pll_data *pll;
|
|
||||||
unsigned long rate = clk->rate;
|
|
||||||
|
|
||||||
/* If this is the PLL base clock, no more calculations needed */
|
|
||||||
if (clk->pll_data)
|
|
||||||
return rate;
|
|
||||||
|
|
||||||
if (WARN_ON(!clk->parent))
|
|
||||||
return rate;
|
|
||||||
|
|
||||||
rate = clk->parent->rate;
|
|
||||||
|
|
||||||
/* Otherwise, the parent must be a PLL */
|
|
||||||
if (WARN_ON(!clk->parent->pll_data))
|
|
||||||
return rate;
|
|
||||||
|
|
||||||
pll = clk->parent->pll_data;
|
|
||||||
|
|
||||||
/* If pre-PLL, source clock is before the multiplier and divider(s) */
|
|
||||||
if (clk->flags & PRE_PLL)
|
|
||||||
rate = pll->input_rate;
|
|
||||||
|
|
||||||
if (!clk->div_reg)
|
|
||||||
return rate;
|
|
||||||
|
|
||||||
v = __raw_readl(pll->base + clk->div_reg);
|
|
||||||
if (v & PLLDIV_EN) {
|
|
||||||
plldiv = (v & pll->div_ratio_mask) + 1;
|
|
||||||
if (plldiv)
|
|
||||||
rate /= plldiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
unsigned v;
|
|
||||||
struct pll_data *pll;
|
|
||||||
unsigned long input;
|
|
||||||
unsigned ratio = 0;
|
|
||||||
|
|
||||||
/* If this is the PLL base clock, wrong function to call */
|
|
||||||
if (clk->pll_data)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* There must be a parent... */
|
|
||||||
if (WARN_ON(!clk->parent))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* ... the parent must be a PLL... */
|
|
||||||
if (WARN_ON(!clk->parent->pll_data))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* ... and this clock must have a divider. */
|
|
||||||
if (WARN_ON(!clk->div_reg))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
pll = clk->parent->pll_data;
|
|
||||||
|
|
||||||
input = clk->parent->rate;
|
|
||||||
|
|
||||||
/* If pre-PLL, source clock is before the multiplier and divider(s) */
|
|
||||||
if (clk->flags & PRE_PLL)
|
|
||||||
input = pll->input_rate;
|
|
||||||
|
|
||||||
if (input > rate) {
|
|
||||||
/*
|
|
||||||
* Can afford to provide an output little higher than requested
|
|
||||||
* only if maximum rate supported by hardware on this sysclk
|
|
||||||
* is known.
|
|
||||||
*/
|
|
||||||
if (clk->maxrate) {
|
|
||||||
ratio = DIV_ROUND_CLOSEST(input, rate);
|
|
||||||
if (input / ratio > clk->maxrate)
|
|
||||||
ratio = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ratio == 0)
|
|
||||||
ratio = DIV_ROUND_UP(input, rate);
|
|
||||||
|
|
||||||
ratio--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ratio > pll->div_ratio_mask)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
do {
|
|
||||||
v = __raw_readl(pll->base + PLLSTAT);
|
|
||||||
} while (v & PLLSTAT_GOSTAT);
|
|
||||||
|
|
||||||
v = __raw_readl(pll->base + clk->div_reg);
|
|
||||||
v &= ~pll->div_ratio_mask;
|
|
||||||
v |= ratio | PLLDIV_EN;
|
|
||||||
__raw_writel(v, pll->base + clk->div_reg);
|
|
||||||
|
|
||||||
v = __raw_readl(pll->base + PLLCMD);
|
|
||||||
v |= PLLCMD_GOSET;
|
|
||||||
__raw_writel(v, pll->base + PLLCMD);
|
|
||||||
|
|
||||||
do {
|
|
||||||
v = __raw_readl(pll->base + PLLSTAT);
|
|
||||||
} while (v & PLLSTAT_GOSTAT);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(davinci_set_sysclk_rate);
|
|
||||||
|
|
||||||
static unsigned long clk_leafclk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (WARN_ON(!clk->parent))
|
|
||||||
return clk->rate;
|
|
||||||
|
|
||||||
return clk->parent->rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
clk->rate = rate;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long clk_pllclk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
|
|
||||||
u8 bypass;
|
|
||||||
struct pll_data *pll = clk->pll_data;
|
|
||||||
unsigned long rate = clk->rate;
|
|
||||||
|
|
||||||
ctrl = __raw_readl(pll->base + PLLCTL);
|
|
||||||
rate = pll->input_rate = clk->parent->rate;
|
|
||||||
|
|
||||||
if (ctrl & PLLCTL_PLLEN) {
|
|
||||||
bypass = 0;
|
|
||||||
mult = __raw_readl(pll->base + PLLM);
|
|
||||||
if (cpu_is_davinci_dm365())
|
|
||||||
mult = 2 * (mult & PLLM_PLLM_MASK);
|
|
||||||
else
|
|
||||||
mult = (mult & PLLM_PLLM_MASK) + 1;
|
|
||||||
} else
|
|
||||||
bypass = 1;
|
|
||||||
|
|
||||||
if (pll->flags & PLL_HAS_PREDIV) {
|
|
||||||
prediv = __raw_readl(pll->base + PREDIV);
|
|
||||||
if (prediv & PLLDIV_EN)
|
|
||||||
prediv = (prediv & pll->div_ratio_mask) + 1;
|
|
||||||
else
|
|
||||||
prediv = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pre-divider is fixed, but (some?) chips won't report that */
|
|
||||||
if (cpu_is_davinci_dm355() && pll->num == 1)
|
|
||||||
prediv = 8;
|
|
||||||
|
|
||||||
if (pll->flags & PLL_HAS_POSTDIV) {
|
|
||||||
postdiv = __raw_readl(pll->base + POSTDIV);
|
|
||||||
if (postdiv & PLLDIV_EN)
|
|
||||||
postdiv = (postdiv & pll->div_ratio_mask) + 1;
|
|
||||||
else
|
|
||||||
postdiv = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bypass) {
|
|
||||||
rate /= prediv;
|
|
||||||
rate *= mult;
|
|
||||||
rate /= postdiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
pr_debug("PLL%d: input = %lu MHz [ ",
|
|
||||||
pll->num, clk->parent->rate / 1000000);
|
|
||||||
if (bypass)
|
|
||||||
pr_debug("bypass ");
|
|
||||||
if (prediv > 1)
|
|
||||||
pr_debug("/ %d ", prediv);
|
|
||||||
if (mult > 1)
|
|
||||||
pr_debug("* %d ", mult);
|
|
||||||
if (postdiv > 1)
|
|
||||||
pr_debug("/ %d ", postdiv);
|
|
||||||
pr_debug("] --> %lu MHz output.\n", rate / 1000000);
|
|
||||||
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* davinci_set_pllrate - set the output rate of a given PLL.
|
|
||||||
*
|
|
||||||
* Note: Currently tested to work with OMAP-L138 only.
|
|
||||||
*
|
|
||||||
* @pll: pll whose rate needs to be changed.
|
|
||||||
* @prediv: The pre divider value. Passing 0 disables the pre-divider.
|
|
||||||
* @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
|
|
||||||
* @postdiv: The post divider value. Passing 0 disables the post-divider.
|
|
||||||
*/
|
|
||||||
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
|
||||||
unsigned int mult, unsigned int postdiv)
|
|
||||||
{
|
|
||||||
u32 ctrl;
|
|
||||||
unsigned int locktime;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (pll->base == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL lock time required per OMAP-L138 datasheet is
|
|
||||||
* (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
|
|
||||||
* as 4 and OSCIN cycle as 25 MHz.
|
|
||||||
*/
|
|
||||||
if (prediv) {
|
|
||||||
locktime = ((2000 * prediv) / 100);
|
|
||||||
prediv = (prediv - 1) | PLLDIV_EN;
|
|
||||||
} else {
|
|
||||||
locktime = PLL_LOCK_TIME;
|
|
||||||
}
|
|
||||||
if (postdiv)
|
|
||||||
postdiv = (postdiv - 1) | PLLDIV_EN;
|
|
||||||
if (mult)
|
|
||||||
mult = mult - 1;
|
|
||||||
|
|
||||||
/* Protect against simultaneous calls to PLL setting seqeunce */
|
|
||||||
spin_lock_irqsave(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
ctrl = __raw_readl(pll->base + PLLCTL);
|
|
||||||
|
|
||||||
/* Switch the PLL to bypass mode */
|
|
||||||
ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
|
|
||||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
|
||||||
|
|
||||||
udelay(PLL_BYPASS_TIME);
|
|
||||||
|
|
||||||
/* Reset and enable PLL */
|
|
||||||
ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
|
|
||||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
|
||||||
|
|
||||||
if (pll->flags & PLL_HAS_PREDIV)
|
|
||||||
__raw_writel(prediv, pll->base + PREDIV);
|
|
||||||
|
|
||||||
__raw_writel(mult, pll->base + PLLM);
|
|
||||||
|
|
||||||
if (pll->flags & PLL_HAS_POSTDIV)
|
|
||||||
__raw_writel(postdiv, pll->base + POSTDIV);
|
|
||||||
|
|
||||||
udelay(PLL_RESET_TIME);
|
|
||||||
|
|
||||||
/* Bring PLL out of reset */
|
|
||||||
ctrl |= PLLCTL_PLLRST;
|
|
||||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
|
||||||
|
|
||||||
udelay(locktime);
|
|
||||||
|
|
||||||
/* Remove PLL from bypass mode */
|
|
||||||
ctrl |= PLLCTL_PLLEN;
|
|
||||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(davinci_set_pllrate);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* davinci_set_refclk_rate() - Set the reference clock rate
|
|
||||||
* @rate: The new rate.
|
|
||||||
*
|
|
||||||
* Sets the reference clock rate to a given value. This will most likely
|
|
||||||
* result in the entire clock tree getting updated.
|
|
||||||
*
|
|
||||||
* This is used to support boards which use a reference clock different
|
|
||||||
* than that used by default in <soc>.c file. The reference clock rate
|
|
||||||
* should be updated early in the boot process; ideally soon after the
|
|
||||||
* clock tree has been initialized once with the default reference clock
|
|
||||||
* rate (davinci_clk_init()).
|
|
||||||
*
|
|
||||||
* Returns 0 on success, error otherwise.
|
|
||||||
*/
|
|
||||||
int davinci_set_refclk_rate(unsigned long rate)
|
|
||||||
{
|
|
||||||
struct clk *refclk;
|
|
||||||
|
|
||||||
refclk = clk_get(NULL, "ref");
|
|
||||||
if (IS_ERR(refclk)) {
|
|
||||||
pr_err("%s: failed to get reference clock\n", __func__);
|
|
||||||
return PTR_ERR(refclk);
|
|
||||||
}
|
|
||||||
|
|
||||||
clk_set_rate(refclk, rate);
|
|
||||||
|
|
||||||
clk_put(refclk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __init davinci_clk_init(struct clk_lookup *clocks)
|
|
||||||
{
|
|
||||||
struct clk_lookup *c;
|
|
||||||
struct clk *clk;
|
|
||||||
size_t num_clocks = 0;
|
|
||||||
|
|
||||||
for (c = clocks; c->clk; c++) {
|
|
||||||
clk = c->clk;
|
|
||||||
|
|
||||||
if (!clk->recalc) {
|
|
||||||
|
|
||||||
/* Check if clock is a PLL */
|
|
||||||
if (clk->pll_data)
|
|
||||||
clk->recalc = clk_pllclk_recalc;
|
|
||||||
|
|
||||||
/* Else, if it is a PLL-derived clock */
|
|
||||||
else if (clk->flags & CLK_PLL)
|
|
||||||
clk->recalc = clk_sysclk_recalc;
|
|
||||||
|
|
||||||
/* Otherwise, it is a leaf clock (PSC clock) */
|
|
||||||
else if (clk->parent)
|
|
||||||
clk->recalc = clk_leafclk_recalc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clk->pll_data) {
|
|
||||||
struct pll_data *pll = clk->pll_data;
|
|
||||||
|
|
||||||
if (!pll->div_ratio_mask)
|
|
||||||
pll->div_ratio_mask = PLLDIV_RATIO_MASK;
|
|
||||||
|
|
||||||
if (pll->phys_base && !pll->base) {
|
|
||||||
pll->base = ioremap(pll->phys_base, SZ_4K);
|
|
||||||
WARN_ON(!pll->base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clk->recalc)
|
|
||||||
clk->rate = clk->recalc(clk);
|
|
||||||
|
|
||||||
if (clk->lpsc)
|
|
||||||
clk->flags |= CLK_PSC;
|
|
||||||
|
|
||||||
if (clk->flags & PSC_LRST)
|
|
||||||
clk->reset = davinci_clk_reset;
|
|
||||||
|
|
||||||
clk_register(clk);
|
|
||||||
num_clocks++;
|
|
||||||
|
|
||||||
/* Turn on clocks that Linux doesn't otherwise manage */
|
|
||||||
if (clk->flags & ALWAYS_ENABLED)
|
|
||||||
clk_enable(clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
clkdev_add_table(clocks, num_clocks);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
|
||||||
#include <linux/seq_file.h>
|
|
||||||
|
|
||||||
#define CLKNAME_MAX 10 /* longest clock name */
|
|
||||||
#define NEST_DELTA 2
|
|
||||||
#define NEST_MAX 4
|
|
||||||
|
|
||||||
static void
|
|
||||||
dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
|
|
||||||
{
|
|
||||||
char *state;
|
|
||||||
char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
|
|
||||||
struct clk *clk;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if (parent->flags & CLK_PLL)
|
|
||||||
state = "pll";
|
|
||||||
else if (parent->flags & CLK_PSC)
|
|
||||||
state = "psc";
|
|
||||||
else
|
|
||||||
state = "";
|
|
||||||
|
|
||||||
/* <nest spaces> name <pad to end> */
|
|
||||||
memset(buf, ' ', sizeof(buf) - 1);
|
|
||||||
buf[sizeof(buf) - 1] = 0;
|
|
||||||
i = strlen(parent->name);
|
|
||||||
memcpy(buf + nest, parent->name,
|
|
||||||
min(i, (unsigned)(sizeof(buf) - 1 - nest)));
|
|
||||||
|
|
||||||
seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
|
|
||||||
buf, parent->usecount, state, clk_get_rate(parent));
|
|
||||||
/* REVISIT show device associations too */
|
|
||||||
|
|
||||||
/* cost is now small, but not linear... */
|
|
||||||
list_for_each_entry(clk, &parent->children, childnode) {
|
|
||||||
dump_clock(s, nest + NEST_DELTA, clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int davinci_ck_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct clk *clk;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show clock tree; We trust nonzero usecounts equate to PSC enables...
|
|
||||||
*/
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
list_for_each_entry(clk, &clocks, node)
|
|
||||||
if (!clk->parent)
|
|
||||||
dump_clock(m, 0, clk);
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int davinci_ck_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, davinci_ck_show, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations davinci_ck_operations = {
|
|
||||||
.open = davinci_ck_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init davinci_clk_debugfs_init(void)
|
|
||||||
{
|
|
||||||
debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
|
|
||||||
&davinci_ck_operations);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
device_initcall(davinci_clk_debugfs_init);
|
|
||||||
#endif /* CONFIG_DEBUG_FS */
|
|
|
@ -12,10 +12,6 @@
|
||||||
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
|
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
|
||||||
#define __ARCH_ARM_DAVINCI_CLOCK_H
|
#define __ARCH_ARM_DAVINCI_CLOCK_H
|
||||||
|
|
||||||
#define DAVINCI_PLL1_BASE 0x01c40800
|
|
||||||
#define DAVINCI_PLL2_BASE 0x01c40c00
|
|
||||||
#define MAX_PLL 2
|
|
||||||
|
|
||||||
/* PLL/Reset register offsets */
|
/* PLL/Reset register offsets */
|
||||||
#define PLLCTL 0x100
|
#define PLLCTL 0x100
|
||||||
#define PLLCTL_PLLEN BIT(0)
|
#define PLLCTL_PLLEN BIT(0)
|
||||||
|
@ -65,76 +61,4 @@
|
||||||
*/
|
*/
|
||||||
#define PLL_LOCK_TIME 20
|
#define PLL_LOCK_TIME 20
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/clkdev.h>
|
|
||||||
|
|
||||||
#define PLLSTAT_GOSTAT BIT(0)
|
|
||||||
#define PLLCMD_GOSET BIT(0)
|
|
||||||
|
|
||||||
struct pll_data {
|
|
||||||
u32 phys_base;
|
|
||||||
void __iomem *base;
|
|
||||||
u32 num;
|
|
||||||
u32 flags;
|
|
||||||
u32 input_rate;
|
|
||||||
u32 div_ratio_mask;
|
|
||||||
};
|
|
||||||
#define PLL_HAS_PREDIV 0x01
|
|
||||||
#define PLL_HAS_POSTDIV 0x02
|
|
||||||
|
|
||||||
struct clk {
|
|
||||||
struct list_head node;
|
|
||||||
struct module *owner;
|
|
||||||
const char *name;
|
|
||||||
unsigned long rate;
|
|
||||||
unsigned long maxrate; /* H/W supported max rate */
|
|
||||||
u8 usecount;
|
|
||||||
u8 lpsc;
|
|
||||||
u8 gpsc;
|
|
||||||
u8 domain;
|
|
||||||
u32 flags;
|
|
||||||
struct clk *parent;
|
|
||||||
struct list_head children; /* list of children */
|
|
||||||
struct list_head childnode; /* parent's child list node */
|
|
||||||
struct pll_data *pll_data;
|
|
||||||
u32 div_reg;
|
|
||||||
unsigned long (*recalc) (struct clk *);
|
|
||||||
int (*set_rate) (struct clk *clk, unsigned long rate);
|
|
||||||
int (*round_rate) (struct clk *clk, unsigned long rate);
|
|
||||||
int (*reset) (struct clk *clk, bool reset);
|
|
||||||
void (*clk_enable) (struct clk *clk);
|
|
||||||
void (*clk_disable) (struct clk *clk);
|
|
||||||
int (*set_parent) (struct clk *clk, struct clk *parent);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Clock flags: SoC-specific flags start at BIT(16) */
|
|
||||||
#define ALWAYS_ENABLED BIT(1)
|
|
||||||
#define CLK_PSC BIT(2)
|
|
||||||
#define CLK_PLL BIT(3) /* PLL-derived clock */
|
|
||||||
#define PRE_PLL BIT(4) /* source is before PLL mult/div */
|
|
||||||
#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
|
|
||||||
#define PSC_FORCE BIT(6) /* Force module state transtition */
|
|
||||||
#define PSC_LRST BIT(8) /* Use local reset on enable/disable */
|
|
||||||
|
|
||||||
#define CLK(dev, con, ck) \
|
|
||||||
{ \
|
|
||||||
.dev_id = dev, \
|
|
||||||
.con_id = con, \
|
|
||||||
.clk = ck, \
|
|
||||||
} \
|
|
||||||
|
|
||||||
int davinci_clk_init(struct clk_lookup *clocks);
|
|
||||||
int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
|
||||||
unsigned int mult, unsigned int postdiv);
|
|
||||||
int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
|
|
||||||
int davinci_set_refclk_rate(unsigned long rate);
|
|
||||||
int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
|
|
||||||
int davinci_clk_reset(struct clk *clk, bool reset);
|
|
||||||
void davinci_clk_enable(struct clk *clk);
|
|
||||||
void davinci_clk_disable(struct clk *clk);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/cputype.h>
|
#include <mach/cputype.h>
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
struct davinci_soc_info davinci_soc_info;
|
struct davinci_soc_info davinci_soc_info;
|
||||||
EXPORT_SYMBOL(davinci_soc_info);
|
EXPORT_SYMBOL(davinci_soc_info);
|
||||||
|
|
||||||
|
@ -118,5 +116,4 @@ err:
|
||||||
void __init davinci_init_late(void)
|
void __init davinci_init_late(void)
|
||||||
{
|
{
|
||||||
davinci_cpufreq_init();
|
davinci_cpufreq_init();
|
||||||
davinci_clk_disable_unused();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,20 @@
|
||||||
* is licensed "as is" without any warranty of any kind, whether express
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
* or implied.
|
* or implied.
|
||||||
*/
|
*/
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/clk/davinci.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/irqs.h>
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/time.h>
|
#include <mach/cputype.h>
|
||||||
#include <mach/da8xx.h>
|
#include <mach/da8xx.h>
|
||||||
|
#include <mach/irqs.h>
|
||||||
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
#include "mux.h"
|
||||||
|
|
||||||
/* Offsets of the 8 compare registers on the da830 */
|
/* Offsets of the 8 compare registers on the da830 */
|
||||||
|
@ -37,402 +36,6 @@
|
||||||
|
|
||||||
#define DA830_REF_FREQ 24000000
|
#define DA830_REF_FREQ 24000000
|
||||||
|
|
||||||
static struct pll_data pll0_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DA8XX_PLL0_BASE,
|
|
||||||
.flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
.rate = DA830_REF_FREQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_clk = {
|
|
||||||
.name = "pll0",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll0_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_aux_clk = {
|
|
||||||
.name = "pll0_aux_clk",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk2 = {
|
|
||||||
.name = "pll0_sysclk2",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk3 = {
|
|
||||||
.name = "pll0_sysclk3",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk4 = {
|
|
||||||
.name = "pll0_sysclk4",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk5 = {
|
|
||||||
.name = "pll0_sysclk5",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk6 = {
|
|
||||||
.name = "pll0_sysclk6",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk7 = {
|
|
||||||
.name = "pll0_sysclk7",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c0_clk = {
|
|
||||||
.name = "i2c0",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timerp64_0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timerp64_1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_rom_clk = {
|
|
||||||
.name = "arm_rom",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk scr0_ss_clk = {
|
|
||||||
.name = "scr0_ss",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_SCR0_SS,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk scr1_ss_clk = {
|
|
||||||
.name = "scr1_ss",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_SCR1_SS,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk scr2_ss_clk = {
|
|
||||||
.name = "scr2_ss",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_SCR2_SS,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk dmax_clk = {
|
|
||||||
.name = "dmax",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_PRUSS,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tpcc_clk = {
|
|
||||||
.name = "tpcc",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPCC,
|
|
||||||
.flags = ALWAYS_ENABLED | CLK_PSC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tptc0_clk = {
|
|
||||||
.name = "tptc0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPTC0,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tptc1_clk = {
|
|
||||||
.name = "tptc1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPTC1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd_clk = {
|
|
||||||
.name = "mmcsd",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_MMC_SD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_UART1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart2_clk = {
|
|
||||||
.name = "uart2",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_UART2,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi0_clk = {
|
|
||||||
.name = "spi0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_SPI0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi1_clk = {
|
|
||||||
.name = "spi1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_SPI1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap0_clk = {
|
|
||||||
.name = "ecap0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_ECAP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap1_clk = {
|
|
||||||
.name = "ecap1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_ECAP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap2_clk = {
|
|
||||||
.name = "ecap2",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_ECAP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm0_clk = {
|
|
||||||
.name = "pwm0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_PWM,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm1_clk = {
|
|
||||||
.name = "pwm1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_PWM,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm2_clk = {
|
|
||||||
.name = "pwm2",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_PWM,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk eqep0_clk = {
|
|
||||||
.name = "eqep0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA830_LPSC1_EQEP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk eqep1_clk = {
|
|
||||||
.name = "eqep1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA830_LPSC1_EQEP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk lcdc_clk = {
|
|
||||||
.name = "lcdc",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_LCDC,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp0_clk = {
|
|
||||||
.name = "mcasp0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_McASP0,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp1_clk = {
|
|
||||||
.name = "mcasp1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA830_LPSC1_McASP1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp2_clk = {
|
|
||||||
.name = "mcasp2",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA830_LPSC1_McASP2,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb20_clk = {
|
|
||||||
.name = "usb20",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_USB20,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk cppi41_clk = {
|
|
||||||
.name = "cppi41",
|
|
||||||
.parent = &usb20_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll0_sysclk3,
|
|
||||||
.lpsc = DA8XX_LPSC0_EMIF25,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aintc_clk = {
|
|
||||||
.name = "aintc",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC0_AINTC,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk secu_mgr_clk = {
|
|
||||||
.name = "secu_mgr",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC0_SECU_MGR,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emac_clk = {
|
|
||||||
.name = "emac",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_CPGMAC,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_GPIO,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c1_clk = {
|
|
||||||
.name = "i2c1",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_I2C,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb11_clk = {
|
|
||||||
.name = "usb11",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_USB11,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emif3_clk = {
|
|
||||||
.name = "emif3",
|
|
||||||
.parent = &pll0_sysclk5,
|
|
||||||
.lpsc = DA8XX_LPSC1_EMIF3C,
|
|
||||||
.gpsc = 1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm",
|
|
||||||
.parent = &pll0_sysclk6,
|
|
||||||
.lpsc = DA8XX_LPSC0_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk rmii_clk = {
|
|
||||||
.name = "rmii",
|
|
||||||
.parent = &pll0_sysclk7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup da830_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "pll0", &pll0_clk),
|
|
||||||
CLK(NULL, "pll0_aux", &pll0_aux_clk),
|
|
||||||
CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
|
|
||||||
CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
|
|
||||||
CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
|
|
||||||
CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
|
|
||||||
CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
|
|
||||||
CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c0_clk),
|
|
||||||
CLK(NULL, "timer0", &timerp64_0_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timerp64_1_clk),
|
|
||||||
CLK(NULL, "arm_rom", &arm_rom_clk),
|
|
||||||
CLK(NULL, "scr0_ss", &scr0_ss_clk),
|
|
||||||
CLK(NULL, "scr1_ss", &scr1_ss_clk),
|
|
||||||
CLK(NULL, "scr2_ss", &scr2_ss_clk),
|
|
||||||
CLK(NULL, "dmax", &dmax_clk),
|
|
||||||
CLK(NULL, "tpcc", &tpcc_clk),
|
|
||||||
CLK(NULL, "tptc0", &tptc0_clk),
|
|
||||||
CLK(NULL, "tptc1", &tptc1_clk),
|
|
||||||
CLK("da830-mmc.0", NULL, &mmcsd_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("serial8250.2", NULL, &uart2_clk),
|
|
||||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
|
||||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
|
||||||
CLK(NULL, "ecap0", &ecap0_clk),
|
|
||||||
CLK(NULL, "ecap1", &ecap1_clk),
|
|
||||||
CLK(NULL, "ecap2", &ecap2_clk),
|
|
||||||
CLK(NULL, "pwm0", &pwm0_clk),
|
|
||||||
CLK(NULL, "pwm1", &pwm1_clk),
|
|
||||||
CLK(NULL, "pwm2", &pwm2_clk),
|
|
||||||
CLK("eqep.0", NULL, &eqep0_clk),
|
|
||||||
CLK("eqep.1", NULL, &eqep1_clk),
|
|
||||||
CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
|
|
||||||
CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
|
|
||||||
CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
|
|
||||||
CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
|
|
||||||
CLK("musb-da8xx", NULL, &usb20_clk),
|
|
||||||
CLK("cppi41-dmaengine", NULL, &cppi41_clk),
|
|
||||||
CLK(NULL, "aemif", &aemif_clk),
|
|
||||||
CLK(NULL, "aintc", &aintc_clk),
|
|
||||||
CLK(NULL, "secu_mgr", &secu_mgr_clk),
|
|
||||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
||||||
CLK("davinci_mdio.0", "fck", &emac_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK("i2c_davinci.2", NULL, &i2c1_clk),
|
|
||||||
CLK("ohci-da8xx", NULL, &usb11_clk),
|
|
||||||
CLK(NULL, "emif3", &emif3_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK(NULL, "rmii", &rmii_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device specific mux setup
|
* Device specific mux setup
|
||||||
*
|
*
|
||||||
|
@ -1130,8 +733,6 @@ static struct map_desc da830_io_desc[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
|
|
||||||
|
|
||||||
/* Contents of JTAG ID register used to identify exact cpu type */
|
/* Contents of JTAG ID register used to identify exact cpu type */
|
||||||
static struct davinci_id da830_ids[] = {
|
static struct davinci_id da830_ids[] = {
|
||||||
{
|
{
|
||||||
|
@ -1200,8 +801,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
|
||||||
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
|
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
|
||||||
.ids = da830_ids,
|
.ids = da830_ids,
|
||||||
.ids_num = ARRAY_SIZE(da830_ids),
|
.ids_num = ARRAY_SIZE(da830_ids),
|
||||||
.psc_bases = da830_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(da830_psc_bases),
|
|
||||||
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
|
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
|
||||||
.pinmux_pins = da830_pins,
|
.pinmux_pins = da830_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(da830_pins),
|
.pinmux_pins_num = ARRAY_SIZE(da830_pins),
|
||||||
|
@ -1223,6 +822,53 @@ void __init da830_init(void)
|
||||||
|
|
||||||
void __init da830_init_time(void)
|
void __init da830_init_time(void)
|
||||||
{
|
{
|
||||||
davinci_clk_init(da830_clks);
|
void __iomem *pll;
|
||||||
davinci_timer_init();
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
|
||||||
|
|
||||||
|
pll = ioremap(DA8XX_PLL0_BASE, SZ_4K);
|
||||||
|
|
||||||
|
da830_pll_init(NULL, pll, NULL);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource da830_psc0_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_PSC0_BASE,
|
||||||
|
.end = DA8XX_PSC0_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da830_psc0_device = {
|
||||||
|
.name = "da830-psc0",
|
||||||
|
.id = -1,
|
||||||
|
.resource = da830_psc0_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(da830_psc0_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource da830_psc1_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_PSC1_BASE,
|
||||||
|
.end = DA8XX_PSC1_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da830_psc1_device = {
|
||||||
|
.name = "da830-psc1",
|
||||||
|
.id = -1,
|
||||||
|
.resource = da830_psc1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(da830_psc1_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init da830_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* PLL is registered in da830_init_time() */
|
||||||
|
platform_device_register(&da830_psc0_device);
|
||||||
|
platform_device_register(&da830_psc1_device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,31 @@
|
||||||
* is licensed "as is" without any warranty of any kind, whether express
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
* or implied.
|
* or implied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/clk/davinci.h>
|
||||||
#include <linux/clkdev.h>
|
#include <linux/clkdev.h>
|
||||||
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/mfd/da8xx-cfgchip.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_data/clk-da8xx-cfgchip.h>
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/platform_data/clk-davinci-pll.h>
|
||||||
#include <linux/regulator/consumer.h>
|
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/irqs.h>
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/time.h>
|
|
||||||
#include <mach/da8xx.h>
|
|
||||||
#include <mach/cpufreq.h>
|
#include <mach/cpufreq.h>
|
||||||
|
#include <mach/cputype.h>
|
||||||
|
#include <mach/da8xx.h>
|
||||||
|
#include <mach/irqs.h>
|
||||||
#include <mach/pm.h>
|
#include <mach/pm.h>
|
||||||
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
#include "mux.h"
|
||||||
|
|
||||||
#define DA850_PLL1_BASE 0x01e1a000
|
#define DA850_PLL1_BASE 0x01e1a000
|
||||||
|
@ -40,550 +44,6 @@
|
||||||
|
|
||||||
#define DA850_REF_FREQ 24000000
|
#define DA850_REF_FREQ 24000000
|
||||||
|
|
||||||
#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
|
|
||||||
#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
|
|
||||||
#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
|
|
||||||
|
|
||||||
static int da850_set_armrate(struct clk *clk, unsigned long rate);
|
|
||||||
static int da850_round_armrate(struct clk *clk, unsigned long rate);
|
|
||||||
static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
|
|
||||||
|
|
||||||
static struct pll_data pll0_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DA8XX_PLL0_BASE,
|
|
||||||
.flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
.rate = DA850_REF_FREQ,
|
|
||||||
.set_rate = davinci_simple_set_rate,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_clk = {
|
|
||||||
.name = "pll0",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll0_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.set_rate = da850_set_pll0rate,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_aux_clk = {
|
|
||||||
.name = "pll0_aux_clk",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk1 = {
|
|
||||||
.name = "pll0_sysclk1",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk2 = {
|
|
||||||
.name = "pll0_sysclk2",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk3 = {
|
|
||||||
.name = "pll0_sysclk3",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
.set_rate = davinci_set_sysclk_rate,
|
|
||||||
.maxrate = 100000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk4 = {
|
|
||||||
.name = "pll0_sysclk4",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk5 = {
|
|
||||||
.name = "pll0_sysclk5",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk6 = {
|
|
||||||
.name = "pll0_sysclk6",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll0_sysclk7 = {
|
|
||||||
.name = "pll0_sysclk7",
|
|
||||||
.parent = &pll0_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pll_data pll1_data = {
|
|
||||||
.num = 2,
|
|
||||||
.phys_base = DA850_PLL1_BASE,
|
|
||||||
.flags = PLL_HAS_POSTDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_clk = {
|
|
||||||
.name = "pll1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll1_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_aux_clk = {
|
|
||||||
.name = "pll1_aux_clk",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk2 = {
|
|
||||||
.name = "pll1_sysclk2",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk3 = {
|
|
||||||
.name = "pll1_sysclk3",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int da850_async3_set_parent(struct clk *clk, struct clk *parent)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
|
||||||
|
|
||||||
if (parent == &pll0_sysclk2) {
|
|
||||||
val &= ~CFGCHIP3_ASYNC3_CLKSRC;
|
|
||||||
} else if (parent == &pll1_sysclk2) {
|
|
||||||
val |= CFGCHIP3_ASYNC3_CLKSRC;
|
|
||||||
} else {
|
|
||||||
pr_err("Bad parent on async3 clock mux\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clk async3_clk = {
|
|
||||||
.name = "async3",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.set_parent = da850_async3_set_parent,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c0_clk = {
|
|
||||||
.name = "i2c0",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timerp64_0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timerp64_1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll0_aux_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_rom_clk = {
|
|
||||||
.name = "arm_rom",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tpcc0_clk = {
|
|
||||||
.name = "tpcc0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPCC,
|
|
||||||
.flags = ALWAYS_ENABLED | CLK_PSC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tptc0_clk = {
|
|
||||||
.name = "tptc0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPTC0,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tptc1_clk = {
|
|
||||||
.name = "tptc1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_TPTC1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tpcc1_clk = {
|
|
||||||
.name = "tpcc1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA850_LPSC1_TPCC1,
|
|
||||||
.gpsc = 1,
|
|
||||||
.flags = CLK_PSC | ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk tptc2_clk = {
|
|
||||||
.name = "tptc2",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA850_LPSC1_TPTC2,
|
|
||||||
.gpsc = 1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pruss_clk = {
|
|
||||||
.name = "pruss",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_PRUSS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_UART1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart2_clk = {
|
|
||||||
.name = "uart2",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_UART2,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aintc_clk = {
|
|
||||||
.name = "aintc",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC0_AINTC,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_GPIO,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c1_clk = {
|
|
||||||
.name = "i2c1",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_I2C,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emif3_clk = {
|
|
||||||
.name = "emif3",
|
|
||||||
.parent = &pll0_sysclk5,
|
|
||||||
.lpsc = DA8XX_LPSC1_EMIF3C,
|
|
||||||
.gpsc = 1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm",
|
|
||||||
.parent = &pll0_sysclk6,
|
|
||||||
.lpsc = DA8XX_LPSC0_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
.set_rate = da850_set_armrate,
|
|
||||||
.round_rate = da850_round_armrate,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk rmii_clk = {
|
|
||||||
.name = "rmii",
|
|
||||||
.parent = &pll0_sysclk7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emac_clk = {
|
|
||||||
.name = "emac",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_CPGMAC,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In order to avoid adding the emac_clk to the clock lookup table twice (and
|
|
||||||
* screwing up the linked list in the process) create a separate clock for
|
|
||||||
* mdio inheriting the rate from emac_clk.
|
|
||||||
*/
|
|
||||||
static struct clk mdio_clk = {
|
|
||||||
.name = "mdio",
|
|
||||||
.parent = &emac_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp_clk = {
|
|
||||||
.name = "mcasp",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_McASP0,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcbsp0_clk = {
|
|
||||||
.name = "mcbsp0",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA850_LPSC1_McBSP0,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcbsp1_clk = {
|
|
||||||
.name = "mcbsp1",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA850_LPSC1_McBSP1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk lcdc_clk = {
|
|
||||||
.name = "lcdc",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_LCDC,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd0_clk = {
|
|
||||||
.name = "mmcsd0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_MMC_SD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd1_clk = {
|
|
||||||
.name = "mmcsd1",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA850_LPSC1_MMC_SD1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll0_sysclk3,
|
|
||||||
.lpsc = DA8XX_LPSC0_EMIF25,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In order to avoid adding the aemif_clk to the clock lookup table twice (and
|
|
||||||
* screwing up the linked list in the process) create a separate clock for
|
|
||||||
* nand inheriting the rate from aemif_clk.
|
|
||||||
*/
|
|
||||||
static struct clk aemif_nand_clk = {
|
|
||||||
.name = "nand",
|
|
||||||
.parent = &aemif_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb11_clk = {
|
|
||||||
.name = "usb11",
|
|
||||||
.parent = &pll0_sysclk4,
|
|
||||||
.lpsc = DA8XX_LPSC1_USB11,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb20_clk = {
|
|
||||||
.name = "usb20",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC1_USB20,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk cppi41_clk = {
|
|
||||||
.name = "cppi41",
|
|
||||||
.parent = &usb20_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi0_clk = {
|
|
||||||
.name = "spi0",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA8XX_LPSC0_SPI0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi1_clk = {
|
|
||||||
.name = "spi1",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_SPI1,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpif_clk = {
|
|
||||||
.name = "vpif",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA850_LPSC1_VPIF,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk sata_clk = {
|
|
||||||
.name = "sata",
|
|
||||||
.parent = &pll0_sysclk2,
|
|
||||||
.lpsc = DA850_LPSC1_SATA,
|
|
||||||
.gpsc = 1,
|
|
||||||
.flags = PSC_FORCE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk dsp_clk = {
|
|
||||||
.name = "dsp",
|
|
||||||
.parent = &pll0_sysclk1,
|
|
||||||
.domain = DAVINCI_GPSC_DSPDOMAIN,
|
|
||||||
.lpsc = DA8XX_LPSC0_GEM,
|
|
||||||
.flags = PSC_LRST | PSC_FORCE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ehrpwm_clk = {
|
|
||||||
.name = "ehrpwm",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_PWM,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ehrpwm0_clk = {
|
|
||||||
.name = "ehrpwm0",
|
|
||||||
.parent = &ehrpwm_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ehrpwm1_clk = {
|
|
||||||
.name = "ehrpwm1",
|
|
||||||
.parent = &ehrpwm_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
|
|
||||||
|
|
||||||
static void ehrpwm_tblck_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
|
|
||||||
val |= DA8XX_EHRPWM_TBCLKSYNC;
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ehrpwm_tblck_disable(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
|
|
||||||
val &= ~DA8XX_EHRPWM_TBCLKSYNC;
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clk ehrpwm_tbclk = {
|
|
||||||
.name = "ehrpwm_tbclk",
|
|
||||||
.parent = &ehrpwm_clk,
|
|
||||||
.clk_enable = ehrpwm_tblck_enable,
|
|
||||||
.clk_disable = ehrpwm_tblck_disable,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ehrpwm0_tbclk = {
|
|
||||||
.name = "ehrpwm0_tbclk",
|
|
||||||
.parent = &ehrpwm_tbclk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ehrpwm1_tbclk = {
|
|
||||||
.name = "ehrpwm1_tbclk",
|
|
||||||
.parent = &ehrpwm_tbclk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap_clk = {
|
|
||||||
.name = "ecap",
|
|
||||||
.parent = &async3_clk,
|
|
||||||
.lpsc = DA8XX_LPSC1_ECAP,
|
|
||||||
.gpsc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap0_clk = {
|
|
||||||
.name = "ecap0_clk",
|
|
||||||
.parent = &ecap_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap1_clk = {
|
|
||||||
.name = "ecap1_clk",
|
|
||||||
.parent = &ecap_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ecap2_clk = {
|
|
||||||
.name = "ecap2_clk",
|
|
||||||
.parent = &ecap_clk,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup da850_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "pll0", &pll0_clk),
|
|
||||||
CLK(NULL, "pll0_aux", &pll0_aux_clk),
|
|
||||||
CLK(NULL, "pll0_sysclk1", &pll0_sysclk1),
|
|
||||||
CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
|
|
||||||
CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
|
|
||||||
CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
|
|
||||||
CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
|
|
||||||
CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
|
|
||||||
CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
|
|
||||||
CLK(NULL, "pll1", &pll1_clk),
|
|
||||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
||||||
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
|
|
||||||
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
|
|
||||||
CLK(NULL, "async3", &async3_clk),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c0_clk),
|
|
||||||
CLK(NULL, "timer0", &timerp64_0_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timerp64_1_clk),
|
|
||||||
CLK(NULL, "arm_rom", &arm_rom_clk),
|
|
||||||
CLK(NULL, "tpcc0", &tpcc0_clk),
|
|
||||||
CLK(NULL, "tptc0", &tptc0_clk),
|
|
||||||
CLK(NULL, "tptc1", &tptc1_clk),
|
|
||||||
CLK(NULL, "tpcc1", &tpcc1_clk),
|
|
||||||
CLK(NULL, "tptc2", &tptc2_clk),
|
|
||||||
CLK("pruss_uio", "pruss", &pruss_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("serial8250.2", NULL, &uart2_clk),
|
|
||||||
CLK(NULL, "aintc", &aintc_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK("i2c_davinci.2", NULL, &i2c1_clk),
|
|
||||||
CLK(NULL, "emif3", &emif3_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK(NULL, "rmii", &rmii_clk),
|
|
||||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
||||||
CLK("davinci_mdio.0", "fck", &mdio_clk),
|
|
||||||
CLK("davinci-mcasp.0", NULL, &mcasp_clk),
|
|
||||||
CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
|
|
||||||
CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
|
|
||||||
CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
|
|
||||||
CLK("da830-mmc.0", NULL, &mmcsd0_clk),
|
|
||||||
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
|
|
||||||
CLK("ti-aemif", NULL, &aemif_clk),
|
|
||||||
CLK("davinci-nand.0", "aemif", &aemif_nand_clk),
|
|
||||||
CLK("ohci-da8xx", NULL, &usb11_clk),
|
|
||||||
CLK("musb-da8xx", NULL, &usb20_clk),
|
|
||||||
CLK("cppi41-dmaengine", NULL, &cppi41_clk),
|
|
||||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
|
||||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
|
||||||
CLK("vpif", NULL, &vpif_clk),
|
|
||||||
CLK("ahci_da850", "fck", &sata_clk),
|
|
||||||
CLK("davinci-rproc.0", NULL, &dsp_clk),
|
|
||||||
CLK(NULL, NULL, &ehrpwm_clk),
|
|
||||||
CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
|
|
||||||
CLK("ehrpwm.1", "fck", &ehrpwm1_clk),
|
|
||||||
CLK(NULL, NULL, &ehrpwm_tbclk),
|
|
||||||
CLK("ehrpwm.0", "tbclk", &ehrpwm0_tbclk),
|
|
||||||
CLK("ehrpwm.1", "tbclk", &ehrpwm1_tbclk),
|
|
||||||
CLK(NULL, NULL, &ecap_clk),
|
|
||||||
CLK("ecap.0", "fck", &ecap0_clk),
|
|
||||||
CLK("ecap.1", "fck", &ecap1_clk),
|
|
||||||
CLK("ecap.2", "fck", &ecap2_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device specific mux setup
|
* Device specific mux setup
|
||||||
*
|
*
|
||||||
|
@ -958,8 +418,6 @@ static struct map_desc da850_io_desc[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
|
|
||||||
|
|
||||||
/* Contents of JTAG ID register used to identify exact cpu type */
|
/* Contents of JTAG ID register used to identify exact cpu type */
|
||||||
static struct davinci_id da850_ids[] = {
|
static struct davinci_id da850_ids[] = {
|
||||||
{
|
{
|
||||||
|
@ -1169,89 +627,11 @@ int da850_register_cpufreq(char *async_clk)
|
||||||
|
|
||||||
return platform_device_register(&da850_cpufreq_device);
|
return platform_device_register(&da850_cpufreq_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int da850_round_armrate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
int ret = 0, diff;
|
|
||||||
unsigned int best = (unsigned int) -1;
|
|
||||||
struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
|
|
||||||
struct cpufreq_frequency_table *pos;
|
|
||||||
|
|
||||||
rate /= 1000; /* convert to kHz */
|
|
||||||
|
|
||||||
cpufreq_for_each_entry(pos, table) {
|
|
||||||
diff = pos->frequency - rate;
|
|
||||||
if (diff < 0)
|
|
||||||
diff = -diff;
|
|
||||||
|
|
||||||
if (diff < best) {
|
|
||||||
best = diff;
|
|
||||||
ret = pos->frequency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int da850_set_armrate(struct clk *clk, unsigned long index)
|
|
||||||
{
|
|
||||||
struct clk *pllclk = &pll0_clk;
|
|
||||||
|
|
||||||
return clk_set_rate(pllclk, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
struct pll_data *pll = clk->pll_data;
|
|
||||||
struct cpufreq_frequency_table *freq;
|
|
||||||
unsigned int prediv, mult, postdiv;
|
|
||||||
struct da850_opp *opp = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
rate /= 1000;
|
|
||||||
|
|
||||||
for (freq = da850_freq_table;
|
|
||||||
freq->frequency != CPUFREQ_TABLE_END; freq++) {
|
|
||||||
/* rate is in Hz, freq->frequency is in KHz */
|
|
||||||
if (freq->frequency == rate) {
|
|
||||||
opp = (struct da850_opp *)freq->driver_data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opp)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
prediv = opp->prediv;
|
|
||||||
mult = opp->mult;
|
|
||||||
postdiv = opp->postdiv;
|
|
||||||
|
|
||||||
ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
|
|
||||||
if (WARN_ON(ret))
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
int __init da850_register_cpufreq(char *async_clk)
|
int __init da850_register_cpufreq(char *async_clk)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int da850_set_armrate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int da850_round_armrate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
return clk->rate;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* VPIF resource, platform data */
|
/* VPIF resource, platform data */
|
||||||
|
@ -1353,8 +733,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
|
||||||
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
|
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
|
||||||
.ids = da850_ids,
|
.ids = da850_ids,
|
||||||
.ids_num = ARRAY_SIZE(da850_ids),
|
.ids_num = ARRAY_SIZE(da850_ids),
|
||||||
.psc_bases = da850_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(da850_psc_bases),
|
|
||||||
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
|
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
|
||||||
.pinmux_pins = da850_pins,
|
.pinmux_pins = da850_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(da850_pins),
|
.pinmux_pins_num = ARRAY_SIZE(da850_pins),
|
||||||
|
@ -1370,8 +748,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
|
||||||
|
|
||||||
void __init da850_init(void)
|
void __init da850_init(void)
|
||||||
{
|
{
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
davinci_common_init(&davinci_soc_info_da850);
|
davinci_common_init(&davinci_soc_info_da850);
|
||||||
|
|
||||||
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
|
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
|
||||||
|
@ -1379,22 +755,124 @@ void __init da850_init(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
|
da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
|
||||||
if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
|
WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module");
|
||||||
return;
|
|
||||||
|
|
||||||
/* Unlock writing to PLL0 registers */
|
|
||||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
|
|
||||||
v &= ~CFGCHIP0_PLL_MASTER_LOCK;
|
|
||||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
|
|
||||||
|
|
||||||
/* Unlock writing to PLL1 registers */
|
|
||||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
|
||||||
v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
|
|
||||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init da850_init_time(void)
|
void __init da850_init_time(void)
|
||||||
{
|
{
|
||||||
davinci_clk_init(da850_clks);
|
void __iomem *pll0;
|
||||||
davinci_timer_init();
|
struct regmap *cfgchip;
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
|
||||||
|
|
||||||
|
pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
|
||||||
|
cfgchip = da8xx_get_cfgchip();
|
||||||
|
|
||||||
|
da850_pll0_init(NULL, pll0, cfgchip);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource da850_pll1_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DA850_PLL1_BASE,
|
||||||
|
.end = DA850_PLL1_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct davinci_pll_platform_data da850_pll1_pdata;
|
||||||
|
|
||||||
|
static struct platform_device da850_pll1_device = {
|
||||||
|
.name = "da850-pll1",
|
||||||
|
.id = -1,
|
||||||
|
.resource = da850_pll1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(da850_pll1_resources),
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_pll1_pdata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource da850_psc0_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_PSC0_BASE,
|
||||||
|
.end = DA8XX_PSC0_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da850_psc0_device = {
|
||||||
|
.name = "da850-psc0",
|
||||||
|
.id = -1,
|
||||||
|
.resource = da850_psc0_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(da850_psc0_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource da850_psc1_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DA8XX_PSC1_BASE,
|
||||||
|
.end = DA8XX_PSC1_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device da850_psc1_device = {
|
||||||
|
.name = "da850-psc1",
|
||||||
|
.id = -1,
|
||||||
|
.resource = da850_psc1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(da850_psc1_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct da8xx_cfgchip_clk_platform_data da850_async1_pdata;
|
||||||
|
|
||||||
|
static struct platform_device da850_async1_clksrc_device = {
|
||||||
|
.name = "da850-async1-clksrc",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_async1_pdata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct da8xx_cfgchip_clk_platform_data da850_async3_pdata;
|
||||||
|
|
||||||
|
static struct platform_device da850_async3_clksrc_device = {
|
||||||
|
.name = "da850-async3-clksrc",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_async3_pdata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct da8xx_cfgchip_clk_platform_data da850_tbclksync_pdata;
|
||||||
|
|
||||||
|
static struct platform_device da850_tbclksync_device = {
|
||||||
|
.name = "da830-tbclksync",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &da850_tbclksync_pdata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init da850_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* PLL0 is registered in da850_init_time() */
|
||||||
|
|
||||||
|
da850_pll1_pdata.cfgchip = da8xx_get_cfgchip();
|
||||||
|
platform_device_register(&da850_pll1_device);
|
||||||
|
|
||||||
|
da850_async1_pdata.cfgchip = da8xx_get_cfgchip();
|
||||||
|
platform_device_register(&da850_async1_clksrc_device);
|
||||||
|
|
||||||
|
da850_async3_pdata.cfgchip = da8xx_get_cfgchip();
|
||||||
|
platform_device_register(&da850_async3_clksrc_device);
|
||||||
|
|
||||||
|
platform_device_register(&da850_psc0_device);
|
||||||
|
|
||||||
|
platform_device_register(&da850_psc1_device);
|
||||||
|
|
||||||
|
da850_tbclksync_pdata.cfgchip = da8xx_get_cfgchip();
|
||||||
|
platform_device_register(&da850_tbclksync_device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,81 +7,16 @@
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/of_irq.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
#include <linux/irqdomain.h>
|
|
||||||
#include <linux/platform_data/ti-aemif.h>
|
|
||||||
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include "cp_intc.h"
|
|
||||||
#include <mach/da8xx.h>
|
#include <mach/da8xx.h>
|
||||||
|
|
||||||
static struct of_dev_auxdata da850_aemif_auxdata_lookup[] = {
|
|
||||||
OF_DEV_AUXDATA("ti,davinci-nand", 0x62000000, "davinci-nand.0", NULL),
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct aemif_platform_data aemif_data = {
|
|
||||||
.dev_lookup = da850_aemif_auxdata_lookup,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
|
|
||||||
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01e28000, "i2c_davinci.2", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm.1", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap.1", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap.2", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-spi", 0x01c41000, "spi_davinci.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
|
|
||||||
OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
|
|
||||||
OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
|
|
||||||
NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", &aemif_data),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
|
|
||||||
OF_DEV_AUXDATA("ti,da850-dsp", 0x11800000, "davinci-rproc.0", NULL),
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_DAVINCI_DA850
|
#ifdef CONFIG_ARCH_DAVINCI_DA850
|
||||||
|
|
||||||
static void __init da850_init_machine(void)
|
static void __init da850_init_machine(void)
|
||||||
{
|
{
|
||||||
/* All existing boards use 100MHz SATA refclkpn */
|
|
||||||
static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = da8xx_register_usb20_phy_clk(false);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
|
|
||||||
__func__, ret);
|
|
||||||
ret = da8xx_register_usb11_phy_clk(false);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
|
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
ret = da850_register_sata_refclk(sata_refclkpn);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: registering SATA REFCLK failed: %d",
|
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
|
|
||||||
davinci_pm_init();
|
davinci_pm_init();
|
||||||
pdata_quirks_init();
|
pdata_quirks_init();
|
||||||
}
|
}
|
||||||
|
@ -96,7 +31,6 @@ static const char *const da850_boards_compat[] __initconst = {
|
||||||
|
|
||||||
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
|
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
|
||||||
.map_io = da850_init,
|
.map_io = da850_init,
|
||||||
.init_time = da850_init_time,
|
|
||||||
.init_machine = da850_init_machine,
|
.init_machine = da850_init_machine,
|
||||||
.dt_compat = da850_boards_compat,
|
.dt_compat = da850_boards_compat,
|
||||||
.init_late = davinci_init_late,
|
.init_late = davinci_init_late,
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
#include <media/davinci/vpbe.h>
|
#include <media/davinci/vpbe.h>
|
||||||
#include <media/davinci/vpbe_osd.h>
|
#include <media/davinci/vpbe_osd.h>
|
||||||
|
|
||||||
|
#define DAVINCI_PLL1_BASE 0x01c40800
|
||||||
|
#define DAVINCI_PLL2_BASE 0x01c40c00
|
||||||
|
#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01c41000
|
||||||
|
|
||||||
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
|
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
|
||||||
#define SYSMOD_VDAC_CONFIG 0x2c
|
#define SYSMOD_VDAC_CONFIG 0x2c
|
||||||
#define SYSMOD_VIDCLKCTL 0x38
|
#define SYSMOD_VIDCLKCTL 0x38
|
||||||
|
@ -84,6 +88,7 @@ int davinci_init_wdt(void);
|
||||||
/* DM355 function declarations */
|
/* DM355 function declarations */
|
||||||
void dm355_init(void);
|
void dm355_init(void);
|
||||||
void dm355_init_time(void);
|
void dm355_init_time(void);
|
||||||
|
void dm355_register_clocks(void);
|
||||||
void dm355_init_spi0(unsigned chipselect_mask,
|
void dm355_init_spi0(unsigned chipselect_mask,
|
||||||
const struct spi_board_info *info, unsigned len);
|
const struct spi_board_info *info, unsigned len);
|
||||||
void dm355_init_asp1(u32 evt_enable);
|
void dm355_init_asp1(u32 evt_enable);
|
||||||
|
@ -93,6 +98,7 @@ int dm355_gpio_register(void);
|
||||||
/* DM365 function declarations */
|
/* DM365 function declarations */
|
||||||
void dm365_init(void);
|
void dm365_init(void);
|
||||||
void dm365_init_time(void);
|
void dm365_init_time(void);
|
||||||
|
void dm365_register_clocks(void);
|
||||||
void dm365_init_asp(void);
|
void dm365_init_asp(void);
|
||||||
void dm365_init_vc(void);
|
void dm365_init_vc(void);
|
||||||
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
|
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
|
||||||
|
@ -106,6 +112,7 @@ int dm365_gpio_register(void);
|
||||||
void dm644x_init(void);
|
void dm644x_init(void);
|
||||||
void dm644x_init_devices(void);
|
void dm644x_init_devices(void);
|
||||||
void dm644x_init_time(void);
|
void dm644x_init_time(void);
|
||||||
|
void dm644x_register_clocks(void);
|
||||||
void dm644x_init_asp(void);
|
void dm644x_init_asp(void);
|
||||||
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
|
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
|
||||||
int dm644x_gpio_register(void);
|
int dm644x_gpio_register(void);
|
||||||
|
@ -113,6 +120,7 @@ int dm644x_gpio_register(void);
|
||||||
/* DM646x function declarations */
|
/* DM646x function declarations */
|
||||||
void dm646x_init(void);
|
void dm646x_init(void);
|
||||||
void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
|
void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
|
||||||
|
void dm646x_register_clocks(void);
|
||||||
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
|
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
|
||||||
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
|
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
|
||||||
int dm646x_init_edma(struct edma_rsv_info *rsv);
|
int dm646x_init_edma(struct edma_rsv_info *rsv);
|
||||||
|
|
|
@ -10,26 +10,26 @@
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
#include <linux/ahci_platform.h>
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
|
#include <linux/dma-contiguous.h>
|
||||||
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/dma-contiguous.h>
|
|
||||||
#include <linux/serial_8250.h>
|
|
||||||
#include <linux/ahci_platform.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/serial_8250.h>
|
||||||
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/time.h>
|
#include <mach/cputype.h>
|
||||||
#include <mach/da8xx.h>
|
#include <mach/da8xx.h>
|
||||||
#include <mach/clock.h>
|
#include <mach/time.h>
|
||||||
|
|
||||||
|
#include "asp.h"
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
#include "asp.h"
|
|
||||||
|
|
||||||
#define DA8XX_TPCC_BASE 0x01c00000
|
#define DA8XX_TPCC_BASE 0x01c00000
|
||||||
#define DA8XX_TPTC0_BASE 0x01c08000
|
#define DA8XX_TPTC0_BASE 0x01c08000
|
||||||
#define DA8XX_TPTC1_BASE 0x01c08400
|
#define DA8XX_TPTC1_BASE 0x01c08400
|
||||||
|
@ -1040,26 +1040,15 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_DAVINCI_DA850
|
#ifdef CONFIG_ARCH_DAVINCI_DA850
|
||||||
static struct clk sata_refclk = {
|
|
||||||
.name = "sata_refclk",
|
|
||||||
.set_rate = davinci_simple_set_rate,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup sata_refclk_lookup =
|
|
||||||
CLK("ahci_da850", "refclk", &sata_refclk);
|
|
||||||
|
|
||||||
int __init da850_register_sata_refclk(int rate)
|
int __init da850_register_sata_refclk(int rate)
|
||||||
{
|
{
|
||||||
int ret;
|
struct clk *clk;
|
||||||
|
|
||||||
sata_refclk.rate = rate;
|
clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
|
||||||
ret = clk_register(&sata_refclk);
|
if (IS_ERR(clk))
|
||||||
if (ret)
|
return PTR_ERR(clk);
|
||||||
return ret;
|
|
||||||
|
|
||||||
clkdev_add(&sata_refclk_lookup);
|
return clk_register_clkdev(clk, "refclk", "ahci_da850");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resource da850_sata_resources[] = {
|
static struct resource da850_sata_resources[] = {
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include "davinci.h"
|
#include "davinci.h"
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
#define DAVINCI_I2C_BASE 0x01C21000
|
#define DAVINCI_I2C_BASE 0x01C21000
|
||||||
#define DAVINCI_ATA_BASE 0x01C66000
|
#define DAVINCI_ATA_BASE 0x01C66000
|
||||||
|
|
|
@ -8,31 +8,32 @@
|
||||||
* is licensed "as is" without any warranty of any kind, whether express
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
* or implied.
|
* or implied.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/clk/davinci.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/clkdev.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_data/edma.h>
|
#include <linux/platform_data/edma.h>
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
#include <linux/platform_data/spi-davinci.h>
|
#include <linux/platform_data/spi-davinci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/mux.h>
|
|
||||||
#include <mach/irqs.h>
|
|
||||||
#include <mach/time.h>
|
|
||||||
#include <mach/serial.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
|
#include <mach/cputype.h>
|
||||||
|
#include <mach/irqs.h>
|
||||||
|
#include <mach/mux.h>
|
||||||
|
#include <mach/serial.h>
|
||||||
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "davinci.h"
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
|
||||||
#include "asp.h"
|
#include "asp.h"
|
||||||
|
#include "davinci.h"
|
||||||
|
#include "mux.h"
|
||||||
|
|
||||||
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
|
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
|
||||||
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
|
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
|
||||||
|
@ -43,348 +44,6 @@
|
||||||
*/
|
*/
|
||||||
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
|
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
|
||||||
|
|
||||||
static struct pll_data pll1_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DAVINCI_PLL1_BASE,
|
|
||||||
.flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pll_data pll2_data = {
|
|
||||||
.num = 2,
|
|
||||||
.phys_base = DAVINCI_PLL2_BASE,
|
|
||||||
.flags = PLL_HAS_PREDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
/* FIXME -- crystal rate is board-specific */
|
|
||||||
.rate = DM355_REF_FREQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_clk = {
|
|
||||||
.name = "pll1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.pll_data = &pll1_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_aux_clk = {
|
|
||||||
.name = "pll1_aux_clk",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk1 = {
|
|
||||||
.name = "pll1_sysclk1",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk2 = {
|
|
||||||
.name = "pll1_sysclk2",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk3 = {
|
|
||||||
.name = "pll1_sysclk3",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk4 = {
|
|
||||||
.name = "pll1_sysclk4",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclkbp = {
|
|
||||||
.name = "pll1_sysclkbp",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_dac_clk = {
|
|
||||||
.name = "vpss_dac",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM355_LPSC_VPSS_DAC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_master_clk = {
|
|
||||||
.name = "vpss_master",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_VPSSMSTR,
|
|
||||||
.flags = CLK_PSC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_slave_clk = {
|
|
||||||
.name = "vpss_slave",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_VPSSSLV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk clkout1_clk = {
|
|
||||||
.name = "clkout1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
/* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk clkout2_clk = {
|
|
||||||
.name = "clkout2",
|
|
||||||
.parent = &pll1_sysclkbp,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_clk = {
|
|
||||||
.name = "pll2",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.pll_data = &pll2_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk1 = {
|
|
||||||
.name = "pll2_sysclk1",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclkbp = {
|
|
||||||
.name = "pll2_sysclkbp",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk clkout3_clk = {
|
|
||||||
.name = "clkout3",
|
|
||||||
.parent = &pll2_sysclkbp,
|
|
||||||
/* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm_clk",
|
|
||||||
.parent = &pll1_sysclk1,
|
|
||||||
.lpsc = DAVINCI_LPSC_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOT LISTED below, and not touched by Linux
|
|
||||||
* - in SyncReset state by default
|
|
||||||
* .lpsc = DAVINCI_LPSC_TPCC,
|
|
||||||
* .lpsc = DAVINCI_LPSC_TPTC0,
|
|
||||||
* .lpsc = DAVINCI_LPSC_TPTC1,
|
|
||||||
* .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
|
|
||||||
* .lpsc = DAVINCI_LPSC_MEMSTICK,
|
|
||||||
* - in Enabled state by default
|
|
||||||
* .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
|
|
||||||
* .lpsc = DAVINCI_LPSC_SCR2, // "bus"
|
|
||||||
* .lpsc = DAVINCI_LPSC_SCR3, // "bus"
|
|
||||||
* .lpsc = DAVINCI_LPSC_SCR4, // "bus"
|
|
||||||
* .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
|
|
||||||
* .lpsc = DAVINCI_LPSC_CFG27, // "test"
|
|
||||||
* .lpsc = DAVINCI_LPSC_CFG3, // "test"
|
|
||||||
* .lpsc = DAVINCI_LPSC_CFG5, // "test"
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct clk mjcp_clk = {
|
|
||||||
.name = "mjcp",
|
|
||||||
.parent = &pll1_sysclk1,
|
|
||||||
.lpsc = DAVINCI_LPSC_IMCOP,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart2_clk = {
|
|
||||||
.name = "uart2",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c_clk = {
|
|
||||||
.name = "i2c",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_I2C,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk asp0_clk = {
|
|
||||||
.name = "asp0",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_McBSP,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk asp1_clk = {
|
|
||||||
.name = "asp1",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM355_LPSC_McBSP1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd0_clk = {
|
|
||||||
.name = "mmcsd0",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_MMC_SD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd1_clk = {
|
|
||||||
.name = "mmcsd1",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM355_LPSC_MMC_SD1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi0_clk = {
|
|
||||||
.name = "spi0",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_SPI,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi1_clk = {
|
|
||||||
.name = "spi1",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM355_LPSC_SPI1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi2_clk = {
|
|
||||||
.name = "spi2",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM355_LPSC_SPI2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_AEMIF,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm0_clk = {
|
|
||||||
.name = "pwm0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm1_clk = {
|
|
||||||
.name = "pwm1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm2_clk = {
|
|
||||||
.name = "pwm2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm3_clk = {
|
|
||||||
.name = "pwm3",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DM355_LPSC_PWM3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer2_clk = {
|
|
||||||
.name = "timer2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER2,
|
|
||||||
.usecount = 1, /* REVISIT: why can't this be disabled? */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer3_clk = {
|
|
||||||
.name = "timer3",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DM355_LPSC_TIMER3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk rto_clk = {
|
|
||||||
.name = "rto",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DM355_LPSC_RTO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb_clk = {
|
|
||||||
.name = "usb",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_USB,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup dm355_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "pll1", &pll1_clk),
|
|
||||||
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
|
|
||||||
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
|
|
||||||
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
|
|
||||||
CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
|
|
||||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
||||||
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
|
|
||||||
CLK(NULL, "vpss_dac", &vpss_dac_clk),
|
|
||||||
CLK("vpss", "master", &vpss_master_clk),
|
|
||||||
CLK("vpss", "slave", &vpss_slave_clk),
|
|
||||||
CLK(NULL, "clkout1", &clkout1_clk),
|
|
||||||
CLK(NULL, "clkout2", &clkout2_clk),
|
|
||||||
CLK(NULL, "pll2", &pll2_clk),
|
|
||||||
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
|
|
||||||
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
|
|
||||||
CLK(NULL, "clkout3", &clkout3_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK(NULL, "mjcp", &mjcp_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("serial8250.2", NULL, &uart2_clk),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c_clk),
|
|
||||||
CLK("davinci-mcbsp.0", NULL, &asp0_clk),
|
|
||||||
CLK("davinci-mcbsp.1", NULL, &asp1_clk),
|
|
||||||
CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
|
|
||||||
CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
|
|
||||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
|
||||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
|
||||||
CLK("spi_davinci.2", NULL, &spi2_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK(NULL, "aemif", &aemif_clk),
|
|
||||||
CLK(NULL, "pwm0", &pwm0_clk),
|
|
||||||
CLK(NULL, "pwm1", &pwm1_clk),
|
|
||||||
CLK(NULL, "pwm2", &pwm2_clk),
|
|
||||||
CLK(NULL, "pwm3", &pwm3_clk),
|
|
||||||
CLK(NULL, "timer0", &timer0_clk),
|
|
||||||
CLK(NULL, "timer1", &timer1_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timer2_clk),
|
|
||||||
CLK(NULL, "timer3", &timer3_clk),
|
|
||||||
CLK(NULL, "rto", &rto_clk),
|
|
||||||
CLK(NULL, "usb", &usb_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
|
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
static struct resource dm355_spi0_resources[] = {
|
static struct resource dm355_spi0_resources[] = {
|
||||||
|
@ -926,8 +585,6 @@ static struct davinci_id dm355_ids[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
||||||
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
||||||
|
@ -1012,8 +669,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
|
||||||
.jtag_id_reg = 0x01c40028,
|
.jtag_id_reg = 0x01c40028,
|
||||||
.ids = dm355_ids,
|
.ids = dm355_ids,
|
||||||
.ids_num = ARRAY_SIZE(dm355_ids),
|
.ids_num = ARRAY_SIZE(dm355_ids),
|
||||||
.psc_bases = dm355_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
|
|
||||||
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
||||||
.pinmux_pins = dm355_pins,
|
.pinmux_pins = dm355_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(dm355_pins),
|
.pinmux_pins_num = ARRAY_SIZE(dm355_pins),
|
||||||
|
@ -1046,8 +701,41 @@ void __init dm355_init(void)
|
||||||
|
|
||||||
void __init dm355_init_time(void)
|
void __init dm355_init_time(void)
|
||||||
{
|
{
|
||||||
davinci_clk_init(dm355_clks);
|
void __iomem *pll1, *psc;
|
||||||
davinci_timer_init();
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
|
||||||
|
|
||||||
|
pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
|
||||||
|
dm355_pll1_init(NULL, pll1, NULL);
|
||||||
|
|
||||||
|
psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
|
||||||
|
dm355_psc_init(NULL, psc);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource dm355_pll2_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DAVINCI_PLL2_BASE,
|
||||||
|
.end = DAVINCI_PLL2_BASE + SZ_1K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device dm355_pll2_device = {
|
||||||
|
.name = "dm355-pll2",
|
||||||
|
.id = -1,
|
||||||
|
.resource = dm355_pll2_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(dm355_pll2_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init dm355_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* PLL1 and PSC are registered in dm355_init_time() */
|
||||||
|
platform_device_register(&dm355_pll2_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
|
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
|
||||||
|
|
|
@ -12,32 +12,33 @@
|
||||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/clk/davinci.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/clkdev.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_data/edma.h>
|
#include <linux/platform_data/edma.h>
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
#include <linux/platform_data/keyscan-davinci.h>
|
#include <linux/platform_data/keyscan-davinci.h>
|
||||||
#include <linux/platform_data/spi-davinci.h>
|
#include <linux/platform_data/spi-davinci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/mux.h>
|
|
||||||
#include <mach/irqs.h>
|
|
||||||
#include <mach/time.h>
|
|
||||||
#include <mach/serial.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
|
#include <mach/cputype.h>
|
||||||
|
#include <mach/irqs.h>
|
||||||
|
#include <mach/mux.h>
|
||||||
|
#include <mach/serial.h>
|
||||||
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "davinci.h"
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
|
||||||
#include "asp.h"
|
#include "asp.h"
|
||||||
|
#include "davinci.h"
|
||||||
|
#include "mux.h"
|
||||||
|
|
||||||
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
|
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
|
||||||
#define DM365_RTC_BASE 0x01c69000
|
#define DM365_RTC_BASE 0x01c69000
|
||||||
|
@ -54,440 +55,6 @@
|
||||||
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
|
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
|
||||||
#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000
|
#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000
|
||||||
|
|
||||||
static struct pll_data pll1_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DAVINCI_PLL1_BASE,
|
|
||||||
.flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pll_data pll2_data = {
|
|
||||||
.num = 2,
|
|
||||||
.phys_base = DAVINCI_PLL2_BASE,
|
|
||||||
.flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
.rate = DM365_REF_FREQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_clk = {
|
|
||||||
.name = "pll1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.pll_data = &pll1_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_aux_clk = {
|
|
||||||
.name = "pll1_aux_clk",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclkbp = {
|
|
||||||
.name = "pll1_sysclkbp",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk clkout0_clk = {
|
|
||||||
.name = "clkout0",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk1 = {
|
|
||||||
.name = "pll1_sysclk1",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk2 = {
|
|
||||||
.name = "pll1_sysclk2",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk3 = {
|
|
||||||
.name = "pll1_sysclk3",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk4 = {
|
|
||||||
.name = "pll1_sysclk4",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk5 = {
|
|
||||||
.name = "pll1_sysclk5",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk6 = {
|
|
||||||
.name = "pll1_sysclk6",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk7 = {
|
|
||||||
.name = "pll1_sysclk7",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk8 = {
|
|
||||||
.name = "pll1_sysclk8",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV8,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk9 = {
|
|
||||||
.name = "pll1_sysclk9",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV9,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_clk = {
|
|
||||||
.name = "pll2",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.pll_data = &pll2_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_aux_clk = {
|
|
||||||
.name = "pll2_aux_clk",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk clkout1_clk = {
|
|
||||||
.name = "clkout1",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk1 = {
|
|
||||||
.name = "pll2_sysclk1",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk2 = {
|
|
||||||
.name = "pll2_sysclk2",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk3 = {
|
|
||||||
.name = "pll2_sysclk3",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk4 = {
|
|
||||||
.name = "pll2_sysclk4",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk5 = {
|
|
||||||
.name = "pll2_sysclk5",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk6 = {
|
|
||||||
.name = "pll2_sysclk6",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk7 = {
|
|
||||||
.name = "pll2_sysclk7",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk8 = {
|
|
||||||
.name = "pll2_sysclk8",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV8,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk9 = {
|
|
||||||
.name = "pll2_sysclk9",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV9,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_dac_clk = {
|
|
||||||
.name = "vpss_dac",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM365_LPSC_DAC_CLK,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_master_clk = {
|
|
||||||
.name = "vpss_master",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DM365_LPSC_VPSSMSTR,
|
|
||||||
.flags = CLK_PSC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_slave_clk = {
|
|
||||||
.name = "vpss_slave",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_VPSSSLV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm_clk",
|
|
||||||
.parent = &pll2_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c_clk = {
|
|
||||||
.name = "i2c",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_I2C,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd0_clk = {
|
|
||||||
.name = "mmcsd0",
|
|
||||||
.parent = &pll1_sysclk8,
|
|
||||||
.lpsc = DAVINCI_LPSC_MMC_SD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd1_clk = {
|
|
||||||
.name = "mmcsd1",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_MMC_SD1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi0_clk = {
|
|
||||||
.name = "spi0",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_SPI,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi1_clk = {
|
|
||||||
.name = "spi1",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_SPI1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi2_clk = {
|
|
||||||
.name = "spi2",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_SPI2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi3_clk = {
|
|
||||||
.name = "spi3",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_SPI3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi4_clk = {
|
|
||||||
.name = "spi4",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DM365_LPSC_SPI4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_AEMIF,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm0_clk = {
|
|
||||||
.name = "pwm0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm1_clk = {
|
|
||||||
.name = "pwm1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm2_clk = {
|
|
||||||
.name = "pwm2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm3_clk = {
|
|
||||||
.name = "pwm3",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.lpsc = DM365_LPSC_PWM3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer2_clk = {
|
|
||||||
.name = "timer2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER2,
|
|
||||||
.usecount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer3_clk = {
|
|
||||||
.name = "timer3",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DM365_LPSC_TIMER3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb_clk = {
|
|
||||||
.name = "usb",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_USB,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emac_clk = {
|
|
||||||
.name = "emac",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_EMAC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk voicecodec_clk = {
|
|
||||||
.name = "voice_codec",
|
|
||||||
.parent = &pll2_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_VOICE_CODEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk asp0_clk = {
|
|
||||||
.name = "asp0",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_McBSP1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk rto_clk = {
|
|
||||||
.name = "rto",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DM365_LPSC_RTO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mjcp_clk = {
|
|
||||||
.name = "mjcp",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM365_LPSC_MJCP,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup dm365_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "pll1", &pll1_clk),
|
|
||||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
||||||
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
|
|
||||||
CLK(NULL, "clkout0", &clkout0_clk),
|
|
||||||
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
|
|
||||||
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
|
|
||||||
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
|
|
||||||
CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
|
|
||||||
CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
|
|
||||||
CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
|
|
||||||
CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
|
|
||||||
CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
|
|
||||||
CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
|
|
||||||
CLK(NULL, "pll2", &pll2_clk),
|
|
||||||
CLK(NULL, "pll2_aux", &pll2_aux_clk),
|
|
||||||
CLK(NULL, "clkout1", &clkout1_clk),
|
|
||||||
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
|
|
||||||
CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
|
|
||||||
CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
|
|
||||||
CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
|
|
||||||
CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
|
|
||||||
CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
|
|
||||||
CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
|
|
||||||
CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
|
|
||||||
CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
|
|
||||||
CLK(NULL, "vpss_dac", &vpss_dac_clk),
|
|
||||||
CLK("vpss", "master", &vpss_master_clk),
|
|
||||||
CLK("vpss", "slave", &vpss_slave_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c_clk),
|
|
||||||
CLK("da830-mmc.0", NULL, &mmcsd0_clk),
|
|
||||||
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
|
|
||||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
|
||||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
|
||||||
CLK("spi_davinci.2", NULL, &spi2_clk),
|
|
||||||
CLK("spi_davinci.3", NULL, &spi3_clk),
|
|
||||||
CLK("spi_davinci.4", NULL, &spi4_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK(NULL, "aemif", &aemif_clk),
|
|
||||||
CLK(NULL, "pwm0", &pwm0_clk),
|
|
||||||
CLK(NULL, "pwm1", &pwm1_clk),
|
|
||||||
CLK(NULL, "pwm2", &pwm2_clk),
|
|
||||||
CLK(NULL, "pwm3", &pwm3_clk),
|
|
||||||
CLK(NULL, "timer0", &timer0_clk),
|
|
||||||
CLK(NULL, "timer1", &timer1_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timer2_clk),
|
|
||||||
CLK(NULL, "timer3", &timer3_clk),
|
|
||||||
CLK(NULL, "usb", &usb_clk),
|
|
||||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
||||||
CLK("davinci_mdio.0", "fck", &emac_clk),
|
|
||||||
CLK("davinci_voicecodec", NULL, &voicecodec_clk),
|
|
||||||
CLK("davinci-mcbsp", NULL, &asp0_clk),
|
|
||||||
CLK(NULL, "rto", &rto_clk),
|
|
||||||
CLK(NULL, "mjcp", &mjcp_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define INTMUX 0x18
|
#define INTMUX 0x18
|
||||||
#define EVTMUX 0x1c
|
#define EVTMUX 0x1c
|
||||||
|
|
||||||
|
@ -1054,8 +621,6 @@ static struct davinci_id dm365_ids[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
|
|
||||||
|
|
||||||
static struct davinci_timer_info dm365_timer_info = {
|
static struct davinci_timer_info dm365_timer_info = {
|
||||||
.timers = davinci_timer_instance,
|
.timers = davinci_timer_instance,
|
||||||
.clockevent_id = T0_BOT,
|
.clockevent_id = T0_BOT,
|
||||||
|
@ -1116,8 +681,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
|
||||||
.jtag_id_reg = 0x01c40028,
|
.jtag_id_reg = 0x01c40028,
|
||||||
.ids = dm365_ids,
|
.ids = dm365_ids,
|
||||||
.ids_num = ARRAY_SIZE(dm365_ids),
|
.ids_num = ARRAY_SIZE(dm365_ids),
|
||||||
.psc_bases = dm365_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
|
|
||||||
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
||||||
.pinmux_pins = dm365_pins,
|
.pinmux_pins = dm365_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(dm365_pins),
|
.pinmux_pins_num = ARRAY_SIZE(dm365_pins),
|
||||||
|
@ -1171,8 +734,28 @@ void __init dm365_init(void)
|
||||||
|
|
||||||
void __init dm365_init_time(void)
|
void __init dm365_init_time(void)
|
||||||
{
|
{
|
||||||
davinci_clk_init(dm365_clks);
|
void __iomem *pll1, *pll2, *psc;
|
||||||
davinci_timer_init();
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
|
||||||
|
|
||||||
|
pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
|
||||||
|
dm365_pll1_init(NULL, pll1, NULL);
|
||||||
|
|
||||||
|
pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_1K);
|
||||||
|
dm365_pll2_init(NULL, pll2, NULL);
|
||||||
|
|
||||||
|
psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
|
||||||
|
dm365_psc_init(NULL, psc);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init dm365_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* all clocks are currently registered in dm365_init_time() */
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resource dm365_vpss_resources[] = {
|
static struct resource dm365_vpss_resources[] = {
|
||||||
|
|
|
@ -8,28 +8,29 @@
|
||||||
* is licensed "as is" without any warranty of any kind, whether express
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
* or implied.
|
* or implied.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/clk/davinci.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_data/edma.h>
|
#include <linux/platform_data/edma.h>
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
#include <mach/common.h>
|
||||||
#include <mach/cputype.h>
|
#include <mach/cputype.h>
|
||||||
#include <mach/irqs.h>
|
#include <mach/irqs.h>
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/mux.h>
|
#include <mach/mux.h>
|
||||||
#include <mach/time.h>
|
|
||||||
#include <mach/serial.h>
|
#include <mach/serial.h>
|
||||||
#include <mach/common.h>
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "davinci.h"
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
|
||||||
#include "asp.h"
|
#include "asp.h"
|
||||||
|
#include "davinci.h"
|
||||||
|
#include "mux.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device specific clocks
|
* Device specific clocks
|
||||||
|
@ -43,290 +44,6 @@
|
||||||
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
|
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
|
||||||
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
|
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
|
||||||
|
|
||||||
static struct pll_data pll1_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DAVINCI_PLL1_BASE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pll_data pll2_data = {
|
|
||||||
.num = 2,
|
|
||||||
.phys_base = DAVINCI_PLL2_BASE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
.rate = DM644X_REF_FREQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_clk = {
|
|
||||||
.name = "pll1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll1_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk1 = {
|
|
||||||
.name = "pll1_sysclk1",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk2 = {
|
|
||||||
.name = "pll1_sysclk2",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk3 = {
|
|
||||||
.name = "pll1_sysclk3",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk5 = {
|
|
||||||
.name = "pll1_sysclk5",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_aux_clk = {
|
|
||||||
.name = "pll1_aux_clk",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclkbp = {
|
|
||||||
.name = "pll1_sysclkbp",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_clk = {
|
|
||||||
.name = "pll2",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll2_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk1 = {
|
|
||||||
.name = "pll2_sysclk1",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk2 = {
|
|
||||||
.name = "pll2_sysclk2",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclkbp = {
|
|
||||||
.name = "pll2_sysclkbp",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk dsp_clk = {
|
|
||||||
.name = "dsp",
|
|
||||||
.parent = &pll1_sysclk1,
|
|
||||||
.lpsc = DAVINCI_LPSC_GEM,
|
|
||||||
.domain = DAVINCI_GPSC_DSPDOMAIN,
|
|
||||||
.usecount = 1, /* REVISIT how to disable? */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vicp_clk = {
|
|
||||||
.name = "vicp",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DAVINCI_LPSC_IMCOP,
|
|
||||||
.domain = DAVINCI_GPSC_DSPDOMAIN,
|
|
||||||
.usecount = 1, /* REVISIT how to disable? */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_master_clk = {
|
|
||||||
.name = "vpss_master",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DAVINCI_LPSC_VPSSMSTR,
|
|
||||||
.flags = CLK_PSC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpss_slave_clk = {
|
|
||||||
.name = "vpss_slave",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DAVINCI_LPSC_VPSSSLV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart2_clk = {
|
|
||||||
.name = "uart2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_UART2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emac_clk = {
|
|
||||||
.name = "emac",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c_clk = {
|
|
||||||
.name = "i2c",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_I2C,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ide_clk = {
|
|
||||||
.name = "ide",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_ATA,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk asp_clk = {
|
|
||||||
.name = "asp0",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_McBSP,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mmcsd_clk = {
|
|
||||||
.name = "mmcsd",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_MMC_SD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk spi_clk = {
|
|
||||||
.name = "spi",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_SPI,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk usb_clk = {
|
|
||||||
.name = "usb",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_USB,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vlynq_clk = {
|
|
||||||
.name = "vlynq",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_VLYNQ,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll1_sysclk5,
|
|
||||||
.lpsc = DAVINCI_LPSC_AEMIF,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm0_clk = {
|
|
||||||
.name = "pwm0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm1_clk = {
|
|
||||||
.name = "pwm1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm2_clk = {
|
|
||||||
.name = "pwm2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_PWM2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer2_clk = {
|
|
||||||
.name = "timer2",
|
|
||||||
.parent = &pll1_aux_clk,
|
|
||||||
.lpsc = DAVINCI_LPSC_TIMER2,
|
|
||||||
.usecount = 1, /* REVISIT: why can't this be disabled? */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup dm644x_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "pll1", &pll1_clk),
|
|
||||||
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
|
|
||||||
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
|
|
||||||
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
|
|
||||||
CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
|
|
||||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
||||||
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
|
|
||||||
CLK(NULL, "pll2", &pll2_clk),
|
|
||||||
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
|
|
||||||
CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
|
|
||||||
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
|
|
||||||
CLK(NULL, "dsp", &dsp_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK(NULL, "vicp", &vicp_clk),
|
|
||||||
CLK("vpss", "master", &vpss_master_clk),
|
|
||||||
CLK("vpss", "slave", &vpss_slave_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("serial8250.2", NULL, &uart2_clk),
|
|
||||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
||||||
CLK("davinci_mdio.0", "fck", &emac_clk),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c_clk),
|
|
||||||
CLK("palm_bk3710", NULL, &ide_clk),
|
|
||||||
CLK("davinci-mcbsp", NULL, &asp_clk),
|
|
||||||
CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
|
|
||||||
CLK(NULL, "spi", &spi_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK(NULL, "usb", &usb_clk),
|
|
||||||
CLK(NULL, "vlynq", &vlynq_clk),
|
|
||||||
CLK(NULL, "aemif", &aemif_clk),
|
|
||||||
CLK(NULL, "pwm0", &pwm0_clk),
|
|
||||||
CLK(NULL, "pwm1", &pwm1_clk),
|
|
||||||
CLK(NULL, "pwm2", &pwm2_clk),
|
|
||||||
CLK(NULL, "timer0", &timer0_clk),
|
|
||||||
CLK(NULL, "timer1", &timer1_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timer2_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct emac_platform_data dm644x_emac_pdata = {
|
static struct emac_platform_data dm644x_emac_pdata = {
|
||||||
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
|
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
|
||||||
.ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
|
.ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
|
||||||
|
@ -819,8 +536,6 @@ static struct davinci_id dm644x_ids[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
||||||
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
||||||
|
@ -905,8 +620,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
|
||||||
.jtag_id_reg = 0x01c40028,
|
.jtag_id_reg = 0x01c40028,
|
||||||
.ids = dm644x_ids,
|
.ids = dm644x_ids,
|
||||||
.ids_num = ARRAY_SIZE(dm644x_ids),
|
.ids_num = ARRAY_SIZE(dm644x_ids),
|
||||||
.psc_bases = dm644x_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
|
|
||||||
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
||||||
.pinmux_pins = dm644x_pins,
|
.pinmux_pins = dm644x_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
|
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
|
||||||
|
@ -934,8 +647,41 @@ void __init dm644x_init(void)
|
||||||
|
|
||||||
void __init dm644x_init_time(void)
|
void __init dm644x_init_time(void)
|
||||||
{
|
{
|
||||||
davinci_clk_init(dm644x_clks);
|
void __iomem *pll1, *psc;
|
||||||
davinci_timer_init();
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
|
||||||
|
|
||||||
|
pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
|
||||||
|
dm644x_pll1_init(NULL, pll1, NULL);
|
||||||
|
|
||||||
|
psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
|
||||||
|
dm644x_psc_init(NULL, psc);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource dm644x_pll2_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DAVINCI_PLL2_BASE,
|
||||||
|
.end = DAVINCI_PLL2_BASE + SZ_1K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device dm644x_pll2_device = {
|
||||||
|
.name = "dm644x-pll2",
|
||||||
|
.id = -1,
|
||||||
|
.resource = dm644x_pll2_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(dm644x_pll2_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init dm644x_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* PLL1 and PSC are registered in dm644x_init_time() */
|
||||||
|
platform_device_register(&dm644x_pll2_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
|
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
|
||||||
|
|
|
@ -8,29 +8,30 @@
|
||||||
* is licensed "as is" without any warranty of any kind, whether express
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
* or implied.
|
* or implied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/clk/davinci.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/serial_8250.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/platform_data/edma.h>
|
#include <linux/platform_data/edma.h>
|
||||||
#include <linux/platform_data/gpio-davinci.h>
|
#include <linux/platform_data/gpio-davinci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
#include <mach/common.h>
|
||||||
#include <mach/cputype.h>
|
#include <mach/cputype.h>
|
||||||
#include <mach/irqs.h>
|
#include <mach/irqs.h>
|
||||||
#include "psc.h"
|
|
||||||
#include <mach/mux.h>
|
#include <mach/mux.h>
|
||||||
#include <mach/time.h>
|
|
||||||
#include <mach/serial.h>
|
#include <mach/serial.h>
|
||||||
#include <mach/common.h>
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "davinci.h"
|
|
||||||
#include "clock.h"
|
|
||||||
#include "mux.h"
|
|
||||||
#include "asp.h"
|
#include "asp.h"
|
||||||
|
#include "davinci.h"
|
||||||
|
#include "mux.h"
|
||||||
|
|
||||||
#define DAVINCI_VPIF_BASE (0x01C12000)
|
#define DAVINCI_VPIF_BASE (0x01C12000)
|
||||||
|
|
||||||
|
@ -46,317 +47,6 @@
|
||||||
#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000
|
#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000
|
||||||
#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000
|
#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000
|
||||||
|
|
||||||
static struct pll_data pll1_data = {
|
|
||||||
.num = 1,
|
|
||||||
.phys_base = DAVINCI_PLL1_BASE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pll_data pll2_data = {
|
|
||||||
.num = 2,
|
|
||||||
.phys_base = DAVINCI_PLL2_BASE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk ref_clk = {
|
|
||||||
.name = "ref_clk",
|
|
||||||
/* rate is initialized in dm646x_init_time() */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aux_clkin = {
|
|
||||||
.name = "aux_clkin",
|
|
||||||
/* rate is initialized in dm646x_init_time() */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_clk = {
|
|
||||||
.name = "pll1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll1_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk1 = {
|
|
||||||
.name = "pll1_sysclk1",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk2 = {
|
|
||||||
.name = "pll1_sysclk2",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk3 = {
|
|
||||||
.name = "pll1_sysclk3",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk4 = {
|
|
||||||
.name = "pll1_sysclk4",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV4,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk5 = {
|
|
||||||
.name = "pll1_sysclk5",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV5,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk6 = {
|
|
||||||
.name = "pll1_sysclk6",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk8 = {
|
|
||||||
.name = "pll1_sysclk8",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV8,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclk9 = {
|
|
||||||
.name = "pll1_sysclk9",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV9,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_sysclkbp = {
|
|
||||||
.name = "pll1_sysclkbp",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
.div_reg = BPDIV,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll1_aux_clk = {
|
|
||||||
.name = "pll1_aux_clk",
|
|
||||||
.parent = &pll1_clk,
|
|
||||||
.flags = CLK_PLL | PRE_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_clk = {
|
|
||||||
.name = "pll2_clk",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.pll_data = &pll2_data,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pll2_sysclk1 = {
|
|
||||||
.name = "pll2_sysclk1",
|
|
||||||
.parent = &pll2_clk,
|
|
||||||
.flags = CLK_PLL,
|
|
||||||
.div_reg = PLLDIV1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk dsp_clk = {
|
|
||||||
.name = "dsp",
|
|
||||||
.parent = &pll1_sysclk1,
|
|
||||||
.lpsc = DM646X_LPSC_C64X_CPU,
|
|
||||||
.usecount = 1, /* REVISIT how to disable? */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk arm_clk = {
|
|
||||||
.name = "arm",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_ARM,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk edma_cc_clk = {
|
|
||||||
.name = "edma_cc",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_TPCC,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk edma_tc0_clk = {
|
|
||||||
.name = "edma_tc0",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_TPTC0,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk edma_tc1_clk = {
|
|
||||||
.name = "edma_tc1",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_TPTC1,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk edma_tc2_clk = {
|
|
||||||
.name = "edma_tc2",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_TPTC2,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk edma_tc3_clk = {
|
|
||||||
.name = "edma_tc3",
|
|
||||||
.parent = &pll1_sysclk2,
|
|
||||||
.lpsc = DM646X_LPSC_TPTC3,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart0_clk = {
|
|
||||||
.name = "uart0",
|
|
||||||
.parent = &aux_clkin,
|
|
||||||
.lpsc = DM646X_LPSC_UART0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart1_clk = {
|
|
||||||
.name = "uart1",
|
|
||||||
.parent = &aux_clkin,
|
|
||||||
.lpsc = DM646X_LPSC_UART1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk uart2_clk = {
|
|
||||||
.name = "uart2",
|
|
||||||
.parent = &aux_clkin,
|
|
||||||
.lpsc = DM646X_LPSC_UART2,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk i2c_clk = {
|
|
||||||
.name = "I2CCLK",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_I2C,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk gpio_clk = {
|
|
||||||
.name = "gpio",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp0_clk = {
|
|
||||||
.name = "mcasp0",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_McASP0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk mcasp1_clk = {
|
|
||||||
.name = "mcasp1",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_McASP1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk aemif_clk = {
|
|
||||||
.name = "aemif",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_AEMIF,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk emac_clk = {
|
|
||||||
.name = "emac",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_EMAC,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm0_clk = {
|
|
||||||
.name = "pwm0",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_PWM0,
|
|
||||||
.usecount = 1, /* REVIST: disabling hangs system */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk pwm1_clk = {
|
|
||||||
.name = "pwm1",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_PWM1,
|
|
||||||
.usecount = 1, /* REVIST: disabling hangs system */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer0_clk = {
|
|
||||||
.name = "timer0",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_TIMER0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer1_clk = {
|
|
||||||
.name = "timer1",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.lpsc = DM646X_LPSC_TIMER1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk timer2_clk = {
|
|
||||||
.name = "timer2",
|
|
||||||
.parent = &pll1_sysclk3,
|
|
||||||
.flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static struct clk ide_clk = {
|
|
||||||
.name = "ide",
|
|
||||||
.parent = &pll1_sysclk4,
|
|
||||||
.lpsc = DAVINCI_LPSC_ATA,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpif0_clk = {
|
|
||||||
.name = "vpif0",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.lpsc = DM646X_LPSC_VPSSMSTR,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk vpif1_clk = {
|
|
||||||
.name = "vpif1",
|
|
||||||
.parent = &ref_clk,
|
|
||||||
.lpsc = DM646X_LPSC_VPSSSLV,
|
|
||||||
.flags = ALWAYS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup dm646x_clks[] = {
|
|
||||||
CLK(NULL, "ref", &ref_clk),
|
|
||||||
CLK(NULL, "aux", &aux_clkin),
|
|
||||||
CLK(NULL, "pll1", &pll1_clk),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
|
|
||||||
CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
|
|
||||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
|
||||||
CLK(NULL, "pll2", &pll2_clk),
|
|
||||||
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
|
|
||||||
CLK(NULL, "dsp", &dsp_clk),
|
|
||||||
CLK(NULL, "arm", &arm_clk),
|
|
||||||
CLK(NULL, "edma_cc", &edma_cc_clk),
|
|
||||||
CLK(NULL, "edma_tc0", &edma_tc0_clk),
|
|
||||||
CLK(NULL, "edma_tc1", &edma_tc1_clk),
|
|
||||||
CLK(NULL, "edma_tc2", &edma_tc2_clk),
|
|
||||||
CLK(NULL, "edma_tc3", &edma_tc3_clk),
|
|
||||||
CLK("serial8250.0", NULL, &uart0_clk),
|
|
||||||
CLK("serial8250.1", NULL, &uart1_clk),
|
|
||||||
CLK("serial8250.2", NULL, &uart2_clk),
|
|
||||||
CLK("i2c_davinci.1", NULL, &i2c_clk),
|
|
||||||
CLK(NULL, "gpio", &gpio_clk),
|
|
||||||
CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
|
|
||||||
CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
|
|
||||||
CLK(NULL, "aemif", &aemif_clk),
|
|
||||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
|
||||||
CLK("davinci_mdio.0", "fck", &emac_clk),
|
|
||||||
CLK(NULL, "pwm0", &pwm0_clk),
|
|
||||||
CLK(NULL, "pwm1", &pwm1_clk),
|
|
||||||
CLK(NULL, "timer0", &timer0_clk),
|
|
||||||
CLK(NULL, "timer1", &timer1_clk),
|
|
||||||
CLK("davinci-wdt", NULL, &timer2_clk),
|
|
||||||
CLK("palm_bk3710", NULL, &ide_clk),
|
|
||||||
CLK(NULL, "vpif0", &vpif0_clk),
|
|
||||||
CLK(NULL, "vpif1", &vpif1_clk),
|
|
||||||
CLK(NULL, NULL, NULL),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct emac_platform_data dm646x_emac_pdata = {
|
static struct emac_platform_data dm646x_emac_pdata = {
|
||||||
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
|
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
|
||||||
.ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
|
.ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
|
||||||
|
@ -796,8 +486,6 @@ static struct davinci_id dm646x_ids[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
|
||||||
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
|
||||||
|
@ -882,8 +570,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
|
||||||
.jtag_id_reg = 0x01c40028,
|
.jtag_id_reg = 0x01c40028,
|
||||||
.ids = dm646x_ids,
|
.ids = dm646x_ids,
|
||||||
.ids_num = ARRAY_SIZE(dm646x_ids),
|
.ids_num = ARRAY_SIZE(dm646x_ids),
|
||||||
.psc_bases = dm646x_psc_bases,
|
|
||||||
.psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
|
|
||||||
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
|
||||||
.pinmux_pins = dm646x_pins,
|
.pinmux_pins = dm646x_pins,
|
||||||
.pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
|
.pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
|
||||||
|
@ -954,10 +640,42 @@ void __init dm646x_init(void)
|
||||||
void __init dm646x_init_time(unsigned long ref_clk_rate,
|
void __init dm646x_init_time(unsigned long ref_clk_rate,
|
||||||
unsigned long aux_clkin_rate)
|
unsigned long aux_clkin_rate)
|
||||||
{
|
{
|
||||||
ref_clk.rate = ref_clk_rate;
|
void __iomem *pll1, *psc;
|
||||||
aux_clkin.rate = aux_clkin_rate;
|
struct clk *clk;
|
||||||
davinci_clk_init(dm646x_clks);
|
|
||||||
davinci_timer_init();
|
clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
|
||||||
|
clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
|
||||||
|
|
||||||
|
pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
|
||||||
|
dm646x_pll1_init(NULL, pll1, NULL);
|
||||||
|
|
||||||
|
psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
|
||||||
|
dm646x_psc_init(NULL, psc);
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "timer0");
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource dm646x_pll2_resources[] = {
|
||||||
|
{
|
||||||
|
.start = DAVINCI_PLL2_BASE,
|
||||||
|
.end = DAVINCI_PLL2_BASE + SZ_1K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device dm646x_pll2_device = {
|
||||||
|
.name = "dm646x-pll2",
|
||||||
|
.id = -1,
|
||||||
|
.resource = dm646x_pll2_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(dm646x_pll2_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init dm646x_register_clocks(void)
|
||||||
|
{
|
||||||
|
/* PLL1 and PSC are registered in dm646x_init_time() */
|
||||||
|
platform_device_register(&dm646x_pll2_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init dm646x_init_devices(void)
|
static int __init dm646x_init_devices(void)
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
|
|
||||||
struct clk;
|
struct clk;
|
||||||
|
|
||||||
extern int clk_register(struct clk *clk);
|
|
||||||
extern void clk_unregister(struct clk *clk);
|
|
||||||
|
|
||||||
int davinci_clk_reset_assert(struct clk *c);
|
int davinci_clk_reset_assert(struct clk *c);
|
||||||
int davinci_clk_reset_deassert(struct clk *c);
|
int davinci_clk_reset_deassert(struct clk *c);
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
|
#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
|
||||||
#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
|
#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
extern void davinci_timer_init(void);
|
void davinci_timer_init(struct clk *clk);
|
||||||
|
|
||||||
extern void davinci_irq_init(void);
|
extern void davinci_irq_init(void);
|
||||||
extern void __iomem *davinci_intc_base;
|
extern void __iomem *davinci_intc_base;
|
||||||
|
@ -53,8 +54,6 @@ struct davinci_soc_info {
|
||||||
u32 jtag_id_reg;
|
u32 jtag_id_reg;
|
||||||
struct davinci_id *ids;
|
struct davinci_id *ids;
|
||||||
unsigned long ids_num;
|
unsigned long ids_num;
|
||||||
u32 *psc_bases;
|
|
||||||
unsigned long psc_bases_num;
|
|
||||||
u32 pinmux_base;
|
u32 pinmux_base;
|
||||||
const struct mux_config *pinmux_pins;
|
const struct mux_config *pinmux_pins;
|
||||||
unsigned long pinmux_pins_num;
|
unsigned long pinmux_pins_num;
|
||||||
|
@ -82,12 +81,6 @@ extern void davinci_common_init(const struct davinci_soc_info *soc_info);
|
||||||
extern void davinci_init_ide(void);
|
extern void davinci_init_ide(void);
|
||||||
void davinci_init_late(void);
|
void davinci_init_late(void);
|
||||||
|
|
||||||
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
|
|
||||||
int davinci_clk_disable_unused(void);
|
|
||||||
#else
|
|
||||||
static inline int davinci_clk_disable_unused(void) { return 0; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_FREQ
|
#ifdef CONFIG_CPU_FREQ
|
||||||
int davinci_cpufreq_init(void);
|
int davinci_cpufreq_init(void);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -89,9 +89,11 @@ extern unsigned int da850_max_speed;
|
||||||
|
|
||||||
void da830_init(void);
|
void da830_init(void);
|
||||||
void da830_init_time(void);
|
void da830_init_time(void);
|
||||||
|
void da830_register_clocks(void);
|
||||||
|
|
||||||
void da850_init(void);
|
void da850_init(void);
|
||||||
void da850_init_time(void);
|
void da850_init_time(void);
|
||||||
|
void da850_register_clocks(void);
|
||||||
|
|
||||||
int da830_register_edma(struct edma_rsv_info *rsv);
|
int da830_register_edma(struct edma_rsv_info *rsv);
|
||||||
int da850_register_edma(struct edma_rsv_info *rsv[2]);
|
int da850_register_edma(struct edma_rsv_info *rsv[2]);
|
||||||
|
@ -101,9 +103,7 @@ int da8xx_register_watchdog(void);
|
||||||
int da8xx_register_usb_phy(void);
|
int da8xx_register_usb_phy(void);
|
||||||
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
|
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
|
||||||
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
|
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
|
||||||
int da8xx_register_usb_refclkin(int rate);
|
int da8xx_register_usb_phy_clocks(void);
|
||||||
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
|
|
||||||
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
|
|
||||||
int da850_register_sata_refclk(int rate);
|
int da850_register_sata_refclk(int rate);
|
||||||
int da8xx_register_emac(void);
|
int da8xx_register_emac(void);
|
||||||
int da8xx_register_uio_pruss(void);
|
int da8xx_register_uio_pruss(void);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/pm_clock.h>
|
#include <linux/pm_clock.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
static struct dev_pm_domain davinci_pm_domain = {
|
static struct dev_pm_domain davinci_pm_domain = {
|
||||||
.ops = {
|
.ops = {
|
||||||
|
@ -28,6 +29,10 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
|
||||||
|
|
||||||
static int __init davinci_pm_runtime_init(void)
|
static int __init davinci_pm_runtime_init(void)
|
||||||
{
|
{
|
||||||
|
if (of_have_populated_dt())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Use pm_clk as fallback if we're not using genpd. */
|
||||||
pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
|
pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
* TI DaVinci Power and Sleep Controller (PSC)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Texas Instruments.
|
|
||||||
*
|
|
||||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
|
|
||||||
#include <mach/cputype.h>
|
|
||||||
#include "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)
|
|
||||||
{
|
|
||||||
void __iomem *psc_base;
|
|
||||||
u32 mdstat;
|
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
|
||||||
|
|
||||||
if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
|
|
||||||
pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
|
|
||||||
(int)soc_info->psc_bases, ctlr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
|
|
||||||
mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
|
|
||||||
iounmap(psc_base);
|
|
||||||
|
|
||||||
/* if clocked, state can be "Enable" or "SyncReset" */
|
|
||||||
return mdstat & BIT(12);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Control "reset" line associated with PSC domain */
|
|
||||||
void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
|
|
||||||
{
|
|
||||||
u32 mdctl;
|
|
||||||
void __iomem *psc_base;
|
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
|
||||||
|
|
||||||
if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
|
|
||||||
pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
|
|
||||||
(int)soc_info->psc_bases, ctlr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
|
|
||||||
|
|
||||||
mdctl = readl(psc_base + MDCTL + 4 * id);
|
|
||||||
if (reset)
|
|
||||||
mdctl &= ~MDCTL_LRST;
|
|
||||||
else
|
|
||||||
mdctl |= MDCTL_LRST;
|
|
||||||
writel(mdctl, psc_base + MDCTL + 4 * id);
|
|
||||||
|
|
||||||
iounmap(psc_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable or disable a PSC domain */
|
|
||||||
void davinci_psc_config(unsigned int domain, unsigned int ctlr,
|
|
||||||
unsigned int id, bool enable, u32 flags)
|
|
||||||
{
|
|
||||||
u32 epcpr, ptcmd, ptstat, pdstat, pdctl, 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_warn("PSC: Bad psc data: 0x%x[%d]\n",
|
|
||||||
(int)soc_info->psc_bases, ctlr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 + 4 * domain);
|
|
||||||
if ((pdstat & PDSTAT_STATE_MASK) == 0) {
|
|
||||||
pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
|
|
||||||
pdctl |= PDCTL_NEXT;
|
|
||||||
__raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
|
|
||||||
|
|
||||||
ptcmd = 1 << domain;
|
|
||||||
__raw_writel(ptcmd, psc_base + PTCMD);
|
|
||||||
|
|
||||||
do {
|
|
||||||
epcpr = __raw_readl(psc_base + EPCPR);
|
|
||||||
} while ((((epcpr >> domain) & 1) == 0));
|
|
||||||
|
|
||||||
pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
|
|
||||||
pdctl |= PDCTL_EPCGOOD;
|
|
||||||
__raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
|
|
||||||
} else {
|
|
||||||
ptcmd = 1 << domain;
|
|
||||||
__raw_writel(ptcmd, psc_base + PTCMD);
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
ptstat = __raw_readl(psc_base + PTSTAT);
|
|
||||||
} while (!(((ptstat >> domain) & 1) == 0));
|
|
||||||
|
|
||||||
do {
|
|
||||||
mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
|
|
||||||
} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
|
|
||||||
|
|
||||||
iounmap(psc_base);
|
|
||||||
}
|
|
|
@ -27,8 +27,6 @@
|
||||||
#ifndef __ASM_ARCH_PSC_H
|
#ifndef __ASM_ARCH_PSC_H
|
||||||
#define __ASM_ARCH_PSC_H
|
#define __ASM_ARCH_PSC_H
|
||||||
|
|
||||||
#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
|
|
||||||
|
|
||||||
/* Power and Sleep Controller (PSC) Domains */
|
/* Power and Sleep Controller (PSC) Domains */
|
||||||
#define DAVINCI_GPSC_ARMDOMAIN 0
|
#define DAVINCI_GPSC_ARMDOMAIN 0
|
||||||
#define DAVINCI_GPSC_DSPDOMAIN 1
|
#define DAVINCI_GPSC_DSPDOMAIN 1
|
||||||
|
@ -206,14 +204,4 @@
|
||||||
#define PDCTL_NEXT BIT(0)
|
#define PDCTL_NEXT BIT(0)
|
||||||
#define PDCTL_EPCGOOD BIT(8)
|
#define PDCTL_EPCGOOD BIT(8)
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
|
|
||||||
extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
|
|
||||||
extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
|
|
||||||
bool reset);
|
|
||||||
extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
|
|
||||||
unsigned int id, bool enable, u32 flags);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_PSC_H */
|
#endif /* __ASM_ARCH_PSC_H */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/sched_clock.h>
|
#include <linux/sched_clock.h>
|
||||||
|
|
||||||
|
@ -27,8 +28,6 @@
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/time.h>
|
#include <mach/time.h>
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
static struct clock_event_device clockevent_davinci;
|
static struct clock_event_device clockevent_davinci;
|
||||||
static unsigned int davinci_clock_tick_rate;
|
static unsigned int davinci_clock_tick_rate;
|
||||||
|
|
||||||
|
@ -334,10 +333,8 @@ static struct clock_event_device clockevent_davinci = {
|
||||||
.set_state_oneshot = davinci_set_oneshot,
|
.set_state_oneshot = davinci_set_oneshot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void __init davinci_timer_init(struct clk *timer_clk)
|
||||||
void __init davinci_timer_init(void)
|
|
||||||
{
|
{
|
||||||
struct clk *timer_clk;
|
|
||||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||||
unsigned int clockevent_id;
|
unsigned int clockevent_id;
|
||||||
unsigned int clocksource_id;
|
unsigned int clocksource_id;
|
||||||
|
@ -373,7 +370,6 @@ void __init davinci_timer_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_clk = clk_get(NULL, "timer0");
|
|
||||||
BUG_ON(IS_ERR(timer_clk));
|
BUG_ON(IS_ERR(timer_clk));
|
||||||
clk_prepare_enable(timer_clk);
|
clk_prepare_enable(timer_clk);
|
||||||
|
|
||||||
|
@ -402,3 +398,17 @@ void __init davinci_timer_init(void)
|
||||||
for (i=0; i< ARRAY_SIZE(timers); i++)
|
for (i=0; i< ARRAY_SIZE(timers); i++)
|
||||||
timer32_config(&timers[i]);
|
timer32_config(&timers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init of_davinci_timer_init(struct device_node *np)
|
||||||
|
{
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk = of_clk_get(np, 0);
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return PTR_ERR(clk);
|
||||||
|
|
||||||
|
davinci_timer_init(clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
TIMER_OF_DECLARE(davinci_timer, "ti,da830-timer", of_davinci_timer_init);
|
||||||
|
|
|
@ -2,29 +2,30 @@
|
||||||
/*
|
/*
|
||||||
* DA8xx USB
|
* DA8xx USB
|
||||||
*/
|
*/
|
||||||
#include <linux/clk.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/mfd/da8xx-cfgchip.h>
|
#include <linux/mfd/da8xx-cfgchip.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
#include <linux/phy/phy.h>
|
#include <linux/phy/phy.h>
|
||||||
|
#include <linux/platform_data/clk-da8xx-cfgchip.h>
|
||||||
#include <linux/platform_data/phy-da8xx-usb.h>
|
#include <linux/platform_data/phy-da8xx-usb.h>
|
||||||
#include <linux/platform_data/usb-davinci.h>
|
#include <linux/platform_data/usb-davinci.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/usb/musb.h>
|
#include <linux/usb/musb.h>
|
||||||
|
|
||||||
#include <mach/clock.h>
|
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/cputype.h>
|
#include <mach/cputype.h>
|
||||||
#include <mach/da8xx.h>
|
#include <mach/da8xx.h>
|
||||||
#include <mach/irqs.h>
|
#include <mach/irqs.h>
|
||||||
|
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
#define DA8XX_USB0_BASE 0x01e00000
|
#define DA8XX_USB0_BASE 0x01e00000
|
||||||
#define DA8XX_USB1_BASE 0x01e25000
|
#define DA8XX_USB1_BASE 0x01e25000
|
||||||
|
|
||||||
|
#ifndef CONFIG_COMMON_CLK
|
||||||
static struct clk *usb20_clk;
|
static struct clk *usb20_clk;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata;
|
static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata;
|
||||||
|
|
||||||
|
@ -81,11 +82,6 @@ static struct platform_device da8xx_usb20_dev = {
|
||||||
.name = "musb-da8xx",
|
.name = "musb-da8xx",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.dev = {
|
.dev = {
|
||||||
/*
|
|
||||||
* Setting init_name so that clock lookup will work in
|
|
||||||
* usb20_phy_clk_enable() even if this device is not registered.
|
|
||||||
*/
|
|
||||||
.init_name = "musb-da8xx",
|
|
||||||
.platform_data = &usb_data,
|
.platform_data = &usb_data,
|
||||||
.dma_mask = &usb_dmamask,
|
.dma_mask = &usb_dmamask,
|
||||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
@ -134,229 +130,17 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
|
||||||
return platform_device_register(&da8xx_usb11_device);
|
return platform_device_register(&da8xx_usb11_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk usb_refclkin = {
|
static struct platform_device da8xx_usb_phy_clks_device = {
|
||||||
.name = "usb_refclkin",
|
.name = "da830-usb-phy-clks",
|
||||||
.set_rate = davinci_simple_set_rate,
|
.id = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_lookup usb_refclkin_lookup =
|
int __init da8xx_register_usb_phy_clocks(void)
|
||||||
CLK(NULL, "usb_refclkin", &usb_refclkin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* da8xx_register_usb_refclkin - register USB_REFCLKIN clock
|
|
||||||
*
|
|
||||||
* @rate: The clock rate in Hz
|
|
||||||
*
|
|
||||||
* This clock is only needed if the board provides an external USB_REFCLKIN
|
|
||||||
* signal, in which case it will be used as the parent of usb20_phy_clk and/or
|
|
||||||
* usb11_phy_clk.
|
|
||||||
*/
|
|
||||||
int __init da8xx_register_usb_refclkin(int rate)
|
|
||||||
{
|
{
|
||||||
int ret;
|
struct da8xx_cfgchip_clk_platform_data pdata;
|
||||||
|
|
||||||
usb_refclkin.rate = rate;
|
pdata.cfgchip = da8xx_get_cfgchip();
|
||||||
ret = clk_register(&usb_refclkin);
|
da8xx_usb_phy_clks_device.dev.platform_data = &pdata;
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
clkdev_add(&usb_refclkin_lookup);
|
return platform_device_register(&da8xx_usb_phy_clks_device);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb20_phy_clk_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
u32 timeout = 500000; /* 500 msec */
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
|
|
||||||
davinci_clk_enable(usb20_clk);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
|
|
||||||
* host may use the PLL clock without USB 2.0 OTG being used.
|
|
||||||
*/
|
|
||||||
val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
|
|
||||||
val |= CFGCHIP2_PHY_PLLON;
|
|
||||||
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
while (--timeout) {
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
if (val & CFGCHIP2_PHYCLKGD)
|
|
||||||
goto done;
|
|
||||||
udelay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
|
|
||||||
done:
|
|
||||||
davinci_clk_disable(usb20_clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb20_phy_clk_disable(struct clk *clk)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
val |= CFGCHIP2_PHYPWRDN;
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
/* Set the mux depending on the parent clock. */
|
|
||||||
if (parent == &usb_refclkin) {
|
|
||||||
val &= ~CFGCHIP2_USB2PHYCLKMUX;
|
|
||||||
} else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
|
|
||||||
val |= CFGCHIP2_USB2PHYCLKMUX;
|
|
||||||
} else {
|
|
||||||
pr_err("Bad parent on USB 2.0 PHY clock\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reference frequency also comes from parent clock */
|
|
||||||
val &= ~CFGCHIP2_REFFREQ_MASK;
|
|
||||||
switch (clk_get_rate(parent)) {
|
|
||||||
case 12000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_12MHZ;
|
|
||||||
break;
|
|
||||||
case 13000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_13MHZ;
|
|
||||||
break;
|
|
||||||
case 19200000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_19_2MHZ;
|
|
||||||
break;
|
|
||||||
case 20000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_20MHZ;
|
|
||||||
break;
|
|
||||||
case 24000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_24MHZ;
|
|
||||||
break;
|
|
||||||
case 26000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_26MHZ;
|
|
||||||
break;
|
|
||||||
case 38400000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_38_4MHZ;
|
|
||||||
break;
|
|
||||||
case 40000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_40MHZ;
|
|
||||||
break;
|
|
||||||
case 48000000:
|
|
||||||
val |= CFGCHIP2_REFFREQ_48MHZ;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clk usb20_phy_clk = {
|
|
||||||
.name = "usb0_clk48",
|
|
||||||
.clk_enable = usb20_phy_clk_enable,
|
|
||||||
.clk_disable = usb20_phy_clk_disable,
|
|
||||||
.set_parent = usb20_phy_clk_set_parent,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup usb20_phy_clk_lookup =
|
|
||||||
CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
|
|
||||||
*
|
|
||||||
* @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
|
|
||||||
* or "pll0_aux" if false.
|
|
||||||
*/
|
|
||||||
int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
|
|
||||||
{
|
|
||||||
struct clk *parent;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
|
|
||||||
ret = PTR_ERR_OR_ZERO(usb20_clk);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
|
|
||||||
ret = PTR_ERR_OR_ZERO(parent);
|
|
||||||
if (ret) {
|
|
||||||
clk_put(usb20_clk);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb20_phy_clk.parent = parent;
|
|
||||||
ret = clk_register(&usb20_phy_clk);
|
|
||||||
if (!ret)
|
|
||||||
clkdev_add(&usb20_phy_clk_lookup);
|
|
||||||
|
|
||||||
clk_put(parent);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
/* Set the USB 1.1 PHY clock mux based on the parent clock. */
|
|
||||||
if (parent == &usb20_phy_clk) {
|
|
||||||
val &= ~CFGCHIP2_USB1PHYCLKMUX;
|
|
||||||
} else if (parent == &usb_refclkin) {
|
|
||||||
val |= CFGCHIP2_USB1PHYCLKMUX;
|
|
||||||
} else {
|
|
||||||
pr_err("Bad parent on USB 1.1 PHY clock\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clk usb11_phy_clk = {
|
|
||||||
.name = "usb1_clk48",
|
|
||||||
.set_parent = usb11_phy_clk_set_parent,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk_lookup usb11_phy_clk_lookup =
|
|
||||||
CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
|
|
||||||
*
|
|
||||||
* @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
|
|
||||||
* or "usb0_clk48" if false.
|
|
||||||
*/
|
|
||||||
int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
|
|
||||||
{
|
|
||||||
struct clk *parent;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (use_usb_refclkin)
|
|
||||||
parent = clk_get(NULL, "usb_refclkin");
|
|
||||||
else
|
|
||||||
parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48");
|
|
||||||
if (IS_ERR(parent))
|
|
||||||
return PTR_ERR(parent);
|
|
||||||
|
|
||||||
usb11_phy_clk.parent = parent;
|
|
||||||
ret = clk_register(&usb11_phy_clk);
|
|
||||||
if (!ret)
|
|
||||||
clkdev_add(&usb11_phy_clk_lookup);
|
|
||||||
|
|
||||||
clk_put(parent);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,8 +190,6 @@ static void __init exynos_dt_fixup(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
|
DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
|
||||||
/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
|
|
||||||
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
|
|
||||||
.l2c_aux_val = 0x3c400001,
|
.l2c_aux_val = 0x3c400001,
|
||||||
.l2c_aux_mask = 0xc20fffff,
|
.l2c_aux_mask = 0xc20fffff,
|
||||||
.smp = smp_ops(exynos_smp_ops),
|
.smp = smp_ops(exynos_smp_ops),
|
||||||
|
|
|
@ -203,6 +203,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
|
||||||
NULL);
|
NULL);
|
||||||
if (!domain) {
|
if (!domain) {
|
||||||
iounmap(pmu_base_addr);
|
iounmap(pmu_base_addr);
|
||||||
|
pmu_base_addr = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,13 +148,20 @@ static int hi3xxx_hotplug_init(void)
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
|
|
||||||
node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
|
node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
|
||||||
if (node) {
|
if (!node) {
|
||||||
ctrl_base = of_iomap(node, 0);
|
id = ERROR_CTRL;
|
||||||
id = HI3620_CTRL;
|
return -ENOENT;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
id = ERROR_CTRL;
|
|
||||||
return -ENOENT;
|
ctrl_base = of_iomap(node, 0);
|
||||||
|
of_node_put(node);
|
||||||
|
if (!ctrl_base) {
|
||||||
|
id = ERROR_CTRL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = HI3620_CTRL;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hi3xxx_set_cpu(int cpu, bool enable)
|
void hi3xxx_set_cpu(int cpu, bool enable)
|
||||||
|
@ -173,11 +180,15 @@ static bool hix5hd2_hotplug_init(void)
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
|
np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
|
||||||
if (np) {
|
if (!np)
|
||||||
ctrl_base = of_iomap(np, 0);
|
return false;
|
||||||
return true;
|
|
||||||
}
|
ctrl_base = of_iomap(np, 0);
|
||||||
return false;
|
of_node_put(np);
|
||||||
|
if (!ctrl_base)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hix5hd2_set_cpu(int cpu, bool enable)
|
void hix5hd2_set_cpu(int cpu, bool enable)
|
||||||
|
@ -219,10 +230,10 @@ void hip01_set_cpu(int cpu, bool enable)
|
||||||
|
|
||||||
if (!ctrl_base) {
|
if (!ctrl_base) {
|
||||||
np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
|
np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
|
||||||
if (np)
|
BUG_ON(!np);
|
||||||
ctrl_base = of_iomap(np, 0);
|
ctrl_base = of_iomap(np, 0);
|
||||||
else
|
of_node_put(np);
|
||||||
BUG();
|
BUG_ON(!ctrl_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
|
|
|
@ -523,18 +523,6 @@ config SOC_IMX6UL
|
||||||
help
|
help
|
||||||
This enables support for Freescale i.MX6 UltraLite processor.
|
This enables support for Freescale i.MX6 UltraLite processor.
|
||||||
|
|
||||||
config SOC_IMX7D
|
|
||||||
bool "i.MX7 Dual support"
|
|
||||||
select PINCTRL_IMX7D
|
|
||||||
select ARM_GIC
|
|
||||||
select HAVE_ARM_ARCH_TIMER
|
|
||||||
select HAVE_IMX_ANATOP
|
|
||||||
select HAVE_IMX_MMDC
|
|
||||||
select HAVE_IMX_SRC
|
|
||||||
select IMX_GPCV2
|
|
||||||
help
|
|
||||||
This enables support for Freescale i.MX7 Dual processor.
|
|
||||||
|
|
||||||
config SOC_LS1021A
|
config SOC_LS1021A
|
||||||
bool "Freescale LS1021A support"
|
bool "Freescale LS1021A support"
|
||||||
select ARM_GIC
|
select ARM_GIC
|
||||||
|
@ -549,6 +537,27 @@ comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
|
||||||
|
|
||||||
if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
|
if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
|
||||||
|
|
||||||
|
config SOC_IMX7D_CA7
|
||||||
|
bool
|
||||||
|
select ARM_GIC
|
||||||
|
select HAVE_ARM_ARCH_TIMER
|
||||||
|
select HAVE_IMX_ANATOP
|
||||||
|
select HAVE_IMX_MMDC
|
||||||
|
select HAVE_IMX_SRC
|
||||||
|
select IMX_GPCV2
|
||||||
|
|
||||||
|
config SOC_IMX7D_CM4
|
||||||
|
bool
|
||||||
|
select ARMV7M_SYSTICK
|
||||||
|
|
||||||
|
config SOC_IMX7D
|
||||||
|
bool "i.MX7 Dual support"
|
||||||
|
select PINCTRL_IMX7D
|
||||||
|
select SOC_IMX7D_CA7 if ARCH_MULTI_V7
|
||||||
|
select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M
|
||||||
|
help
|
||||||
|
This enables support for Freescale i.MX7 Dual processor.
|
||||||
|
|
||||||
config SOC_VF610
|
config SOC_VF610
|
||||||
bool "Vybrid Family VF610 support"
|
bool "Vybrid Family VF610 support"
|
||||||
select ARM_GIC if ARCH_MULTI_V7
|
select ARM_GIC if ARCH_MULTI_V7
|
||||||
|
|
|
@ -26,7 +26,7 @@ ifeq ($(CONFIG_CPU_IDLE),y)
|
||||||
obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
|
obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
|
||||||
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
|
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
|
||||||
obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
|
obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
|
||||||
obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sl.o
|
obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sx.o
|
||||||
obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
|
obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
|
||||||
obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
|
obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
|
||||||
endif
|
endif
|
||||||
|
@ -81,7 +81,8 @@ obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
|
||||||
obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
|
obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
|
||||||
obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
|
obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
|
||||||
obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
|
obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
|
||||||
obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
|
obj-$(CONFIG_SOC_IMX7D_CA7) += mach-imx7d.o
|
||||||
|
obj-$(CONFIG_SOC_IMX7D_CM4) += mach-imx7d-cm4.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_SUSPEND),y)
|
ifeq ($(CONFIG_SUSPEND),y)
|
||||||
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
|
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
|
||||||
|
|
|
@ -38,7 +38,6 @@ void imx21_soc_init(void);
|
||||||
void imx27_soc_init(void);
|
void imx27_soc_init(void);
|
||||||
void imx31_soc_init(void);
|
void imx31_soc_init(void);
|
||||||
void imx35_soc_init(void);
|
void imx35_soc_init(void);
|
||||||
void epit_timer_init(void __iomem *base, int irq);
|
|
||||||
int mx21_clocks_init(unsigned long lref, unsigned long fref);
|
int mx21_clocks_init(unsigned long lref, unsigned long fref);
|
||||||
int mx27_clocks_init(unsigned long fref);
|
int mx27_clocks_init(unsigned long fref);
|
||||||
int mx31_clocks_init(unsigned long fref);
|
int mx31_clocks_init(unsigned long fref);
|
||||||
|
@ -58,10 +57,12 @@ struct device *imx_soc_device_init(void);
|
||||||
void imx6_enable_rbc(bool enable);
|
void imx6_enable_rbc(bool enable);
|
||||||
void imx_gpc_check_dt(void);
|
void imx_gpc_check_dt(void);
|
||||||
void imx_gpc_set_arm_power_in_lpm(bool power_off);
|
void imx_gpc_set_arm_power_in_lpm(bool power_off);
|
||||||
|
void imx_gpc_set_l2_mem_power_in_lpm(bool power_off);
|
||||||
void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
|
void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
|
||||||
void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
|
void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
|
||||||
void imx25_pm_init(void);
|
void imx25_pm_init(void);
|
||||||
void imx27_pm_init(void);
|
void imx27_pm_init(void);
|
||||||
|
void imx5_pmu_init(void);
|
||||||
|
|
||||||
enum mxc_cpu_pwr_mode {
|
enum mxc_cpu_pwr_mode {
|
||||||
WAIT_CLOCKED, /* wfi only */
|
WAIT_CLOCKED, /* wfi only */
|
||||||
|
|
|
@ -117,3 +117,48 @@ int mx53_revision(void)
|
||||||
return mx5_cpu_rev;
|
return mx5_cpu_rev;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mx53_revision);
|
EXPORT_SYMBOL(mx53_revision);
|
||||||
|
|
||||||
|
#define ARM_GPC 0x4
|
||||||
|
#define DBGEN BIT(16)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This enables the DBGEN bit in ARM_GPC register, which is
|
||||||
|
* required for accessing some performance counter features.
|
||||||
|
* Technically it is only required while perf is used, but to
|
||||||
|
* keep the source code simple we just enable it all the time
|
||||||
|
* when the kernel configuration allows using the feature.
|
||||||
|
*/
|
||||||
|
void __init imx5_pmu_init(void)
|
||||||
|
{
|
||||||
|
void __iomem *tigerp_base;
|
||||||
|
struct device_node *np;
|
||||||
|
u32 gpc;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_ARM_PMU))
|
||||||
|
return;
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
|
||||||
|
if (!np)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!of_property_read_bool(np, "secure-reg-access"))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
|
||||||
|
if (!np)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tigerp_base = of_iomap(np, 0);
|
||||||
|
if (!tigerp_base)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
gpc = readl_relaxed(tigerp_base + ARM_GPC);
|
||||||
|
gpc |= DBGEN;
|
||||||
|
writel_relaxed(gpc, tigerp_base + ARM_GPC);
|
||||||
|
iounmap(tigerp_base);
|
||||||
|
exit:
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ void __init imx_aips_allow_unprivileged_access(
|
||||||
|
|
||||||
for_each_compatible_node(np, NULL, compat) {
|
for_each_compatible_node(np, NULL, compat) {
|
||||||
aips_base_addr = of_iomap(np, 0);
|
aips_base_addr = of_iomap(np, 0);
|
||||||
|
WARN_ON(!aips_base_addr);
|
||||||
imx_set_aips(aips_base_addr);
|
imx_set_aips(aips_base_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
#include "hardware.h"
|
|
||||||
|
|
||||||
static int imx6sl_enter_wait(struct cpuidle_device *dev,
|
static int imx6sl_enter_wait(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv, int index)
|
struct cpuidle_driver *drv, int index)
|
||||||
|
@ -22,11 +21,9 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
|
||||||
* Software workaround for ERR005311, see function
|
* Software workaround for ERR005311, see function
|
||||||
* description for details.
|
* description for details.
|
||||||
*/
|
*/
|
||||||
if (cpu_is_imx6sl())
|
imx6sl_set_wait_clk(true);
|
||||||
imx6sl_set_wait_clk(true);
|
|
||||||
cpu_do_idle();
|
cpu_do_idle();
|
||||||
if (cpu_is_imx6sl())
|
imx6sl_set_wait_clk(false);
|
||||||
imx6sl_set_wait_clk(false);
|
|
||||||
imx6_set_lpm(WAIT_CLOCKED);
|
imx6_set_lpm(WAIT_CLOCKED);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
|
@ -103,6 +103,7 @@ int __init imx6sx_cpuidle_init(void)
|
||||||
{
|
{
|
||||||
imx6_set_int_mem_clk_lpm(true);
|
imx6_set_int_mem_clk_lpm(true);
|
||||||
imx6_enable_rbc(false);
|
imx6_enable_rbc(false);
|
||||||
|
imx_gpc_set_l2_mem_power_in_lpm(false);
|
||||||
/*
|
/*
|
||||||
* set ARM power up/down timing to the fastest,
|
* set ARM power up/down timing to the fastest,
|
||||||
* sw2iso and sw can be set to one 32K cycle = 31us
|
* sw2iso and sw can be set to one 32K cycle = 31us
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
|
||||||
|
#define GPC_CNTR 0x0
|
||||||
#define GPC_IMR1 0x008
|
#define GPC_IMR1 0x008
|
||||||
#define GPC_PGC_CPU_PDN 0x2a0
|
#define GPC_PGC_CPU_PDN 0x2a0
|
||||||
#define GPC_PGC_CPU_PUPSCR 0x2a4
|
#define GPC_PGC_CPU_PUPSCR 0x2a4
|
||||||
|
@ -27,6 +28,8 @@
|
||||||
#define GPC_PGC_SW2ISO_SHIFT 0x8
|
#define GPC_PGC_SW2ISO_SHIFT 0x8
|
||||||
#define GPC_PGC_SW_SHIFT 0x0
|
#define GPC_PGC_SW_SHIFT 0x0
|
||||||
|
|
||||||
|
#define GPC_CNTR_L2_PGE_SHIFT 22
|
||||||
|
|
||||||
#define IMR_NUM 4
|
#define IMR_NUM 4
|
||||||
#define GPC_MAX_IRQS (IMR_NUM * 32)
|
#define GPC_MAX_IRQS (IMR_NUM * 32)
|
||||||
|
|
||||||
|
@ -51,6 +54,17 @@ void imx_gpc_set_arm_power_in_lpm(bool power_off)
|
||||||
writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN);
|
writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imx_gpc_set_l2_mem_power_in_lpm(bool power_off)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = readl_relaxed(gpc_base + GPC_CNTR);
|
||||||
|
val &= ~(1 << GPC_CNTR_L2_PGE_SHIFT);
|
||||||
|
if (power_off)
|
||||||
|
val |= 1 << GPC_CNTR_L2_PGE_SHIFT;
|
||||||
|
writel_relaxed(val, gpc_base + GPC_CNTR);
|
||||||
|
}
|
||||||
|
|
||||||
void imx_gpc_pre_suspend(bool arm_power_off)
|
void imx_gpc_pre_suspend(bool arm_power_off)
|
||||||
{
|
{
|
||||||
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
||||||
|
|
|
@ -9,35 +9,17 @@
|
||||||
* http://www.gnu.org/copyleft/gpl.html
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/of_irq.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/time.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "mx31.h"
|
|
||||||
|
|
||||||
static const char * const imx31_dt_board_compat[] __initconst = {
|
static const char * const imx31_dt_board_compat[] __initconst = {
|
||||||
"fsl,imx31",
|
"fsl,imx31",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: replace with DT binding */
|
|
||||||
static const struct resource imx31_rnga_res[] __initconst = {
|
|
||||||
DEFINE_RES_MEM(MX31_RNGA_BASE_ADDR, SZ_16K),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init imx31_dt_mach_init(void)
|
|
||||||
{
|
|
||||||
platform_device_register_simple("mxc_rnga", -1, imx31_rnga_res,
|
|
||||||
ARRAY_SIZE(imx31_rnga_res));
|
|
||||||
}
|
|
||||||
|
|
||||||
DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
|
DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
|
||||||
.map_io = mx31_map_io,
|
.map_io = mx31_map_io,
|
||||||
.init_early = imx31_init_early,
|
.init_early = imx31_init_early,
|
||||||
.init_irq = mx31_init_irq,
|
.init_irq = mx31_init_irq,
|
||||||
.init_machine = imx31_dt_mach_init,
|
|
||||||
.dt_compat = imx31_dt_board_compat,
|
.dt_compat = imx31_dt_board_compat,
|
||||||
MACHINE_END
|
MACHINE_END
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
|
@ -48,11 +49,38 @@ static void __init imx51_ipu_mipi_setup(void)
|
||||||
iounmap(hsc_addr);
|
iounmap(hsc_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init imx51_m4if_setup(void)
|
||||||
|
{
|
||||||
|
void __iomem *m4if_base;
|
||||||
|
struct device_node *np;
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "fsl,imx51-m4if");
|
||||||
|
if (!np)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m4if_base = of_iomap(np, 0);
|
||||||
|
if (!m4if_base) {
|
||||||
|
pr_err("Unable to map M4IF registers\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure VPU and IPU with higher priorities
|
||||||
|
* in order to avoid artifacts during video playback
|
||||||
|
*/
|
||||||
|
writel_relaxed(0x00000203, m4if_base + 0x40);
|
||||||
|
writel_relaxed(0x00000000, m4if_base + 0x44);
|
||||||
|
writel_relaxed(0x00120125, m4if_base + 0x9c);
|
||||||
|
writel_relaxed(0x001901A3, m4if_base + 0x48);
|
||||||
|
iounmap(m4if_base);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init imx51_dt_init(void)
|
static void __init imx51_dt_init(void)
|
||||||
{
|
{
|
||||||
imx51_ipu_mipi_setup();
|
imx51_ipu_mipi_setup();
|
||||||
imx_src_init();
|
imx_src_init();
|
||||||
|
imx51_m4if_setup();
|
||||||
|
imx5_pmu_init();
|
||||||
imx_aips_allow_unprivileged_access("fsl,imx51-aipstz");
|
imx_aips_allow_unprivileged_access("fsl,imx51-aipstz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ static void __init imx53_init_early(void)
|
||||||
static void __init imx53_dt_init(void)
|
static void __init imx53_dt_init(void)
|
||||||
{
|
{
|
||||||
imx_src_init();
|
imx_src_init();
|
||||||
|
imx5_pmu_init();
|
||||||
imx_aips_allow_unprivileged_access("fsl,imx53-aipstz");
|
imx_aips_allow_unprivileged_access("fsl,imx53-aipstz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,10 @@ static void __init imx6sl_init_late(void)
|
||||||
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
|
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
|
||||||
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
|
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
|
||||||
|
|
||||||
imx6sl_cpuidle_init();
|
if (IS_ENABLED(CONFIG_SOC_IMX6SL) && cpu_is_imx6sl())
|
||||||
|
imx6sl_cpuidle_init();
|
||||||
|
else if (IS_ENABLED(CONFIG_SOC_IMX6SLL))
|
||||||
|
imx6sx_cpuidle_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init imx6sl_init_machine(void)
|
static void __init imx6sl_init_machine(void)
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <asm/v7m.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
|
||||||
|
static const char * const imx7d_cm4_dt_compat[] __initconst = {
|
||||||
|
"fsl,imx7d-cm4",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual Cortex-M4 (Device Tree)")
|
||||||
|
.dt_compat = imx7d_cm4_dt_compat,
|
||||||
|
.restart = armv7m_restart,
|
||||||
|
MACHINE_END
|
|
@ -130,6 +130,13 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = {
|
||||||
0x330, 0x334, 0x320, /* SDCKE0, SDCKE1, RESET */
|
0x330, 0x334, 0x320, /* SDCKE0, SDCKE1, RESET */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u32 imx6sll_mmdc_io_offset[] __initconst = {
|
||||||
|
0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
|
||||||
|
0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
|
||||||
|
0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
|
||||||
|
0x2a4, 0x2a8, /* SDCKE0, SDCKE1*/
|
||||||
|
};
|
||||||
|
|
||||||
static const u32 imx6sx_mmdc_io_offset[] __initconst = {
|
static const u32 imx6sx_mmdc_io_offset[] __initconst = {
|
||||||
0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
|
0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
|
||||||
0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
|
0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
|
||||||
|
@ -175,6 +182,16 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
|
||||||
.mmdc_io_offset = imx6sl_mmdc_io_offset,
|
.mmdc_io_offset = imx6sl_mmdc_io_offset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
|
||||||
|
.mmdc_compat = "fsl,imx6sll-mmdc",
|
||||||
|
.src_compat = "fsl,imx6sll-src",
|
||||||
|
.iomuxc_compat = "fsl,imx6sll-iomuxc",
|
||||||
|
.gpc_compat = "fsl,imx6sll-gpc",
|
||||||
|
.pl310_compat = "arm,pl310-cache",
|
||||||
|
.mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
|
||||||
|
.mmdc_io_offset = imx6sll_mmdc_io_offset,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
|
static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
|
||||||
.mmdc_compat = "fsl,imx6sx-mmdc",
|
.mmdc_compat = "fsl,imx6sx-mmdc",
|
||||||
.src_compat = "fsl,imx6sx-src",
|
.src_compat = "fsl,imx6sx-src",
|
||||||
|
@ -296,7 +313,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||||
if (cpu_is_imx6sl())
|
if (cpu_is_imx6sl())
|
||||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||||
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
|
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
|
||||||
cpu_is_imx6ull())
|
cpu_is_imx6ull() || cpu_is_imx6sll())
|
||||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||||
else
|
else
|
||||||
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
||||||
|
@ -314,7 +331,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||||
if (cpu_is_imx6sl() || cpu_is_imx6sx())
|
if (cpu_is_imx6sl() || cpu_is_imx6sx())
|
||||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||||
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
|
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
|
||||||
cpu_is_imx6ull())
|
cpu_is_imx6ull() || cpu_is_imx6sll())
|
||||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||||
else
|
else
|
||||||
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
||||||
|
@ -631,7 +648,17 @@ void __init imx6dl_pm_init(void)
|
||||||
|
|
||||||
void __init imx6sl_pm_init(void)
|
void __init imx6sl_pm_init(void)
|
||||||
{
|
{
|
||||||
imx6_pm_common_init(&imx6sl_pm_data);
|
struct regmap *gpr;
|
||||||
|
|
||||||
|
if (cpu_is_imx6sl()) {
|
||||||
|
imx6_pm_common_init(&imx6sl_pm_data);
|
||||||
|
} else {
|
||||||
|
imx6_pm_common_init(&imx6sll_pm_data);
|
||||||
|
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
|
||||||
|
if (!IS_ERR(gpr))
|
||||||
|
regmap_update_bits(gpr, IOMUXC_GPR5,
|
||||||
|
IMX6SLL_GPR5_AFCG_X_BYPASS_MASK, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init imx6sx_pm_init(void)
|
void __init imx6sx_pm_init(void)
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#define AXP_BOOTROM_BASE 0xfff00000
|
#define AXP_BOOTROM_BASE 0xfff00000
|
||||||
#define AXP_BOOTROM_SIZE 0x100000
|
#define AXP_BOOTROM_SIZE 0x100000
|
||||||
|
|
||||||
|
static struct clk *boot_cpu_clk;
|
||||||
|
|
||||||
static struct clk *get_cpu_clk(int cpu)
|
static struct clk *get_cpu_clk(int cpu)
|
||||||
{
|
{
|
||||||
struct clk *cpu_clk;
|
struct clk *cpu_clk;
|
||||||
|
@ -48,30 +50,6 @@ static struct clk *get_cpu_clk(int cpu)
|
||||||
return cpu_clk;
|
return cpu_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_secondary_cpu_clock(unsigned int cpu)
|
|
||||||
{
|
|
||||||
int thiscpu;
|
|
||||||
unsigned long rate;
|
|
||||||
struct clk *cpu_clk;
|
|
||||||
|
|
||||||
thiscpu = get_cpu();
|
|
||||||
|
|
||||||
cpu_clk = get_cpu_clk(thiscpu);
|
|
||||||
if (!cpu_clk)
|
|
||||||
goto out;
|
|
||||||
clk_prepare_enable(cpu_clk);
|
|
||||||
rate = clk_get_rate(cpu_clk);
|
|
||||||
|
|
||||||
cpu_clk = get_cpu_clk(cpu);
|
|
||||||
if (!cpu_clk)
|
|
||||||
goto out;
|
|
||||||
clk_set_rate(cpu_clk, rate);
|
|
||||||
clk_prepare_enable(cpu_clk);
|
|
||||||
|
|
||||||
out:
|
|
||||||
put_cpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
{
|
{
|
||||||
int ret, hw_cpu;
|
int ret, hw_cpu;
|
||||||
|
@ -79,7 +57,6 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
pr_info("Booting CPU %d\n", cpu);
|
pr_info("Booting CPU %d\n", cpu);
|
||||||
|
|
||||||
hw_cpu = cpu_logical_map(cpu);
|
hw_cpu = cpu_logical_map(cpu);
|
||||||
set_secondary_cpu_clock(hw_cpu);
|
|
||||||
mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
|
mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -122,6 +99,19 @@ static void __init armada_xp_smp_init_cpus(void)
|
||||||
panic("Invalid number of CPUs in DT\n");
|
panic("Invalid number of CPUs in DT\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int armada_xp_sync_secondary_clk(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct clk *cpu_clk = get_cpu_clk(cpu);
|
||||||
|
|
||||||
|
if (!cpu_clk || !boot_cpu_clk)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
clk_prepare_enable(cpu_clk);
|
||||||
|
clk_set_rate(cpu_clk, clk_get_rate(boot_cpu_clk));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
|
static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
{
|
{
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
|
@ -131,6 +121,14 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
flush_cache_all();
|
flush_cache_all();
|
||||||
set_cpu_coherent();
|
set_cpu_coherent();
|
||||||
|
|
||||||
|
boot_cpu_clk = get_cpu_clk(smp_processor_id());
|
||||||
|
if (boot_cpu_clk) {
|
||||||
|
clk_prepare_enable(boot_cpu_clk);
|
||||||
|
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_MVEBU_SYNC_CLOCKS,
|
||||||
|
"arm/mvebu/sync_clocks:online",
|
||||||
|
armada_xp_sync_secondary_clk, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In order to boot the secondary CPUs we need to ensure
|
* In order to boot the secondary CPUs we need to ensure
|
||||||
* the bootROM is mapped at the correct address.
|
* the bootROM is mapped at the correct address.
|
||||||
|
@ -223,7 +221,6 @@ static int mv98dx3236_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
int ret, hw_cpu;
|
int ret, hw_cpu;
|
||||||
|
|
||||||
hw_cpu = cpu_logical_map(cpu);
|
hw_cpu = cpu_logical_map(cpu);
|
||||||
set_secondary_cpu_clock(hw_cpu);
|
|
||||||
mv98dx3236_resume_set_cpu_boot_addr(hw_cpu,
|
mv98dx3236_resume_set_cpu_boot_addr(hw_cpu,
|
||||||
armada_xp_secondary_startup);
|
armada_xp_secondary_startup);
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,8 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
|
||||||
PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
|
PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned char mvebu_boot_wa_start;
|
extern unsigned char mvebu_boot_wa_start[];
|
||||||
extern unsigned char mvebu_boot_wa_end;
|
extern unsigned char mvebu_boot_wa_end[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sets up the boot address workaround needed for SMP
|
* This function sets up the boot address workaround needed for SMP
|
||||||
|
@ -130,7 +130,7 @@ int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target,
|
||||||
phys_addr_t resume_addr_reg)
|
phys_addr_t resume_addr_reg)
|
||||||
{
|
{
|
||||||
void __iomem *sram_virt_base;
|
void __iomem *sram_virt_base;
|
||||||
u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
|
u32 code_len = mvebu_boot_wa_end - mvebu_boot_wa_start;
|
||||||
|
|
||||||
mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
|
mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
|
||||||
mvebu_mbus_add_window_by_id(crypto_eng_target, crypto_eng_attribute,
|
mvebu_mbus_add_window_by_id(crypto_eng_target, crypto_eng_attribute,
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <linux/platform_data/ams-delta-fiq.h>
|
||||||
|
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
|
|
||||||
#include <mach/board-ams-delta.h>
|
#include <mach/board-ams-delta.h>
|
||||||
#include <mach/ams-delta-fiq.h>
|
|
||||||
|
|
||||||
|
#include "ams-delta-fiq.h"
|
||||||
#include "iomap.h"
|
#include "iomap.h"
|
||||||
#include "soc.h"
|
#include "soc.h"
|
||||||
|
|
||||||
|
|
|
@ -13,17 +13,20 @@
|
||||||
* under the terms of the GNU General Public License version 2 as published by
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
* the Free Software Foundation.
|
* the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/gpio/driver.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/platform_data/ams-delta-fiq.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <mach/board-ams-delta.h>
|
#include <mach/board-ams-delta.h>
|
||||||
|
|
||||||
#include <asm/fiq.h>
|
#include <asm/fiq.h>
|
||||||
|
|
||||||
#include <mach/ams-delta-fiq.h>
|
#include "ams-delta-fiq.h"
|
||||||
|
|
||||||
static struct fiq_handler fh = {
|
static struct fiq_handler fh = {
|
||||||
.name = "ams-delta-fiq"
|
.name = "ams-delta-fiq"
|
||||||
|
@ -34,20 +37,24 @@ static struct fiq_handler fh = {
|
||||||
* The FIQ and IRQ isrs can both read and write it.
|
* The FIQ and IRQ isrs can both read and write it.
|
||||||
* It is structured as a header section several 32bit slots,
|
* It is structured as a header section several 32bit slots,
|
||||||
* followed by the circular buffer where the FIQ isr stores
|
* followed by the circular buffer where the FIQ isr stores
|
||||||
* keystrokes received from the qwerty keyboard.
|
* keystrokes received from the qwerty keyboard. See
|
||||||
* See ams-delta-fiq.h for details of offsets.
|
* <linux/platform_data/ams-delta-fiq.h> for details of offsets.
|
||||||
*/
|
*/
|
||||||
unsigned int fiq_buffer[1024];
|
static unsigned int fiq_buffer[1024];
|
||||||
EXPORT_SYMBOL(fiq_buffer);
|
|
||||||
|
|
||||||
|
static struct irq_chip *irq_chip;
|
||||||
|
static struct irq_data *irq_data[16];
|
||||||
static unsigned int irq_counter[16];
|
static unsigned int irq_counter[16];
|
||||||
|
|
||||||
|
static const char *pin_name[16] __initconst = {
|
||||||
|
[AMS_DELTA_GPIO_PIN_KEYBRD_DATA] = "keybrd_data",
|
||||||
|
[AMS_DELTA_GPIO_PIN_KEYBRD_CLK] = "keybrd_clk",
|
||||||
|
};
|
||||||
|
|
||||||
static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
|
struct irq_data *d;
|
||||||
int gpio, irq_num, fiq_count;
|
int gpio, irq_num, fiq_count;
|
||||||
struct irq_chip *irq_chip;
|
|
||||||
|
|
||||||
irq_chip = irq_get_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each handled GPIO interrupt, keep calling its interrupt handler
|
* For each handled GPIO interrupt, keep calling its interrupt handler
|
||||||
|
@ -55,24 +62,21 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
||||||
*/
|
*/
|
||||||
for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
|
for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
|
||||||
gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
|
gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
|
||||||
irq_num = gpio_to_irq(gpio);
|
d = irq_data[gpio];
|
||||||
|
irq_num = d->irq;
|
||||||
fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
|
fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
|
||||||
|
|
||||||
if (irq_counter[gpio] < fiq_count &&
|
if (irq_counter[gpio] < fiq_count &&
|
||||||
gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
|
gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
|
||||||
struct irq_data *d = irq_get_irq_data(irq_num);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle_simple_irq() that OMAP GPIO edge
|
* handle_simple_irq() that OMAP GPIO edge
|
||||||
* interrupts default to since commit 80ac93c27441
|
* interrupts default to since commit 80ac93c27441
|
||||||
* requires interrupt already acked and unmasked.
|
* requires interrupt already acked and unmasked.
|
||||||
*/
|
*/
|
||||||
if (irq_chip) {
|
if (irq_chip->irq_ack)
|
||||||
if (irq_chip->irq_ack)
|
irq_chip->irq_ack(d);
|
||||||
irq_chip->irq_ack(d);
|
if (irq_chip->irq_unmask)
|
||||||
if (irq_chip->irq_unmask)
|
irq_chip->irq_unmask(d);
|
||||||
irq_chip->irq_unmask(d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
|
for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
|
||||||
generic_handle_irq(irq_num);
|
generic_handle_irq(irq_num);
|
||||||
|
@ -80,14 +84,56 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init ams_delta_init_fiq(void)
|
void __init ams_delta_init_fiq(struct gpio_chip *chip,
|
||||||
|
struct platform_device *serio)
|
||||||
{
|
{
|
||||||
|
struct gpio_desc *gpiod, *data = NULL, *clk = NULL;
|
||||||
void *fiqhandler_start;
|
void *fiqhandler_start;
|
||||||
unsigned int fiqhandler_length;
|
unsigned int fiqhandler_length;
|
||||||
struct pt_regs FIQ_regs;
|
struct pt_regs FIQ_regs;
|
||||||
unsigned long val, offset;
|
unsigned long val, offset;
|
||||||
int i, retval;
|
int i, retval;
|
||||||
|
|
||||||
|
/* Store irq_chip location for IRQ handler use */
|
||||||
|
irq_chip = chip->irq.chip;
|
||||||
|
if (!irq_chip) {
|
||||||
|
pr_err("%s: GPIO chip %s is missing IRQ function\n", __func__,
|
||||||
|
chip->label);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(irq_data); i++) {
|
||||||
|
gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]);
|
||||||
|
if (IS_ERR(gpiod)) {
|
||||||
|
pr_err("%s: failed to get GPIO pin %d (%ld)\n",
|
||||||
|
__func__, i, PTR_ERR(gpiod));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Store irq_data location for IRQ handler use */
|
||||||
|
irq_data[i] = irq_get_irq_data(gpiod_to_irq(gpiod));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIQ handler takes full control over serio data and clk GPIO
|
||||||
|
* pins. Initiaize them and keep requested so nobody can
|
||||||
|
* interfere. Fail if any of those two couldn't be requested.
|
||||||
|
*/
|
||||||
|
switch (i) {
|
||||||
|
case AMS_DELTA_GPIO_PIN_KEYBRD_DATA:
|
||||||
|
data = gpiod;
|
||||||
|
gpiod_direction_input(data);
|
||||||
|
break;
|
||||||
|
case AMS_DELTA_GPIO_PIN_KEYBRD_CLK:
|
||||||
|
clk = gpiod;
|
||||||
|
gpiod_direction_input(clk);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gpiochip_free_own_desc(gpiod);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!data || !clk)
|
||||||
|
goto out_gpio;
|
||||||
|
|
||||||
fiqhandler_start = &qwerty_fiqin_start;
|
fiqhandler_start = &qwerty_fiqin_start;
|
||||||
fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
|
fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
|
||||||
pr_info("Installing fiq handler from %p, length 0x%x\n",
|
pr_info("Installing fiq handler from %p, length 0x%x\n",
|
||||||
|
@ -97,7 +143,7 @@ void __init ams_delta_init_fiq(void)
|
||||||
if (retval) {
|
if (retval) {
|
||||||
pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
|
pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
|
||||||
retval);
|
retval);
|
||||||
return;
|
goto out_gpio;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
|
retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
|
||||||
|
@ -105,7 +151,7 @@ void __init ams_delta_init_fiq(void)
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
|
pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
|
||||||
release_fiq(&fh);
|
release_fiq(&fh);
|
||||||
return;
|
goto out_gpio;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Since no set_type() method is provided by OMAP irq chip,
|
* Since no set_type() method is provided by OMAP irq chip,
|
||||||
|
@ -155,4 +201,29 @@ void __init ams_delta_init_fiq(void)
|
||||||
offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4;
|
offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4;
|
||||||
val = omap_readl(OMAP_IH1_BASE + offset) | 1;
|
val = omap_readl(OMAP_IH1_BASE + offset) | 1;
|
||||||
omap_writel(val, OMAP_IH1_BASE + offset);
|
omap_writel(val, OMAP_IH1_BASE + offset);
|
||||||
|
|
||||||
|
/* Initialize serio device IRQ resource and platform_data */
|
||||||
|
serio->resource[0].start = gpiod_to_irq(clk);
|
||||||
|
serio->resource[0].end = serio->resource[0].start;
|
||||||
|
serio->dev.platform_data = fiq_buffer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since FIQ handler performs handling of GPIO registers for
|
||||||
|
* "keybrd_clk" IRQ pin, ams_delta_serio driver used to set
|
||||||
|
* handle_simple_irq() as active IRQ handler for that pin to avoid
|
||||||
|
* bad interaction with gpio-omap driver. This is no longer needed
|
||||||
|
* as handle_simple_irq() is now the default handler for OMAP GPIO
|
||||||
|
* edge interrupts.
|
||||||
|
* This comment replaces the obsolete code which has been removed
|
||||||
|
* from the ams_delta_serio driver and stands here only as a reminder
|
||||||
|
* of that dependency on gpio-omap driver behavior.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_gpio:
|
||||||
|
if (data)
|
||||||
|
gpiochip_free_own_desc(data);
|
||||||
|
if (clk)
|
||||||
|
gpiochip_free_own_desc(clk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-omap1/ams-delta-fiq.h
|
||||||
|
*
|
||||||
|
* Taken from the original Amstrad modifications to fiq.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004 Amstrad Plc
|
||||||
|
* Copyright (c) 2006 Matt Callow
|
||||||
|
* Copyright (c) 2010 Janusz Krzysztofik
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __AMS_DELTA_FIQ_H
|
||||||
|
#define __AMS_DELTA_FIQ_H
|
||||||
|
|
||||||
|
#include <mach/irqs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt number used for passing control from FIQ to IRQ.
|
||||||
|
* IRQ12, described as reserved, has been selected.
|
||||||
|
*/
|
||||||
|
#define INT_DEFERRED_FIQ INT_1510_RES12
|
||||||
|
/*
|
||||||
|
* Base address of an interrupt handler that the INT_DEFERRED_FIQ belongs to.
|
||||||
|
*/
|
||||||
|
#if (INT_DEFERRED_FIQ < IH2_BASE)
|
||||||
|
#define DEFERRED_FIQ_IH_BASE OMAP_IH1_BASE
|
||||||
|
#else
|
||||||
|
#define DEFERRED_FIQ_IH_BASE OMAP_IH2_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end;
|
||||||
|
|
||||||
|
extern void __init ams_delta_init_fiq(struct gpio_chip *chip,
|
||||||
|
struct platform_device *pdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -41,10 +41,10 @@
|
||||||
#include <mach/mux.h>
|
#include <mach/mux.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/ams-delta-fiq.h>
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include <mach/usb.h>
|
#include <mach/usb.h>
|
||||||
|
|
||||||
|
#include "ams-delta-fiq.h"
|
||||||
#include "iomap.h"
|
#include "iomap.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
@ -179,7 +179,10 @@ static struct resource latch1_resources[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LATCH1_LABEL "latch1"
|
||||||
|
|
||||||
static struct bgpio_pdata latch1_pdata = {
|
static struct bgpio_pdata latch1_pdata = {
|
||||||
|
.label = LATCH1_LABEL,
|
||||||
.base = LATCH1_GPIO_BASE,
|
.base = LATCH1_GPIO_BASE,
|
||||||
.ngpio = LATCH1_NGPIO,
|
.ngpio = LATCH1_NGPIO,
|
||||||
};
|
};
|
||||||
|
@ -194,6 +197,15 @@ static struct platform_device latch1_gpio_device = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LATCH1_PIN_LED_CAMERA 0
|
||||||
|
#define LATCH1_PIN_LED_ADVERT 1
|
||||||
|
#define LATCH1_PIN_LED_MAIL 2
|
||||||
|
#define LATCH1_PIN_LED_HANDSFREE 3
|
||||||
|
#define LATCH1_PIN_LED_VOICEMAIL 4
|
||||||
|
#define LATCH1_PIN_LED_VOICE 5
|
||||||
|
#define LATCH1_PIN_DOCKIT1 6
|
||||||
|
#define LATCH1_PIN_DOCKIT2 7
|
||||||
|
|
||||||
static struct resource latch2_resources[] = {
|
static struct resource latch2_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.name = "dat",
|
.name = "dat",
|
||||||
|
@ -398,38 +410,43 @@ static struct gpiod_lookup_table ams_delta_lcd_gpio_table = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gpio_led gpio_leds[] __initconst = {
|
/*
|
||||||
{
|
* Dynamically allocated GPIO numbers must be obtained fromm GPIO device
|
||||||
|
* before they can be put in the gpio_led table. Before that happens,
|
||||||
|
* initialize the table with invalid GPIO numbers, not 0.
|
||||||
|
*/
|
||||||
|
static struct gpio_led gpio_leds[] __initdata = {
|
||||||
|
[LATCH1_PIN_LED_CAMERA] = {
|
||||||
.name = "camera",
|
.name = "camera",
|
||||||
.gpio = LATCH1_GPIO_BASE + 0,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
#ifdef CONFIG_LEDS_TRIGGERS
|
#ifdef CONFIG_LEDS_TRIGGERS
|
||||||
.default_trigger = "ams_delta_camera",
|
.default_trigger = "ams_delta_camera",
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
{
|
[LATCH1_PIN_LED_ADVERT] = {
|
||||||
.name = "advert",
|
.name = "advert",
|
||||||
.gpio = LATCH1_GPIO_BASE + 1,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
},
|
},
|
||||||
{
|
[LATCH1_PIN_LED_MAIL] = {
|
||||||
.name = "email",
|
.name = "email",
|
||||||
.gpio = LATCH1_GPIO_BASE + 2,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
},
|
},
|
||||||
{
|
[LATCH1_PIN_LED_HANDSFREE] = {
|
||||||
.name = "handsfree",
|
.name = "handsfree",
|
||||||
.gpio = LATCH1_GPIO_BASE + 3,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
},
|
},
|
||||||
{
|
[LATCH1_PIN_LED_VOICEMAIL] = {
|
||||||
.name = "voicemail",
|
.name = "voicemail",
|
||||||
.gpio = LATCH1_GPIO_BASE + 4,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
},
|
},
|
||||||
{
|
[LATCH1_PIN_LED_VOICE] = {
|
||||||
.name = "voice",
|
.name = "voice",
|
||||||
.gpio = LATCH1_GPIO_BASE + 5,
|
.gpio = -EINVAL,
|
||||||
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
.default_state = LEDS_GPIO_DEFSTATE_OFF,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -504,16 +521,70 @@ static struct platform_device cx20442_codec_device = {
|
||||||
.id = -1,
|
.id = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table ams_delta_serio_gpio_table = {
|
static struct resource ams_delta_serio_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
/*
|
||||||
|
* Initialize IRQ resource with invalid IRQ number.
|
||||||
|
* It will be replaced with dynamically allocated GPIO IRQ
|
||||||
|
* obtained from GPIO chip as soon as the chip is available.
|
||||||
|
*/
|
||||||
|
.start = -EINVAL,
|
||||||
|
.end = -EINVAL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device ams_delta_serio_device = {
|
||||||
|
.name = "ams-delta-serio",
|
||||||
|
.id = PLATFORM_DEVID_NONE,
|
||||||
|
.dev = {
|
||||||
|
/*
|
||||||
|
* Initialize .platform_data explicitly with NULL to
|
||||||
|
* indicate it is going to be used. It will be replaced
|
||||||
|
* with FIQ buffer address as soon as FIQ is initialized.
|
||||||
|
*/
|
||||||
|
.platform_data = NULL,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(ams_delta_serio_resources),
|
||||||
|
.resource = ams_delta_serio_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply keybrd_pwr_consumers[] = {
|
||||||
|
/*
|
||||||
|
* Initialize supply .dev_name with NULL. It will be replaced
|
||||||
|
* with serio dev_name() as soon as the serio device is registered.
|
||||||
|
*/
|
||||||
|
REGULATOR_SUPPLY("vcc", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_init_data keybrd_pwr_initdata = {
|
||||||
|
.constraints = {
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = ARRAY_SIZE(keybrd_pwr_consumers),
|
||||||
|
.consumer_supplies = keybrd_pwr_consumers,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fixed_voltage_config keybrd_pwr_config = {
|
||||||
|
.supply_name = "keybrd_pwr",
|
||||||
|
.microvolts = 5000000,
|
||||||
|
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR,
|
||||||
|
.enable_high = 1,
|
||||||
|
.init_data = &keybrd_pwr_initdata,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device keybrd_pwr_device = {
|
||||||
|
.name = "reg-fixed-voltage",
|
||||||
|
.id = PLATFORM_DEVID_AUTO,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &keybrd_pwr_config,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpiod_lookup_table keybrd_pwr_gpio_table = {
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
|
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR, NULL,
|
||||||
"data", 0),
|
GPIO_ACTIVE_HIGH),
|
||||||
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
|
|
||||||
"clock", 0),
|
|
||||||
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR,
|
|
||||||
"power", 0),
|
|
||||||
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT,
|
|
||||||
"dataout", 0),
|
|
||||||
{ },
|
{ },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -524,9 +595,7 @@ static struct platform_device *ams_delta_devices[] __initdata = {
|
||||||
&ams_delta_kp_device,
|
&ams_delta_kp_device,
|
||||||
&ams_delta_camera_device,
|
&ams_delta_camera_device,
|
||||||
&ams_delta_audio_device,
|
&ams_delta_audio_device,
|
||||||
};
|
&ams_delta_serio_device,
|
||||||
|
|
||||||
static struct platform_device *late_devices[] __initdata = {
|
|
||||||
&ams_delta_nand_device,
|
&ams_delta_nand_device,
|
||||||
&ams_delta_lcd_device,
|
&ams_delta_lcd_device,
|
||||||
&cx20442_codec_device,
|
&cx20442_codec_device,
|
||||||
|
@ -534,14 +603,55 @@ static struct platform_device *late_devices[] __initdata = {
|
||||||
|
|
||||||
static struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = {
|
static struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = {
|
||||||
&ams_delta_audio_gpio_table,
|
&ams_delta_audio_gpio_table,
|
||||||
&ams_delta_serio_gpio_table,
|
&keybrd_pwr_gpio_table,
|
||||||
};
|
|
||||||
|
|
||||||
static struct gpiod_lookup_table *late_gpio_tables[] __initdata = {
|
|
||||||
&ams_delta_lcd_gpio_table,
|
&ams_delta_lcd_gpio_table,
|
||||||
&ams_delta_nand_gpio_table,
|
&ams_delta_nand_gpio_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some drivers may not use GPIO lookup tables but need to be provided
|
||||||
|
* with GPIO numbers. The same applies to GPIO based IRQ lines - some
|
||||||
|
* drivers may even not use GPIO layer but expect just IRQ numbers.
|
||||||
|
* We could either define GPIO lookup tables then use them on behalf
|
||||||
|
* of those devices, or we can use GPIO driver level methods for
|
||||||
|
* identification of GPIO and IRQ numbers. For the purpose of the latter,
|
||||||
|
* defina a helper function which identifies GPIO chips by their labels.
|
||||||
|
*/
|
||||||
|
static int gpiochip_match_by_label(struct gpio_chip *chip, void *data)
|
||||||
|
{
|
||||||
|
char *label = data;
|
||||||
|
|
||||||
|
return !strcmp(label, chip->label);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gpiod_hog ams_delta_gpio_hogs[] = {
|
||||||
|
GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout",
|
||||||
|
GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW),
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The purpose of this function is to take care of proper initialization of
|
||||||
|
* devices and data structures which depend on GPIO lines provided by OMAP GPIO
|
||||||
|
* banks but their drivers don't use GPIO lookup tables or GPIO layer at all.
|
||||||
|
* The function may be called as soon as OMAP GPIO devices are probed.
|
||||||
|
* Since that happens at postcore_initcall, it can be called successfully
|
||||||
|
* from init_machine or later.
|
||||||
|
* Dependent devices may be registered from within this function or later.
|
||||||
|
*/
|
||||||
|
static void __init omap_gpio_deps_init(void)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip;
|
||||||
|
|
||||||
|
chip = gpiochip_find(OMAP_GPIO_LABEL, gpiochip_match_by_label);
|
||||||
|
if (!chip) {
|
||||||
|
pr_err("%s: OMAP GPIO chip not found\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ams_delta_init_fiq(chip, &ams_delta_serio_device);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init ams_delta_init(void)
|
static void __init ams_delta_init(void)
|
||||||
{
|
{
|
||||||
/* mux pins for uarts */
|
/* mux pins for uarts */
|
||||||
|
@ -562,6 +672,9 @@ static void __init ams_delta_init(void)
|
||||||
omap_cfg_reg(J19_1610_CAM_D6);
|
omap_cfg_reg(J19_1610_CAM_D6);
|
||||||
omap_cfg_reg(J18_1610_CAM_D7);
|
omap_cfg_reg(J18_1610_CAM_D7);
|
||||||
|
|
||||||
|
omap_gpio_deps_init();
|
||||||
|
gpiod_add_hogs(ams_delta_gpio_hogs);
|
||||||
|
|
||||||
omap_serial_init();
|
omap_serial_init();
|
||||||
omap_register_i2c_bus(1, 100, NULL, 0);
|
omap_register_i2c_bus(1, 100, NULL, 0);
|
||||||
|
|
||||||
|
@ -571,25 +684,38 @@ static void __init ams_delta_init(void)
|
||||||
led_trigger_register_simple("ams_delta_camera",
|
led_trigger_register_simple("ams_delta_camera",
|
||||||
&ams_delta_camera_led_trigger);
|
&ams_delta_camera_led_trigger);
|
||||||
#endif
|
#endif
|
||||||
gpio_led_register_device(-1, &leds_pdata);
|
|
||||||
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
|
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As soon as devices have been registered, assign their dev_names
|
* As soon as regulator consumers have been registered, assign their
|
||||||
* to respective GPIO lookup tables before they are added.
|
* dev_names to consumer supply entries of respective regulators.
|
||||||
|
*/
|
||||||
|
keybrd_pwr_consumers[0].dev_name =
|
||||||
|
dev_name(&ams_delta_serio_device.dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Once consumer supply entries are populated with dev_names,
|
||||||
|
* register regulator devices. At this stage only the keyboard
|
||||||
|
* power regulator has its consumer supply table fully populated.
|
||||||
|
*/
|
||||||
|
platform_device_register(&keybrd_pwr_device);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As soon as GPIO consumers have been registered, assign
|
||||||
|
* their dev_names to respective GPIO lookup tables.
|
||||||
*/
|
*/
|
||||||
ams_delta_audio_gpio_table.dev_id =
|
ams_delta_audio_gpio_table.dev_id =
|
||||||
dev_name(&ams_delta_audio_device.dev);
|
dev_name(&ams_delta_audio_device.dev);
|
||||||
/*
|
keybrd_pwr_gpio_table.dev_id = dev_name(&keybrd_pwr_device.dev);
|
||||||
* No device name is assigned to GPIO lookup table for serio device
|
ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
|
||||||
* as long as serio driver is not converted to platform device driver.
|
ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
|
||||||
*/
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Once GPIO lookup tables are populated with dev_names, register them.
|
||||||
|
*/
|
||||||
gpiod_add_lookup_tables(ams_delta_gpio_tables,
|
gpiod_add_lookup_tables(ams_delta_gpio_tables,
|
||||||
ARRAY_SIZE(ams_delta_gpio_tables));
|
ARRAY_SIZE(ams_delta_gpio_tables));
|
||||||
|
|
||||||
ams_delta_init_fiq();
|
|
||||||
|
|
||||||
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
|
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
|
||||||
|
|
||||||
omapfb_set_lcd_config(&ams_delta_lcd_config);
|
omapfb_set_lcd_config(&ams_delta_lcd_config);
|
||||||
|
@ -643,35 +769,84 @@ static struct platform_device ams_delta_modem_device = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init late_init(void)
|
/*
|
||||||
|
* leds-gpio driver doesn't make use of GPIO lookup tables,
|
||||||
|
* it has to be provided with GPIO numbers over platform data
|
||||||
|
* if GPIO descriptor info can't be obtained from device tree.
|
||||||
|
* We could either define GPIO lookup tables and use them on behalf
|
||||||
|
* of the leds-gpio device, or we can use GPIO driver level methods
|
||||||
|
* for identification of GPIO numbers as long as we don't support
|
||||||
|
* device tree. Let's do the latter.
|
||||||
|
*/
|
||||||
|
static void __init ams_delta_led_init(struct gpio_chip *chip)
|
||||||
{
|
{
|
||||||
|
struct gpio_desc *gpiod;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = LATCH1_PIN_LED_CAMERA; i < LATCH1_PIN_DOCKIT1; i++) {
|
||||||
|
gpiod = gpiochip_request_own_desc(chip, i, NULL);
|
||||||
|
if (IS_ERR(gpiod)) {
|
||||||
|
pr_warn("%s: %s GPIO %d request failed (%ld)\n",
|
||||||
|
__func__, LATCH1_LABEL, i, PTR_ERR(gpiod));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign GPIO numbers to LED device. */
|
||||||
|
gpio_leds[i].gpio = desc_to_gpio(gpiod);
|
||||||
|
|
||||||
|
gpiochip_free_own_desc(gpiod);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The purpose of this function is to take care of assignment of GPIO numbers
|
||||||
|
* to platform devices which depend on GPIO lines provided by Amstrad Delta
|
||||||
|
* latch1 and/or latch2 GPIO devices but don't use GPIO lookup tables.
|
||||||
|
* The function may be called as soon as latch1/latch2 GPIO devices are
|
||||||
|
* initilized. Since basic-mmio-gpio driver is not registered before
|
||||||
|
* device_initcall, this may happen at erliest during device_initcall_sync.
|
||||||
|
* Dependent devices shouldn't be registered before that, their
|
||||||
|
* registration may be performed from within this function or later.
|
||||||
|
*/
|
||||||
|
static int __init ams_delta_gpio_init(void)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!machine_is_ams_delta())
|
if (!machine_is_ams_delta())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
chip = gpiochip_find(LATCH1_LABEL, gpiochip_match_by_label);
|
||||||
|
if (!chip)
|
||||||
|
pr_err("%s: latch1 GPIO chip not found\n", __func__);
|
||||||
|
else
|
||||||
|
ams_delta_led_init(chip);
|
||||||
|
|
||||||
err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
|
err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
|
||||||
if (err) {
|
if (err)
|
||||||
pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
|
pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
|
return err;
|
||||||
|
}
|
||||||
|
device_initcall_sync(ams_delta_gpio_init);
|
||||||
|
|
||||||
/*
|
static int __init modem_nreset_init(void)
|
||||||
* As soon as devices have been registered, assign their dev_names
|
{
|
||||||
* to respective GPIO lookup tables before they are added.
|
int err;
|
||||||
*/
|
|
||||||
ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
|
|
||||||
ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
|
|
||||||
|
|
||||||
gpiod_add_lookup_tables(late_gpio_tables, ARRAY_SIZE(late_gpio_tables));
|
|
||||||
|
|
||||||
err = platform_device_register(&modem_nreset_device);
|
err = platform_device_register(&modem_nreset_device);
|
||||||
if (err) {
|
if (err)
|
||||||
pr_err("Couldn't register the modem regulator device\n");
|
pr_err("Couldn't register the modem regulator device\n");
|
||||||
return err;
|
|
||||||
}
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __init ams_delta_modem_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
omap_cfg_reg(M14_1510_GPIO2);
|
omap_cfg_reg(M14_1510_GPIO2);
|
||||||
ams_delta_modem_ports[0].irq =
|
ams_delta_modem_ports[0].irq =
|
||||||
|
@ -692,7 +867,22 @@ static int __init late_init(void)
|
||||||
|
|
||||||
err = platform_device_register(&ams_delta_modem_device);
|
err = platform_device_register(&ams_delta_modem_device);
|
||||||
if (err)
|
if (err)
|
||||||
goto gpio_free;
|
gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init late_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = modem_nreset_init();
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = ams_delta_modem_init();
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Once the modem device is registered, the modem_nreset
|
* Once the modem device is registered, the modem_nreset
|
||||||
|
@ -708,7 +898,6 @@ static int __init late_init(void)
|
||||||
|
|
||||||
unregister:
|
unregister:
|
||||||
platform_device_unregister(&ams_delta_modem_device);
|
platform_device_unregister(&ams_delta_modem_device);
|
||||||
gpio_free:
|
|
||||||
gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
|
gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ static struct platform_device h2_kp_device = {
|
||||||
.resource = h2_kp_resources,
|
.resource = h2_kp_resources,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpio_led h2_gpio_led_pins[] = {
|
static const struct gpio_led h2_gpio_led_pins[] = {
|
||||||
{
|
{
|
||||||
.name = "h2:red",
|
.name = "h2:red",
|
||||||
.default_trigger = "heartbeat",
|
.default_trigger = "heartbeat",
|
||||||
|
|
|
@ -326,7 +326,7 @@ static struct spi_board_info h3_spi_board_info[] __initdata = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpio_led h3_gpio_led_pins[] = {
|
static const struct gpio_led h3_gpio_led_pins[] = {
|
||||||
{
|
{
|
||||||
.name = "h3:red",
|
.name = "h3:red",
|
||||||
.default_trigger = "heartbeat",
|
.default_trigger = "heartbeat",
|
||||||
|
|
|
@ -292,7 +292,7 @@ static struct platform_device herald_gpiokeys_device = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */
|
/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */
|
||||||
static struct gpio_led gpio_leds[] = {
|
static const struct gpio_led gpio_leds[] = {
|
||||||
{"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
{"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
||||||
{"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
{"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
||||||
{"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
{"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
|
||||||
|
|
|
@ -167,7 +167,7 @@ static struct platform_device *osk5912_devices[] __initdata = {
|
||||||
&osk5912_cf_device,
|
&osk5912_cf_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpio_led tps_leds[] = {
|
static const struct gpio_led tps_leds[] = {
|
||||||
/* NOTE: D9 and D2 have hardware blink support.
|
/* NOTE: D9 and D2 have hardware blink support.
|
||||||
* Also, D9 requires non-battery power.
|
* Also, D9 requires non-battery power.
|
||||||
*/
|
*/
|
||||||
|
@ -385,7 +385,7 @@ static struct platform_device osk5912_lcd_device = {
|
||||||
.id = -1,
|
.id = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpio_led mistral_gpio_led_pins[] = {
|
static const struct gpio_led mistral_gpio_led_pins[] = {
|
||||||
{
|
{
|
||||||
.name = "mistral:red",
|
.name = "mistral:red",
|
||||||
.default_trigger = "heartbeat",
|
.default_trigger = "heartbeat",
|
||||||
|
|
|
@ -92,11 +92,13 @@ static void omap_rtc_wait_not_busy(struct omap_hwmod *oh)
|
||||||
*/
|
*/
|
||||||
void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
|
void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
|
||||||
{
|
{
|
||||||
local_irq_disable();
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
omap_rtc_wait_not_busy(oh);
|
omap_rtc_wait_not_busy(oh);
|
||||||
omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
|
omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
|
||||||
omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
|
omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
|
||||||
local_irq_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,9 +112,11 @@ void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
|
||||||
*/
|
*/
|
||||||
void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
|
void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
|
||||||
{
|
{
|
||||||
local_irq_disable();
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
omap_rtc_wait_not_busy(oh);
|
omap_rtc_wait_not_busy(oh);
|
||||||
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
|
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
|
||||||
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
|
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
|
||||||
local_irq_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ int main(void)
|
||||||
offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
|
offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
|
||||||
DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
|
DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
|
||||||
offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
|
offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
|
||||||
|
DEFINE(AMX3_PM_RTC_BASE_VIRT_OFFSET,
|
||||||
|
offsetof(struct am33xx_pm_ro_sram_data, rtc_base_virt));
|
||||||
DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
|
DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
|
||||||
sizeof(struct am33xx_pm_ro_sram_data));
|
sizeof(struct am33xx_pm_ro_sram_data));
|
||||||
|
|
||||||
|
|
|
@ -47,11 +47,6 @@ static int pm_dbg_init_done;
|
||||||
|
|
||||||
static int pm_dbg_init(void);
|
static int pm_dbg_init(void);
|
||||||
|
|
||||||
enum {
|
|
||||||
DEBUG_FILE_COUNTERS = 0,
|
|
||||||
DEBUG_FILE_TIMERS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
|
static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
|
||||||
"OFF",
|
"OFF",
|
||||||
"RET",
|
"RET",
|
||||||
|
@ -141,39 +136,21 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pm_dbg_show_counters(struct seq_file *s, void *unused)
|
static int pm_dbg_counters_show(struct seq_file *s, void *unused)
|
||||||
{
|
{
|
||||||
pwrdm_for_each(pwrdm_dbg_show_counter, s);
|
pwrdm_for_each(pwrdm_dbg_show_counter, s);
|
||||||
clkdm_for_each(clkdm_dbg_show_counter, s);
|
clkdm_for_each(clkdm_dbg_show_counter, s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
DEFINE_SHOW_ATTRIBUTE(pm_dbg_counters);
|
||||||
|
|
||||||
static int pm_dbg_show_timers(struct seq_file *s, void *unused)
|
static int pm_dbg_timers_show(struct seq_file *s, void *unused)
|
||||||
{
|
{
|
||||||
pwrdm_for_each(pwrdm_dbg_show_timer, s);
|
pwrdm_for_each(pwrdm_dbg_show_timer, s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
DEFINE_SHOW_ATTRIBUTE(pm_dbg_timers);
|
||||||
static int pm_dbg_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
switch ((int)inode->i_private) {
|
|
||||||
case DEBUG_FILE_COUNTERS:
|
|
||||||
return single_open(file, pm_dbg_show_counters,
|
|
||||||
&inode->i_private);
|
|
||||||
case DEBUG_FILE_TIMERS:
|
|
||||||
default:
|
|
||||||
return single_open(file, pm_dbg_show_timers,
|
|
||||||
&inode->i_private);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations debug_fops = {
|
|
||||||
.open = pm_dbg_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int pwrdm_suspend_get(void *data, u64 *val)
|
static int pwrdm_suspend_get(void *data, u64 *val)
|
||||||
{
|
{
|
||||||
|
@ -259,10 +236,8 @@ static int __init pm_dbg_init(void)
|
||||||
if (!d)
|
if (!d)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
(void) debugfs_create_file("count", S_IRUGO,
|
(void) debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops);
|
||||||
d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
|
(void) debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops);
|
||||||
(void) debugfs_create_file("time", S_IRUGO,
|
|
||||||
d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
|
|
||||||
|
|
||||||
pwrdm_for_each(pwrdms_setup, (void *)d);
|
pwrdm_for_each(pwrdms_setup, (void *)d);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
|
static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
|
||||||
static struct clockdomain *gfx_l4ls_clkdm;
|
static struct clockdomain *gfx_l4ls_clkdm;
|
||||||
static void __iomem *scu_base;
|
static void __iomem *scu_base;
|
||||||
|
static struct omap_hwmod *rtc_oh;
|
||||||
|
|
||||||
static int __init am43xx_map_scu(void)
|
static int __init am43xx_map_scu(void)
|
||||||
{
|
{
|
||||||
|
@ -106,12 +107,13 @@ static void amx3_post_suspend_common(void)
|
||||||
pr_err("PM: GFX domain did not transition: %x\n", status);
|
pr_err("PM: GFX domain did not transition: %x\n", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
|
static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long),
|
||||||
|
unsigned long args)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
amx3_pre_suspend_common();
|
amx3_pre_suspend_common();
|
||||||
ret = cpu_suspend(0, fn);
|
ret = cpu_suspend(args, fn);
|
||||||
amx3_post_suspend_common();
|
amx3_post_suspend_common();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -128,13 +130,14 @@ static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long))
|
static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
|
||||||
|
unsigned long args)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
amx3_pre_suspend_common();
|
amx3_pre_suspend_common();
|
||||||
scu_power_mode(scu_base, SCU_PM_POWEROFF);
|
scu_power_mode(scu_base, SCU_PM_POWEROFF);
|
||||||
ret = cpu_suspend(0, fn);
|
ret = cpu_suspend(args, fn);
|
||||||
scu_power_mode(scu_base, SCU_PM_NORMAL);
|
scu_power_mode(scu_base, SCU_PM_NORMAL);
|
||||||
amx3_post_suspend_common();
|
amx3_post_suspend_common();
|
||||||
|
|
||||||
|
@ -151,16 +154,25 @@ static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __iomem *am43xx_get_rtc_base_addr(void)
|
||||||
|
{
|
||||||
|
rtc_oh = omap_hwmod_lookup("rtc");
|
||||||
|
|
||||||
|
return omap_hwmod_get_mpu_rt_va(rtc_oh);
|
||||||
|
}
|
||||||
|
|
||||||
static struct am33xx_pm_platform_data am33xx_ops = {
|
static struct am33xx_pm_platform_data am33xx_ops = {
|
||||||
.init = am33xx_suspend_init,
|
.init = am33xx_suspend_init,
|
||||||
.soc_suspend = am33xx_suspend,
|
.soc_suspend = am33xx_suspend,
|
||||||
.get_sram_addrs = amx3_get_sram_addrs,
|
.get_sram_addrs = amx3_get_sram_addrs,
|
||||||
|
.get_rtc_base_addr = am43xx_get_rtc_base_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct am33xx_pm_platform_data am43xx_ops = {
|
static struct am33xx_pm_platform_data am43xx_ops = {
|
||||||
.init = am43xx_suspend_init,
|
.init = am43xx_suspend_init,
|
||||||
.soc_suspend = am43xx_suspend,
|
.soc_suspend = am43xx_suspend,
|
||||||
.get_sram_addrs = amx3_get_sram_addrs,
|
.get_sram_addrs = amx3_get_sram_addrs,
|
||||||
|
.get_rtc_base_addr = am43xx_get_rtc_base_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
|
static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <generated/ti-pm-asm-offsets.h>
|
#include <generated/ti-pm-asm-offsets.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <linux/platform_data/pm33xx.h>
|
||||||
#include <linux/ti-emif-sram.h>
|
#include <linux/ti-emif-sram.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
#include <asm/memory.h>
|
#include <asm/memory.h>
|
||||||
|
@ -19,12 +20,25 @@
|
||||||
#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
|
#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
|
||||||
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
|
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
|
||||||
|
|
||||||
|
/* replicated define because linux/bitops.h cannot be included in assembly */
|
||||||
|
#define BIT(nr) (1 << (nr))
|
||||||
|
|
||||||
.arm
|
.arm
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
ENTRY(am33xx_do_wfi)
|
ENTRY(am33xx_do_wfi)
|
||||||
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
||||||
|
|
||||||
|
/* Save wfi_flags arg to data space */
|
||||||
|
mov r4, r0
|
||||||
|
adr r3, am33xx_pm_ro_sram_data
|
||||||
|
ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
|
||||||
|
str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
|
||||||
|
|
||||||
|
/* Only flush cache is we know we are losing MPU context */
|
||||||
|
tst r4, #WFI_FLAG_FLUSH_CACHE
|
||||||
|
beq cache_skip_flush
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush all data from the L1 and L2 data cache before disabling
|
* Flush all data from the L1 and L2 data cache before disabling
|
||||||
* SCTLR.C bit.
|
* SCTLR.C bit.
|
||||||
|
@ -48,14 +62,33 @@ ENTRY(am33xx_do_wfi)
|
||||||
ldr r1, kernel_flush
|
ldr r1, kernel_flush
|
||||||
blx r1
|
blx r1
|
||||||
|
|
||||||
|
adr r3, am33xx_pm_ro_sram_data
|
||||||
|
ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
|
||||||
|
ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
|
||||||
|
|
||||||
|
cache_skip_flush:
|
||||||
|
/* Check if we want self refresh */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_enter_sr
|
||||||
|
|
||||||
adr r9, am33xx_emif_sram_table
|
adr r9, am33xx_emif_sram_table
|
||||||
|
|
||||||
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
|
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
|
||||||
blx r3
|
blx r3
|
||||||
|
|
||||||
|
emif_skip_enter_sr:
|
||||||
|
/* Only necessary if PER is losing context */
|
||||||
|
tst r4, #WFI_FLAG_SAVE_EMIF
|
||||||
|
beq emif_skip_save
|
||||||
|
|
||||||
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
|
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
|
||||||
blx r3
|
blx r3
|
||||||
|
|
||||||
|
emif_skip_save:
|
||||||
|
/* Only can disable EMIF if we have entered self refresh */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_disable
|
||||||
|
|
||||||
/* Disable EMIF */
|
/* Disable EMIF */
|
||||||
ldr r1, virt_emif_clkctrl
|
ldr r1, virt_emif_clkctrl
|
||||||
ldr r2, [r1]
|
ldr r2, [r1]
|
||||||
|
@ -69,6 +102,10 @@ wait_emif_disable:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bne wait_emif_disable
|
bne wait_emif_disable
|
||||||
|
|
||||||
|
emif_skip_disable:
|
||||||
|
tst r4, #WFI_FLAG_WAKE_M3
|
||||||
|
beq wkup_m3_skip
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the MPU WFI to be registered as an interrupt
|
* For the MPU WFI to be registered as an interrupt
|
||||||
* to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
|
* to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
|
||||||
|
@ -79,6 +116,7 @@ wait_emif_disable:
|
||||||
bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
|
bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
|
||||||
str r2, [r1]
|
str r2, [r1]
|
||||||
|
|
||||||
|
wkup_m3_skip:
|
||||||
/*
|
/*
|
||||||
* Execute an ISB instruction to ensure that all of the
|
* Execute an ISB instruction to ensure that all of the
|
||||||
* CP15 register changes have been committed.
|
* CP15 register changes have been committed.
|
||||||
|
@ -132,10 +170,18 @@ wait_emif_enable:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bne wait_emif_enable
|
bne wait_emif_enable
|
||||||
|
|
||||||
|
/* Only necessary if PER is losing context */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_exit_sr_abt
|
||||||
|
|
||||||
|
adr r9, am33xx_emif_sram_table
|
||||||
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
|
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
|
||||||
blx r1
|
blx r1
|
||||||
|
|
||||||
|
emif_skip_exit_sr_abt:
|
||||||
|
tst r4, #WFI_FLAG_FLUSH_CACHE
|
||||||
|
beq cache_skip_restore
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set SCTLR.C bit to allow data cache allocation
|
* Set SCTLR.C bit to allow data cache allocation
|
||||||
*/
|
*/
|
||||||
|
@ -144,6 +190,7 @@ wait_emif_enable:
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
isb
|
isb
|
||||||
|
|
||||||
|
cache_skip_restore:
|
||||||
/* Let the suspend code know about the abort */
|
/* Let the suspend code know about the abort */
|
||||||
mov r0, #1
|
mov r0, #1
|
||||||
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
|
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
|
||||||
|
@ -181,8 +228,6 @@ ENDPROC(am33xx_resume_from_deep_sleep)
|
||||||
* Local variables
|
* Local variables
|
||||||
*/
|
*/
|
||||||
.align
|
.align
|
||||||
resume_addr:
|
|
||||||
.word cpu_resume - PAGE_OFFSET + 0x80000000
|
|
||||||
kernel_flush:
|
kernel_flush:
|
||||||
.word v7_flush_dcache_all
|
.word v7_flush_dcache_all
|
||||||
virt_mpu_clkctrl:
|
virt_mpu_clkctrl:
|
||||||
|
@ -205,6 +250,9 @@ ENTRY(am33xx_pm_sram)
|
||||||
.word am33xx_emif_sram_table
|
.word am33xx_emif_sram_table
|
||||||
.word am33xx_pm_ro_sram_data
|
.word am33xx_pm_ro_sram_data
|
||||||
|
|
||||||
|
resume_addr:
|
||||||
|
.word cpu_resume - PAGE_OFFSET + 0x80000000
|
||||||
|
|
||||||
.align 3
|
.align 3
|
||||||
ENTRY(am33xx_pm_ro_sram_data)
|
ENTRY(am33xx_pm_ro_sram_data)
|
||||||
.space AMX3_PM_RO_SRAM_DATA_SIZE
|
.space AMX3_PM_RO_SRAM_DATA_SIZE
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <generated/ti-pm-asm-offsets.h>
|
#include <generated/ti-pm-asm-offsets.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <linux/ti-emif-sram.h>
|
#include <linux/ti-emif-sram.h>
|
||||||
|
#include <linux/platform_data/pm33xx.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
#include <asm/hardware/cache-l2x0.h>
|
#include <asm/hardware/cache-l2x0.h>
|
||||||
#include <asm/memory.h>
|
#include <asm/memory.h>
|
||||||
|
@ -22,6 +22,9 @@
|
||||||
#include "prm33xx.h"
|
#include "prm33xx.h"
|
||||||
#include "prcm43xx.h"
|
#include "prcm43xx.h"
|
||||||
|
|
||||||
|
/* replicated define because linux/bitops.h cannot be included in assembly */
|
||||||
|
#define BIT(nr) (1 << (nr))
|
||||||
|
|
||||||
#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000
|
#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000
|
||||||
#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
|
#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
|
||||||
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
|
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
|
||||||
|
@ -45,12 +48,25 @@
|
||||||
AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
|
AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
|
||||||
#define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030
|
#define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030
|
||||||
|
|
||||||
|
#define RTC_SECONDS_REG 0x0
|
||||||
|
#define RTC_PMIC_REG 0x98
|
||||||
|
#define RTC_PMIC_POWER_EN BIT(16)
|
||||||
|
#define RTC_PMIC_EXT_WAKEUP_STS BIT(12)
|
||||||
|
#define RTC_PMIC_EXT_WAKEUP_POL BIT(4)
|
||||||
|
#define RTC_PMIC_EXT_WAKEUP_EN BIT(0)
|
||||||
|
|
||||||
.arm
|
.arm
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
ENTRY(am43xx_do_wfi)
|
ENTRY(am43xx_do_wfi)
|
||||||
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
||||||
|
|
||||||
|
/* Save wfi_flags arg to data space */
|
||||||
|
mov r4, r0
|
||||||
|
adr r3, am43xx_pm_ro_sram_data
|
||||||
|
ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
|
||||||
|
str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
|
||||||
|
|
||||||
#ifdef CONFIG_CACHE_L2X0
|
#ifdef CONFIG_CACHE_L2X0
|
||||||
/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
|
/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
|
||||||
ldr r1, get_l2cache_base
|
ldr r1, get_l2cache_base
|
||||||
|
@ -58,6 +74,10 @@ ENTRY(am43xx_do_wfi)
|
||||||
mov r8, r0
|
mov r8, r0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Only flush cache is we know we are losing MPU context */
|
||||||
|
tst r4, #WFI_FLAG_FLUSH_CACHE
|
||||||
|
beq cache_skip_flush
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush all data from the L1 and L2 data cache before disabling
|
* Flush all data from the L1 and L2 data cache before disabling
|
||||||
* SCTLR.C bit.
|
* SCTLR.C bit.
|
||||||
|
@ -128,13 +148,47 @@ sync:
|
||||||
bne sync
|
bne sync
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Restore wfi_flags */
|
||||||
|
adr r3, am43xx_pm_ro_sram_data
|
||||||
|
ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
|
||||||
|
ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
|
||||||
|
|
||||||
|
cache_skip_flush:
|
||||||
|
/*
|
||||||
|
* If we are trying to enter RTC+DDR mode we must perform
|
||||||
|
* a read from the rtc address space to ensure translation
|
||||||
|
* presence in the TLB to avoid page table walk after DDR
|
||||||
|
* is unavailable.
|
||||||
|
*/
|
||||||
|
tst r4, #WFI_FLAG_RTC_ONLY
|
||||||
|
beq skip_rtc_va_refresh
|
||||||
|
|
||||||
|
adr r3, am43xx_pm_ro_sram_data
|
||||||
|
ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
|
||||||
|
ldr r0, [r1]
|
||||||
|
|
||||||
|
skip_rtc_va_refresh:
|
||||||
|
/* Check if we want self refresh */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_enter_sr
|
||||||
|
|
||||||
adr r9, am43xx_emif_sram_table
|
adr r9, am43xx_emif_sram_table
|
||||||
|
|
||||||
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
|
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
|
||||||
blx r3
|
blx r3
|
||||||
|
|
||||||
|
emif_skip_enter_sr:
|
||||||
|
/* Only necessary if PER is losing context */
|
||||||
|
tst r4, #WFI_FLAG_SAVE_EMIF
|
||||||
|
beq emif_skip_save
|
||||||
|
|
||||||
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
|
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
|
||||||
blx r3
|
blx r3
|
||||||
|
|
||||||
|
emif_skip_save:
|
||||||
|
/* Only can disable EMIF if we have entered self refresh */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_disable
|
||||||
|
|
||||||
/* Disable EMIF */
|
/* Disable EMIF */
|
||||||
ldr r1, am43xx_virt_emif_clkctrl
|
ldr r1, am43xx_virt_emif_clkctrl
|
||||||
|
@ -148,6 +202,38 @@ wait_emif_disable:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bne wait_emif_disable
|
bne wait_emif_disable
|
||||||
|
|
||||||
|
emif_skip_disable:
|
||||||
|
tst r4, #WFI_FLAG_RTC_ONLY
|
||||||
|
beq skip_rtc_only
|
||||||
|
|
||||||
|
adr r3, am43xx_pm_ro_sram_data
|
||||||
|
ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
|
||||||
|
|
||||||
|
ldr r0, [r1, #RTC_PMIC_REG]
|
||||||
|
orr r0, r0, #RTC_PMIC_POWER_EN
|
||||||
|
orr r0, r0, #RTC_PMIC_EXT_WAKEUP_STS
|
||||||
|
orr r0, r0, #RTC_PMIC_EXT_WAKEUP_EN
|
||||||
|
orr r0, r0, #RTC_PMIC_EXT_WAKEUP_POL
|
||||||
|
str r0, [r1, #RTC_PMIC_REG]
|
||||||
|
ldr r0, [r1, #RTC_PMIC_REG]
|
||||||
|
/* Wait for 2 seconds to lose power */
|
||||||
|
mov r3, #2
|
||||||
|
ldr r2, [r1, #RTC_SECONDS_REG]
|
||||||
|
rtc_loop:
|
||||||
|
ldr r0, [r1, #RTC_SECONDS_REG]
|
||||||
|
cmp r0, r2
|
||||||
|
beq rtc_loop
|
||||||
|
mov r2, r0
|
||||||
|
subs r3, r3, #1
|
||||||
|
bne rtc_loop
|
||||||
|
|
||||||
|
b re_enable_emif
|
||||||
|
|
||||||
|
skip_rtc_only:
|
||||||
|
|
||||||
|
tst r4, #WFI_FLAG_WAKE_M3
|
||||||
|
beq wkup_m3_skip
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the MPU WFI to be registered as an interrupt
|
* For the MPU WFI to be registered as an interrupt
|
||||||
* to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
|
* to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
|
||||||
|
@ -165,6 +251,7 @@ wait_emif_disable:
|
||||||
mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
|
mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
|
||||||
str r2, [r1]
|
str r2, [r1]
|
||||||
|
|
||||||
|
wkup_m3_skip:
|
||||||
/*
|
/*
|
||||||
* Execute a barrier instruction to ensure that all cache,
|
* Execute a barrier instruction to ensure that all cache,
|
||||||
* TLB and branch predictor maintenance operations issued
|
* TLB and branch predictor maintenance operations issued
|
||||||
|
@ -209,6 +296,7 @@ wait_emif_disable:
|
||||||
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
|
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
|
||||||
str r2, [r1]
|
str r2, [r1]
|
||||||
|
|
||||||
|
re_enable_emif:
|
||||||
/* Re-enable EMIF */
|
/* Re-enable EMIF */
|
||||||
ldr r1, am43xx_virt_emif_clkctrl
|
ldr r1, am43xx_virt_emif_clkctrl
|
||||||
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
|
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
|
||||||
|
@ -218,6 +306,9 @@ wait_emif_enable:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bne wait_emif_enable
|
bne wait_emif_enable
|
||||||
|
|
||||||
|
tst r4, #WFI_FLAG_FLUSH_CACHE
|
||||||
|
beq cache_skip_restore
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set SCTLR.C bit to allow data cache allocation
|
* Set SCTLR.C bit to allow data cache allocation
|
||||||
*/
|
*/
|
||||||
|
@ -226,9 +317,16 @@ wait_emif_enable:
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
isb
|
isb
|
||||||
|
|
||||||
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
|
cache_skip_restore:
|
||||||
blx r1
|
/* Only necessary if PER is losing context */
|
||||||
|
tst r4, #WFI_FLAG_SELF_REFRESH
|
||||||
|
beq emif_skip_exit_sr_abt
|
||||||
|
|
||||||
|
adr r9, am43xx_emif_sram_table
|
||||||
|
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
|
||||||
|
blx r1
|
||||||
|
|
||||||
|
emif_skip_exit_sr_abt:
|
||||||
/* Let the suspend code know about the abort */
|
/* Let the suspend code know about the abort */
|
||||||
mov r0, #1
|
mov r0, #1
|
||||||
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
|
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
|
||||||
|
@ -333,8 +431,6 @@ ENDPROC(am43xx_resume_from_deep_sleep)
|
||||||
* Local variables
|
* Local variables
|
||||||
*/
|
*/
|
||||||
.align
|
.align
|
||||||
resume_addr:
|
|
||||||
.word cpu_resume - PAGE_OFFSET + 0x80000000
|
|
||||||
kernel_flush:
|
kernel_flush:
|
||||||
.word v7_flush_dcache_all
|
.word v7_flush_dcache_all
|
||||||
ddr_start:
|
ddr_start:
|
||||||
|
@ -381,6 +477,8 @@ ENTRY(am43xx_pm_sram)
|
||||||
.word am43xx_emif_sram_table
|
.word am43xx_emif_sram_table
|
||||||
.word am43xx_pm_ro_sram_data
|
.word am43xx_pm_ro_sram_data
|
||||||
|
|
||||||
|
resume_addr:
|
||||||
|
.word cpu_resume - PAGE_OFFSET + 0x80000000
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
ENTRY(am43xx_pm_ro_sram_data)
|
ENTRY(am43xx_pm_ro_sram_data)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/spi/pxa2xx_spi.h>
|
#include <linux/spi/pxa2xx_spi.h>
|
||||||
|
@ -477,6 +478,18 @@ struct platform_device pxa_device_ac97 = {
|
||||||
|
|
||||||
void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops)
|
void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = clk_add_alias("ac97_clk", "pxa2xx-ac97:0", "AC97CLK",
|
||||||
|
&pxa_device_ac97.dev);
|
||||||
|
if (ret)
|
||||||
|
pr_err("PXA AC97 clock1 alias error: %d\n", ret);
|
||||||
|
|
||||||
|
ret = clk_add_alias("ac97_clk", "pxa2xx-ac97:1", "AC97CLK",
|
||||||
|
&pxa_device_ac97.dev);
|
||||||
|
if (ret)
|
||||||
|
pr_err("PXA AC97 clock2 alias error: %d\n", ret);
|
||||||
|
|
||||||
pxa_register_device(&pxa_device_ac97, ops);
|
pxa_register_device(&pxa_device_ac97, ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
#include "generic.h"
|
#include "generic.h"
|
||||||
|
#include "udc.h"
|
||||||
|
|
||||||
/* Physical address space information */
|
/* Physical address space information */
|
||||||
|
|
||||||
|
@ -594,6 +595,8 @@ static struct platform_device gpio_vbus = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct pxa2xx_udc_mach_info hx4700_udc_info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Touchscreen - TSC2046 connected to SSP2
|
* Touchscreen - TSC2046 connected to SSP2
|
||||||
*/
|
*/
|
||||||
|
@ -891,6 +894,7 @@ static void __init hx4700_init(void)
|
||||||
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
|
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
|
pxa_set_udc_info(&hx4700_udc_info);
|
||||||
regulator_has_full_constraints();
|
regulator_has_full_constraints();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -677,14 +677,12 @@ MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info)
|
||||||
MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL)
|
MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL)
|
||||||
MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
|
MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
|
||||||
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
|
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
|
||||||
MIO_SIMPLE_DEV(wm9713_acodec, "wm9713-codec", NULL);
|
|
||||||
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
|
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
|
||||||
|
|
||||||
static struct platform_device *devices[] __initdata = {
|
static struct platform_device *devices[] __initdata = {
|
||||||
&mioa701_gpio_keys,
|
&mioa701_gpio_keys,
|
||||||
&mioa701_backlight,
|
&mioa701_backlight,
|
||||||
&mioa701_led,
|
&mioa701_led,
|
||||||
&wm9713_acodec,
|
|
||||||
&pxa2xx_pcm,
|
&pxa2xx_pcm,
|
||||||
&mioa701_sound,
|
&mioa701_sound,
|
||||||
&power_dev,
|
&power_dev,
|
||||||
|
|
|
@ -47,16 +47,6 @@ int wm9713_irq;
|
||||||
int lcd_id;
|
int lcd_id;
|
||||||
int lcd_orientation;
|
int lcd_orientation;
|
||||||
|
|
||||||
struct platform_device pxa_device_wm9713_audio = {
|
|
||||||
.name = "wm9713-codec",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init zylonite_init_wm9713_audio(void)
|
|
||||||
{
|
|
||||||
platform_device_register(&pxa_device_wm9713_audio);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct resource smc91x_resources[] = {
|
static struct resource smc91x_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = ZYLONITE_ETH_PHYS + 0x300,
|
.start = ZYLONITE_ETH_PHYS + 0x300,
|
||||||
|
@ -428,7 +418,6 @@ static void __init zylonite_init(void)
|
||||||
zylonite_init_nand();
|
zylonite_init_nand();
|
||||||
zylonite_init_leds();
|
zylonite_init_leds();
|
||||||
zylonite_init_ohci();
|
zylonite_init_ohci();
|
||||||
zylonite_init_wm9713_audio();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
|
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
|
#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
|
||||||
#define __ARCH_ARM_REGS_S3C24XX_S3C2412_H __FILE__
|
#define __ARCH_ARM_MACH_S3C24XX_S3C2412_H __FILE__
|
||||||
|
|
||||||
#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
|
#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
|
||||||
#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
|
#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
|
||||||
|
|
|
@ -15,6 +15,7 @@ config ARCH_RCAR_GEN1
|
||||||
|
|
||||||
config ARCH_RCAR_GEN2
|
config ARCH_RCAR_GEN2
|
||||||
bool
|
bool
|
||||||
|
select HAVE_ARM_ARCH_TIMER
|
||||||
select PM
|
select PM
|
||||||
select PM_GENERIC_DOMAINS
|
select PM_GENERIC_DOMAINS
|
||||||
select RENESAS_IRQC
|
select RENESAS_IRQC
|
||||||
|
@ -58,6 +59,7 @@ config ARCH_R8A73A4
|
||||||
bool "R-Mobile APE6 (R8A73A40)"
|
bool "R-Mobile APE6 (R8A73A40)"
|
||||||
select ARCH_RMOBILE
|
select ARCH_RMOBILE
|
||||||
select ARM_ERRATA_798181 if SMP
|
select ARM_ERRATA_798181 if SMP
|
||||||
|
select HAVE_ARM_ARCH_TIMER
|
||||||
select RENESAS_IRQC
|
select RENESAS_IRQC
|
||||||
|
|
||||||
config ARCH_R8A7740
|
config ARCH_R8A7740
|
||||||
|
|
|
@ -11,9 +11,7 @@ obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o
|
||||||
obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o
|
obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o
|
||||||
obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o
|
obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o
|
||||||
obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
|
obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
|
||||||
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
|
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o
|
||||||
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
|
|
||||||
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
|
|
||||||
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
|
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
|
||||||
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
|
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
|
||||||
|
|
||||||
|
@ -23,17 +21,15 @@ cpu-y := platsmp.o headsmp.o
|
||||||
# Shared SoC family objects
|
# Shared SoC family objects
|
||||||
obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
|
obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
|
||||||
CFLAGS_setup-rcar-gen2.o += -march=armv7-a
|
CFLAGS_setup-rcar-gen2.o += -march=armv7-a
|
||||||
obj-$(CONFIG_ARCH_RCAR_GEN2) += headsmp-apmu.o
|
|
||||||
obj-$(CONFIG_ARCH_R8A7790) += regulator-quirk-rcar-gen2.o
|
obj-$(CONFIG_ARCH_R8A7790) += regulator-quirk-rcar-gen2.o
|
||||||
obj-$(CONFIG_ARCH_R8A7791) += regulator-quirk-rcar-gen2.o
|
obj-$(CONFIG_ARCH_R8A7791) += regulator-quirk-rcar-gen2.o
|
||||||
obj-$(CONFIG_ARCH_R8A7793) += regulator-quirk-rcar-gen2.o
|
obj-$(CONFIG_ARCH_R8A7793) += regulator-quirk-rcar-gen2.o
|
||||||
|
|
||||||
# SMP objects
|
# SMP objects
|
||||||
smp-y := $(cpu-y)
|
smp-y := $(cpu-y)
|
||||||
|
smp-$(CONFIG_ARCH_RCAR_GEN2) += headsmp-apmu.o
|
||||||
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
|
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
|
||||||
smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
|
smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
|
||||||
smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o
|
|
||||||
smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o
|
|
||||||
smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
|
smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
|
||||||
|
|
||||||
# PM objects
|
# PM objects
|
||||||
|
|
|
@ -15,7 +15,6 @@ extern void shmobile_smp_sleep(void);
|
||||||
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
|
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
|
extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
|
||||||
extern bool shmobile_smp_init_fallback_ops(void);
|
|
||||||
extern void shmobile_boot_apmu(void);
|
extern void shmobile_boot_apmu(void);
|
||||||
extern void shmobile_boot_scu(void);
|
extern void shmobile_boot_scu(void);
|
||||||
extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,
|
extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* SMP support for APMU based systems with Cortex A7/A15
|
* SMP support for APMU based systems with Cortex A7/A15
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Renesas Electronics Corporation
|
* Copyright (C) 2014 Renesas Electronics Corporation
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
ENTRY(shmobile_boot_apmu)
|
ENTRY(shmobile_boot_apmu)
|
||||||
bl secure_cntvoff_init
|
bl secure_cntvoff_init
|
||||||
b secondary_startup
|
b secondary_startup
|
||||||
ENDPROC(shmobile_boot_apmu)
|
ENDPROC(shmobile_boot_apmu)
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* SMP support for SoCs with APMU
|
* SMP support for SoCs with APMU
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Renesas Electronics Corporation
|
* Copyright (C) 2014 Renesas Electronics Corporation
|
||||||
* Copyright (C) 2013 Magnus Damm
|
* Copyright (C) 2013 Magnus Damm
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
*/
|
||||||
#include <linux/cpu_pm.h>
|
#include <linux/cpu_pm.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
@ -23,7 +20,6 @@
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
#include <asm/suspend.h>
|
#include <asm/suspend.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "platsmp-apmu.h"
|
|
||||||
#include "rcar-gen2.h"
|
#include "rcar-gen2.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -87,6 +83,104 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
|
||||||
return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
|
return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
|
||||||
|
/* nicked from arch/arm/mach-exynos/hotplug.c */
|
||||||
|
static inline void cpu_enter_lowpower_a15(void)
|
||||||
|
{
|
||||||
|
unsigned int v;
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
" mrc p15, 0, %0, c1, c0, 0\n"
|
||||||
|
" bic %0, %0, %1\n"
|
||||||
|
" mcr p15, 0, %0, c1, c0, 0\n"
|
||||||
|
: "=&r" (v)
|
||||||
|
: "Ir" (CR_C)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
flush_cache_louis();
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
/*
|
||||||
|
* Turn off coherency
|
||||||
|
*/
|
||||||
|
" mrc p15, 0, %0, c1, c0, 1\n"
|
||||||
|
" bic %0, %0, %1\n"
|
||||||
|
" mcr p15, 0, %0, c1, c0, 1\n"
|
||||||
|
: "=&r" (v)
|
||||||
|
: "Ir" (0x40)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
isb();
|
||||||
|
dsb();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Select next sleep mode using the APMU */
|
||||||
|
apmu_wrap(cpu, apmu_power_off);
|
||||||
|
|
||||||
|
/* Do ARM specific CPU shutdown */
|
||||||
|
cpu_enter_lowpower_a15();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_HOTPLUG_CPU)
|
||||||
|
static void shmobile_smp_apmu_cpu_die(unsigned int cpu)
|
||||||
|
{
|
||||||
|
/* For this particular CPU deregister boot vector */
|
||||||
|
shmobile_smp_hook(cpu, 0, 0);
|
||||||
|
|
||||||
|
/* Shutdown CPU core */
|
||||||
|
shmobile_smp_apmu_cpu_shutdown(cpu);
|
||||||
|
|
||||||
|
/* jump to shared mach-shmobile sleep / reset code */
|
||||||
|
shmobile_smp_sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
|
||||||
|
{
|
||||||
|
return apmu_wrap(cpu, apmu_power_off_poll);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SUSPEND)
|
||||||
|
static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
|
||||||
|
{
|
||||||
|
shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
|
||||||
|
shmobile_smp_apmu_cpu_shutdown(cpu);
|
||||||
|
cpu_do_idle(); /* WFI selects Core Standby */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cpu_leave_lowpower(void)
|
||||||
|
{
|
||||||
|
unsigned int v;
|
||||||
|
|
||||||
|
asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
|
||||||
|
" orr %0, %0, %1\n"
|
||||||
|
" mcr p15, 0, %0, c1, c0, 0\n"
|
||||||
|
" mrc p15, 0, %0, c1, c0, 1\n"
|
||||||
|
" orr %0, %0, %2\n"
|
||||||
|
" mcr p15, 0, %0, c1, c0, 1\n"
|
||||||
|
: "=&r" (v)
|
||||||
|
: "Ir" (CR_C), "Ir" (0x40)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
|
||||||
|
{
|
||||||
|
cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
|
||||||
|
cpu_leave_lowpower();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init shmobile_smp_apmu_suspend_init(void)
|
||||||
|
{
|
||||||
|
shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
||||||
{
|
{
|
||||||
|
@ -106,38 +200,6 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
||||||
writel(x, apmu_cpus[cpu].iomem + DBGRCR_OFFS);
|
writel(x, apmu_cpus[cpu].iomem + DBGRCR_OFFS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
|
|
||||||
struct rcar_apmu_config *apmu_config, int num)
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
int k;
|
|
||||||
int bit, index;
|
|
||||||
bool is_allowed;
|
|
||||||
|
|
||||||
for (k = 0; k < num; k++) {
|
|
||||||
/* only enable the cluster that includes the boot CPU */
|
|
||||||
is_allowed = false;
|
|
||||||
for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
|
|
||||||
id = apmu_config[k].cpus[bit];
|
|
||||||
if (id >= 0) {
|
|
||||||
if (id == cpu_logical_map(0))
|
|
||||||
is_allowed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_allowed)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
|
|
||||||
id = apmu_config[k].cpus[bit];
|
|
||||||
if (id >= 0) {
|
|
||||||
index = get_logical_index(id);
|
|
||||||
if (index >= 0)
|
|
||||||
fn(&apmu_config[k].iomem, index, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct of_device_id apmu_ids[] = {
|
static const struct of_device_id apmu_ids[] = {
|
||||||
{ .compatible = "renesas,apmu" },
|
{ .compatible = "renesas,apmu" },
|
||||||
{ /*sentinel*/ }
|
{ /*sentinel*/ }
|
||||||
|
@ -194,15 +256,8 @@ static void __init shmobile_smp_apmu_setup_boot(void)
|
||||||
shmobile_boot_fn_gen2 = shmobile_boot_fn;
|
shmobile_boot_fn_gen2 = shmobile_boot_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
|
static int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
|
||||||
struct rcar_apmu_config *apmu_config,
|
struct task_struct *idle)
|
||||||
int num)
|
|
||||||
{
|
|
||||||
shmobile_smp_apmu_setup_boot();
|
|
||||||
apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|
||||||
{
|
{
|
||||||
/* For this particular CPU register boot vector */
|
/* For this particular CPU register boot vector */
|
||||||
shmobile_smp_hook(cpu, __pa_symbol(shmobile_boot_apmu), 0);
|
shmobile_smp_hook(cpu, __pa_symbol(shmobile_boot_apmu), 0);
|
||||||
|
@ -229,101 +284,3 @@ static struct smp_operations apmu_smp_ops __initdata = {
|
||||||
|
|
||||||
CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
|
CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
|
|
||||||
/* nicked from arch/arm/mach-exynos/hotplug.c */
|
|
||||||
static inline void cpu_enter_lowpower_a15(void)
|
|
||||||
{
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
" mrc p15, 0, %0, c1, c0, 0\n"
|
|
||||||
" bic %0, %0, %1\n"
|
|
||||||
" mcr p15, 0, %0, c1, c0, 0\n"
|
|
||||||
: "=&r" (v)
|
|
||||||
: "Ir" (CR_C)
|
|
||||||
: "cc");
|
|
||||||
|
|
||||||
flush_cache_louis();
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
/*
|
|
||||||
* Turn off coherency
|
|
||||||
*/
|
|
||||||
" mrc p15, 0, %0, c1, c0, 1\n"
|
|
||||||
" bic %0, %0, %1\n"
|
|
||||||
" mcr p15, 0, %0, c1, c0, 1\n"
|
|
||||||
: "=&r" (v)
|
|
||||||
: "Ir" (0x40)
|
|
||||||
: "cc");
|
|
||||||
|
|
||||||
isb();
|
|
||||||
dsb();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Select next sleep mode using the APMU */
|
|
||||||
apmu_wrap(cpu, apmu_power_off);
|
|
||||||
|
|
||||||
/* Do ARM specific CPU shutdown */
|
|
||||||
cpu_enter_lowpower_a15();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_leave_lowpower(void)
|
|
||||||
{
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
|
|
||||||
" orr %0, %0, %1\n"
|
|
||||||
" mcr p15, 0, %0, c1, c0, 0\n"
|
|
||||||
" mrc p15, 0, %0, c1, c0, 1\n"
|
|
||||||
" orr %0, %0, %2\n"
|
|
||||||
" mcr p15, 0, %0, c1, c0, 1\n"
|
|
||||||
: "=&r" (v)
|
|
||||||
: "Ir" (CR_C), "Ir" (0x40)
|
|
||||||
: "cc");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_HOTPLUG_CPU)
|
|
||||||
void shmobile_smp_apmu_cpu_die(unsigned int cpu)
|
|
||||||
{
|
|
||||||
/* For this particular CPU deregister boot vector */
|
|
||||||
shmobile_smp_hook(cpu, 0, 0);
|
|
||||||
|
|
||||||
/* Shutdown CPU core */
|
|
||||||
shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
||||||
|
|
||||||
/* jump to shared mach-shmobile sleep / reset code */
|
|
||||||
shmobile_smp_sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
|
|
||||||
{
|
|
||||||
return apmu_wrap(cpu, apmu_power_off_poll);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SUSPEND)
|
|
||||||
static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
|
|
||||||
{
|
|
||||||
shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
|
|
||||||
shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
||||||
cpu_do_idle(); /* WFI selects Core Standby */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
|
|
||||||
{
|
|
||||||
cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
|
|
||||||
cpu_leave_lowpower();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init shmobile_smp_apmu_suspend_init(void)
|
|
||||||
{
|
|
||||||
shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* rmobile apmu definition
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014 Renesas Electronics Corporation
|
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLATSMP_APMU_H
|
|
||||||
#define PLATSMP_APMU_H
|
|
||||||
|
|
||||||
struct rcar_apmu_config {
|
|
||||||
struct resource iomem;
|
|
||||||
int cpus[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
|
|
||||||
struct rcar_apmu_config *apmu_config,
|
|
||||||
int num);
|
|
||||||
extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
|
|
||||||
struct task_struct *idle);
|
|
||||||
extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
|
|
||||||
extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
|
|
||||||
|
|
||||||
#endif /* PLATSMP_APMU_H */
|
|
|
@ -36,12 +36,3 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu)
|
||||||
return true; /* Hotplug of any CPU is supported */
|
return true; /* Hotplug of any CPU is supported */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool __init shmobile_smp_init_fallback_ops(void)
|
|
||||||
{
|
|
||||||
/* fallback on PSCI/smp_ops if no other DT based method is detected */
|
|
||||||
if (!IS_ENABLED(CONFIG_SMP))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return platform_can_secondary_boot() ? true : false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* r8a7779 Power management support
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 Renesas Solutions Corp.
|
|
||||||
* Copyright (C) 2011 Magnus Damm
|
|
||||||
*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/soc/renesas/rcar-sysc.h>
|
|
||||||
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#include "r8a7779.h"
|
|
||||||
|
|
||||||
/* SYSC */
|
|
||||||
#define SYSCIER 0x0c
|
|
||||||
#define SYSCIMR 0x10
|
|
||||||
|
|
||||||
#if defined(CONFIG_PM) || defined(CONFIG_SMP)
|
|
||||||
|
|
||||||
static void __init r8a7779_sysc_init(void)
|
|
||||||
{
|
|
||||||
rcar_sysc_init(0xffd85000, 0x0131000e);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* CONFIG_PM || CONFIG_SMP */
|
|
||||||
|
|
||||||
static inline void r8a7779_sysc_init(void) {}
|
|
||||||
|
|
||||||
#endif /* CONFIG_PM || CONFIG_SMP */
|
|
||||||
|
|
||||||
void __init r8a7779_pm_init(void)
|
|
||||||
{
|
|
||||||
static int once;
|
|
||||||
|
|
||||||
if (!once++)
|
|
||||||
r8a7779_sysc_init();
|
|
||||||
}
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/soc/renesas/rcar-sysc.h>
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/cputype.h>
|
#include <asm/cputype.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -46,23 +45,6 @@ static inline u32 phys_to_sbar(phys_addr_t addr)
|
||||||
return (addr >> 8) & 0xfffffc00;
|
return (addr >> 8) & 0xfffffc00;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYSC */
|
|
||||||
#define SYSCIER 0x0c
|
|
||||||
#define SYSCIMR 0x10
|
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
|
||||||
|
|
||||||
static void __init rcar_gen2_sysc_init(u32 syscier)
|
|
||||||
{
|
|
||||||
rcar_sysc_init(0xe6180000, syscier);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* CONFIG_SMP */
|
|
||||||
|
|
||||||
static inline void rcar_gen2_sysc_init(u32 syscier) {}
|
|
||||||
|
|
||||||
#endif /* CONFIG_SMP */
|
|
||||||
|
|
||||||
void __init rcar_gen2_pm_init(void)
|
void __init rcar_gen2_pm_init(void)
|
||||||
{
|
{
|
||||||
void __iomem *p;
|
void __iomem *p;
|
||||||
|
@ -72,7 +54,6 @@ void __init rcar_gen2_pm_init(void)
|
||||||
bool has_a7 = false;
|
bool has_a7 = false;
|
||||||
bool has_a15 = false;
|
bool has_a15 = false;
|
||||||
struct resource res;
|
struct resource res;
|
||||||
u32 syscier = 0;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (once++)
|
if (once++)
|
||||||
|
@ -89,11 +70,6 @@ void __init rcar_gen2_pm_init(void)
|
||||||
has_a7 = true;
|
has_a7 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (of_machine_is_compatible("renesas,r8a7790"))
|
|
||||||
syscier = 0x013111ef;
|
|
||||||
else if (of_machine_is_compatible("renesas,r8a7791"))
|
|
||||||
syscier = 0x00111003;
|
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram");
|
np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram");
|
||||||
if (!np) {
|
if (!np) {
|
||||||
/* No smp-sram in DT, fall back to hardcoded address */
|
/* No smp-sram in DT, fall back to hardcoded address */
|
||||||
|
@ -155,6 +131,5 @@ map:
|
||||||
}
|
}
|
||||||
iounmap(p);
|
iounmap(p);
|
||||||
|
|
||||||
rcar_gen2_sysc_init(syscier);
|
|
||||||
shmobile_smp_apmu_suspend_init();
|
shmobile_smp_apmu_suspend_init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
#ifndef __ASM_R8A7779_H__
|
#ifndef __ASM_R8A7779_H__
|
||||||
#define __ASM_R8A7779_H__
|
#define __ASM_R8A7779_H__
|
||||||
|
|
||||||
extern void r8a7779_pm_init(void);
|
|
||||||
|
|
||||||
extern const struct smp_operations r8a7779_smp_ops;
|
extern const struct smp_operations r8a7779_smp_ops;
|
||||||
|
|
||||||
#endif /* __ASM_R8A7779_H__ */
|
#endif /* __ASM_R8A7779_H__ */
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_R8A7790_H__
|
|
||||||
#define __ASM_R8A7790_H__
|
|
||||||
|
|
||||||
extern const struct smp_operations r8a7790_smp_ops;
|
|
||||||
|
|
||||||
#endif /* __ASM_R8A7790_H__ */
|
|
|
@ -1,7 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_R8A7791_H__
|
|
||||||
#define __ASM_R8A7791_H__
|
|
||||||
|
|
||||||
extern const struct smp_operations r8a7791_smp_ops;
|
|
||||||
|
|
||||||
#endif /* __ASM_R8A7791_H__ */
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* R-Car Generation 2 da9063/da9210 regulator quirk
|
* R-Car Generation 2 da9063/da9210 regulator quirk
|
||||||
*
|
*
|
||||||
|
@ -16,15 +17,6 @@
|
||||||
* been initialized, but before the i2c slave drivers are initialized.
|
* been initialized, but before the i2c slave drivers are initialized.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Glider bvba
|
* Copyright (C) 2015 Glider bvba
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Emma Mobile EV2 processor support
|
* Emma Mobile EV2 processor support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Magnus Damm
|
* Copyright (C) 2012 Magnus Damm
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* r7s72100 processor support
|
* r7s72100 processor support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||||
* Copyright (C) 2013 Magnus Damm
|
* Copyright (C) 2013 Magnus Damm
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* r8a73a4 processor support
|
* r8a73a4 processor support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||||
* Copyright (C) 2013 Magnus Damm
|
* Copyright (C) 2013 Magnus Damm
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -26,7 +18,6 @@ static const char *const r8a73a4_boards_compat_dt[] __initconst = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
|
DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
|
||||||
.init_early = shmobile_init_delay,
|
|
||||||
.init_late = shmobile_init_late,
|
.init_late = shmobile_init_late,
|
||||||
.dt_compat = r8a73a4_boards_compat_dt,
|
.dt_compat = r8a73a4_boards_compat_dt,
|
||||||
MACHINE_END
|
MACHINE_END
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* R8A7740 processor support
|
* R8A7740 processor support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Renesas Solutions Corp.
|
* Copyright (C) 2011 Renesas Solutions Corp.
|
||||||
* Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
* Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* r8a7778 processor support
|
* r8a7778 processor support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||||
* Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
* Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||||
* Copyright (C) 2013 Cogent Embedded, Inc.
|
* Copyright (C) 2013 Cogent Embedded, Inc.
|
||||||
*
|
|
||||||
* 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; version 2 of the License.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue