arm:switch to dynamic configuration for the kernel.

During startup machine.board_id is now determined. The kernel can now
at runtime determine how to configure itself and does so.

Change-Id: I4f615af9bfa5add219e618b911a51af127591d6a
This commit is contained in:
Kees Jongenburger 2013-12-13 14:12:50 +01:00
parent 3a2fb1ae8c
commit aa94c9ed55
14 changed files with 210 additions and 189 deletions

View file

@ -3,10 +3,8 @@
#ifndef _ARM_MEMORY_H #ifndef _ARM_MEMORY_H
#define _ARM_MEMORY_H #define _ARM_MEMORY_H
#if defined(DM37XX) || defined(AM335X)
/* omap */ /* omap */
#define PHYS_MEM_BEGIN 0x80000000 #define PHYS_MEM_BEGIN 0x80000000
#define PHYS_MEM_END 0xbfffffff #define PHYS_MEM_END 0xbfffffff
#endif /* defined(DM37XX) || defined(AM335X) */
#endif /* _ARM_MEMORY_H */ #endif /* _ARM_MEMORY_H */

View file

@ -5,15 +5,12 @@
* The base must be page aligned, so we round down and the kernel adds the * The base must be page aligned, so we round down and the kernel adds the
* offset. The size must be a multiple of ARM_PAGE_SIZE, so we round up to 4KB. * offset. The size must be a multiple of ARM_PAGE_SIZE, so we round up to 4KB.
*/ */
#ifdef AM335X #define PADCONF_AM335X_REGISTERS_BASE 0x44E10000
#define PADCONF_REGISTERS_BASE 0x44E10000 #define PADCONF_AM335X_REGISTERS_OFFSET 0x0000
#define PADCONF_REGISTERS_OFFSET 0x0000 #define PADCONF_AM335X_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */
#define PADCONF_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */ #define PADCONF_DM37XX_REGISTERS_BASE 0x48002000
#elif DM37XX #define PADCONF_DM37XX_REGISTERS_OFFSET 0x0030
#define PADCONF_REGISTERS_BASE 0x48002000 #define PADCONF_DM37XX_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */
#define PADCONF_REGISTERS_OFFSET 0x0030
#define PADCONF_REGISTERS_SIZE 0x1000 /* OFFSET + highest reg, rounded up */
#endif
#define PADCONF_MUXMODE(X) (X & 0x7) /* mode 1 til 7 [2:0] */ #define PADCONF_MUXMODE(X) (X & 0x7) /* mode 1 til 7 [2:0] */
#define PADCONF_PULL_MODE(X) ((X & 0x3) << 3) /* 2 bits[4:3] */ #define PADCONF_PULL_MODE(X) ((X & 0x3) << 3) /* 2 bits[4:3] */

View file

@ -7,6 +7,7 @@
#include "kernel/proc.h" #include "kernel/proc.h"
#include "kernel/interrupt.h" #include "kernel/interrupt.h"
#include <minix/u64.h> #include <minix/u64.h>
#include <minix/board.h>
#include "kernel/glo.h" #include "kernel/glo.h"
#include "kernel/profile.h" #include "kernel/profile.h"
@ -28,12 +29,14 @@ int init_local_timer(unsigned freq)
{ {
omap3_timer_init(freq); omap3_timer_init(freq);
omap3_frclock_init(); omap3_frclock_init();
#ifdef DM37XX
if (BOARD_IS_BBXM(machine.board_id)){
tsc_per_ms[0] = 16250; tsc_per_ms[0] = 16250;
#endif } else if (BOARD_IS_BB(machine.board_id)){
#ifdef AM335X
tsc_per_ms[0] = 15000; tsc_per_ms[0] = 15000;
#endif } else {
panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id);
};
return 0; return 0;
} }

View file

