Chinaunix首页 | 论坛 | 博客
  • 博客访问: 36843
  • 博文数量: 17
  • 博客积分: 105
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-05 14:15
文章分类

全部博文(17)

文章存档

2012年(17)

我的朋友

分类: LINUX

2012-05-06 15:49:46

1、时钟节拍的产生
/* linux/arch/arm/plat-s3c/time.c

点击(此处)折叠或打开

  1. MACHINE_START(SMDK6410, "LDD6410")
  2.     /* Maintainer: Barry Song <21cnbao@gmail.com> */
  3.     .phys_io    = S3C_PA_UART & 0xfff00000,
  4.     .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
  5.     .boot_params    = S3C64XX_PA_SDRAM 0x100,

  6.     .init_irq    = s3c6410_init_irq,
  7.     .map_io        = ldd6410_map_io,
  8.     .init_machine    = ldd6410_machine_init,
  9.     .timer        = &s3c64xx_timer,
  10. MACHINE_END

  1. struct sys_timer s3c64xx_timer = {
  2.     .init        = s3c64xx_timer_init,
  3.     .offset        = s3c2410_gettimeoffset,
  4.     .resume        = s3c64xx_timer_setup
  5. };

  1. static void __init s3c64xx_timer_init(void)
  2. {
  3.     s3c64xx_timer_setup();
  4.     setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
  5. }


点击(此处)折叠或打开

  1. static void s3c64xx_timer_setup (void)
  2. {
  3.     unsigned long tcon;
  4.     unsigned long tcnt;
  5.     unsigned long tcfg1;
  6.     unsigned long tcfg0;

  7.     tcnt = TICK_MAX; /* default value for tcnt */

  8.     /* read the current timer configuration bits */

  9.     tcon = __raw_readl(S3C2410_TCON);
  10.     tcfg1 = __raw_readl(S3C2410_TCFG1);
  11.     tcfg0 = __raw_readl(S3C2410_TCFG0);

  12.     /* configure the system for whichever machine is in use */

  13.     if (use_tclk1_12()) {
  14.         /* timer is at 12MHz, scaler is 1 */
  15.         timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
  16.         tcnt = 12000000 / HZ;

  17.         tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
  18.         tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
  19.     } else {
  20.         unsigned long pclk;
  21.         struct clk *clk;

  22.         /* for the h1940 (and others), we use the pclk from the core
  23.          * to generate the timer values. since values around 50 to
  24.          * 70MHz are not values we can directly generate the timer
  25.          * value from, we need to pre-scale and divide before using it.
  26.          *
  27.          * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
  28.          * (8.45 ticks per usec)
  29.          */

  30.         /* this is used as default if no other timer can be found */

  31.         clk = clk_get(NULL, "timers");
  32.         if (IS_ERR(clk))
  33.             panic("failed to get clock for system timer");

  34.         clk_enable(clk);

  35.         pclk = clk_get_rate(clk);

  36.         /* configure clock tick */

  37.         timer_usec_ticks = timer_mask_usec_ticks(6, pclk);

  38.         tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
  39.         tcfg1 |= S3C2410_TCFG1_MUX4_DIV1;

  40.         tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
  41.         tcfg0 |= (6) << S3C2410_TCFG_PRESCALER1_SHIFT;

  42.         tcnt = (pclk / 7) / HZ;
  43.     }

  44.     /* timers reload after counting zero, so reduce the count by 1 */

  45.     tcnt--;

  46.     printk(KERN_DEBUG "timer tcon=lx, tcnt lx, tcfg lx,lx, usec lx\n",
  47.      tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);

  48.     /* check to see if timer is within 16bit range... */
  49.     if (tcnt > TICK_MAX) {
  50.         panic("setup_timer: HZ is too small, cannot configure timer!");
  51.         return;
  52.     }

  53.     __raw_writel(tcfg1, S3C2410_TCFG1);
  54.     __raw_writel(tcfg0, S3C2410_TCFG0);

  55.     timer_startval = tcnt;
  56.     __raw_writel(tcnt, S3C2410_TCNTB(4));

  57.     /* ensure timer is stopped... */

  58.     tcon &= ~(7<<20);
  59.     tcon |= S3C2410_TCON_T4RELOAD;
  60.     tcon |= S3C2410_TCON_T4MANUALUPD;

  61.     __raw_writel(tcon, S3C2410_TCON);
  62.     __raw_writel(tcnt, S3C2410_TCNTB(4));
  63.     __raw_writel(tcnt, S3C2410_TCMPB(4));

  64.     /* start the timer running */
  65.     tcon |= S3C2410_TCON_T4START;
  66.     tcon &= ~S3C2410_TCON_T4MANUALUPD;
  67.     __raw_writel(tcon, S3C2410_TCON);

  68.     /* Timer interrupt Enable */
  69.     __raw_writel(__raw_readl(S3C64XX_TINT_CSTAT) | S3C_TINT_CSTAT_T4INTEN , S3C64XX_TINT_CSTAT);
  70. }



阅读(1189) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~