Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 4c754f6 in mainline


Ignore:
Timestamp:
2013-02-11T22:55:29Z (9 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master
Children:
0f66886
Parents:
40762c6
Message:

Improve the dmtimer modules initialization.

Location:
kernel
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/src/mach/beaglebone/beaglebone.c

    r40762c6 r4c754f6  
    11/*
    22 * Copyright (c) 2012 Matteo Facchinetti
     3 * Copyright (c) 2012 Maurizio Lombardi
    34 * All rights reserved.
    45 *
     
    3839#include <genarch/drivers/am335x/uart.h>
    3940#include <genarch/drivers/am335x/timer.h>
     41#include <genarch/drivers/am335x/cm_per.h>
     42#include <genarch/drivers/am335x/cm_dpll.h>
     43#include <genarch/drivers/am335x/ctrl_module.h>
    4044#include <genarch/srln/srln.h>
    4145#include <interrupt.h>
     
    6064static struct beaglebone {
    6165        am335x_irc_regs_t *irc_addr;
     66        am335x_cm_per_regs_t *cm_per_addr;
     67        am335x_cm_dpll_regs_t *cm_dpll_addr;
     68        am335x_ctrl_module_t  *ctrl_module;
    6269        am335x_timer_t timer;
    6370        am335x_uart_t uart;
     
    7986static void bbone_init(void)
    8087{
    81         /* Initialize the interrupt controller */
    8288        bbone.irc_addr = (void *) km_map(AM335x_IRC_BASE_ADDRESS,
    8389            AM335x_IRC_SIZE, PAGE_NOT_CACHEABLE);
    8490
     91        bbone.cm_per_addr = (void *) km_map(AM335x_CM_PER_BASE_ADDRESS,
     92            AM335x_CM_PER_SIZE, PAGE_NOT_CACHEABLE);
     93
     94        bbone.cm_dpll_addr = (void *) km_map(AM335x_CM_DPLL_BASE_ADDRESS,
     95            AM335x_CM_DPLL_SIZE, PAGE_NOT_CACHEABLE);
     96
     97        bbone.ctrl_module = (void *) km_map(AM335x_CTRL_MODULE_BASE_ADDRESS,
     98            AM335x_CTRL_MODULE_SIZE, PAGE_NOT_CACHEABLE);
     99
     100        /* Initialize the interrupt controller */
    85101        am335x_irc_init(bbone.irc_addr);
    86102}
     
    105121        irq_initialize(&timer_irq);
    106122        timer_irq.devno = device_assign_devno();
    107         timer_irq.inr = AM335x_DMTIMER0_IRQ;
     123        timer_irq.inr = AM335x_DMTIMER2_IRQ;
    108124        timer_irq.claim = bbone_timer_irq_claim;
    109125        timer_irq.handler = bbone_timer_irq_handler;
    110126        irq_register(&timer_irq);
    111127
    112         /* Initialize the DMTIMER0 */
    113         am335x_timer_init(&bbone.timer, DMTIMER0, HZ);
     128        /* Enable the DMTIMER2 clock module */
     129        am335x_clock_module_enable(bbone.cm_per_addr, DMTIMER2);
     130        /* Select the SYSCLK as the clock source for the dmtimer2 module */
     131        am335x_clock_source_select(bbone.cm_dpll_addr, DMTIMER2,
     132           CLK_SRC_M_OSC);
     133        /* Initialize the DMTIMER2 */
     134        am335x_timer_init(&bbone.timer, DMTIMER2, HZ,
     135            am335x_ctrl_module_clock_freq_get(bbone.ctrl_module));
    114136        /* Enable the interrupt */
    115         am335x_irc_enable(bbone.irc_addr, AM335x_DMTIMER0_IRQ);
     137        am335x_irc_enable(bbone.irc_addr, AM335x_DMTIMER2_IRQ);
    116138        /* Start the timer */
    117139        am335x_timer_start(&bbone.timer);
  • kernel/genarch/include/drivers/am335x/cm_dpll.h

    r40762c6 r4c754f6  
    3737#define _KERN_AM335X_CM_DPLL_H_
    3838
    39 #include <drivers/am335x/cm_dpll_regs.h>
     39#include "cm_dpll_regs.h"
     40#include "timer.h"
    4041
    4142#define AM335x_CM_DPLL_BASE_ADDRESS   0x44E00500
    4243#define AM335x_CM_DPLL_SIZE           256
     44
     45static ioport32_t *am335x_cm_dpll_timer_reg_get(am335x_cm_dpll_regs_t *cm,
     46    am335x_timer_id_t id)
     47{
     48        switch (id) {
     49        default:
     50                return NULL;
     51        case DMTIMER2:
     52                return &cm->clksel_timer2;
     53        case DMTIMER3:
     54                return &cm->clksel_timer3;
     55        case DMTIMER4:
     56                return &cm->clksel_timer4;
     57        case DMTIMER5:
     58                return &cm->clksel_timer5;
     59        case DMTIMER6:
     60                return &cm->clksel_timer6;
     61        case DMTIMER7:
     62                return &cm->clksel_timer7;
     63        }
     64}
     65
     66static void am335x_clock_source_select(am335x_cm_dpll_regs_t *cm,
     67    am335x_timer_id_t id, am335x_clk_src_t src)
     68{
     69        ioport32_t *reg = am335x_cm_dpll_timer_reg_get(cm, id);
     70        if (!reg)
     71                return;
     72
     73        *reg = (*reg & ~0x03) | src;
     74}
    4375
    4476#endif
  • kernel/genarch/include/drivers/am335x/cm_dpll_regs.h

    r40762c6 r4c754f6  
    3737#define _KERN_AM335X_CM_DPLL_REGS_H_
    3838
    39 #define AM335x_CM_CLKSEL_TIMERS_CLK32KHZ    0x02
    40 #define AM335x_CM_CLKSEL_TIMERS_CLKMOSC     0x01
    41 #define AM335x_CM_CLKSEL_TIMERS_TCLKIN      0x00
     39typedef enum {
     40        CLK_SRC_TCLKIN = 0x00,
     41        CLK_SRC_M_OSC,
     42        CLK_SRC_32_KHZ
     43} am335x_clk_src_t;
    4244
    4345typedef struct am335x_cm_dpll_regs {
     
    7678        ioport32_t clksel_gpio0_db;
    7779
    78 
    7980} am335x_cm_dpll_regs_t;
    8081
  • kernel/genarch/include/drivers/am335x/cm_per_regs.h

    r40762c6 r4c754f6  
    3737#define _KERN_AM335X_CM_PER_REGS_H_
    3838
     39#include <typedefs.h>
     40
    3941typedef struct am335x_cm_per_regs {
    4042
     
    145147#define AM335x_CM_PER_MMC0_CLKCTRL_IDLEST_SHIFT     16
    146148
    147         ioport32_ elm_clkctrl;
     149        ioport32_t elm_clkctrl;
    148150#define AM335x_CM_PER_ELM_CLKCTRL_MODULEMODE_MASK  0x3
    149151#define AM335x_CM_PER_ELM_CLKCTRL_MODULEMODE_SHIFT 0
     
    406408        ioport32_t const pad7[2];
    407409
    408         ioport32_t l3_clkstctrl;
    409 #define AM335x_CM_PER_L3_CLKSTCTRL_CLKTRCTRL_MASK     0x3
    410 #define AM335x_CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SHIFT    0
    411 #define AM335x_CM_PER_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_FLAG (1 << 4)
    412 #define AM335x_CM_PER_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_FLAG (1 << 5)
     410        ioport32_t ocpwp_l3_clkstctrl;
     411#define AM335x_CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_MASK     0x3
     412#define AM335x_CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SHIFT    0
     413#define AM335x_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_FLAG (1 << 4)
     414#define AM335x_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_FLAG (1 << 5)
    413415
    414416        ioport32_t ocpwp_clkctrl;
  • kernel/genarch/include/drivers/am335x/ctrl_module.h

    r40762c6 r4c754f6  
    3737#define _KERN_AM335X_CTRL_MODULE_H_
    3838
    39 #include <drivers/am335x/ctrl_module_regs.h>
     39#include <typedefs.h>
     40#include "ctrl_module_regs.h"
    4041
    4142#define AM335x_CTRL_MODULE_BASE_ADDRESS  0x44E10000
    4243#define AM335x_CTRL_MODULE_SIZE          131072 /* 128 Kb */
    4344
    44 static unsigned am335x_ctrl_module_clock_freq_get(void *base)
     45typedef ioport32_t am335x_ctrl_module_t;
     46
     47static unsigned am335x_ctrl_module_clock_freq_get(am335x_ctrl_module_t *base)
    4548{
    46         unsigned const control_status = AM335x_CTRL_MODULE_REG_ADDR(base,
     49        unsigned const control_status = *AM335x_CTRL_MODULE_REG_ADDR(base,
    4750            CONTROL_SYSCONFIG);
    4851        unsigned const sysboot1 = (control_status >> 22) & 0x03;
    4952
    50         switch (sysboot) {
     53        switch (sysboot1) {
    5154        default:
    5255        case 0:
  • kernel/genarch/include/drivers/am335x/timer.h

    r40762c6 r4c754f6  
    3737#define _KERN_AM335X_TIMER_H_
    3838
    39 #include "timer_regs.h"
     39#include <genarch/drivers/am335x/timer_regs.h>
    4040
    4141#define AM335x_DMTIMER0_BASE_ADDRESS    0x44E05000
     
    8686
    8787extern void am335x_timer_init(am335x_timer_t *timer, am335x_timer_id_t id,
    88     unsigned hz);
     88    unsigned hz, unsigned srcclk_hz);
    8989extern void am335x_timer_intr_ack(am335x_timer_t *timer);
    9090extern void am335x_timer_reset(am335x_timer_t *timer);
  • kernel/genarch/src/drivers/am335x/timer.c

    r40762c6 r4c754f6  
    5656
    5757void
    58 am335x_timer_init(am335x_timer_t *timer, am335x_timer_id_t id, unsigned hz)
     58am335x_timer_init(am335x_timer_t *timer, am335x_timer_id_t id, unsigned hz,
     59    unsigned srcclk_hz)
    5960{
    6061        uintptr_t base_addr;
     
    8687        regs->tclr |= AM335x_TIMER_TCLR_AR_FLAG;
    8788
    88         /* XXX Here we assume that the timer clock source
    89          * is running at 32 Khz but this is not always the
    90          * case; DMTIMER[2 - 7] can use the internal system 24 Mhz
    91          * clock source or an external clock also.
    92          */
    93         unsigned const count = 0xFFFFFFFE - 32768 / hz;
     89        /* Disable the emulation mode */
     90        regs->tiocp_cfg |= AM335x_TIMER_TIOCPCFG_EMUFREE_FLAG;
     91
     92        unsigned const count = 0xFFFFFFFE - (srcclk_hz / hz);
    9493        regs->tcrr = count;
    9594        regs->tldr = count;
Note: See TracChangeset for help on using the changeset viewer.