summaryrefslogtreecommitdiff
path: root/arch/arm/mach-u300
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-u300')
-rw-r--r--arch/arm/mach-u300/clock.c133
-rw-r--r--arch/arm/mach-u300/clock.h5
-rw-r--r--arch/arm/mach-u300/core.c21
-rw-r--r--arch/arm/mach-u300/gpio.c2
-rw-r--r--arch/arm/mach-u300/include/mach/memory.h8
-rw-r--r--arch/arm/mach-u300/mmc.c8
-rw-r--r--arch/arm/mach-u300/timer.c28
-rw-r--r--arch/arm/mach-u300/u300.c17
8 files changed, 108 insertions, 114 deletions
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 5af71d5ba665..60acf9e708ae 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -947,6 +947,10 @@ static struct clk fast_clk = {
.lock = __SPIN_LOCK_UNLOCKED(fast_clk.lock),
};
+/*
+ * The MMCI apb_pclk is hardwired to the same terminal as the
+ * external MCI clock. Thus this will be referenced twice.
+ */
static struct clk mmcsd_clk = {
.name = "MCLK",
.parent = &fast_clk,
@@ -1024,6 +1028,10 @@ static struct clk i2c1_clk = {
.lock = __SPIN_LOCK_UNLOCKED(i2c1_clk.lock),
};
+/*
+ * The SPI apb_pclk is hardwired to the same terminal as the
+ * external SPI clock. Thus this will be referenced twice.
+ */
static struct clk spi_clk = {
.name = "SPI",
.parent = &fast_clk,
@@ -1040,10 +1048,9 @@ static struct clk spi_clk = {
};
#ifdef CONFIG_MACH_U300_BS335
-static struct clk uart1_clk = {
- .name = "UART1",
+static struct clk uart1_pclk = {
+ .name = "UART1_PCLK",
.parent = &fast_clk,
- .rate = 13000000,
.hw_ctrld = false,
.reset = true,
.res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
@@ -1051,6 +1058,14 @@ static struct clk uart1_clk = {
.clk_val = U300_SYSCON_SBCER_UART1_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(uart1_pclk.lock),
+};
+
+/* This one is hardwired to PLL13 */
+static struct clk uart1_clk = {
+ .name = "UART1_CLK",
+ .rate = 13000000,
+ .hw_ctrld = true,
.lock = __SPIN_LOCK_UNLOCKED(uart1_clk.lock),
};
#endif
@@ -1085,11 +1100,9 @@ static struct clk wdog_clk = {
.lock = __SPIN_LOCK_UNLOCKED(wdog_clk.lock),
};
-/* This one is hardwired to PLL13 */
-static struct clk uart_clk = {
- .name = "UARTCLK",
+static struct clk uart0_pclk = {
+ .name = "UART0_PCLK",
.parent = &slow_clk,
- .rate = 13000000,
.hw_ctrld = false,
.reset = true,
.res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
@@ -1097,7 +1110,16 @@ static struct clk uart_clk = {
.clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(uart_clk.lock),
+ .lock = __SPIN_LOCK_UNLOCKED(uart0_pclk.lock),
+};
+
+/* This one is hardwired to PLL13 */
+static struct clk uart0_clk = {
+ .name = "UART0_CLK",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .lock = __SPIN_LOCK_UNLOCKED(uart0_clk.lock),
};
static struct clk keypad_clk = {
@@ -1182,10 +1204,14 @@ static struct clk timer_clk = {
.lock = __SPIN_LOCK_UNLOCKED(timer_clk.lock),
};
+/*
+ * There is a binary divider in the hardware that divides
+ * the 13MHz PLL by 13 down to 1 MHz.
+ */
static struct clk app_timer_clk = {
.name = "TIMER_APP",
.parent = &slow_clk,
- .rate = 13000000,
+ .rate = 1000000,
.hw_ctrld = true,
.reset = true,
.res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
@@ -1218,6 +1244,13 @@ static struct clk ppm_clk = {
.clk = clkref, \
}
+#define DEF_LOOKUP_CON(devid, conid, clkref) \
+ { \
+ .dev_id = devid, \
+ .con_id = conid, \
+ .clk = clkref, \
+ }
+
/*
* Here we only define clocks that are meaningful to
* look up through clockdevice.
@@ -1241,11 +1274,14 @@ static struct clk_lookup lookups[] = {
/* AHB bridge clocks */
DEF_LOOKUP("ahb_subsys", &ahb_subsys_clk),
DEF_LOOKUP("intcon", &intcon_clk),
+ DEF_LOOKUP_CON("intcon", "apb_pclk", &intcon_clk),
DEF_LOOKUP("mspro", &mspro_clk),
DEF_LOOKUP("pl172", &emif_clk),
+ DEF_LOOKUP_CON("pl172", "apb_pclk", &emif_clk),
/* FAST bridge clocks */
DEF_LOOKUP("fast", &fast_clk),
DEF_LOOKUP("mmci", &mmcsd_clk),
+ DEF_LOOKUP_CON("mmci", "apb_pclk", &mmcsd_clk),
/*
* The .0 and .1 identifiers on these comes from the platform device
* .id field and are assigned when the platform devices are registered.
@@ -1255,13 +1291,16 @@ static struct clk_lookup lookups[] = {
DEF_LOOKUP("stu300.0", &i2c0_clk),
DEF_LOOKUP("stu300.1", &i2c1_clk),
DEF_LOOKUP("pl022", &spi_clk),
+ DEF_LOOKUP_CON("pl022", "apb_pclk", &spi_clk),
#ifdef CONFIG_MACH_U300_BS335
DEF_LOOKUP("uart1", &uart1_clk),
+ DEF_LOOKUP_CON("uart1", "apb_pclk", &uart1_pclk),
#endif
/* SLOW bridge clocks */
DEF_LOOKUP("slow", &slow_clk),
DEF_LOOKUP("coh901327_wdog", &wdog_clk),
- DEF_LOOKUP("uart0", &uart_clk),
+ DEF_LOOKUP("uart0", &uart0_clk),
+ DEF_LOOKUP_CON("uart0", "apb_pclk", &uart0_pclk),
DEF_LOOKUP("apptimer", &app_timer_clk),
DEF_LOOKUP("coh901461-keypad", &keypad_clk),
DEF_LOOKUP("u300-gpio", &gpio_clk),
@@ -1280,64 +1319,6 @@ static void __init clk_register(void)
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
}
-/*
- * These are the clocks for cells registered as primecell drivers
- * on the AMBA bus. These must be on during AMBA device registration
- * since the bus probe will attempt to read magic configuration
- * registers for these devices. If they are deactivated these probes
- * will fail.
- *
- *
- * Please note that on emif, both RAM and NAND is connected in dual
- * RAM phones. On single RAM phones, ram is on semi and NAND on emif.
- *
- */
-void u300_clock_primecells(void)
-{
- clk_enable(&intcon_clk);
- clk_enable(&uart_clk);
-#ifdef CONFIG_MACH_U300_BS335
- clk_enable(&uart1_clk);
-#endif
- clk_enable(&spi_clk);
-
- clk_enable(&mmcsd_clk);
-
-}
-EXPORT_SYMBOL(u300_clock_primecells);
-
-void u300_unclock_primecells(void)
-{
-
- clk_disable(&intcon_clk);
- clk_disable(&uart_clk);
-#ifdef CONFIG_MACH_U300_BS335
- clk_disable(&uart1_clk);
-#endif
- clk_disable(&spi_clk);
- clk_disable(&mmcsd_clk);
-
-}
-EXPORT_SYMBOL(u300_unclock_primecells);
-
-/*
- * The interrupt controller is enabled before the clock API is registered.
- */
-void u300_enable_intcon_clock(void)
-{
- clk_enable(&intcon_clk);
-}
-EXPORT_SYMBOL(u300_enable_intcon_clock);
-
-/*
- * The timer is enabled before the clock API is registered.
- */
-void u300_enable_timer_clock(void)
-{
- clk_enable(&app_timer_clk);
-}
-EXPORT_SYMBOL(u300_enable_timer_clock);
-
#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
/*
* The following makes it possible to view the status (especially
@@ -1379,11 +1360,13 @@ static struct clk *clks[] = {
&spi_clk,
#ifdef CONFIG_MACH_U300_BS335
&uart1_clk,
+ &uart1_pclk,
#endif
/* SLOW bridge clocks */
&slow_clk,
&wdog_clk,
- &uart_clk,
+ &uart0_clk,
+ &uart0_pclk,
&app_timer_clk,
&keypad_clk,
&gpio_clk,
@@ -1424,7 +1407,7 @@ static int u300_clocks_show(struct seq_file *s, void *data)
chars++;
}
cdp[32] = '\0';
- if (clk->get_rate)
+ if (clk->get_rate || clk->rate != 0)
seq_printf(s,
"%s%s\t%s\t%d\t%s\t%lu Hz\n",
&cdp[0],
@@ -1433,7 +1416,7 @@ static int u300_clocks_show(struct seq_file *s, void *data)
clk->usecount ? "ON" : "OFF",
clk->usecount,
clk->hw_ctrld ? "YES" : "NO ",
- clk->get_rate(clk));
+ clk_get_rate(clk));
else
seq_printf(s,
"%s%s\t%s\t%d\t%s\t" \
@@ -1477,7 +1460,7 @@ static int __init init_clk_read_debugfs(void)
module_init(init_clk_read_debugfs);
#endif
-static int __init u300_clock_init(void)
+int __init u300_clock_init(void)
{
u16 val;
@@ -1514,10 +1497,8 @@ static int __init u300_clock_init(void)
*/
syscon_block_reset_disable(&semi_clk);
syscon_block_reset_disable(&emif_clk);
- semi_clk.enable(&semi_clk);
- emif_clk.enable(&emif_clk);
+ clk_enable(&semi_clk);
+ clk_enable(&emif_clk);
return 0;
}
-/* initialize clocking early to be available later in the boot */
-core_initcall(u300_clock_init);
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h
index fc6d9ccfe7e3..c34f3ea3017c 100644
--- a/arch/arm/mach-u300/clock.h
+++ b/arch/arm/mach-u300/clock.h
@@ -45,9 +45,6 @@ struct clk {
void (*disable) (struct clk *);
};
-void u300_clock_primecells(void);
-void u300_unclock_primecells(void);
-void u300_enable_intcon_clock(void);
-void u300_enable_timer_clock(void);
+int u300_clock_init(void);
#endif
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 5f34eb674d68..ea41c236be0f 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -19,6 +19,8 @@
#include <linux/amba/bus.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/coh901318.h>
#include <asm/types.h>
@@ -1477,11 +1479,19 @@ static struct platform_device *platform_devs[] __initdata = {
void __init u300_init_irq(void)
{
u32 mask[2] = {0, 0};
+ struct clk *clk;
int i;
+ /* initialize clocking early, we want to clock the INTCON */
+ u300_clock_init();
+
+ /* Clock the interrupt controller */
+ clk = clk_get_sys("intcon", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+
for (i = 0; i < NR_IRQS; i++)
set_bit(i, (unsigned long *) &mask[0]);
- u300_enable_intcon_clock();
vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]);
vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);
}
@@ -1561,13 +1571,6 @@ static void __init u300_init_check_chip(void)
printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
"(chip ID 0x%04x)\n", chipname, val);
-#ifdef CONFIG_MACH_U300_BS26
- if ((val & 0xFF00U) != 0xc800) {
- printk(KERN_ERR "Platform configured for BS25/BS26 " \
- "with DB3150 but %s detected, expect problems!",
- chipname);
- }
-#endif
#ifdef CONFIG_MACH_U300_BS330
if ((val & 0xFF00U) != 0xd800) {
printk(KERN_ERR "Platform configured for BS330 " \
@@ -1642,12 +1645,10 @@ void __init u300_init_devices(void)
u300_spi_init(&pl022_device);
/* Register the AMBA devices in the AMBA bus abstraction layer */
- u300_clock_primecells();
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
- u300_unclock_primecells();
u300_assign_physmem();
diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c
index 5f61fd45a0c8..d92790140fe5 100644
--- a/arch/arm/mach-u300/gpio.c
+++ b/arch/arm/mach-u300/gpio.c
@@ -523,7 +523,7 @@ static void gpio_set_initial_values(void)
/*
* Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
- * to output and 'GPIO_IN' to input for each port. And initalize
+ * to output and 'GPIO_IN' to input for each port. And initialize
* default value on outputs.
*/
for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
index ab000df7fc03..bf134bcc129d 100644
--- a/arch/arm/mach-u300/include/mach/memory.h
+++ b/arch/arm/mach-u300/include/mach/memory.h
@@ -35,14 +35,6 @@
#endif
/*
- * TCM memory whereabouts
- */
-#define ITCM_OFFSET 0xffff2000
-#define ITCM_END 0xffff3fff
-#define DTCM_OFFSET 0xffff4000
-#define DTCM_END 0xffff5fff
-
-/*
* We enable a real big DMA buffer if need be.
*/
#define CONSISTENT_DMA_SIZE SZ_4M
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 88506d030596..de1ac9ad2213 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -74,16 +74,16 @@ static void _mmci_callback(struct work_struct *ws)
mdelay(20);
- mmci_card->mmc_inserted = !!gpio_get_value(U300_GPIO_PIN_MMC_CD);
+ mmci_card->mmc_inserted = !gpio_get_value(U300_GPIO_PIN_MMC_CD);
input_report_switch(mmci_card->mmc_input, KEY_INSERT,
- !mmci_card->mmc_inserted);
+ mmci_card->mmc_inserted);
input_sync(mmci_card->mmc_input);
pr_debug("MMC/SD card was %s\n",
- mmci_card->mmc_inserted ? "removed" : "inserted");
+ mmci_card->mmc_inserted ? "inserted" : "removed");
- enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, !mmci_card->mmc_inserted);
+ enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, mmci_card->mmc_inserted);
}
int __devinit mmc_init(struct amba_device *adev)
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 26d26f5100fe..3fc4472719be 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -15,6 +15,8 @@
#include <linux/clocksource.h>
#include <linux/types.h>
#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/hardware.h>
@@ -23,7 +25,8 @@
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
-#include "clock.h"
+/* Be able to sleep for atleast 4 seconds (usually more) */
+#define APPTIMER_MIN_RANGE 4
/*
* APP side special timer registers
@@ -307,8 +310,6 @@ static struct clock_event_device clockevent_u300_1mhz = {
.name = "GPT1",
.rating = 300, /* Reasonably fast and accurate clock event */
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
- .shift = 22,
.set_next_event = u300_set_next_event,
.set_mode = u300_set_mode,
};
@@ -341,8 +342,6 @@ static struct clocksource clocksource_u300_1mhz = {
.rating = 300, /* Reasonably fast and accurate clock source */
.read = u300_get_cycles,
.mask = CLOCKSOURCE_MASK(32), /* 32 bits */
- /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
- .shift = 22,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -367,7 +366,15 @@ unsigned long long notrace sched_clock(void)
*/
static void __init u300_timer_init(void)
{
- u300_enable_timer_clock();
+ struct clk *clk;
+ unsigned long rate;
+
+ /* Clock the interrupt controller */
+ clk = clk_get_sys("apptimer", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+ rate = clk_get_rate(clk);
+
/*
* Disable the "OS" and "DD" timers - these are designed for Symbian!
* Example usage in cnh1601578 cpu subsystem pd_timer_app.c
@@ -405,15 +412,14 @@ static void __init u300_timer_init(void)
writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
- /* This is a pure microsecond clock source */
- clocksource_u300_1mhz.mult =
- clocksource_khz2mult(1000, clocksource_u300_1mhz.shift);
+ clocksource_calc_mult_shift(&clocksource_u300_1mhz,
+ rate, APPTIMER_MIN_RANGE);
if (clocksource_register(&clocksource_u300_1mhz))
printk(KERN_ERR "timer: failed to initialize clock "
"source %s\n", clocksource_u300_1mhz.name);
- clockevent_u300_1mhz.mult =
- div_sc(1000000, NSEC_PER_SEC, clockevent_u300_1mhz.shift);
+ clockevents_calc_mult_shift(&clockevent_u300_1mhz,
+ rate, APPTIMER_MIN_RANGE);
/* 32bit counter, so 32bits delta is max */
clockevent_u300_1mhz.max_delta_ns =
clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz);
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b8847a18..bfcda9820888 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/memblock.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -22,6 +23,21 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+static void __init u300_reserve(void)
+{
+ /*
+ * U300 - This platform family can share physical memory
+ * between two ARM cpus, one running Linux and the other
+ * running another OS.
+ */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+ memblock_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
static void __init u300_init_machine(void)
{
u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
.io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = BOOT_PARAMS_OFFSET,
.map_io = u300_map_io,
+ .reserve = u300_reserve,
.init_irq = u300_init_irq,
.timer = &u300_timer,
.init_machine = u300_init_machine,