@ -11,6 +11,7 @@
#include <io.h> #include <io.h>
#include <minix/reboot.h> #include <minix/reboot.h>
#include <minix/board.h>
#include <minix/u64.h> #include <minix/u64.h>
#include "archconst.h" #include "archconst.h"
@ -51,7 +52,7 @@ poweroff(void)
* The only way to pull the pin low is via ALARM2 (see TRM 20.3.3.8). * The only way to pull the pin low is via ALARM2 (see TRM 20.3.3.8).
* At this point PM should have already signaled readclock to set the alarm. * At this point PM should have already signaled readclock to set the alarm.
*/ */
#ifdef AM335X if (BOARD_IS_BB(machine.board_id)){
/* Powers down the SoC within 3 seconds */ /* Powers down the SoC within 3 seconds */
direct_print("PMIC Power-Off in 3 Seconds\n"); direct_print("PMIC Power-Off in 3 Seconds\n");
@ -62,7 +63,7 @@ poweroff(void)
/* wait for the alarm to go off and PMIC to disable power to SoC */ /* wait for the alarm to go off and PMIC to disable power to SoC */
while (1); while (1);
#endif /* AM335X */ }
/* fallback option: hang */ /* fallback option: hang */
direct_print("Unable to power-off this device."); direct_print("Unable to power-off this device.");

View file

