• I.MX6 U-boot PWM hacking


    /*******************************************************************************
     *                          I.MX6 U-boot PWM hacking
     * 说明:
     *     本文主要记录I.MX6 U-boot是如何配置PWM,发现文中的pwm0对应的引脚和真正的
     * 电路板的pwm0不是一个,也就意味着其实是引脚连接错了,另外之前一直有一个
     * 疑问:为什么双屏显示的时候,有一个屏在U-boot阶段和Kernel阶段总是不亮。原因
     * 应该是这里只初始化了一个显示控制部分,也就是不会初始两个PWM。
     *
     *                                          2016-3-7 深圳 南山平山村 曾剑锋
     ******************************************************************************/
    
    cat bootable/bootloader/uboot-imx/board/freescale/mx6q_sabresd/mx6q_sabresd.c                       
        ......                                                                                          
        #ifdef CONFIG_LCD                                                                               
        void lcd_enable(void)                                                                           
        {                                                                                               
            ......                                                                                      
            imx_pwm_config(pwm0, 25000, 50000);                     ------------+                       
            imx_pwm_enable(pwm0);                                   ------------*-+                     
                                                                                | |                     
            #if defined CONFIG_MX6Q                                             | |                     
            /* PWM backlight */                                                 | |                     
            mxc_iomux_v3_setup_pad(MX6Q_PAD_SD1_DAT3__PWM1_PWMO);               | |                     
            /* LVDS panel CABC_EN0 */                                           | |                     
            mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS2__GPIO_6_15);              | |                     
            /* LVDS panel CABC_EN1 */                                           | |                     
            mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS3__GPIO_6_16);              | |                     
            #elif defined CONFIG_MX6DL                                          | |                     
            /* PWM backlight */                                                 | |                     
            mxc_iomux_v3_setup_pad(MX6DL_PAD_SD1_DAT3__PWM1_PWMO);              | |                     
            /* LVDS panel CABC_EN0 */                                           | |                     
            mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS2__GPIO_6_15);             | |                     
            /* LVDS panel CABC_EN1 */                                           | |                     
            mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS3__GPIO_6_16);             | |                     
            #endif                                                              | |                     
            ......                                                              | |                     
        }                                                                       | |                     
        ......                                                                  | |                     
                                                                                | |                     
    static struct pwm_device pwm0 = {                               <-----------+ |                     
        .pwm_id = 0,                                                            | |                     
        .pwmo_invert = 0,                                                       | |                     
    };                                                                          | |                     
                                                                                | |                     
                                                                                | |                     
    int imx_pwm_config(struct pwm_device pwm, int duty_ns, int period_ns)  <----+ |                     
    {                                                                             |                     
        unsigned long long c;                                                     |                     
        unsigned long period_cycles, duty_cycles, prescale;                       |                     
        u32 cr;                                                                   |                     
                                                                                  |                     
        if (period_ns == 0 || duty_ns > period_ns)                                |                     
            return -1;                                                            |                     
                                                                                  |                     
        pwm.mmio_base = pwm.pwm_id ? (unsigned long)IMX_PWM2_BASE:                |                     
                    (unsigned long)IMX_PWM1_BASE;                                 |                     
                                                                                  |                     
        if (pwm.pwmo_invert)                                                      |                     
            duty_ns = period_ns - duty_ns;                                        |                     
                                                                                  |                     
        c = mxc_get_clock(MXC_IPG_PERCLK);                                        |                     
        c = c * period_ns;                                                        |                     
        do_div(c, 1000000000);                                                    |                     
        period_cycles = c;                                                        |                     
                                                                                  |                     
        prescale = period_cycles / 0x10000 + 1;                                   |                     
                                                                                  |                     
        period_cycles /= prescale;                                                |                     
        c = (unsigned long long)period_cycles * duty_ns;                          |                     
        do_div(c, period_ns);                                                     |                     
        duty_cycles = c;                                                          |                     
                                                                                  |                     
        writel(duty_cycles, pwm.mmio_base + MX_PWMSAR);                           |                     
        writel(period_cycles, pwm.mmio_base + MX_PWMPR);                          |                     
                                                                                  |                     
        cr = MX_PWMCR_PRESCALER(prescale) |                                       |                     
            MX_PWMCR_STOPEN | MX_PWMCR_DOZEEN |                                   |                     
            MX_PWMCR_WAITEN | MX_PWMCR_DBGEN;                                     |                     
                                                                                  |                     
        cr |= MX_PWMCR_CLKSRC_IPG_HIGH;                                           |                     
                                                                                  |                     
        writel(cr, pwm.mmio_base + MX_PWMCR);                                     |                     
                                                                                  |                     
        return 0;                                                                 |                     
    }                                                                             |                     
                                                                                  |                     
    int imx_pwm_enable(struct pwm_device pwm)                    <----------------+                     
    {                                                                                                   
        unsigned long reg;                                                                              
        int rc = 0;                                                                                     
                                                                                                        
        if (pwm.enable_pwm_clk)                                                                         
            pwm.enable_pwm_clk();                                                                       
                                                                                                        
        pwm.mmio_base = pwm.pwm_id ? (unsigned long)IMX_PWM2_BASE:                                      
                    (unsigned long)IMX_PWM1_BASE;                                                       
                                                                                                        
        reg = readl(pwm.mmio_base + MX_PWMCR);                                                          
        reg |= MX_PWMCR_EN;                                                                             
        writel(reg, pwm.mmio_base + MX_PWMCR);                                                          
                                                                                                        
        if (pwm.enable_pwm_pad)                                                                         
            pwm.enable_pwm_pad();                                                                       
                                                                                                        
        return rc;                                                                                      
    }                                                                                                   
  • 相关阅读:
    swoole 查看tcp开启进程数
    详解LRU缓存算法
    glib 双向链表
    清华计算机本科 课表
    glib 单向链表
    通信课程
    基数排序
    glib 数组
    glib 散列表
    清华计算机博士 课表
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5250475.html
Copyright © 2020-2023  润新知