7.8.2. 参数配置¶
7.8.2.1. 内核配置¶
在luban根目录下执行 make kernel-menuconfig,进入kernel的功能配置,按如下选择:
Linux
    Device Drivers  --->
        [*] Pulse-Width Modulation (PWM) Support  --->
            <*>   ArtInChip PWM support
            <*>   ArtInChip EPWM support
通常,PWM模块被用于 背光控制功能,以下是打开Linux中背光控制模块的方法:
Linux
    Device Drivers  --->
        Graphics support  --->
            Backlight & LCD device support  --->
                <*> Lowlevel Backlight controls
                <*>   Generic PWM based Backlight Driver
当使用boot logo功能时,在U-Boot阶段也需要打开屏幕的背光。在U-Boot中打开背光控制模块的方法(在luban根目录下执行 make bm/boot-menuconfig):
U-Boot
    Device Drivers  --->
        [*] Enable support for pulse-width modulation devices (PWM)
        [*]   Enable support for ArtInChip PWM
        Graphics support  --->
            [*] Generic PWM based Backlight Driver
7.8.2.2. DTS 参数配置¶
7.8.2.2.1. PWM 自定义参数¶
PWM驱动支持从DTS中配置的自定义参数,如下表:
| 参数名称 | 类型 | 取值范围 | 功能说明 | 
|---|---|---|---|
| mode | 字符串 | up/down/up-down-count | 配置增减模式 | 
| tb-clk-rate | 正整数 | (0, 24000000) | 时基计数器的工作时钟 | 
| action0 | 字符串 | none/low/high/inverse | 多个关键时点的触发行为 | 
| action1 | 字符串 | none/low/high/inverse | 多个关键时点的触发行为 | 
| default-level | 正整数 | [0, 1] | 默认/初始电平 | 
注意,表中为了更加简洁,参数名称都省略了前缀“aic,”。
表中 action0和action1 四种取值的含义,定义如下:
| Action类型 | 行为描述 | 
|---|---|
| none | 不做任何变化,保持之前的输出电平 | 
| low | 跳变为0电平 | 
| high | 跳变为1电平 | 
| inverse | 跳变为反向的电平,比如从 0 跳变为 1 | 
7.8.2.2.2. 时钟配置¶
PWM 模块涉及时钟的衍生关系:
 
图 7.25 PWM 模块的时钟衍生关系图¶
EWM 模块涉及时钟的衍生关系:
 
图 7.26 EPWM 模块的时钟衍生关系图¶
其中,前两个时钟在PWM控制器的节点中配置,后两个时钟在Board中的PWM子节点(对应通道)中配置。
注解
容易混淆的sysclk:
- PWM 驱动中,按照惯例将父时钟称作 - sysclk,即上图的 PLL INT1;
- PWM 硬件spec 中,将上图中的 PWM Clk 称作 - sysclk。
7.8.2.2.3. D211 配置¶
common/d211.dtsi中的参数配置:
pwm: pwm@19240000 {
    compatible = "artinchip,aic-pwm-v1.0";
    reg = <0x0 0x19240000 0x0 0x1000>;
    interrupts-extended = <&plic0 90 IRQ_TYPE_LEVEL_HIGH>;
    #pwm-cells = <3>;
    clocks = <&cmu CLK_PWM>, <&cmu CLK_PLL_INT1>;
    clock-names = "pwm", "sysclk";
    resets = <&rst RESET_PWM>;
    clock-rate = <48000000>;
};
epwm: epwm@18200000 {
    compatible = "artinchip,aic-epwm-v1.0";
    reg = <0x0 0x18200000 0x0 0x600>, <0 0x1820F000 0x0 0x1000>;
    interrupts-extended = <&plic0 25 IRQ_TYPE_LEVEL_HIGH>;
    #pwm-cells = <3>;
    clocks = <&cmu CLK_PWMCS>, <&cmu CLK_PLL_INT1>;
    clock-names = "pwmcs", "sysclk";
    resets = <&rst RESET_PWMCS>;
    clock-rate = <48000000>;
    status = "disabled";
};
7.8.2.2.4. Board 配置¶
7.8.2.2.4.1. PWM 通道配置¶
xxx/board.dts中的参数配置:
&pwm {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pwm2_pins_b>;
    /* mode: up-count, down-count, up-down-count
       action: none, low, high, inverse */
    pwm0 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        aic,rise-edge-delay = <10>;
        aic,fall-edge-delay = <10>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "low", "none", "high";
        aic,action1 = "none", "none", "none", "high", "none", "low";
        status = "disabled";
    };
    pwm1 {
        aic,mode = "down-count";
        aic,tb-clk-rate = <24000000>;
        aic,rise-edge-delay = <10>;
        aic,fall-edge-delay = <10>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "low", "none", "high";
        aic,action1 = "none", "none", "none", "high", "none", "low";
        status = "disabled";
    };
    pwm2 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "low", "none";
        aic,action1 = "none", "none", "none", "low", "high", "none";
        aic,default-level = <0>;
        aic,rise-edge-delay = <10>;
        aic,fall-edge-delay = <10>;
        status = "okay";
    };
    pwm3 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "low", "high", "none";
        aic,action1 = "none", "none", "none", "high", "low", "none";
        aic,rise-edge-delay = <10>;
        aic,fall-edge-delay = <10>;
        status = "disabled";
    };
};
&epwm {
    status = "disabled";
    pinctrl-names = "default";
    pinctrl-0 = <&epwm0_pins_a>,
             <&epwm1_pins_a>,
             <&epwm2_pins_a>;
    /* mode: up-count, down-count, up-down-count
    action: none, low, high, inverse */
    epwm0 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
    epwm1 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
    epwm2 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
    epwm3 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
    epwm4 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
    epwm5 {
        aic,mode = "up-count";
        aic,tb-clk-rate = <24000000>;
        /*            CBD,    CBU,    CAD,    CAU,    PRD,   ZRO */
        aic,action0 = "none", "none", "none", "high", "none", "low";
        aic,action1 = "none", "high", "none", "none", "none", "low";
        status = "disabled";
    };
};
7.8.2.2.4.2. 背光控制配置¶
需要在xxx/board.dts中新增一个backlight节点,如下:
backlight: backlight {
    compatible = "pwm-backlight";
    /* pwm node name; pwm device No.; period_ns; pwm_polarity */
    pwms = <&pwm 2 1000000 0>;
    brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
    default-brightness-level = <8>;
    status = "okay";
};
其中 “&pwm 2” 表示要使用 pwm2 通道作为背光控制用(要确认和硬件上的电路连接是一致的)。
在屏幕panel节点中,需要引用backlight:
panel_lvds {
    compatible = "artinchip,aic-general-lvds-panel";
    data-mapping = "vesa-24";
    data-channel = "single-link1";
    backlight = <&backlight>;
    status = "okay";
    ...
};