@ -4,9 +4,7 @@
#if USE_PADCONF #if USE_PADCONF
/* get arch specific arch_padconf_set() */ /* get arch specific arch_padconf_set() */
#if defined(AM335X) || defined(DM37XX)
#include "omap_padconf.h" #include "omap_padconf.h"
#endif
/*===========================================================================* /*===========================================================================*
* do_padconf * * do_padconf *

View file

@ -6,6 +6,7 @@
#include <machine/vm.h> #include <machine/vm.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/board.h>
#include <minix/syslib.h> #include <minix/syslib.h>
#include <minix/cpufeature.h> #include <minix/cpufeature.h>
#include <string.h> #include <string.h>
@ -737,12 +738,13 @@ int arch_phys_map(const int index,
} }
else if (index == frclock_index) { else if (index == frclock_index) {
#ifdef DM37XX if (BOARD_IS_BBXM(machine.board_id)){
*addr = OMAP3_GPTIMER10_BASE; *addr = OMAP3_GPTIMER10_BASE;
#endif } else if (BOARD_IS_BB(machine.board_id)){
#ifdef AM335X
*addr = AM335X_DMTIMER7_BASE; *addr = AM335X_DMTIMER7_BASE;
#endif } else {
panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id);
};
*len = ARM_PAGE_SIZE; *len = ARM_PAGE_SIZE;
*flags = VMMF_UNCACHED | VMMF_USER; *flags = VMMF_UNCACHED | VMMF_USER;
return OK; return OK;
@ -792,15 +794,15 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
return OK; return OK;
} }
else if (index == frclock_index) { else if (index == frclock_index) {
#if defined(DM37XX) if (BOARD_IS_BBXM(machine.board_id)){
minix_kerninfo.minix_frclock_tcrr = addr + OMAP3_TIMER_TCRR; minix_kerninfo.minix_frclock_tcrr = addr + OMAP3_TIMER_TCRR;
minix_kerninfo.minix_arm_frclock_hz = 1625000; minix_kerninfo.minix_arm_frclock_hz = 1625000;
#elif defined(AM335X) } else if (BOARD_IS_BB(machine.board_id)){
minix_kerninfo.minix_frclock_tcrr = addr + AM335X_TIMER_TCRR; minix_kerninfo.minix_frclock_tcrr = addr + AM335X_TIMER_TCRR;
minix_kerninfo.minix_arm_frclock_hz = 1500000; minix_kerninfo.minix_arm_frclock_hz = 1500000;
#else } else {
#error ARM: plese define either AM335X or DM37XX. panic("memory setup errot machine (0x%08x) is unhandled\n",machine.board_id);
#endif };
return OK; return OK;
} }

View file

@ -1,6 +1,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/board.h>
#include <io.h> #include <io.h>
#include "kernel/kernel.h" #include "kernel/kernel.h"
@ -21,12 +22,13 @@ static kern_phys_map intr_phys_map;
int intr_init(const int auto_eoi) int intr_init(const int auto_eoi)
{ {
#ifdef DM37XX if (BOARD_IS_BBXM(machine.board_id)){
omap_intr.base = OMAP3_DM37XX_INTR_BASE; omap_intr.base = OMAP3_DM37XX_INTR_BASE;
#endif } else if (BOARD_IS_BB(machine.board_id)){
#ifdef AM335X
omap_intr.base = OMAP3_AM335X_INTR_BASE; omap_intr.base = OMAP3_AM335X_INTR_BASE;
#endif } else {
panic("Can not do the interrupt setup. machine (0x%08x) is unknown\n",machine.board_id);
};
omap_intr.size = 0x1000 ; /* 4K */ omap_intr.size = 0x1000 ; /* 4K */
kern_phys_map_ptr(omap_intr.base,omap_intr.size, kern_phys_map_ptr(omap_intr.base,omap_intr.size,

View file

@ -1,16 +1,12 @@
#ifndef _OMAP_INTR_H #ifndef _OMAP_INTR_H
#define _OMAP_INTR_H #define _OMAP_INTR_H
#ifdef DM37XX
/* Interrupt controller memory map */ /* Interrupt controller memory map */
#define OMAP3_DM37XX_INTR_BASE 0x48200000 /* INTCPS physical address */ #define OMAP3_DM37XX_INTR_BASE 0x48200000 /* INTCPS physical address */
#endif /* DM37XX */
#ifdef AM335X
/* Interrupt controller memory map */ /* Interrupt controller memory map */
#define OMAP3_AM335X_INTR_BASE 0x48200000 /* INTCPS physical address */ #define OMAP3_AM335X_INTR_BASE 0x48200000 /* INTCPS physical address */
#endif /* AM335X */
/* Interrupt controller registers */ /* Interrupt controller registers */
#define OMAP3_INTCPS_REVISION 0x000 /* IP revision code */ #define OMAP3_INTCPS_REVISION 0x000 /* IP revision code */
@ -59,7 +55,6 @@
#ifdef DM37XX
#define OMAP3_DM337X_NR_IRQ_VECTORS 96 #define OMAP3_DM337X_NR_IRQ_VECTORS 96
@ -135,9 +130,7 @@
#define OMAP3_HSUSB_DMA_IRQ 93 /* High-speed USB OTG DMA */ #define OMAP3_HSUSB_DMA_IRQ 93 /* High-speed USB OTG DMA */
#define OMAP3_MMC3_IRQ 94 /* MMC/SD module 3 */ #define OMAP3_MMC3_IRQ 94 /* MMC/SD module 3 */
#endif
#ifdef AM335X
#define AM335X_INT_EMUINT 0 /* Emulation interrupt (EMUICINTR) */ #define AM335X_INT_EMUINT 0 /* Emulation interrupt (EMUICINTR) */
#define AM335X_INT_COMMTX 1 /* CortexA8 COMMTX */ #define AM335X_INT_COMMTX 1 /* CortexA8 COMMTX */
#define AM335X_INT_COMMRX 2 /* CortexA8 COMMRX */ #define AM335X_INT_COMMRX 2 /* CortexA8 COMMRX */
@ -239,7 +232,6 @@
#define AM335X_INT_SPI1INT 125 /* McSPI1 SINTERRUPTN */ #define AM335X_INT_SPI1INT 125 /* McSPI1 SINTERRUPTN */
#define OMAP3_AM335X_NR_IRQ_VECTORS 125 #define OMAP3_AM335X_NR_IRQ_VECTORS 125
#endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__

View file

@ -6,6 +6,7 @@
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/mmio.h> #include <minix/mmio.h>
#include <minix/padconf.h> #include <minix/padconf.h>
#include <minix/board.h>
#include <assert.h> #include <assert.h>
#include <io.h> #include <io.h>
#include <stdlib.h> #include <stdlib.h>
@ -18,25 +19,43 @@ struct omap_padconf
vir_bytes base; vir_bytes base;
vir_bytes offset; vir_bytes offset;
vir_bytes size; vir_bytes size;
unsigned int board_filter_value;
unsigned int board_filter_mask;
}; };
static struct omap_padconf omap_padconf = {
.base = PADCONF_REGISTERS_BASE, struct omap_padconf omap_padconfs[] = {
.offset = PADCONF_REGISTERS_OFFSET, {
.size = PADCONF_REGISTERS_SIZE .base = PADCONF_DM37XX_REGISTERS_BASE,
.offset = PADCONF_DM37XX_REGISTERS_OFFSET,
.size = PADCONF_DM37XX_REGISTERS_SIZE,
.board_filter_value = BOARD_FILTER_BBXM_VALUE,
.board_filter_mask = BOARD_FILTER_BBXM_MASK,
},
{
.base = PADCONF_AM335X_REGISTERS_BASE,
.offset = PADCONF_AM335X_REGISTERS_OFFSET,
.size = PADCONF_AM335X_REGISTERS_SIZE,
.board_filter_value = BOARD_FILTER_BB_VALUE,
.board_filter_mask = BOARD_FILTER_BB_MASK,
},
}; };
/* initialized in init */
static struct omap_padconf *omap_padconf;
static kern_phys_map padconf_phys_map; static kern_phys_map padconf_phys_map;
int int
arch_padconf_set(u32_t padconf, u32_t mask, u32_t value) arch_padconf_set(u32_t padconf, u32_t mask, u32_t value)
{ {
/* check that the value will be inside the padconf memory range */ /* check that the value will be inside the padconf memory range */
if (padconf >= (PADCONF_REGISTERS_SIZE - PADCONF_REGISTERS_OFFSET)) { if (padconf >= (omap_padconf->size - omap_padconf->offset)) {
return EINVAL; /* outside of valid range */ return EINVAL; /* outside of valid range */
} }
set32(padconf + omap_padconf.base + omap_padconf.offset, mask, value); set32(padconf + omap_padconf->base + omap_padconf->offset, mask, value);
return OK; return OK;
} }
@ -44,8 +63,19 @@ arch_padconf_set(u32_t padconf, u32_t mask, u32_t value)
void void
arch_padconf_init(void) arch_padconf_init(void)
{ {
kern_phys_map_ptr(omap_padconf.base, omap_padconf.size, int x;
&padconf_phys_map, (vir_bytes) &omap_padconf.base); omap_padconf = NULL;
/* find the correct padconf */
for (x =0 ; x < sizeof(omap_padconfs)/sizeof(omap_padconfs[0]) ; x++){
if ( (omap_padconfs[x].board_filter_mask & machine.board_id) == omap_padconfs[x].board_filter_value){
omap_padconf = &omap_padconfs[x];
break;
}
}
assert(omap_padconf);
kern_phys_map_ptr(omap_padconf->base, omap_padconf->size,
&padconf_phys_map, (vir_bytes) &omap_padconf->base);
return; return;
} }

