1
0
Fork 0

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
Linus Torvalds 2018-08-23 13:44:43 -07:00
commit 9e259f9352
133 changed files with 2446 additions and 5321 deletions

View File

@ -1295,11 +1295,6 @@ F: arch/arm/mach-aspeed/
F: arch/arm/boot/dts/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
M: Rob Herring <robh@kernel.org>
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/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
M: Lennert Buytenhek <kernel@wantstofly.org>
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: drivers/i2c/busses/i2c-omap.c
F: include/linux/platform_data/i2c-omap.h
F: include/linux/platform_data/ams-delta-fiq.h
OMAP2+ SUPPORT
M: Tony Lindgren <tony@atomide.com>

View File

@ -603,13 +603,16 @@ config ARCH_S3C24XX
config ARCH_DAVINCI
bool "TI DaVinci"
select ARCH_HAS_HOLES_MEMORYMODEL
select CLKDEV_LOOKUP
select COMMON_CLK
select CPU_ARM926T
select GENERIC_ALLOCATOR
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select GPIOLIB
select HAVE_IDE
select PM_GENERIC_DOMAINS if PM
select PM_GENERIC_DOMAINS_OF if PM && OF
select RESET_CONTROLLER
select USE_OF
select ZONE_DMA
help

View File

@ -204,6 +204,14 @@ choice
depends on ARCH_BCM_HR2
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
bool "Kernel low-level debugging messages via BCM KONA UART"
depends on ARCH_BCM_MOBILE
@ -1562,14 +1570,15 @@ config DEBUG_UART_PHYS
default 0x18000400 if DEBUG_BCM_HR2
default 0x18010000 if DEBUG_SIRFATLAS7_UART0
default 0x18020000 if DEBUG_SIRFATLAS7_UART1
default 0x18023000 if DEBUG_BCM_IPROC_UART3
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
default 0x20001000 if DEBUG_HIP01_UART
default 0x20060000 if DEBUG_RK29_UART0
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
default 0x20201000 if DEBUG_BCM2835
default 0x3f201000 if DEBUG_BCM2836
default 0x3e000000 if DEBUG_BCM_KONA_UART
default 0x3f201000 if DEBUG_BCM2836
default 0x4000e400 if DEBUG_LL_UART_EFM32
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
default 0x40081000 if DEBUG_LPC18XX_UART0
@ -1682,6 +1691,7 @@ config DEBUG_UART_VIRT
default 0xf1002000 if DEBUG_MT8127_UART0
default 0xf1006000 if DEBUG_MT6589_UART0
default 0xf1009000 if DEBUG_MT8135_UART3
default 0xf1023000 if DEBUG_BCM_IPROC_UART3
default 0xf11f1000 if DEBUG_VERSATILE
default 0xf1600000 if DEBUG_INTEGRATOR
default 0xf1c28000 if DEBUG_SUNXI_UART0
@ -1797,7 +1807,7 @@ config DEBUG_UART_8250_WORD
DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
DEBUG_ALPINE_UART0 || \
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
config DEBUG_UART_8250_PALMCHIP

View File

@ -219,7 +219,6 @@ machine-$(CONFIG_ARCH_TANGO) += tango
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U300) += u300
machine-$(CONFIG_ARCH_U8500) += ux500
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_VERSATILE) += versatile
machine-$(CONFIG_ARCH_VEXPRESS) += vexpress
machine-$(CONFIG_ARCH_VT8500) += vt8500

View File

@ -31,21 +31,25 @@
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(
".arch_extension sec\n\t"
"stmfd sp!, {r4 - r11, lr}\n\t"
"stmfd sp!, {r4 - r11}\n\t"
__asmeq("%0", "r0")
__asmeq("%1", "r1")
__asmeq("%2", "r2")
"mov r3, #0\n\t"
"mov r4, #0\n\t"
"smc #0\n\t"
"ldmfd sp!, {r4 - r11, pc}"
"ldmfd sp!, {r4 - r11}\n\t"
:
: "r" (type), "r" (arg1), "r" (arg2)
: "memory");
: "r" (r0), "r" (r1), "r" (r2)
: "memory", "r3", "r12", "lr");
}
static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Renesas SCIF(A) debugging macro include header
*
@ -5,10 +6,6 @@
*
* Copyright (C) 2012-2013 Renesas Electronics Corporation
* 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

View File

