diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-08 14:17:27 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-08 14:17:27 -0800 |
commit | 4ef1a30c6bd2555d4177fc9286df32e9166d58ba (patch) | |
tree | 0ebec2569f8bf099596448539215f1299202cbd7 /arch/arm/mach-davinci | |
parent | 5939224ccdcc9244ab82cdbdc9d21eb019f7db6a (diff) | |
parent | a832eb203ecd34e486bdde0042cf166e687eb227 (diff) |
Merge tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC late updates from Olof Johansson:
"This is some material that we picked up into our tree late, or that
had more complex dependencies on more than one topic branch that makes
sense to keep separately.
- TI support for secure accelerators and hwrng on OMAP4/5
- TI camera changes for dra7 and am437x and SGX improvement due to
better reset control support on am335x, am437x and dra7
- Davinci moves to proper clocksource on DM365, and regulator/audio
improvements for DM365 and DM644x eval boards"
* tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (32 commits)
ARM: dts: omap4-droid4: Enable hdq for droid4 ds250x 1-wire battery nvmem
ARM: dts: motorola-cpcap-mapphone: Configure calibration interrupt
ARM: dts: Configure interconnect target module for am437x sgx
ARM: dts: Configure sgx for dra7
ARM: dts: Configure rstctrl reset for am335x SGX
ARM: dts: dra7: Add ti-sysc node for VPE
ARM: dts: dra7: add vpe clkctrl node
ARM: dts: am43x-epos-evm: Add VPFE and OV2659 entries
ARM: dts: am437x-sk-evm: Add VPFE and OV2659 entries
ARM: dts: am43xx: add support for clkout1 clock
arm: dts: dra76-evm: Add CAL and OV5640 nodes
arm: dtsi: dra76x: Add CAL dtsi node
arm: dts: dra72-evm-common: Add entries for the CSI2 cameras
ARM: dts: DRA72: Add CAL dtsi node
ARM: dts: dra7-l4: Add ti-sysc node for CAM
ARM: OMAP: DRA7xx: Make CAM clock domain SWSUP only
ARM: dts: dra7: add cam clkctrl node
ARM: OMAP2+: Drop legacy platform data for omap4 des
ARM: OMAP2+: Drop legacy platform data for omap4 sham
ARM: OMAP2+: Drop legacy platform data for omap4 aes
...
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r-- | arch/arm/mach-davinci/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-dm365-evm.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-dm644x-evm.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-davinci/devices-da8xx.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/devices.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-davinci/dm365.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/common.h | 17 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/time.h | 33 | ||||
-rw-r--r-- | arch/arm/mach-davinci/time.c | 400 |
9 files changed, 56 insertions, 479 deletions
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a03d8443ef08..58838a9de651 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -7,8 +7,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include # Common objects -obj-y := time.o serial.o usb.o \ - common.o sram.o +obj-y := serial.o usb.o common.o sram.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 150a36f333df..2328b15ac067 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -30,6 +30,8 @@ #include <linux/spi/eeprom.h> #include <linux/v4l2-dv-timings.h> #include <linux/platform_data/ti-aemif.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -245,6 +247,19 @@ static struct davinci_i2c_platform_data i2c_pdata = { .bus_delay = 0 /* usec */, }; +/* Fixed regulator support */ +static struct regulator_consumer_supply fixed_supplies_3_3v[] = { + /* Baseboard 3.3V: 5V -> TPS767D301 -> 3.3V */ + REGULATOR_SUPPLY("AVDD", "1-0018"), + REGULATOR_SUPPLY("DRVDD", "1-0018"), + REGULATOR_SUPPLY("IOVDD", "1-0018"), +}; + +static struct regulator_consumer_supply fixed_supplies_1_8v[] = { + /* Baseboard 1.8V: 5V -> TPS767D301 -> 1.8V */ + REGULATOR_SUPPLY("DVDD", "1-0018"), +}; + static int dm365evm_keyscan_enable(struct device *dev) { return davinci_cfg_reg(DM365_KEYSCAN); @@ -800,6 +815,11 @@ static __init void dm365_evm_init(void) if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + regulator_register_always_on(0, "fixed-dummy", fixed_supplies_1_8v, + ARRAY_SIZE(fixed_supplies_1_8v), 1800000); + regulator_register_always_on(1, "fixed-dummy", fixed_supplies_3_3v, + ARRAY_SIZE(fixed_supplies_3_3v), 3300000); + nvmem_add_cell_table(&davinci_nvmem_cell_table); nvmem_add_cell_lookups(&davinci_nvmem_cell_lookup, 1); diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 040c949414fa..3461d12bbfc0 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -29,6 +29,8 @@ #include <linux/v4l2-dv-timings.h> #include <linux/export.h> #include <linux/leds.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <media/i2c/tvp514x.h> @@ -653,6 +655,19 @@ static struct i2c_board_info __initdata i2c_info[] = { }, }; +/* Fixed regulator support */ +static struct regulator_consumer_supply fixed_supplies_3_3v[] = { + /* Baseboard 3.3V: 5V -> TPS54310PWP -> 3.3V */ + REGULATOR_SUPPLY("AVDD", "1-001b"), + REGULATOR_SUPPLY("DRVDD", "1-001b"), +}; + +static struct regulator_consumer_supply fixed_supplies_1_8v[] = { + /* Baseboard 1.8V: 5V -> TPS54310PWP -> 1.8V */ + REGULATOR_SUPPLY("IOVDD", "1-001b"), + REGULATOR_SUPPLY("DVDD", "1-001b"), +}; + #define DM644X_I2C_SDA_PIN GPIO_TO_PIN(2, 12) #define DM644X_I2C_SCL_PIN GPIO_TO_PIN(2, 11) @@ -842,6 +857,11 @@ static __init void davinci_evm_init(void) dm644x_register_clocks(); + regulator_register_always_on(0, "fixed-dummy", fixed_supplies_1_8v, + ARRAY_SIZE(fixed_supplies_1_8v), 1800000); + regulator_register_always_on(1, "fixed-dummy", fixed_supplies_3_3v, + ARRAY_SIZE(fixed_supplies_3_3v), 3300000); + dm644x_init_devices(); ret = dm644x_gpio_register(); diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 2d69e704f7f6..feb206bdf6e1 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -21,7 +21,6 @@ #include <mach/common.h> #include <mach/cputype.h> #include <mach/da8xx.h> -#include <mach/time.h> #include "asp.h" #include "cpuidle.h" diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index e650131ee88f..849e811fade7 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -17,7 +17,6 @@ #include <mach/hardware.h> #include <mach/cputype.h> #include <mach/mux.h> -#include <mach/time.h> #include "davinci.h" #include "irqs.h" @@ -303,21 +302,3 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata) davinci_gpio_device.dev.platform_data = pdata; return platform_device_register(&davinci_gpio_device); } - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -struct davinci_timer_instance davinci_timer_instance[2] = { - { - .base = DAVINCI_TIMER0_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34), - }, - { - .base = DAVINCI_TIMER1_BASE, - .bottom_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT12), - .top_irq = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT34), - }, -}; - diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 9fc5c73cc0be..c1e0d46996e4 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -35,7 +35,8 @@ #include <mach/cputype.h> #include <mach/mux.h> #include <mach/serial.h> -#include <mach/time.h> + +#include <clocksource/timer-davinci.h> #include "asp.h" #include "davinci.h" @@ -660,10 +661,16 @@ static struct davinci_id dm365_ids[] = { }, }; -static struct davinci_timer_info dm365_timer_info = { - .timers = davinci_timer_instance, - .clockevent_id = T0_BOT, - .clocksource_id = T0_TOP, +/* + * Bottom half of timer0 is used for clockevent, top half is used for + * clocksource. + */ +static const struct davinci_timer_cfg dm365_timer_cfg = { + .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_128), + .irq = { + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)), + DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)), + }, }; #define DM365_UART1_BASE (IO_PHYS + 0x106000) @@ -723,7 +730,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = { .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm365_pins, .pinmux_pins_num = ARRAY_SIZE(dm365_pins), - .timer_info = &dm365_timer_info, .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, @@ -771,6 +777,7 @@ void __init dm365_init_time(void) { void __iomem *pll1, *pll2, *psc; struct clk *clk; + int rv; clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ); @@ -789,7 +796,8 @@ void __init dm365_init_time(void) return; } - davinci_timer_init(clk); + rv = davinci_timer_register(clk, &dm365_timer_cfg); + WARN(rv, "Unable to register the timer: %d\n", rv); } void __init dm365_register_clocks(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 9526e5da0d33..139b83de011d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -22,22 +22,6 @@ #define DAVINCI_INTC_START NR_IRQS #define DAVINCI_INTC_IRQ(_irqnum) (DAVINCI_INTC_START + (_irqnum)) -void davinci_timer_init(struct clk *clk); - -struct davinci_timer_instance { - u32 base; - u32 bottom_irq; - u32 top_irq; - unsigned long cmp_off; - unsigned int cmp_irq; -}; - -struct davinci_timer_info { - struct davinci_timer_instance *timers; - unsigned int clockevent_id; - unsigned int clocksource_id; -}; - struct davinci_gpio_controller; /* @@ -58,7 +42,6 @@ struct davinci_soc_info { u32 pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; - struct davinci_timer_info *timer_info; int gpio_type; u32 gpio_base; unsigned gpio_num; diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h deleted file mode 100644 index ba913736990f..000000000000 --- a/arch/arm/mach-davinci/include/mach/time.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Local header file for DaVinci time code. - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H -#define __ARCH_ARM_MACH_DAVINCI_TIME_H - -#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) - -enum { - T0_BOT, - T0_TOP, - T1_BOT, - T1_TOP, - NUM_TIMERS -}; - -#define IS_TIMER1(id) (id & 0x2) -#define IS_TIMER0(id) (!IS_TIMER1(id)) -#define IS_TIMER_TOP(id) ((id & 0x1)) -#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) - -#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0) - -extern struct davinci_timer_instance davinci_timer_instance[]; - -#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c deleted file mode 100644 index 740410a3bb6a..000000000000 --- a/arch/arm/mach-davinci/time.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * DaVinci timer subsystem - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#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> - -#include <asm/mach/irq.h> -#include <asm/mach/time.h> - -#include <mach/cputype.h> -#include <mach/hardware.h> -#include <mach/time.h> - -static struct clock_event_device clockevent_davinci; -static unsigned int davinci_clock_tick_rate; - -/* - * This driver configures the 2 64-bit count-up timers as 4 independent - * 32-bit count-up timers used as follows: - */ - -enum { - TID_CLOCKEVENT, - TID_CLOCKSOURCE, -}; - -/* Timer register offsets */ -#define PID12 0x0 -#define TIM12 0x10 -#define TIM34 0x14 -#define PRD12 0x18 -#define PRD34 0x1c -#define TCR 0x20 -#define TGCR 0x24 -#define WDTCR 0x28 - -/* Offsets of the 8 compare registers */ -#define CMP12_0 0x60 -#define CMP12_1 0x64 -#define CMP12_2 0x68 -#define CMP12_3 0x6c -#define CMP12_4 0x70 -#define CMP12_5 0x74 -#define CMP12_6 0x78 -#define CMP12_7 0x7c - -/* Timer register bitfields */ -#define TCR_ENAMODE_DISABLE 0x0 -#define TCR_ENAMODE_ONESHOT 0x1 -#define TCR_ENAMODE_PERIODIC 0x2 -#define TCR_ENAMODE_MASK 0x3 - -#define TGCR_TIMMODE_SHIFT 2 -#define TGCR_TIMMODE_64BIT_GP 0x0 -#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1 -#define TGCR_TIMMODE_64BIT_WDOG 0x2 -#define TGCR_TIMMODE_32BIT_CHAINED 0x3 - -#define TGCR_TIM12RS_SHIFT 0 -#define TGCR_TIM34RS_SHIFT 1 -#define TGCR_RESET 0x0 -#define TGCR_UNRESET 0x1 -#define TGCR_RESET_MASK 0x3 - -struct timer_s { - char *name; - unsigned int id; - unsigned long period; - unsigned long opts; - unsigned long flags; - void __iomem *base; - unsigned long tim_off; - unsigned long prd_off; - unsigned long enamode_shift; - struct irqaction irqaction; -}; -static struct timer_s timers[]; - -/* values for 'opts' field of struct timer_s */ -#define TIMER_OPTS_DISABLED 0x01 -#define TIMER_OPTS_ONESHOT 0x02 -#define TIMER_OPTS_PERIODIC 0x04 -#define TIMER_OPTS_STATE_MASK 0x07 - -#define TIMER_OPTS_USE_COMPARE 0x80000000 -#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE) - -static char *id_to_name[] = { - [T0_BOT] = "timer0_0", - [T0_TOP] = "timer0_1", - [T1_BOT] = "timer1_0", - [T1_TOP] = "timer1_1", -}; - -static int timer32_config(struct timer_s *t) -{ - u32 tcr; - struct davinci_soc_info *soc_info = &davinci_soc_info; - - if (USING_COMPARE(t)) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id); - - /* - * Next interrupt should be the current time reg value plus - * the new period (using 32-bit unsigned addition/wrapping - * to 0 on overflow). This assumes that the clocksource - * is setup to count to 2^32-1 before wrapping around to 0. - */ - __raw_writel(__raw_readl(t->base + t->tim_off) + t->period, - t->base + dtip[event_timer].cmp_off); - } else { - tcr = __raw_readl(t->base + TCR); - - /* disable timer */ - tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); - __raw_writel(tcr, t->base + TCR); - - /* reset counter to zero, set new period */ - __raw_writel(0, t->base + t->tim_off); - __raw_writel(t->period, t->base + t->prd_off); - - /* Set enable mode */ - if (t->opts & TIMER_OPTS_ONESHOT) - tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; - else if (t->opts & TIMER_OPTS_PERIODIC) - tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; - - __raw_writel(tcr, t->base + TCR); - } - return 0; -} - -static inline u32 timer32_read(struct timer_s *t) -{ - return __raw_readl(t->base + t->tim_off); -} - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_davinci; - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -/* called when 32-bit counter wraps */ -static irqreturn_t freerun_interrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static struct timer_s timers[] = { - [TID_CLOCKEVENT] = { - .name = "clockevent", - .opts = TIMER_OPTS_DISABLED, - .irqaction = { - .flags = IRQF_TIMER, - .handler = timer_interrupt, - } - }, - [TID_CLOCKSOURCE] = { - .name = "free-run counter", - .period = ~0, - .opts = TIMER_OPTS_PERIODIC, - .irqaction = { - .flags = IRQF_TIMER, - .handler = freerun_interrupt, - } - }, -}; - -static void __init timer_init(void) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - struct davinci_timer_instance *dtip = soc_info->timer_info->timers; - void __iomem *base[2]; - int i; - - /* Global init of each 64-bit timer as a whole */ - for(i=0; i<2; i++) { - u32 tgcr; - - base[i] = ioremap(dtip[i].base, SZ_4K); - if (WARN_ON(!base[i])) - continue; - - /* Disabled, Internal clock source */ - __raw_writel(0, base[i] + TCR); - - /* reset both timers, no pre-scaler for timer34 */ - tgcr = 0; - __raw_writel(tgcr, base[i] + TGCR); - - /* Set both timers to unchained 32-bit */ - tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; - __raw_writel(tgcr, base[i] + TGCR); - - /* Unreset timers */ - tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | - (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); - __raw_writel(tgcr, base[i] + TGCR); - - /* Init both counters to zero */ - __raw_writel(0, base[i] + TIM12); - __raw_writel(0, base[i] + TIM34); - } - - /* Init of each timer as a 32-bit timer */ - for (i=0; i< ARRAY_SIZE(timers); i++) { - struct timer_s *t = &timers[i]; - int timer = ID_TO_TIMER(t->id); - u32 irq; - - t->base = base[timer]; - if (!t->base) - continue; - - if (IS_TIMER_BOT(t->id)) { - t->enamode_shift = 6; - t->tim_off = TIM12; - t->prd_off = PRD12; - irq = dtip[timer].bottom_irq; - } else { - t->enamode_shift = 22; - t->tim_off = TIM34; - t->prd_off = PRD34; - irq = dtip[timer].top_irq; - } - - /* Register interrupt */ - t->irqaction.name = t->name; - t->irqaction.dev_id = (void *)t; - - if (t->irqaction.handler != NULL) { - irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; - setup_irq(irq, &t->irqaction); - } - } -} - -/* - * clocksource - */ -static u64 read_cycles(struct clocksource *cs) -{ - struct timer_s *t = &timers[TID_CLOCKSOURCE]; - - return (cycles_t)timer32_read(t); -} - -static struct clocksource clocksource_davinci = { - .rating = 300, - .read = read_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/* - * Overwrite weak default sched_clock with something more precise - */ -static u64 notrace davinci_read_sched_clock(void) -{ - return timer32_read(&timers[TID_CLOCKSOURCE]); -} - -/* - * clockevent - */ -static int davinci_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = cycles; - timer32_config(t); - return 0; -} - -static int davinci_shutdown(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_DISABLED; - return 0; -} - -static int davinci_set_oneshot(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_ONESHOT; - return 0; -} - -static int davinci_set_periodic(struct clock_event_device *evt) -{ - struct timer_s *t = &timers[TID_CLOCKEVENT]; - - t->period = davinci_clock_tick_rate / (HZ); - t->opts &= ~TIMER_OPTS_STATE_MASK; - t->opts |= TIMER_OPTS_PERIODIC; - timer32_config(t); - return 0; -} - -static struct clock_event_device clockevent_davinci = { - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = davinci_set_next_event, - .set_state_shutdown = davinci_shutdown, - .set_state_periodic = davinci_set_periodic, - .set_state_oneshot = davinci_set_oneshot, -}; - -void __init davinci_timer_init(struct clk *timer_clk) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - unsigned int clockevent_id; - unsigned int clocksource_id; - int i; - - clockevent_id = soc_info->timer_info->clockevent_id; - clocksource_id = soc_info->timer_info->clocksource_id; - - timers[TID_CLOCKEVENT].id = clockevent_id; - timers[TID_CLOCKSOURCE].id = clocksource_id; - - /* - * If using same timer for both clock events & clocksource, - * a compare register must be used to generate an event interrupt. - * This is equivalent to a oneshot timer only (not periodic). - */ - if (clockevent_id == clocksource_id) { - struct davinci_timer_instance *dtip = - soc_info->timer_info->timers; - int event_timer = ID_TO_TIMER(clockevent_id); - - /* Only bottom timers can use compare regs */ - if (IS_TIMER_TOP(clockevent_id)) - pr_warn("%s: Invalid use of system timers. Results unpredictable.\n", - __func__); - else if ((dtip[event_timer].cmp_off == 0) - || (dtip[event_timer].cmp_irq == 0)) - pr_warn("%s: Invalid timer instance setup. Results unpredictable.\n", - __func__); - else { - timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; - clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; - } - } - - BUG_ON(IS_ERR(timer_clk)); - clk_prepare_enable(timer_clk); - - /* init timer hw */ - timer_init(); - - davinci_clock_tick_rate = clk_get_rate(timer_clk); - - /* setup clocksource */ - clocksource_davinci.name = id_to_name[clocksource_id]; - if (clocksource_register_hz(&clocksource_davinci, - davinci_clock_tick_rate)) - pr_err("%s: can't register clocksource!\n", - clocksource_davinci.name); - - sched_clock_register(davinci_read_sched_clock, 32, - davinci_clock_tick_rate); - - /* setup clockevent */ - clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; - - clockevent_davinci.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_davinci, - davinci_clock_tick_rate, 1, 0xfffffffe); - - for (i=0; i< ARRAY_SIZE(timers); i++) - timer32_config(&timers[i]); -} |