View file

@ -2,6 +2,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/board.h>
#include <io.h> #include <io.h>
#include "kernel/kernel.h" #include "kernel/kernel.h"
@ -11,21 +12,17 @@
#include "arch_proto.h" #include "arch_proto.h"
#include "omap_reset.h" #include "omap_reset.h"
#ifdef AM335X #define AM335X_CM_BASE 0x44E00000
#define CM_BASE 0x44E00000 #define AM335X_CM_SIZE 0x1000
#define CM_SIZE 0x1000
#define PRM_DEVICE_OFFSET 0xf00 #define AM335X_PRM_DEVICE_OFFSET 0xf00
#define PRM_RSTCTRL_REG 0x00 #define AM335X_PRM_RSTCTRL_REG 0x00
#define RST_GLOBAL_WARM_SW_BIT 0 #define AM335X_RST_GLOBAL_WARM_SW_BIT 0
#elif DM37XX
#define CM_BASE 0x48307000 #define DM37XX_CM_BASE 0x48307000
#define CM_SIZE 0x1000 #define DM37XX_CM_SIZE 0x1000
#define PRM_RSTCTRL_REG 0x250 #define DM37XX_PRM_RSTCTRL_REG 0x250
#define RST_DPLL3_BIT 2 #define DM37XX_RST_DPLL3_BIT 2
#else
#define CM_BASE 0x00000000
#define CM_SIZE 0x1000
#endif
struct omap_reset struct omap_reset
{ {
@ -33,28 +30,32 @@ struct omap_reset
vir_bytes size; vir_bytes size;
}; };
static struct omap_reset omap_reset = { static struct omap_reset omap_reset;
.base = CM_BASE,
.size = CM_SIZE
};
static kern_phys_map reset_phys_map; static kern_phys_map reset_phys_map;
void void
omap3_reset_init(void) omap3_reset_init(void)
{ {
#if defined(AM335X) || defined(DM37XX)
if(BOARD_IS_BBXM(machine.board_id)){
omap_reset.base = DM37XX_CM_BASE;
omap_reset.size = DM37XX_CM_SIZE;
} else if(BOARD_IS_BB(machine.board_id)){
omap_reset.base = AM335X_CM_BASE;
omap_reset.size = AM335X_CM_SIZE;
}
kern_phys_map_ptr(omap_reset.base, omap_reset.size, &reset_phys_map, kern_phys_map_ptr(omap_reset.base, omap_reset.size, &reset_phys_map,
(vir_bytes) &omap_reset.base); (vir_bytes) &omap_reset.base);
#endif /* AM335X || DM37XX */
} }
void void
omap3_reset(void) omap3_reset(void)
{ {
#ifdef AM335X if(BOARD_IS_BBXM(machine.board_id)){
mmio_set((omap_reset.base + PRM_DEVICE_OFFSET + PRM_RSTCTRL_REG), (1 << RST_GLOBAL_WARM_SW_BIT)); mmio_set((omap_reset.base + DM37XX_PRM_RSTCTRL_REG), (1 << DM37XX_RST_DPLL3_BIT));
#elif DM37XX } else if(BOARD_IS_BB(machine.board_id)){
mmio_set((omap_reset.base + PRM_RSTCTRL_REG), (1 << RST_DPLL3_BIT)); mmio_set((omap_reset.base + AM335X_PRM_DEVICE_OFFSET + AM335X_PRM_RSTCTRL_REG), (1 << AM335X_RST_GLOBAL_WARM_SW_BIT));
#endif }
} }

