您好,欢迎来到61ic! | [登录] [注册] 忘记密码 | 设为首页 帮助
 . 网站首页 . 业界新闻 . 设计中心 . 移动技术 . TI专栏 . ADI专栏 . FPGA专栏 . 代码工厂 . 官方商城 . 
 . 活动专区 . 新品快递 . 解决方案 . 前沿科技 . TI资源 . ADI资源 . FPGA资源 . 下载中心 . 产品展示 . 
加入收藏
付款方式
联系我们
您现在的位置: 61IC电子在线 >> TI专栏 >> TI DaVinci >> TMS320DM646x SOC >> 正文
  Davinci 引脚复用模块代码分析           ★★★ 【字体:
Davinci 引脚复用模块代码分析
作者:piaozhiy…    文章来源:piaozhiye    点击数:    更新时间:2013-12-6    

在分析davinci输出视频模块的时候(drivers/media/video/davinci/davincihd_display.c )有这个函数set_vpif_display_pinmux();顾名思义是将引脚复用配置成VPIF的显示功能,刚开始没有在意,后来多看几下就看得迷糊了,就做个分析笔记。

arch/arm/mach-davinci/video_hdevm.c 定义如下:

  1. 236 void set_vpif_display_pinmux()  
  2. 237 {  
  3. 238         davinci_cfg_reg(DM646X_STSOMUX_DISABLE);  
  4. 239         davinci_cfg_reg(DM646X_STSIMUX_DISABLE);  
  5. 240         davinci_cfg_reg(DM646X_PTSOMUX_DISABLE);  
  6. 241 }   

davinci_cfg_reg()是在arch/arm/mach-davinci/mux.c中定义的寄存器配置函数,其参数就是就是复用表的索引,如下:

  1. 100 enum davinci_dm646x_index {  
  2. 101         /* ATA function */  
  3. 102         DM646X_ATAEN,  
  4. 103   
  5. 104         /* USB */  
  6. 105         DM646X_VBUSDIS,  
  7. 106         DM646X_VBUSDIS_GPIO22,  
  8. 107   
  9. 108         /* STC source clock input */  
  10. 109         DM646X_STCCK,  
  11. 110   
  12. 111         /* AUDIO Clock */  
  13. 112         DM646X_AUDCK1,  
  14. 113         DM646X_AUDCK0,  
  15. 114   
  16. 115         /* CRGEN Control */  
  17. 116         DM646X_CRGMUX,  
  18. 117   
  19. 118         /* VPIF Control */  
  20. 119         DM646X_STSOMUX_DISABLE,  
  21. 120         DM646X_STSIMUX_DISABLE,  
  22. 121         DM646X_PTSOMUX_DISABLE,  
  23. 122         DM646X_PTSIMUX_DISABLE,  
  24.     ………………  
  25.     }  

因为其索引表是枚举类型的,也就是整数,就没弄明白它是什么样配置寄存器的。刚开始就很疑惑。后来经进一步分析发现是在/board-dm6467-evm.c 中初始化,以下是整理一下流程。

在arch/arm/mach-davinci/board-dm6467-evm.c 中初始化,将其编译进内核。最开始内核启动的时候就会打印出DaVinci DM6467 EVM字符串了。

  1. 380 MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM6467 EVM")  
  2. 381         .phys_io      = IO_PHYS,  
  3. 382         .io_pg_offst  = (io_p2v(IO_PHYS) >> 18) & 0xfffc,  
  4. 383         .boot_params  = (0x80000100),  
  5. 384         .map_io       = davinci_map_io,  
  6. 385         .init_irq     = davinci_dm6467_evm_irq_init,  
  7. 386         .timer        = &davinci_timer,  
  8. 387         .init_machine = dm6467_evm_init,  
  9. 388 MACHINE_END  

davinci_dm6467_evm_irq_init中调用davinci_init_common_hw()初始化公共硬件,函数如下,

  1. static __init void davinci_dm6467_evm_irq_init(void)  
  2. {  
  3.         davinci_init_common_hw();  
  4.         davinci_irq_init();  
  5. }  

 davinci_init_common_hw()在 arch/arm/mach-davinci/io.c 实现,主要是引脚复用初始化和时钟初始化。

  1. 55 void __init davinci_init_common_hw(void)  
  2. 56 {         
  3. 57         davinci_mux_init();  
  4. 58         davinci_clk_init();  
  5. 59 }     

davinci_mux_init()在arch/arm/mach-davinci/mux_cfg.c 中实现,代码如下:

调用在arch/arm/mach-davinci/mux.c 中实现的davinci_mux_register注册引脚复用表。

  1. 182 void __init davinci_mux_init(void)  
  2. 183 {  
  3. 184         if (cpu_is_davinci_dm355())  
  4. 185                 davinci_mux_register(davinci_dm355_pins,  
  5. 186                                         ARRAY_SIZE(davinci_dm355_pins));  
  6. 187         else if (cpu_is_davinci_dm6467())  
  7. 188                 davinci_mux_register(davinci_dm646x_pins,  
  8. 189                                         ARRAY_SIZE(davinci_dm646x_pins));  
  9. 190         else  
  10. 191                 davinci_mux_register(davinci_dm644x_pins,  
  11. 192                                         ARRAY_SIZE(davinci_dm644x_pins));  
  12. 193 }  