@ -40,15 +40,16 @@ extern void at91_pinctrl_gpio_resume(void);
#endif
static const match_table_t pm_modes __initconst = {
{ 0, "standby" },
{ AT91_PM_SLOW_CLOCK, "ulp0" },
{ AT91_PM_STANDBY, "standby" },
{ AT91_PM_ULP0, "ulp0" },
{ AT91_PM_ULP1, "ulp1" },
{ AT91_PM_BACKUP, "backup" },
{ -1, NULL },
};
static struct at91_pm_data pm_data = {
.standby_mode = 0,
.suspend_mode = AT91_PM_SLOW_CLOCK,
.standby_mode = AT91_PM_STANDBY,
.suspend_mode = AT91_PM_ULP0,
};
#define at91_ramc_read(id, field) \
@ -79,6 +80,90 @@ static struct at91_pm_bu {
phys_addr_t resume;
} *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.
*/
@ -97,7 +182,7 @@ static int at91_pm_begin(suspend_state_t state)
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)
{
return (pm_data.mode >= AT91_PM_SLOW_CLOCK);
return (pm_data.mode >= AT91_PM_ULP0);
}
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
* 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
* the main oscillator
*
@ -204,7 +289,7 @@ static int at91_pm_enter(suspend_state_t 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())
goto error;
@ -233,6 +318,7 @@ error:
*/
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);
}
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 device_node *np;
struct platform_device *pdev = NULL;
int ret = -ENODEV;
if ((pm_data.standby_mode != AT91_PM_BACKUP) &&
(pm_data.suspend_mode != AT91_PM_BACKUP))
return;
if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
return 0;
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");
if (!np) {
pr_warn("%s: failed to find sfrbu!\n", __func__);
goto sfrbu_fail;
return ret;
}
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));
if (!pm_bu) {
pr_warn("%s: unable to alloc securam!\n", __func__);
ret = -ENOMEM;
goto securam_fail;
}
@ -536,19 +620,60 @@ static void __init at91_pm_backup_init(void)
pm_bu->canary = __pa_symbol(&canary);
pm_bu->resume = __pa_symbol(cpu_resume);
return;
return 0;
sfrbu_fail:
iounmap(pm_data.shdwc);
pm_data.shdwc = NULL;
securam_fail:
iounmap(pm_data.sfrbu);
pm_data.sfrbu = NULL;
return ret;
}
if (pm_data.standby_mode == AT91_PM_BACKUP)
pm_data.standby_mode = AT91_PM_SLOW_CLOCK;
if (pm_data.suspend_mode == AT91_PM_BACKUP)
pm_data.suspend_mode = AT91_PM_SLOW_CLOCK;
static void __init at91_pm_use_default_mode(int pm_mode)
{
if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
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 {
@ -644,7 +769,7 @@ void __init sama5d2_pm_init(void)
if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
return;
at91_pm_backup_init();
at91_pm_modes_init();
sama5_pm_init();
}

View File

@ -21,8 +21,10 @@
#define AT91_MEMCTRL_SDRAMC 1
#define AT91_MEMCTRL_DDRSDR 2
#define AT91_PM_SLOW_CLOCK 0x01
#define AT91_PM_BACKUP 0x02
#define AT91_PM_STANDBY 0x00
#define AT91_PM_ULP0 0x01
#define AT91_PM_ULP1 0x02
#define AT91_PM_BACKUP 0x03
#ifndef __ASSEMBLY__
struct at91_pm_data {

View File

@ -41,6 +41,15 @@ tmp2 .req r5
beq 1b
.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.
*/
@ -112,19 +121,20 @@ ENTRY(at91_pm_suspend_in_sram)
bl at91_sramc_self_refresh
ldr r0, .pm_mode
cmp r0, #AT91_PM_SLOW_CLOCK
beq slow_clock
cmp r0, #AT91_PM_STANDBY
beq standby
cmp r0, #AT91_PM_BACKUP
beq backup_mode
bl at91_ulp_mode
b exit_suspend
standby:
/* Wait for interrupt */
ldr pmc, .pmc_base
at91_cpu_idle
b exit_suspend
slow_clock:
bl at91_slowck_mode
b exit_suspend
backup_mode:
bl at91_backup_mode
b exit_suspend
@ -151,7 +161,102 @@ ENTRY(at91_backup_mode)
str tmp1, [r0, #0]
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
/* Save Master clock setting */
@ -174,22 +279,19 @@ ENTRY(at91_slowck_mode)
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
str tmp1, [pmc, #AT91_CKGR_PLLAR]
/* Turn off the main 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]
ldr r0, .pm_mode
cmp r0, #AT91_PM_ULP1
beq ulp1_mode
/* Wait for interrupt */
at91_cpu_idle
at91_pm_ulp0_mode
b ulp_exit
/* Turn on the main 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]
ulp1_mode:
at91_pm_ulp1_mode
b ulp_exit
wait_moscrdy
ulp_exit:
ldr pmc, .pmc_base
/* Restore PLLA setting */
ldr tmp1, .saved_pllar
@ -212,7 +314,7 @@ ENTRY(at91_slowck_mode)
wait_mckrdy
mov pc, lr
ENDPROC(at91_slowck_mode)
ENDPROC(at91_ulp_mode)
/*
* void at91_sramc_self_refresh(unsigned int is_active)

View File

@ -59,6 +59,7 @@ config MACH_DA8XX_DT
default y
depends on ARCH_DAVINCI_DA850
select PINCTRL
select TIMER_OF
help
Say y here to include support for TI DaVinci DA850 based using
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
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
endif

View File

@ -5,8 +5,8 @@
#
# Common objects
obj-y := time.o clock.o serial.o psc.o \
usb.o common.o sram.o aemif.o
obj-y := time.o serial.o usb.o \
common.o sram.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o

View File

@ -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;
}

View File

@ -28,6 +28,7 @@
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/ti-aemif.h>
#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
@ -110,15 +111,9 @@ static __init void da830_evm_usb_init(void)
{
int ret;
/* USB_REFCLKIN is not used. */
ret = da8xx_register_usb20_phy_clk(false);
ret = da8xx_register_usb_phy_clocks();
if (ret)
pr_warn("%s: USB 2.0 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",
pr_warn("%s: USB PHY CLK registration failed: %d\n",
__func__, ret);
ret = da8xx_register_usb_phy();
@ -339,14 +334,48 @@ static struct resource da830_evm_nand_resources[] = {
},
};
static struct platform_device da830_evm_nand_device = {
.name = "davinci_nand",
.id = 1,
.dev = {
.platform_data = &da830_evm_nand_pdata,
static struct platform_device da830_evm_aemif_devices[] = {
{
.name = "davinci_nand",
.id = 1,
.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)
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)
pr_warn("%s: NAND device not registered\n", __func__);
if (davinci_aemif_setup(&da830_evm_nand_device))
pr_warn("%s: Cannot configure AEMIF\n", __func__);
pr_warn("%s: AEMIF device not registered\n", __func__);
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;
int ret;
da830_register_clocks();
ret = da830_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);

View File

@ -33,6 +33,7 @@
#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/platform_data/spi-davinci.h>
#include <linux/platform_data/uio_pruss.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
* (128K blocks). It may be used instead of the (default) SPI flash
* 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 = {
.name = "davinci_nand",
.id = 1,
.dev = {
.platform_data = &da850_evm_nandflash_data,
static struct resource da850_evm_aemif_resource[] = {
{
.start = DA8XX_AEMIF_CTL_BASE,
.end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
.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[] = {
&da850_evm_nandflash_device,
&da850_evm_norflash_device,
static struct aemif_platform_data da850_evm_aemif_pdata = {
.cs_offset = 2,
.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
#define DA8XX_AEMIF_ASIZE_16BIT 0x1
static void __init da850_evm_init_nor(void)
{
void __iomem *aemif_addr;
aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
/* 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 struct platform_device da850_evm_aemif_device = {
.name = "ti-aemif",
.id = -1,
.dev = {
.platform_data = &da850_evm_aemif_pdata,
},
.resource = da850_evm_aemif_resource,
.num_resources = ARRAY_SIZE(da850_evm_aemif_resource),
};
static const short da850_evm_nand_pins[] = {
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",
__func__, ret);
da850_evm_init_nor();
platform_add_devices(da850_evm_devices,
ARRAY_SIZE(da850_evm_devices));
if (davinci_aemif_setup(&da850_evm_nandflash_device))
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
ret = platform_device_register(&da850_evm_aemif_device);
if (ret)
pr_warn("%s: registering aemif failed: %d\n",
__func__, ret);
}
}
@ -1340,6 +1349,8 @@ static __init void da850_evm_init(void)
{
int ret;
da850_register_clocks();
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);

View File

@ -394,6 +394,8 @@ static __init void dm355_evm_init(void)
struct clk *aemif;
int ret;
dm355_register_clocks();
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);

View File

@ -234,6 +234,8 @@ static __init void dm355_leopard_init(void)
struct clk *aemif;
int ret;
dm355_register_clocks();
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);

View File

@ -28,6 +28,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/v4l2-dv-timings.h>
#include <linux/platform_data/ti-aemif.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -159,16 +160,49 @@ static struct resource davinci_nand_resources[] = {
},
};
static struct platform_device davinci_nand_device = {
.name = "davinci_nand",
.id = 0,
.num_resources = ARRAY_SIZE(davinci_nand_resources),
.resource = davinci_nand_resources,
.dev = {
.platform_data = &davinci_nand_data,
static struct platform_device davinci_aemif_devices[] = {
{
.name = "davinci_nand",
.id = 0,
.num_resources = ARRAY_SIZE(davinci_nand_resources),
.resource = davinci_nand_resources,
.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 = {
.byte_len = (256*1024) / 8,
.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));
}
static struct platform_device *dm365_evm_nand_devices[] __initdata = {
&davinci_nand_device,
};
static inline int have_leds(void)
{
#ifdef CONFIG_LEDS_CLASS
@ -628,6 +658,7 @@ static void __init evm_init_cpld(void)
u8 mux, resets;
const char *label;
struct clk *aemif_clk;
int rc;
/* Make sure we can configure the CPLD through CS1. Then
* leave it on for later access to MMC and LED registers.
@ -660,8 +691,10 @@ fail:
/* external keypad mux */
mux |= BIT(7);
platform_add_devices(dm365_evm_nand_devices,
ARRAY_SIZE(dm365_evm_nand_devices));
rc = platform_device_register(&davinci_aemif_device);
if (rc)
pr_warn("%s(): error registering the aemif device: %d\n",
__func__, rc);
} else {
/* no OneNAND support yet */
}
@ -742,6 +775,8 @@ static __init void dm365_evm_init(void)
{
int ret;
dm365_register_clocks();
ret = dm365_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);

View File

@ -42,6 +42,7 @@
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/ti-aemif.h>
#include "davinci.h"
@ -174,14 +175,47 @@ static struct resource davinci_evm_nandflash_resource[] = {
},
};
static struct platform_device davinci_evm_nandflash_device = {
.name = "davinci_nand",
.id = 0,
.dev = {
.platform_data = &davinci_evm_nandflash_data,
static struct resource davinci_evm_aemif_resource[] = {
{
.start = DM644X_ASYNC_EMIF_CONTROL_BASE,
.end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
.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);
@ -773,6 +807,8 @@ static __init void davinci_evm_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_register_clocks();
dm644x_init_devices();
ret = dm644x_gpio_register();
@ -793,12 +829,7 @@ static __init void davinci_evm_init(void)
/* only one device will be jumpered and detected */
if (HAS_NAND) {
platform_device_register(&davinci_evm_nandflash_device);
if (davinci_aemif_setup(&davinci_evm_nandflash_device))
pr_warn("%s: Cannot configure AEMIF\n",
__func__);
platform_device_register(&davinci_evm_aemif_device);
#ifdef CONFIG_I2C
evm_leds[7].default_trigger = "nand-disk";
#endif

View File

@ -24,6 +24,7 @@
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/platform_data/ti-aemif.h>
#include <media/i2c/tvp514x.h>
#include <media/i2c/adv7343.h>
@ -106,18 +107,49 @@ static struct resource davinci_nand_resources[] = {
},
};
static struct platform_device davinci_nand_device = {
.name = "davinci_nand",
.id = 0,
.num_resources = ARRAY_SIZE(davinci_nand_resources),
.resource = davinci_nand_resources,
.dev = {
.platform_data = &davinci_nand_data,
static struct platform_device davinci_aemif_devices[] = {
{
.name = "davinci_nand",
.id = 0,
.num_resources = ARRAY_SIZE(davinci_nand_resources),
.resource = davinci_nand_resources,
.dev = {
.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) || \
IS_ENABLED(CONFIG_PATA_BK3710))
@ -776,6 +808,8 @@ static __init void evm_init(void)
int ret;
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm646x_register_clocks();
ret = dm646x_gpio_register();
if (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())
davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
platform_device_register(&davinci_nand_device);
if (davinci_aemif_setup(&davinci_nand_device))
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
if (platform_device_register(&davinci_aemif_device))
pr_warn("%s: Cannot register AEMIF device.\n", __func__);
dm646x_init_edma(dm646x_edma_rsv);

View File

@ -30,6 +30,7 @@
#include <mach/da8xx.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/ti-aemif.h>
#include <mach/mux.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 = {
.name = "davinci_nand",
.id = 1,
.dev = {
.platform_data = &mityomapl138_nandflash_data,
static struct platform_device mityomapl138_aemif_devices[] = {
{
.name = "davinci_nand",
.id = 1,
.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 = {
&mityomapl138_nandflash_device,
static struct resource mityomapl138_aemif_resources[] = {
{
.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)
{
platform_add_devices(mityomapl138_devices,
ARRAY_SIZE(mityomapl138_devices));
if (davinci_aemif_setup(&mityomapl138_nandflash_device))
pr_warn("%s: Cannot configure AEMIF\n", __func__);
if (platform_device_register(&mityomapl138_aemif_device))
pr_warn("%s: Cannot register AEMIF device\n", __func__);
}
static const short mityomap_mii_pins[] = {
@ -503,6 +530,8 @@ static void __init mityomapl138_init(void)
{
int ret;
da850_register_clocks();
/* for now, no special EDMA channels are reserved */
ret = da850_register_edma(NULL);
if (ret)

View File

@ -175,6 +175,8 @@ static __init void davinci_ntosd2_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_register_clocks();
dm644x_init_devices();
ret = dm644x_gpio_register();

View File

@ -15,7 +15,12 @@
#include <linux/interrupt.h>
#include <linux/gpio.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/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/ti-aemif.h>
#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
@ -166,6 +171,129 @@ mmc_setup_mmcsd_fail:
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 da8xx_ocic_handler_t hawk_usb_ocic_handler;
@ -236,14 +364,9 @@ static __init void omapl138_hawk_usb_init(void)
return;
}
ret = da8xx_register_usb20_phy_clk(false);
ret = da8xx_register_usb_phy_clocks();
if (ret)
pr_warn("%s: USB 2.0 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",
pr_warn("%s: USB PHY CLK registration failed: %d\n",
__func__, ret);
ret = da8xx_register_usb_phy();
@ -285,6 +408,8 @@ static __init void omapl138_hawk_init(void)
{
int ret;
da850_register_clocks();
ret = da850_register_gpio();
if (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();
ret = omapl138_hawk_register_aemif();
if (ret)
pr_warn("%s: aemif registration failed: %d\n", __func__, ret);
ret = da8xx_register_watchdog();
if (ret)
pr_warn("%s: watchdog registration failed: %d\n",

View File

@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_register_clocks();
dm644x_init_devices();
platform_add_devices(davinci_sffsdr_devices,

View File

@ -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 */

View File

@ -12,10 +12,6 @@
#ifndef __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 */
#define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0)
@ -65,76 +61,4 @@
*/
#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

View File

@ -20,8 +20,6 @@
#include <mach/common.h>
#include <mach/cputype.h>
#include "clock.h"
struct davinci_soc_info davinci_soc_info;
EXPORT_SYMBOL(davinci_soc_info);
@ -118,5 +116,4 @@ err:
void __init davinci_init_late(void)
{
davinci_cpufreq_init();
davinci_clk_disable_unused();
}

View File

@ -8,21 +8,20 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
#include "psc.h"
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/common.h>
#include <mach/time.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
#include <mach/time.h>
#include "clock.h"
#include "mux.h"
/* Offsets of the 8 compare registers on the da830 */
@ -37,402 +36,6 @@
#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
*
@ -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 */
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,
.ids = 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_pins = da830_pins,
.pinmux_pins_num = ARRAY_SIZE(da830_pins),
@ -1223,6 +822,53 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
davinci_clk_init(da830_clks);
davinci_timer_init();
void __iomem *pll;
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);
}

View File

@ -11,27 +11,31 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/da8xx-cfgchip.h>
#include <linux/platform_data/clk-da8xx-cfgchip.h>
#include <linux/platform_data/clk-davinci-pll.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 "psc.h"
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
#include <mach/cpufreq.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
#include <mach/pm.h>
#include <mach/time.h>
#include "clock.h"
#include "mux.h"
#define DA850_PLL1_BASE 0x01e1a000
@ -40,550 +44,6 @@
#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
*
@ -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 */
static struct davinci_id da850_ids[] = {
{
@ -1169,89 +627,11 @@ int da850_register_cpufreq(char *async_clk)
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
int __init da850_register_cpufreq(char *async_clk)
{
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
/* 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,
.ids = 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_pins = 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)
{
unsigned int v;
davinci_common_init(&davinci_soc_info_da850);
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
@ -1379,22 +755,124 @@ void __init da850_init(void)
return;
da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
if (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));
WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module");
}
void __init da850_init_time(void)
{
davinci_clk_init(da850_clks);
davinci_timer_init();
void __iomem *pll0;
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);
}

View File

@ -7,81 +7,16 @@
* it under the terms of the GNU General Public License version 2 as
* 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 <mach/common.h>
#include "cp_intc.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
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();
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")
.map_io = da850_init,
.init_time = da850_init_time,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,

View File

@ -35,6 +35,10 @@
#include <media/davinci/vpbe.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 SYSMOD_VDAC_CONFIG 0x2c
#define SYSMOD_VIDCLKCTL 0x38
@ -84,6 +88,7 @@ int davinci_init_wdt(void);
/* DM355 function declarations */
void dm355_init(void);
void dm355_init_time(void);
void dm355_register_clocks(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable);
@ -93,6 +98,7 @@ int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_init(void);
void dm365_init_time(void);
void dm365_register_clocks(void);
void dm365_init_asp(void);
void dm365_init_vc(void);
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_devices(void);
void dm644x_init_time(void);
void dm644x_register_clocks(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
@ -113,6 +120,7 @@ int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_init(void);
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_mcasp1(struct snd_platform_data *pdata);
int dm646x_init_edma(struct edma_rsv_info *rsv);

View File

@ -10,26 +10,26 @@
* the Free Software Foundation; either version 2 of the License, or
* (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/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/dmaengine.h>
#include <linux/serial_8250.h>
#include <mach/cputype.h>
#include <mach/common.h>
#include <mach/time.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/clock.h>
#include <mach/time.h>
#include "asp.h"
#include "cpuidle.h"
#include "sram.h"
#include "clock.h"
#include "asp.h"
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
#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
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 ret;
struct clk *clk;
sata_refclk.rate = rate;
ret = clk_register(&sata_refclk);
if (ret)
return ret;
clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
if (IS_ERR(clk))
return PTR_ERR(clk);
clkdev_add(&sata_refclk_lookup);
return 0;
return clk_register_clkdev(clk, "refclk", "ahci_da850");
}
static struct resource da850_sata_resources[] = {

View File

@ -26,7 +26,6 @@
#include "davinci.h"
#include "clock.h"
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_ATA_BASE 0x01C66000

View File

@ -8,31 +8,32 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/spi/spi.h>
#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-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 <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/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 "davinci.h"
#include "mux.h"
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
@ -43,348 +44,6 @@
*/
#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 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_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,
.ids = 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_pins = dm355_pins,
.pinmux_pins_num = ARRAY_SIZE(dm355_pins),
@ -1046,8 +701,41 @@ void __init dm355_init(void)
void __init dm355_init_time(void)
{
davinci_clk_init(dm355_clks);
davinci_timer_init();
void __iomem *pll1, *psc;
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,

View File

@ -12,32 +12,33 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/spi/spi.h>
#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/keyscan-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 <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/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 "davinci.h"
#include "mux.h"
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
#define DM365_RTC_BASE 0x01c69000
@ -54,440 +55,6 @@
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
#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 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 = {
.timers = davinci_timer_instance,
.clockevent_id = T0_BOT,
@ -1116,8 +681,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
.jtag_id_reg = 0x01c40028,
.ids = 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_pins = dm365_pins,
.pinmux_pins_num = ARRAY_SIZE(dm365_pins),
@ -1171,8 +734,28 @@ void __init dm365_init(void)
void __init dm365_init_time(void)
{
davinci_clk_init(dm365_clks);
davinci_timer_init();
void __iomem *pll1, *pll2, *psc;
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[] = {

View File

@ -8,28 +8,29 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/dmaengine.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <asm/mach/map.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
#include "psc.h"
#include <mach/mux.h>
#include <mach/time.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 "davinci.h"
#include "mux.h"
/*
* Device specific clocks
@ -43,290 +44,6 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 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 = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_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_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,
.ids = 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_pins = dm644x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
@ -934,8 +647,41 @@ void __init dm644x_init(void)
void __init dm644x_init_time(void)
{
davinci_clk_init(dm644x_clks);
davinci_timer_init();
void __iomem *pll1, *psc;
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,

View File

@ -8,29 +8,30 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/clk-provider.h>
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.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/gpio-davinci.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <asm/mach/map.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
#include "psc.h"
#include <mach/mux.h>
#include <mach/time.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 "davinci.h"
#include "mux.h"
#define DAVINCI_VPIF_BASE (0x01C12000)
@ -46,317 +47,6 @@
#define DM646X_EMAC_CNTRL_RAM_OFFSET 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 = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_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_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,
.ids = 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_pins = 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,
unsigned long aux_clkin_rate)
{
ref_clk.rate = ref_clk_rate;
aux_clkin.rate = aux_clkin_rate;
davinci_clk_init(dm646x_clks);
davinci_timer_init();
void __iomem *pll1, *psc;
struct clk *clk;
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)

View File

@ -15,9 +15,6 @@
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_deassert(struct clk *c);

View File

@ -12,11 +12,12 @@
#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/types.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 __iomem *davinci_intc_base;
@ -53,8 +54,6 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
u32 *psc_bases;
unsigned long psc_bases_num;
u32 pinmux_base;
const struct mux_config *pinmux_pins;
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);
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
int davinci_cpufreq_init(void);
#else

View File

@ -89,9 +89,11 @@ extern unsigned int da850_max_speed;
void da830_init(void);
void da830_init_time(void);
void da830_register_clocks(void);
void da850_init(void);
void da850_init_time(void);
void da850_register_clocks(void);
int da830_register_edma(struct edma_rsv_info *rsv);
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_usb20(unsigned mA, unsigned potpgt);
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_usb_refclkin(int rate);
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb_phy_clocks(void);
int da850_register_sata_refclk(int rate);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);

View File

@ -13,6 +13,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_clock.h>
#include <linux/platform_device.h>
#include <linux/of.h>
static struct dev_pm_domain davinci_pm_domain = {
.ops = {
@ -28,6 +29,10 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
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);
return 0;

View File

@ -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);
}

View File

@ -27,8 +27,6 @@
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_PSC_H
#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
/* Power and Sleep Controller (PSC) Domains */
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1
@ -206,14 +204,4 @@
#define PDCTL_NEXT BIT(0)
#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 */

View File

@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/sched_clock.h>
@ -27,8 +28,6 @@
#include <mach/hardware.h>
#include <mach/time.h>
#include "clock.h"
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
@ -334,10 +333,8 @@ static struct clock_event_device clockevent_davinci = {
.set_state_oneshot = davinci_set_oneshot,
};
void __init davinci_timer_init(void)
void __init davinci_timer_init(struct clk *timer_clk)
{
struct clk *timer_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
unsigned int clockevent_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));
clk_prepare_enable(timer_clk);
@ -402,3 +398,17 @@ void __init davinci_timer_init(void)
for (i=0; i< ARRAY_SIZE(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);

View File

@ -2,29 +2,30 @@
/*
* DA8xx USB
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/mfd/da8xx-cfgchip.h>
#include <linux/mfd/syscon.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/usb-davinci.h>
#include <linux/platform_device.h>
#include <linux/usb/musb.h>
#include <mach/clock.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
#include "clock.h"
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
#ifndef CONFIG_COMMON_CLK
static struct clk *usb20_clk;
#endif
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",
.id = -1,
.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,
.dma_mask = &usb_dmamask,
.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);
}
static struct clk usb_refclkin = {
.name = "usb_refclkin",
.set_rate = davinci_simple_set_rate,
static struct platform_device da8xx_usb_phy_clks_device = {
.name = "da830-usb-phy-clks",
.id = -1,
};
static struct clk_lookup usb_refclkin_lookup =
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 __init da8xx_register_usb_phy_clocks(void)
{
int ret;
struct da8xx_cfgchip_clk_platform_data pdata;
usb_refclkin.rate = rate;
ret = clk_register(&usb_refclkin);
if (ret)
return ret;
pdata.cfgchip = da8xx_get_cfgchip();
da8xx_usb_phy_clks_device.dev.platform_data = &pdata;
clkdev_add(&usb_refclkin_lookup);
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;
return platform_device_register(&da8xx_usb_phy_clks_device);
}

View File

@ -190,8 +190,6 @@ static void __init exynos_dt_fixup(void)
}
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_mask = 0xc20fffff,
.smp = smp_ops(exynos_smp_ops),

View File

@ -203,6 +203,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
NULL);
if (!domain) {
iounmap(pmu_base_addr);
pmu_base_addr = NULL;
return -ENOMEM;
}

View File

@ -148,13 +148,20 @@ static int hi3xxx_hotplug_init(void)
struct device_node *node;
node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
if (node) {
ctrl_base = of_iomap(node, 0);
id = HI3620_CTRL;
return 0;
if (!node) {
id = ERROR_CTRL;
return -ENOENT;
}
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)
@ -173,11 +180,15 @@ static bool hix5hd2_hotplug_init(void)
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
if (np) {
ctrl_base = of_iomap(np, 0);
return true;
}
return false;
if (!np)
return false;
ctrl_base = of_iomap(np, 0);
of_node_put(np);
if (!ctrl_base)
return false;
return true;
}
void hix5hd2_set_cpu(int cpu, bool enable)
@ -219,10 +230,10 @@ void hip01_set_cpu(int cpu, bool enable)
if (!ctrl_base) {
np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
if (np)
ctrl_base = of_iomap(np, 0);
else
BUG();
BUG_ON(!np);
ctrl_base = of_iomap(np, 0);
of_node_put(np);
BUG_ON(!ctrl_base);
}
if (enable) {

View File

@ -523,18 +523,6 @@ config SOC_IMX6UL
help
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
bool "Freescale LS1021A support"
select ARM_GIC
@ -549,6 +537,27 @@ comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
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
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7

View File

@ -26,7 +26,7 @@ ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.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_IMX6UL) += cpuidle-imx6sx.o
endif
@ -81,7 +81,8 @@ obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.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)
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a

View File

@ -38,7 +38,6 @@ void imx21_soc_init(void);
void imx27_soc_init(void);
void imx31_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 mx27_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 imx_gpc_check_dt(void);
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_down_timing(u32 sw2iso, u32 sw);
void imx25_pm_init(void);
void imx27_pm_init(void);
void imx5_pmu_init(void);
enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */

View File

@ -117,3 +117,48 @@ int mx53_revision(void)
return mx5_cpu_rev;
}
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);
}

View File

@ -68,6 +68,7 @@ void __init imx_aips_allow_unprivileged_access(
for_each_compatible_node(np, NULL, compat) {
aips_base_addr = of_iomap(np, 0);
WARN_ON(!aips_base_addr);
imx_set_aips(aips_base_addr);
}
}

View File

@ -12,7 +12,6 @@
#include "common.h"
#include "cpuidle.h"
#include "hardware.h"
static int imx6sl_enter_wait(struct cpuidle_device *dev,
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
* description for details.
*/
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(true);
imx6sl_set_wait_clk(true);
cpu_do_idle();
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(false);
imx6sl_set_wait_clk(false);
imx6_set_lpm(WAIT_CLOCKED);
return index;

View File

@ -103,6 +103,7 @@ int __init imx6sx_cpuidle_init(void)
{
imx6_set_int_mem_clk_lpm(true);
imx6_enable_rbc(false);
imx_gpc_set_l2_mem_power_in_lpm(false);
/*
* set ARM power up/down timing to the fastest,
* sw2iso and sw can be set to one 32K cycle = 31us

View File

@ -20,6 +20,7 @@
#include "common.h"
#include "hardware.h"
#define GPC_CNTR 0x0
#define GPC_IMR1 0x008
#define GPC_PGC_CPU_PDN 0x2a0
#define GPC_PGC_CPU_PUPSCR 0x2a4
@ -27,6 +28,8 @@
#define GPC_PGC_SW2ISO_SHIFT 0x8
#define GPC_PGC_SW_SHIFT 0x0
#define GPC_CNTR_L2_PGE_SHIFT 22
#define IMR_NUM 4
#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);
}
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 __iomem *reg_imr1 = gpc_base + GPC_IMR1;

View File

@ -9,35 +9,17 @@
* 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/time.h>
#include "common.h"
#include "mx31.h"
static const char * const imx31_dt_board_compat[] __initconst = {
"fsl,imx31",
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)")
.map_io = mx31_map_io,
.init_early = imx31_init_early,
.init_irq = mx31_init_irq,
.init_machine = imx31_dt_mach_init,
.dt_compat = imx31_dt_board_compat,
MACHINE_END

View File

@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
@ -48,11 +49,38 @@ static void __init imx51_ipu_mipi_setup(void)
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)
{
imx51_ipu_mipi_setup();
imx_src_init();
imx51_m4if_setup();
imx5_pmu_init();
imx_aips_allow_unprivileged_access("fsl,imx51-aipstz");
}

View File

@ -31,7 +31,7 @@ static void __init imx53_init_early(void)
static void __init imx53_dt_init(void)
{
imx_src_init();
imx5_pmu_init();
imx_aips_allow_unprivileged_access("fsl,imx53-aipstz");
}

View File

@ -42,7 +42,10 @@ static void __init imx6sl_init_late(void)
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
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)

View File

@ -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

View File

@ -130,6 +130,13 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = {
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 = {
0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
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,
};
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 = {
.mmdc_compat = "fsl,imx6sx-mmdc",
.src_compat = "fsl,imx6sx-src",
@ -296,7 +313,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
if (cpu_is_imx6sl())
val |= BM_CLPCR_BYPASS_PMIC_READY;
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;
else
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())
val |= BM_CLPCR_BYPASS_PMIC_READY;
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;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@ -631,7 +648,17 @@ void __init imx6dl_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)

View File

@ -35,6 +35,8 @@
#define AXP_BOOTROM_BASE 0xfff00000
#define AXP_BOOTROM_SIZE 0x100000
static struct clk *boot_cpu_clk;
static struct clk *get_cpu_clk(int cpu)
{
struct clk *cpu_clk;
@ -48,30 +50,6 @@ static struct clk *get_cpu_clk(int cpu)
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)
{
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);
hw_cpu = cpu_logical_map(cpu);
set_secondary_cpu_clock(hw_cpu);
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");
}
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)
{
struct device_node *node;
@ -131,6 +121,14 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
flush_cache_all();
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
* 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;
hw_cpu = cpu_logical_map(cpu);
set_secondary_cpu_clock(hw_cpu);
mv98dx3236_resume_set_cpu_boot_addr(hw_cpu,
armada_xp_secondary_startup);

View File

@ -116,8 +116,8 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
}
extern unsigned char mvebu_boot_wa_start;
extern unsigned char mvebu_boot_wa_end;
extern unsigned char mvebu_boot_wa_start[];
extern unsigned char mvebu_boot_wa_end[];
/*
* 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)
{
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_add_window_by_id(crypto_eng_target, crypto_eng_attribute,

View File

@ -14,11 +14,12 @@
*/
#include <linux/linkage.h>
#include <linux/platform_data/ams-delta-fiq.h>
#include <asm/assembler.h>
#include <mach/board-ams-delta.h>
#include <mach/ams-delta-fiq.h>
#include "ams-delta-fiq.h"
#include "iomap.h"
#include "soc.h"

View File

@ -13,17 +13,20 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.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 <asm/fiq.h>
#include <mach/ams-delta-fiq.h>
#include "ams-delta-fiq.h"
static struct fiq_handler fh = {
.name = "ams-delta-fiq"
@ -34,20 +37,24 @@ static struct fiq_handler fh = {
* The FIQ and IRQ isrs can both read and write it.
* It is structured as a header section several 32bit slots,
* followed by the circular buffer where the FIQ isr stores
* keystrokes received from the qwerty keyboard.
* See ams-delta-fiq.h for details of offsets.
* keystrokes received from the qwerty keyboard. See
* <linux/platform_data/ams-delta-fiq.h> for details of offsets.
*/
unsigned int fiq_buffer[1024];
EXPORT_SYMBOL(fiq_buffer);
static unsigned int fiq_buffer[1024];
static struct irq_chip *irq_chip;
static struct irq_data *irq_data[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)
{
struct irq_data *d;
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
@ -55,24 +62,21 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
*/
for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
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];
if (irq_counter[gpio] < fiq_count &&
gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
struct irq_data *d = irq_get_irq_data(irq_num);
/*
* handle_simple_irq() that OMAP GPIO edge
* interrupts default to since commit 80ac93c27441
* requires interrupt already acked and unmasked.
*/
if (irq_chip) {
if (irq_chip->irq_ack)
irq_chip->irq_ack(d);
if (irq_chip->irq_unmask)
irq_chip->irq_unmask(d);
}
if (irq_chip->irq_ack)
irq_chip->irq_ack(d);
if (irq_chip->irq_unmask)
irq_chip->irq_unmask(d);
}
for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
generic_handle_irq(irq_num);
@ -80,14 +84,56 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
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;
unsigned int fiqhandler_length;
struct pt_regs FIQ_regs;
unsigned long val, offset;
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_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
pr_info("Installing fiq handler from %p, length 0x%x\n",
@ -97,7 +143,7 @@ void __init ams_delta_init_fiq(void)
if (retval) {
pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
retval);
return;
goto out_gpio;
}
retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
@ -105,7 +151,7 @@ void __init ams_delta_init_fiq(void)
if (retval < 0) {
pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
release_fiq(&fh);
return;
goto out_gpio;
}
/*
* 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;
val = omap_readl(OMAP_IH1_BASE + offset) | 1;
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);
}

View File

@ -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

View File

@ -41,10 +41,10 @@
#include <mach/mux.h>
#include <mach/hardware.h>
#include <mach/ams-delta-fiq.h>
#include "camera.h"
#include <mach/usb.h>
#include "ams-delta-fiq.h"
#include "iomap.h"
#include "common.h"
@ -179,7 +179,10 @@ static struct resource latch1_resources[] = {
},
};
#define LATCH1_LABEL "latch1"
static struct bgpio_pdata latch1_pdata = {
.label = LATCH1_LABEL,
.base = LATCH1_GPIO_BASE,
.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[] = {
[0] = {
.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",
.gpio = LATCH1_GPIO_BASE + 0,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
#ifdef CONFIG_LEDS_TRIGGERS
.default_trigger = "ams_delta_camera",
#endif
},
{
[LATCH1_PIN_LED_ADVERT] = {
.name = "advert",
.gpio = LATCH1_GPIO_BASE + 1,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
[LATCH1_PIN_LED_MAIL] = {
.name = "email",
.gpio = LATCH1_GPIO_BASE + 2,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
[LATCH1_PIN_LED_HANDSFREE] = {
.name = "handsfree",
.gpio = LATCH1_GPIO_BASE + 3,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
[LATCH1_PIN_LED_VOICEMAIL] = {
.name = "voicemail",
.gpio = LATCH1_GPIO_BASE + 4,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
[LATCH1_PIN_LED_VOICE] = {
.name = "voice",
.gpio = LATCH1_GPIO_BASE + 5,
.gpio = -EINVAL,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
};
@ -504,16 +521,70 @@ static struct platform_device cx20442_codec_device = {
.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 = {
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
"data", 0),
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),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR, NULL,
GPIO_ACTIVE_HIGH),
{ },
},
};
@ -524,9 +595,7 @@ static struct platform_device *ams_delta_devices[] __initdata = {
&ams_delta_kp_device,
&ams_delta_camera_device,
&ams_delta_audio_device,
};
static struct platform_device *late_devices[] __initdata = {
&ams_delta_serio_device,
&ams_delta_nand_device,
&ams_delta_lcd_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 = {
&ams_delta_audio_gpio_table,
&ams_delta_serio_gpio_table,
};
static struct gpiod_lookup_table *late_gpio_tables[] __initdata = {
&keybrd_pwr_gpio_table,
&ams_delta_lcd_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)
{
/* 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(J18_1610_CAM_D7);
omap_gpio_deps_init();
gpiod_add_hogs(ams_delta_gpio_hogs);
omap_serial_init();
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",
&ams_delta_camera_led_trigger);
#endif
gpio_led_register_device(-1, &leds_pdata);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
/*
* As soon as devices have been registered, assign their dev_names
* to respective GPIO lookup tables before they are added.
* As soon as regulator consumers have been registered, assign their
* 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 =
dev_name(&ams_delta_audio_device.dev);
/*
* No device name is assigned to GPIO lookup table for serio device
* as long as serio driver is not converted to platform device driver.
*/
keybrd_pwr_gpio_table.dev_id = dev_name(&keybrd_pwr_device.dev);
ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
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,
ARRAY_SIZE(ams_delta_gpio_tables));
ams_delta_init_fiq();
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
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;
if (!machine_is_ams_delta())
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));
if (err) {
if (err)
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);
/*
* As soon as devices have been registered, assign their dev_names
* to respective GPIO lookup tables before they are added.
*/
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));
static int __init modem_nreset_init(void)
{
int err;
err = platform_device_register(&modem_nreset_device);
if (err) {
if (err)
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);
ams_delta_modem_ports[0].irq =
@ -692,7 +867,22 @@ static int __init late_init(void)
err = platform_device_register(&ams_delta_modem_device);
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
@ -708,7 +898,6 @@ static int __init late_init(void)
unregister:
platform_device_unregister(&ams_delta_modem_device);
gpio_free:
gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
return err;
}

View File

@ -274,7 +274,7 @@ static struct platform_device h2_kp_device = {
.resource = h2_kp_resources,
};
static struct gpio_led h2_gpio_led_pins[] = {
static const struct gpio_led h2_gpio_led_pins[] = {
{
.name = "h2:red",
.default_trigger = "heartbeat",

View File

@ -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",
.default_trigger = "heartbeat",

View File

@ -292,7 +292,7 @@ static struct platform_device herald_gpiokeys_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},
{"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
{"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},

View File

@ -167,7 +167,7 @@ static struct platform_device *osk5912_devices[] __initdata = {
&osk5912_cf_device,
};
static struct gpio_led tps_leds[] = {
static const struct gpio_led tps_leds[] = {
/* NOTE: D9 and D2 have hardware blink support.
* Also, D9 requires non-battery power.
*/
@ -385,7 +385,7 @@ static struct platform_device osk5912_lcd_device = {
.id = -1,
};
static struct gpio_led mistral_gpio_led_pins[] = {
static const struct gpio_led mistral_gpio_led_pins[] = {
{
.name = "mistral:red",
.default_trigger = "heartbeat",

View File

@ -92,11 +92,13 @@ static void omap_rtc_wait_not_busy(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_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_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)
{
local_irq_disable();
unsigned long flags;
local_irq_save(flags);
omap_rtc_wait_not_busy(oh);
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
local_irq_enable();
local_irq_restore(flags);
}

View File

@ -27,6 +27,8 @@ int main(void)
offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
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,
sizeof(struct am33xx_pm_ro_sram_data));

View File

@ -47,11 +47,6 @@ static int pm_dbg_init_done;
static int pm_dbg_init(void);
enum {
DEBUG_FILE_COUNTERS = 0,
DEBUG_FILE_TIMERS,
};
static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
"OFF",
"RET",
@ -141,39 +136,21 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
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);
clkdm_for_each(clkdm_dbg_show_counter, s);
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);
return 0;
}
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,
};
DEFINE_SHOW_ATTRIBUTE(pm_dbg_timers);
static int pwrdm_suspend_get(void *data, u64 *val)
{
@ -259,10 +236,8 @@ static int __init pm_dbg_init(void)
if (!d)
return -EINVAL;
(void) debugfs_create_file("count", S_IRUGO,
d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
(void) debugfs_create_file("time", S_IRUGO,
d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
(void) debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops);
(void) debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops);
pwrdm_for_each(pwrdms_setup, (void *)d);

View File

@ -26,6 +26,7 @@
static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
static struct clockdomain *gfx_l4ls_clkdm;
static void __iomem *scu_base;
static struct omap_hwmod *rtc_oh;
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);
}
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;
amx3_pre_suspend_common();
ret = cpu_suspend(0, fn);
ret = cpu_suspend(args, fn);
amx3_post_suspend_common();
/*
@ -128,13 +130,14 @@ static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
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;
amx3_pre_suspend_common();
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);
amx3_post_suspend_common();
@ -151,16 +154,25 @@ static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
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 = {
.init = am33xx_suspend_init,
.soc_suspend = am33xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
.get_rtc_base_addr = am43xx_get_rtc_base_addr,
};
static struct am33xx_pm_platform_data am43xx_ops = {
.init = am43xx_suspend_init,
.soc_suspend = am43xx_suspend,
.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)

View File

@ -8,6 +8,7 @@
#include <generated/ti-pm-asm-offsets.h>
#include <linux/linkage.h>
#include <linux/platform_data/pm33xx.h>
#include <linux/ti-emif-sram.h>
#include <asm/assembler.h>
#include <asm/memory.h>
@ -19,12 +20,25 @@
#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
/* replicated define because linux/bitops.h cannot be included in assembly */
#define BIT(nr) (1 << (nr))
.arm
.align 3
ENTRY(am33xx_do_wfi)
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
* SCTLR.C bit.
@ -48,14 +62,33 @@ ENTRY(am33xx_do_wfi)
ldr r1, kernel_flush
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
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
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]
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 */
ldr r1, virt_emif_clkctrl
ldr r2, [r1]
@ -69,6 +102,10 @@ wait_emif_disable:
cmp r2, r3
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
* 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
str r2, [r1]
wkup_m3_skip:
/*
* Execute an ISB instruction to ensure that all of the
* CP15 register changes have been committed.
@ -132,10 +170,18 @@ wait_emif_enable:
cmp r2, r3
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]
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
*/
@ -144,6 +190,7 @@ wait_emif_enable:
mcr p15, 0, r0, c1, c0, 0
isb
cache_skip_restore:
/* Let the suspend code know about the abort */
mov r0, #1
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
@ -181,8 +228,6 @@ ENDPROC(am33xx_resume_from_deep_sleep)
* Local variables
*/
.align
resume_addr:
.word cpu_resume - PAGE_OFFSET + 0x80000000
kernel_flush:
.word v7_flush_dcache_all
virt_mpu_clkctrl:
@ -205,6 +250,9 @@ ENTRY(am33xx_pm_sram)
.word am33xx_emif_sram_table
.word am33xx_pm_ro_sram_data
resume_addr:
.word cpu_resume - PAGE_OFFSET + 0x80000000
.align 3
ENTRY(am33xx_pm_ro_sram_data)
.space AMX3_PM_RO_SRAM_DATA_SIZE

View File

@ -9,7 +9,7 @@
#include <generated/ti-pm-asm-offsets.h>
#include <linux/linkage.h>
#include <linux/ti-emif-sram.h>
#include <linux/platform_data/pm33xx.h>
#include <asm/assembler.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/memory.h>
@ -22,6 +22,9 @@
#include "prm33xx.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_MODULEMODE_DISABLE 0x0003
#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
@ -45,12 +48,25 @@
AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
#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
.align 3
ENTRY(am43xx_do_wfi)
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
/* Retrieve l2 cache virt address BEFORE we shut off EMIF */
ldr r1, get_l2cache_base
@ -58,6 +74,10 @@ ENTRY(am43xx_do_wfi)
mov r8, r0
#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
* SCTLR.C bit.
@ -128,13 +148,47 @@ sync:
bne sync
#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
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
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]
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 */
ldr r1, am43xx_virt_emif_clkctrl
@ -148,6 +202,38 @@ wait_emif_disable:
cmp r2, r3
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
* 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
str r2, [r1]
wkup_m3_skip:
/*
* Execute a barrier instruction to ensure that all cache,
* TLB and branch predictor maintenance operations issued
@ -209,6 +296,7 @@ wait_emif_disable:
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
str r2, [r1]
re_enable_emif:
/* Re-enable EMIF */
ldr r1, am43xx_virt_emif_clkctrl
mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
@ -218,6 +306,9 @@ wait_emif_enable:
cmp r2, r3
bne wait_emif_enable
tst r4, #WFI_FLAG_FLUSH_CACHE
beq cache_skip_restore
/*
* Set SCTLR.C bit to allow data cache allocation
*/
@ -226,9 +317,16 @@ wait_emif_enable:
mcr p15, 0, r0, c1, c0, 0
isb
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
blx r1
cache_skip_restore:
/* 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 */
mov r0, #1
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
@ -333,8 +431,6 @@ ENDPROC(am43xx_resume_from_deep_sleep)
* Local variables
*/
.align
resume_addr:
.word cpu_resume - PAGE_OFFSET + 0x80000000
kernel_flush:
.word v7_flush_dcache_all
ddr_start:
@ -381,6 +477,8 @@ ENTRY(am43xx_pm_sram)
.word am43xx_emif_sram_table
.word am43xx_pm_ro_sram_data
resume_addr:
.word cpu_resume - PAGE_OFFSET + 0x80000000
.align 3
ENTRY(am43xx_pm_ro_sram_data)

View File

@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.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)
{
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);
}

View File

@ -54,6 +54,7 @@
#include "devices.h"
#include "generic.h"
#include "udc.h"
/* 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
*/
@ -891,6 +894,7 @@ static void __init hx4700_init(void)
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
mdelay(10);
pxa_set_udc_info(&hx4700_udc_info);
regulator_has_full_constraints();
}

View File

@ -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(mioa701_sound, "mioa701-wm9713", 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);
static struct platform_device *devices[] __initdata = {
&mioa701_gpio_keys,
&mioa701_backlight,
&mioa701_led,
&wm9713_acodec,
&pxa2xx_pcm,
&mioa701_sound,
&power_dev,

View File

@ -47,16 +47,6 @@ int wm9713_irq;
int lcd_id;
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[] = {
[0] = {
.start = ZYLONITE_ETH_PHYS + 0x300,
@ -428,7 +418,6 @@ static void __init zylonite_init(void)
zylonite_init_nand();
zylonite_init_leds();
zylonite_init_ohci();
zylonite_init_wm9713_audio();
}
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")

View File

@ -6,7 +6,7 @@
*/
#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_EBIREG(x) (S3C2412_VA_EBI + (x))

View File

@ -15,6 +15,7 @@ config ARCH_RCAR_GEN1
config ARCH_RCAR_GEN2
bool
select HAVE_ARM_ARCH_TIMER
select PM
select PM_GENERIC_DOMAINS
select RENESAS_IRQC
@ -58,6 +59,7 @@ config ARCH_R8A73A4
bool "R-Mobile APE6 (R8A73A40)"
select ARCH_RMOBILE
select ARM_ERRATA_798181 if SMP
select HAVE_ARM_ARCH_TIMER
select RENESAS_IRQC
config ARCH_R8A7740

View File

@ -11,9 +11,7 @@ obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o
obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o
obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o
obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
@ -23,17 +21,15 @@ cpu-y := platsmp.o headsmp.o
# Shared SoC family objects
obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
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_R8A7791) += regulator-quirk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7793) += regulator-quirk-rcar-gen2.o
# SMP objects
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_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
# PM objects

View File

@ -15,7 +15,6 @@ extern void shmobile_smp_sleep(void);
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
unsigned long arg);
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_scu(void);
extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,

View File

@ -1,19 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* SMP support for APMU based systems with Cortex A7/A15
*
* 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 <asm/assembler.h>
#ifdef CONFIG_SMP
ENTRY(shmobile_boot_apmu)
bl secure_cntvoff_init
b secondary_startup
ENDPROC(shmobile_boot_apmu)
#endif

View File

@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* SMP support for SoCs with APMU
*
* Copyright (C) 2014 Renesas Electronics Corporation
* 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/delay.h>
@ -23,7 +20,6 @@
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include "common.h"
#include "platsmp-apmu.h"
#include "rcar-gen2.h"
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;
}
#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
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);
}
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[] = {
{ .compatible = "renesas,apmu" },
{ /*sentinel*/ }
@ -194,15 +256,8 @@ static void __init shmobile_smp_apmu_setup_boot(void)
shmobile_boot_fn_gen2 = shmobile_boot_fn;
}
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
struct rcar_apmu_config *apmu_config,
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)
static int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
struct task_struct *idle)
{
/* For this particular CPU register boot vector */
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);
#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

View File

@ -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 */

View File

@ -36,12 +36,3 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu)
return true; /* Hotplug of any CPU is supported */
}
#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;
}

View File

@ -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();
}

View File

@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/smp.h>
#include <linux/soc/renesas/rcar-sysc.h>
#include <asm/io.h>
#include <asm/cputype.h>
#include "common.h"
@ -46,23 +45,6 @@ static inline u32 phys_to_sbar(phys_addr_t addr)
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 __iomem *p;
@ -72,7 +54,6 @@ void __init rcar_gen2_pm_init(void)
bool has_a7 = false;
bool has_a15 = false;
struct resource res;
u32 syscier = 0;
int error;
if (once++)
@ -89,11 +70,6 @@ void __init rcar_gen2_pm_init(void)
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");
if (!np) {
/* No smp-sram in DT, fall back to hardcoded address */
@ -155,6 +131,5 @@ map:
}
iounmap(p);
rcar_gen2_sysc_init(syscier);
shmobile_smp_apmu_suspend_init();
}

View File

@ -2,8 +2,6 @@
#ifndef __ASM_R8A7779_H__
#define __ASM_R8A7779_H__
extern void r8a7779_pm_init(void);
extern const struct smp_operations r8a7779_smp_ops;
#endif /* __ASM_R8A7779_H__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* R-Car Generation 2 da9063/da9210 regulator quirk
*
@ -16,15 +17,6 @@
* been initialized, but before the i2c slave drivers are initialized.
*
* 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>

View File

@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Emma Mobile EV2 processor support
*
* 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/init.h>

View File

@ -1,17 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* r7s72100 processor support
*
* Copyright (C) 2013 Renesas Solutions Corp.
* 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>

View File

@ -1,17 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* r8a73a4 processor support
*
* Copyright (C) 2013 Renesas Solutions Corp.
* 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>
@ -26,7 +18,6 @@ static const char *const r8a73a4_boards_compat_dt[] __initconst = {
};
DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
.init_early = shmobile_init_delay,
.init_late = shmobile_init_late,
.dt_compat = r8a73a4_boards_compat_dt,
MACHINE_END

View File

@ -1,17 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* R8A7740 processor support
*
* Copyright (C) 2011 Renesas Solutions Corp.
* 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/init.h>

View File

@ -1,18 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* r8a7778 processor support
*
* Copyright (C) 2013 Renesas Solutions Corp.
* Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
* 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>

Some files were not shown because too many files have changed in this diff Show More