View file

@ -9,6 +9,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/board.h>
#include <io.h> #include <io.h>
#include "kernel/kernel.h" #include "kernel/kernel.h"
@ -39,17 +40,17 @@ static kern_phys_map rtc_phys_map;
void void
omap3_rtc_init(void) omap3_rtc_init(void)
{ {
#ifdef AM335X if (BOARD_IS_BB(machine.board_id)){
kern_phys_map_ptr(omap_rtc.base, omap_rtc.size, &rtc_phys_map, kern_phys_map_ptr(omap_rtc.base, omap_rtc.size, &rtc_phys_map,
(vir_bytes) &omap_rtc.base); (vir_bytes) &omap_rtc.base);
#endif /* AM335X */ }
} }
void void
omap3_rtc_run(void) omap3_rtc_run(void)
{ {
#ifdef AM335X if (BOARD_IS_BB(machine.board_id)){
/* Setting the stop bit starts the RTC running */ /* Setting the stop bit starts the RTC running */
mmio_set((omap_rtc.base + RTC_CTRL_REG), (1 << RTC_CTRL_RTC_STOP_BIT)); mmio_set((omap_rtc.base + RTC_CTRL_REG), (1 << RTC_CTRL_RTC_STOP_BIT));
#endif /* AM335X */ }
} }

View file

