diff options
Diffstat (limited to 'arch/arm/mach-u300')
-rw-r--r-- | arch/arm/mach-u300/clock.c | 133 | ||||
-rw-r--r-- | arch/arm/mach-u300/clock.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-u300/core.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-u300/gpio.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/memory.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-u300/mmc.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-u300/timer.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-u300/u300.c | 17 |
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, |