Chinaunix首页 | 论坛 | 博客
  • 博客访问: 203218
  • 博文数量: 68
  • 博客积分: 529
  • 博客等级: 中士
  • 技术积分: 721
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-10 16:38
文章分类

全部博文(68)

文章存档

2014年(2)

2013年(4)

2012年(16)

2011年(34)

2010年(4)

2009年(8)

分类: LINUX

2011-09-07 18:38:01

1) device power management introduction
   three levels of resource management:
   clock, power, and valtage
 
clock:
   a) interface clock _ICLK
   b) function clock  _FCLK
 
2) module-level clock management
 
|--master satandby protocol:CM___CLKCTRL[x].STBYST
|--slave standby protocol:  Cm___CLKCTRL[x].IDLEST
 
3) module wake-up request:
 
   slave module --> wake-up request --> PRCM
   
   PRCM --> activates the module clocks and acknowledges the module wake-up request.
 
4) clock domain
 
   CM__CLKSTCTRl[x] CLKACTIVITY_
 
   clock domain state transitions
   CM__CLKSTCTRL[x] CLKTRCTRL
 
5) Clock domain HW_ATTO Mode sequences

主要数据结构:
  1. struct power_state {
  2.     struct powerdomain *pwrdm;
  3.     u32 next_state;
  4. #ifdef CONFIG_SUSPEND
  5.     u32 saved_state;
  6.     u32 saved_logic_state;
  7. #endif
  8.     struct list_head node;
  9. };