@ -2,6 +2,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/board.h>
#include <io.h> #include <io.h>
#include "kernel/kernel.h" #include "kernel/kernel.h"
@ -41,13 +42,13 @@ static kern_phys_map serial_phys_map;
* The serial driver also gets used in the "pre_init" stage before the kernel is loaded * The serial driver also gets used in the "pre_init" stage before the kernel is loaded
* in high memory so keep in mind there are two copies of this code in the kernel. * in high memory so keep in mind there are two copies of this code in the kernel.
*/ */
void omap3_ser_init(){ void omap3_ser_init()
#ifdef DM37XX {
if(BOARD_IS_BBXM(machine.board_id)){
omap_serial.base = OMAP3_DM37XX_DEBUG_UART_BASE; omap_serial.base = OMAP3_DM37XX_DEBUG_UART_BASE;
#endif } else if (BOARD_IS_BB(machine.board_id)){
#ifdef AM335X
omap_serial.base = OMAP3_AM335X_DEBUG_UART_BASE; omap_serial.base = OMAP3_AM335X_DEBUG_UART_BASE;
#endif }
omap_serial.size = 0x1000 ; /* 4k */ omap_serial.size = 0x1000 ; /* 4k */

View file

@ -2,6 +2,7 @@
#include "kernel/clock.h" #include "kernel/clock.h"
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/board.h>
#include <minix/mmio.h> #include <minix/mmio.h>
#include <assert.h> #include <assert.h>
#include <io.h> #include <io.h>
@ -69,24 +70,6 @@ static struct omap_timer_registers regs_v1 = {
.TOWR = OMAP3_TIMER_TOWR, .TOWR = OMAP3_TIMER_TOWR,
}; };
#ifdef DM37XX
static struct omap_timer timer = {
.base = OMAP3_GPTIMER1_BASE,
.irq_nr = OMAP3_GPT1_IRQ,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer fr_timer = {
.base = OMAP3_GPTIMER10_BASE,
.irq_nr = OMAP3_GPT10_IRQ,
.regs = &regs_v1
};
#endif
#ifdef AM335X
/* AM335X has a different ip block for the non /* AM335X has a different ip block for the non
1ms timers */ 1ms timers */
static struct omap_timer_registers regs_v2 = { static struct omap_timer_registers regs_v2 = {
@ -112,8 +95,20 @@ static struct omap_timer_registers regs_v2 = {
.TOWR = -1 /* UNDEF */ .TOWR = -1 /* UNDEF */
}; };
static struct omap_timer dm37xx_timer = {
.base = OMAP3_GPTIMER1_BASE,
.irq_nr = OMAP3_GPT1_IRQ,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer dm37xx_fr_timer = {
.base = OMAP3_GPTIMER10_BASE,
.irq_nr = OMAP3_GPT10_IRQ,
.regs = &regs_v1
};
/* normal timer */ /* normal timer */
static struct omap_timer timer = { static struct omap_timer am335x_timer = {
.base = AM335X_DMTIMER1_1MS_BASE, .base = AM335X_DMTIMER1_1MS_BASE,
.irq_nr = AM335X_INT_TINT1_1MS, .irq_nr = AM335X_INT_TINT1_1MS,
.regs = &regs_v1 .regs = &regs_v1
@ -121,13 +116,15 @@ static struct omap_timer timer = {
}; };
/* free running timer */ /* free running timer */
static struct omap_timer fr_timer = { static struct omap_timer am335x_fr_timer = {
.base = AM335X_DMTIMER7_BASE, .base = AM335X_DMTIMER7_BASE,
.irq_nr = AM335X_INT_TINT7, .irq_nr = AM335X_INT_TINT7,
.regs = &regs_v2 .regs = &regs_v2
}; };
#endif static struct omap_timer *timer;
static struct omap_timer *fr_timer;
static int done = 0; static int done = 0;
@ -135,11 +132,11 @@ int omap3_register_timer_handler(const irq_handler_t handler)
{ {
/* Initialize the CLOCK's interrupt hook. */ /* Initialize the CLOCK's interrupt hook. */
omap3_timer_hook.proc_nr_e = NONE; omap3_timer_hook.proc_nr_e = NONE;
omap3_timer_hook.irq = timer.irq_nr; omap3_timer_hook.irq = timer->irq_nr;
put_irq_handler(&omap3_timer_hook, timer.irq_nr, handler); put_irq_handler(&omap3_timer_hook, timer->irq_nr, handler);
/* only unmask interrupts after registering */ /* only unmask interrupts after registering */
omap3_irq_unmask(timer.irq_nr); omap3_irq_unmask(timer->irq_nr);
return 0; return 0;
} }
@ -153,11 +150,24 @@ void omap3_frclock_init(void)
{ {
u32_t tisr; u32_t tisr;
kern_phys_map_ptr(fr_timer.base,ARM_PAGE_SIZE,
&fr_timer_phys_map, (vir_bytes) &fr_timer.base);
/* enable the clock */ /* enable the clock */
#ifdef AM335X if(BOARD_IS_BBXM(machine.board_id)){
fr_timer = &dm37xx_fr_timer;
kern_phys_map_ptr(fr_timer->base,ARM_PAGE_SIZE, &fr_timer_phys_map, (vir_bytes) &fr_timer->base);
/* Stop timer */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
/* Use functional clock source for GPTIMER10 */
mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
/* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */
/* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8.
*/
mmio_set(fr_timer->base + fr_timer->regs->TCLR, (2 << OMAP3_TCLR_PTV));
} else if(BOARD_IS_BB(machine.board_id)){
fr_timer = &am335x_fr_timer;
kern_phys_map_ptr(fr_timer->base,ARM_PAGE_SIZE, &fr_timer_phys_map, (vir_bytes) &fr_timer->base);
/* Disable the module and wait for the module to be disabled */ /* Disable the module and wait for the module to be disabled */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED); set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED);
while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE); while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE);
@ -168,46 +178,35 @@ void omap3_frclock_init(void)
/* enable the module and wait for the module to be ready */ /* enable the module and wait for the module to be ready */
set32(CM_PER_TIMER7_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE); set32(CM_PER_TIMER7_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE);
while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC); while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC);
#endif
/* Stop timer */ /* Stop timer */
mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
#ifdef DM37XX
/* Use functional clock source for GPTIMER10 */
mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
#endif
#ifdef DM37XX
/* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */
/* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8.
*/
mmio_set(fr_timer.base + fr_timer.regs->TCLR, (2 << OMAP3_TCLR_PTV));
#endif
#ifdef AM335X
/* 24Mhz / 16 = 1.5 Mhz */ /* 24Mhz / 16 = 1.5 Mhz */
mmio_set(fr_timer.base + fr_timer.regs->TCLR, (3 << OMAP3_TCLR_PTV)); mmio_set(fr_timer->base + fr_timer->regs->TCLR, (3 << OMAP3_TCLR_PTV));
#endif }
/* Start and auto-reload at 0 */ /* Start and auto-reload at 0 */
mmio_write(fr_timer.base + fr_timer.regs->TLDR, 0x0); mmio_write(fr_timer->base + fr_timer->regs->TLDR, 0x0);
mmio_write(fr_timer.base + fr_timer.regs->TCRR, 0x0); mmio_write(fr_timer->base + fr_timer->regs->TCRR, 0x0);
/* Set up overflow interrupt */ /* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(fr_timer.base + fr_timer.regs->TISR, tisr); /* Clear interrupt status */ mmio_write(fr_timer->base + fr_timer->regs->TISR, tisr); /* Clear interrupt status */
mmio_write(fr_timer.base + fr_timer.regs->TIER, OMAP3_TIER_OVF_IT_ENA); mmio_write(fr_timer->base + fr_timer->regs->TIER, OMAP3_TIER_OVF_IT_ENA);
/* Start timer */ /* Start timer */
mmio_set(fr_timer.base + fr_timer.regs->TCLR, mmio_set(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST|OMAP3_TCLR_PRE); OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST|OMAP3_TCLR_PRE);
done = 1; done = 1;
} }
void omap3_frclock_stop() void omap3_frclock_stop()
{ {
mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST); mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
} }
@ -215,9 +214,17 @@ void omap3_timer_init(unsigned freq)
{ {
/* we only support 1ms resolution */ /* we only support 1ms resolution */
u32_t tisr; u32_t tisr;
kern_phys_map_ptr(timer.base,ARM_PAGE_SIZE, if(BOARD_IS_BBXM(machine.board_id)){
&timer_phys_map, (vir_bytes) &timer.base); timer = &dm37xx_timer;
#ifdef AM335X kern_phys_map_ptr(timer->base,ARM_PAGE_SIZE, &timer_phys_map, (vir_bytes) &timer->base);
/* Stop timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
/* Use 32 KHz clock source for GPTIMER1 */
mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1);
} else if(BOARD_IS_BB(machine.board_id)){
timer = &am335x_timer;
kern_phys_map_ptr(timer->base,ARM_PAGE_SIZE, &timer_phys_map, (vir_bytes) &timer->base);
/* disable the module and wait for the module to be disabled */ /* disable the module and wait for the module to be disabled */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED); set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED);
while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE); while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE);
@ -230,43 +237,40 @@ void omap3_timer_init(unsigned freq)
/* enable the module and wait for the module to be ready */ /* enable the module and wait for the module to be ready */
set32(CM_WKUP_TIMER1_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE); set32(CM_WKUP_TIMER1_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE);
while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC); while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC);
#endif
/* Stop timer */
mmio_clear(timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST);
#ifdef DM37XX /* Stop timer */
/* Use 32 KHz clock source for GPTIMER1 */ mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1); }
#endif
/* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */ /* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */
mmio_write(timer.base + timer.regs->TPIR, 232000); mmio_write(timer->base + timer->regs->TPIR, 232000);
mmio_write(timer.base + timer.regs->TNIR, -768000); mmio_write(timer->base + timer->regs->TNIR, -768000);
mmio_write(timer.base + timer.regs->TLDR, 0xffffffff - (32768 / freq) +1); mmio_write(timer->base + timer->regs->TLDR, 0xffffffff - (32768 / freq) +1);
mmio_write(timer.base + timer.regs->TCRR, 0xffffffff - (32768 / freq) +1); mmio_write(timer->base + timer->regs->TCRR, 0xffffffff - (32768 / freq) +1);
/* Set up overflow interrupt */ /* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(timer.base + timer.regs->TISR, tisr); /* Clear interrupt status */ mmio_write(timer->base + timer->regs->TISR, tisr); /* Clear interrupt status */
mmio_write(timer.base + timer.regs->TIER, OMAP3_TIER_OVF_IT_ENA); mmio_write(timer->base + timer->regs->TIER, OMAP3_TIER_OVF_IT_ENA);
/* Start timer */ /* Start timer */
mmio_set(timer.base + timer.regs->TCLR, mmio_set(timer->base + timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST); OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST);
} }
void omap3_timer_stop() void omap3_timer_stop()
{ {
mmio_clear(timer.base + timer.regs->TCLR, OMAP3_TCLR_ST); mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
} }
static u32_t read_frc(void) static u32_t read_frc(void)
{ {
if (done == 0) if (done == 0)
return 0; return 0;
return mmio_read(fr_timer.base + fr_timer.regs->TCRR); return mmio_read(fr_timer->base + fr_timer->regs->TCRR);
} }
/* /*
@ -305,7 +309,7 @@ void omap3_timer_int_handler()
*/ */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(timer.base + timer.regs->TISR, tisr); mmio_write(timer->base + timer->regs->TISR, tisr);
now = read_frc(); now = read_frc();
frc_overflow_check(now); frc_overflow_check(now);