同时mux_cfg.c中也初始化了复用列表,一直想找到复用列表就在这里初始化

  1. 64 struct pin_config __initdata_or_module davinci_dm646x_pins[] = {  
  2. 65 /* 
  3. 66  *       description            mux  mode   mode  mux    dbg 
  4. 67  *                              reg  offset mask  mode 
  5. 68  */  
  6. 69 MUX_CFG("ATAEN",                 0,   0,     1,   1,     1)  
  7. 70   
  8. 71 MUX_CFG("VBUSDIS",               0,   31,    1,   0,     0)  
  9. 72   
  10. 73 MUX_CFG("VBUSDIS_GPIO22",        0,   31,    1,   1,     0)  
  11. 74   
  12. 75 MUX_CFG("STCCK",                 0,   30,    1,   1,     0)  
  13. 76   
  14. 77 MUX_CFG("AUDCK1",                0,   29,    1,   0,     0)  
  15. 78   
  16. 79 MUX_CFG("AUDCK0",                0,   28,    1,   0,     0)  
  17. 80   
  18. 81 MUX_CFG("CRGMUX",                0,   24,    7,   5,     0)  
  19. 82   
  20. 83 MUX_CFG("STSOMUX_DISABLE",       0,   22,    3,   0,     0)  
  21. 84   
  22. 85 MUX_CFG("STSIMUX_DISABLE",       0,   20,    3,   0,     0)  
  23. 86   
  24. 87 MUX_CFG("PTSOMUX_DISABLE",       0,   18,    3,   0,     0)  
  25. 88   
  26. 89 MUX_CFG("PTSIMUX_DISABLE",       0,   16,    3,   0,     0)  

MUX_CFG 就是在include/asm-arm/arch-davinci/mux.h 中的配置宏

  1. 34 #define MUX_CFG(desc, mux_reg, mode_offset, mode_mask, mux_mode, dbg) \  
  2. 35 { \  
  3. 36         .name =  desc, \  
  4. 37         .debug = dbg, \  
  5. 38         MUX_REG(mux_reg, mode_offset, mode_mask, mux_mode) \  
  6. 39 },  

arch/arm/mach-davinci/mux.c 提供了复用的注册和寄存器的配置的接口,具体如下:

  1. 28 int __init davinci_mux_register(struct pin_config *pins, unsigned long size)  
  2. 29 {  
  3. 30         pin_table = pins;  
  4. 31         pin_table_sz = size;  
  5. 32                   
  6. 33         return 0;                         
  7. 34 }         
  8. 35      
  9. 36 /* 
  10. 37  * Sets the DAVINCI MUX register based on the table 
  11. 38  */  
  12. 39 int __init_or_module davinci_cfg_reg(const unsigned long index)  
  13. 40 {  
  14. 41         static DEFINE_SPINLOCK(mux_spin_lock);  
  15. 42   
  16. 43         unsigned long flags;  
  17. 44         struct pin_config *cfg;  
  18. 45         unsigned int reg_orig = 0, reg = 0;  
  19. 46         unsigned int mask, warn = 0;  
  20. 47   
  21. 48         if (!pin_table)  
  22. 49                 BUG();  
  23. 50   
  24. 51         if (index >= pin_table_sz) {  
  25. 52                 printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",  
  26. 53                        index, pin_table_sz);  
  27. 54                 dump_stack();  
  28. 55                 return -ENODEV;  
  29. 56         }  
  30. 57   
  31. 58         cfg = (struct pin_config *)&pin_table[index];  
  32. 59   
  33. 60         /* Check the mux register in question */  
  34. 61         if (cfg->mux_reg) {  
  35. 62                 unsigned        tmp1, tmp2;  
  36. 63   
  37. 64                 spin_lock_irqsave(&mux_spin_lock, flags);  
  38. 65                 reg_orig = davinci_readl(cfg->mux_reg);  
  39. 66   
  40. 67                 mask = (cfg->mask << cfg->mask_offset);  
  41. 68                 tmp1 = reg_orig & mask;  
  42. 69                 reg = reg_orig & ~mask;  
  43. 70   
  44. 71                 tmp2 = (cfg->mode << cfg->mask_offset);  
  45. 72                 reg |= tmp2;  
  46. 73   
  47. 74                 if (tmp1 != tmp2)  
  48. 75                         warn = 1;  
  49. 76   
  50. 77                 davinci_writel(reg, cfg->mux_reg);  
  51. 78                 spin_unlock_irqrestore(&mux_spin_lock, flags);  
  52. 79         }  
  53. 80   
  54. 81         if (warn) {  
  55. 82 #ifdef CONFIG_DAVINCI_MUX_WARNINGS  
  56. 83             printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);  
  57. 84 #endif  
  58. 85         }  
  59. 86   
  60. 87 #ifdef CONFIG_DAVINCI_MUX_DEBUG  
  61. 88         if (cfg->debug || warn) {  
  62. 89                 printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);  
  63. 90                 printk(KERN_WARNING "      %s (0x%08x) = 0x%08x -> 0x%08x\n",  
  64. 91                        cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);  
  65. 92         }  
  66. 93 #endif  
  67. 94   
  68. 95         return 0;  
  69. 96 }  
  70. 97 EXPORT_SYMBOL(davinci_cfg_reg);  

它的流程就是这样,使用的时候就像以下代码:
  1. 236 void set_vpif_display_pinmux()  
  2. 237 {  
  3. 238         davinci_cfg_reg(DM646X_STSOMUX_DISABLE);  
  4. 239         davinci_cfg_reg(DM646X_STSIMUX_DISABLE);  
  5. 240         davinci_cfg_reg(DM646X_PTSOMUX_DISABLE);  
  6. 241 }   
文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    解决Sending DHCP and RARP …
    关于DM6467由5150导致 I2C t…
    改变DM6467的内存划分
    DM6467硬件安装
    基于DM6467的TVP7002 Linux驱…
    DM6467的CAN模块调试(SPI转…
    移植EMCV到DM6467(1)——C++…
    移植EMCV到DM6467(2)——Ope…
    移植EMCV到DM6467(3)——CCS…
    移植EMCV到DM6467(4)——vid…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61 湘ICP备13001086号-2