pwrst_list 构建:

  1. static int __init omap4_pm_init(void)
  2. {
  3.     int ret;
  4.     int ram_addr;

  5.     if (!cpu_is_omap44xx())
  6.         return -ENODEV;

  7.     /*
  8.      * Keep volt/device off disabled by default
  9.      * on 446x.
  10.      */
  11.     if (cpu_is_omap446x())
  12.         volt_off_mode = 0;
  13.     else
  14.         volt_off_mode = 1;

  15.     enable_off_mode = 0;

  16.     pr_err("Power Management for TI OMAP4.\n");
  17.     mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
  18.     cpu0_pwrdm = pwrdm_lookup("cpu0_pwrdm");
  19.     cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
  20.     core_pwrdm = pwrdm_lookup("core_pwrdm");
  21.     per_pwrdm = pwrdm_lookup("l4per_pwrdm");


  22. #ifdef CONFIG_PM
  23.     prcm_setup_regs();
  24.     prcm_clear_statdep_regs();

  25.     ret = request_irq(OMAP44XX_IRQ_PRCM,
  26.              (irq_handler_t)prcm_interrupt_handler,
  27.              IRQF_DISABLED, "prcm", NULL);
  28.     if (ret) {
  29.         printk(KERN_ERR "request_irq failed to register for 0x%x\n",
  30.          OMAP44XX_IRQ_PRCM);
  31.         goto err2;
  32.     }

  33.     so_ram_address = (void *)dma_alloc_so_coherent(NULL, 1024,
  34.             (dma_addr_t *)&ram_addr, GFP_KERNEL);

  35.     if (!so_ram_address) {
  36.         printk ("omap4_pm_init: failed to allocate SO mem.\n");
  37.         return -ENOMEM;
  38.     }

  39.     ret = pwrdm_for_each(pwrdms_setup, NULL); //对于每个power domain 创建power stat
  40.     if (ret) {
  41.         pr_err("Failed to setup powerdomains\n");
  42.         goto err2;
  43.     }

  44.     mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
  45.     if (!mpu_pwrdm) {
  46.         printk(KERN_ERR "Failed to get lookup for MPU pwrdm's\n");
  47.         goto err2;
  48.     }

  49.     (void) clkdm_for_each(clkdms_setup, NULL);

  50.     /* Get handles for VDD's for enabling/disabling SR */
  51.     vdd_mpu = omap_voltage_domain_get("mpu");
  52.     if (IS_ERR(vdd_mpu)) {
  53.         printk(KERN_ERR "Failed to get handle for VDD MPU\n");
  54.         goto err2;
  55.     }

  56.     vdd_iva = omap_voltage_domain_get("iva");
  57.     if (IS_ERR(vdd_iva)) {
  58.         printk(KERN_ERR "Failed to get handle for VDD IVA\n");
  59.         goto err2;
  60.     }

  61.     vdd_core = omap_voltage_domain_get("core");
  62.     if (IS_ERR(vdd_core)) {
  63.         printk(KERN_ERR "Failed to get handle for VDD CORE\n");
  64.         goto err2;
  65.     }

  66.     omap4_mpuss_init();
  67.     omap4_pm_off_mode_enable(enable_off_mode);
  68. #endif

  69. #ifdef CONFIG_SUSPEND
  70.     suspend_set_ops(&omap_pm_ops);
  71. #endif /* CONFIG_SUSPEND */

  72.     omap4_idle_init();
  73.     omap4_trigger_ioctrl();

  74. err2:
  75.     return ret;
  76. }
  1. static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
  2. {
  3.     struct power_state *pwrst;

  4.     if (!pwrdm->pwrsts)
  5.         return 0;

  6.     pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
  7.     if (!pwrst)
  8.         return -ENOMEM;
  9.     pwrst->pwrdm = pwrdm;
  10.     if ((!strcmp(pwrdm->name, mpu_pwrdm->name)) ||
  11.             (!strcmp(pwrdm->name, core_pwrdm->name)) ||
  12.             (!strcmp(pwrdm->name, cpu0_pwrdm->name)) ||
  13.             (!strcmp(pwrdm->name, cpu1_pwrdm->name)))
  14.         pwrst->next_state = PWRDM_POWER_ON;  // 
  15.     else
  16.         pwrst->next_state = PWRDM_POWER_RET;
  17.     list_add(&pwrst->node, &pwrst_list);
  18.      /* 核心的power domain 的电源状态设置为 PWRDM_POWER_ON, 其他的设置成 PWRDM_POWER_RET × /

  19.     return omap4_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
  20. }






  1.  omap4 power domain  的定义
    1. static struct powerdomain *powerdomains_omap[] __initdata = {
    2. #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
    3. &wkup_omap2_pwrdm,
    4. &gfx_omap2_pwrdm,
    5. #endif
    6. #ifdef CONFIG_ARCH_OMAP2
    7. &dsp_pwrdm,
    8. &mpu_24xx_pwrdm,
    9. &core_24xx_pwrdm,
    10. #endif
    11. #ifdef CONFIG_ARCH_OMAP2430
    12. &mdm_pwrdm,
    13. #endif
    14. #ifdef CONFIG_ARCH_OMAP3
    15. &iva2_pwrdm,
    16. &mpu_3xxx_pwrdm,
    17. &neon_pwrdm,
    18. &core_3xxx_pre_es3_1_pwrdm,
    19. &core_3xxx_es3_1_pwrdm,
    20. &cam_pwrdm,
    21. &dss_pwrdm,
    22. &per_pwrdm,
    23. &emu_pwrdm,
    24. &sgx_pwrdm,
    25. &usbhost_pwrdm,
    26. &dpll1_pwrdm,
    27. &dpll2_pwrdm,
    28. &dpll3_pwrdm,
    29. &dpll4_pwrdm,
    30. &dpll5_pwrdm,
    31. #endif
    32. #ifdef CONFIG_ARCH_OMAP4
    33. &core_44xx_pwrdm,
    34. &gfx_44xx_pwrdm,
    35. &abe_44xx_pwrdm,
    36. &dss_44xx_pwrdm,
    37. &tesla_44xx_pwrdm,
    38. &wkup_44xx_pwrdm,
    39. &cpu0_44xx_pwrdm,
    40. &cpu1_44xx_pwrdm,
    41. &emu_44xx_pwrdm,
    42. &mpu_443x_pwrdm,
    43. &mpu_446x_pwrdm,
    44. &ivahd_44xx_pwrdm,
    45. &cam_44xx_pwrdm,
    46. &l3init_44xx_pwrdm,
    47. &l4per_44xx_pwrdm,
    48. &always_on_core_44xx_pwrdm,
    49. &cefuse_44xx_pwrdm,
    50. #endif
    51. NULL
    52. };
   power domain list  的构建:
   static void __init omap_4430sdp_init_irq(void) 调用

void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1)
调用
pwrdm_init(powerdomains_omap, &omap4_pwrdm_functions);


  1. void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_functions * custom_funcs)
  2. {
  3.     struct powerdomain **p = NULL;

  4.     /*Initialise the global latency constraint mutex */
  5.     mutex_init(&global_wakeuplat_mutex);

  6.     if (!custom_funcs) {
  7.         printk(KERN_ERR "No custom pwrdm functions registered\n");
  8.         BUG();
  9.     }

  10.     arch_pwrdm = custom_funcs;

  11.     if (pwrdm_list) {
  12.         for (p = pwrdm_list; *p; p++)
  13.             _pwrdm_register(*p);  //这个函数将把list  建起了
  14.     }
  15. }





  
 
 
 
 
 
 
 
 
 
 
 
阅读(1213) | 评论(0) | 转发(0) |
0

上一篇:omap4430 cpuidle

下一篇:hardware study

给主人留下些什么吧!~~