View file

@ -1,7 +1,6 @@
#ifndef _OMAP_TIMER_REGISTERS_H #ifndef _OMAP_TIMER_REGISTERS_H
#define _OMAP_TIMER_REGISTERS_H #define _OMAP_TIMER_REGISTERS_H
#ifdef DM37XX
/* General-purpose timer register map */ /* General-purpose timer register map */
#define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */ #define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */
@ -16,7 +15,6 @@
#define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */ #define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */
#define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */ #define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */
#endif /* DM37XX */
/* General-purpose timer registers */ /* General-purpose timer registers */
#define OMAP3_TIMER_TIDR 0x000 /* IP revision code */ #define OMAP3_TIMER_TIDR 0x000 /* IP revision code */
@ -40,7 +38,6 @@
#define OMAP3_TIMER_TOCR 0x054 /* Masks tick interrupt */ #define OMAP3_TIMER_TOCR 0x054 /* Masks tick interrupt */
#define OMAP3_TIMER_TOWR 0x058 /* Number of masked overflow interrupts */ #define OMAP3_TIMER_TOWR 0x058 /* Number of masked overflow interrupts */
#ifdef AM335X
#define AM335X_DMTIMER0_BASE 0x44E05000 /* DMTimer0 Registers */ #define AM335X_DMTIMER0_BASE 0x44E05000 /* DMTimer0 Registers */
#define AM335X_DMTIMER1_1MS_BASE 0x44E31000 /* DMTimer1 1ms Registers (Accurate 1ms timer) */ #define AM335X_DMTIMER1_1MS_BASE 0x44E31000 /* DMTimer1 1ms Registers (Accurate 1ms timer) */
#define AM335X_DMTIMER2_BASE 0x48040000 /* DMTimer2 Registers */ #define AM335X_DMTIMER2_BASE 0x48040000 /* DMTimer2 Registers */
@ -68,7 +65,6 @@
#define AM335X_TIMER_TSICR 0x054 /* Control posted mode and functional SW reset */ #define AM335X_TIMER_TSICR 0x054 /* Control posted mode and functional SW reset */
#define AM335X_TIMER_TCAR2 0x058 /* Second captured value of counter register */ #define AM335X_TIMER_TCAR2 0x058 /* Second captured value of counter register */
#endif
/* Interrupt status register fields */ /* Interrupt status register fields */
@ -88,7 +84,6 @@
#define OMAP3_TCLR_PTV 2 #define OMAP3_TCLR_PTV 2
#define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */ #define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */
#ifdef DM37XX
#define OMAP3_CM_CLKSEL_GFX 0x48004b40 #define OMAP3_CM_CLKSEL_GFX 0x48004b40
#define OMAP3_CM_CLKEN_PLL 0x48004d00 #define OMAP3_CM_CLKEN_PLL 0x48004d00
@ -98,9 +93,6 @@
#define OMAP3_CM_CLKSEL_PER 0x48005040 #define OMAP3_CM_CLKSEL_PER 0x48005040
#define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */ #define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */
#endif /* DM37XX */
#ifdef AM335X
#define CM_MODULEMODE_MASK (0x3 << 0) #define CM_MODULEMODE_MASK (0x3 << 0)
#define CM_MODULEMODE_ENABLE (0x2 << 0) #define CM_MODULEMODE_ENABLE (0x2 << 0)
@ -146,7 +138,6 @@
#endif /* AM335X */
#define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source #define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source
* clock: * clock: