static __s32 pwm_set_duty_ns(__u32 channel, __u32 duty_ns) { __u32 active_cycle = 0; __u32 tmp; active_cycle = (duty_ns * gdisp.pwm[channel].entire_cycle + (gdisp.pwm[channel].period_ns / 2)) / gdisp.pwm[channel].period_ns; if (channel == 0) { tmp = pwm_read_reg(0x204); pwm_write_reg(0x204, (tmp & 0xffff0000) | active_cycle); } else { tmp = pwm_read_reg(0x208); pwm_write_reg(0x208, (tmp & 0xffff0000) | active_cycle); } gdisp.pwm[channel].duty_ns = duty_ns; /* DE_INF("%d,%d,%d,%d\n", duty_ns, gdisp.pwm[channel].period_ns, " "active_cycle, gdisp.pwm[channel].entire_cycle); */ return 0; }
static void __sramfunc rk29_pwm_set_core_voltage(unsigned int uV) { u32 gate1; gate1 = cru_readl(CRU_CLKGATE1_CON); cru_writel(gate1 & ~((1 << CLK_GATE_PCLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_CPU_PERI % 32)), CRU_CLKGATE1_CON); /* iomux pwm2 */ writel((readl(RK29_GRF_BASE + 0x58) & ~(0x3<<6)) | (0x2<<6), RK29_GRF_BASE + 0x58); if (uV) { pwm_lrc = pwm_read_reg(PWM_REG_LRC); pwm_hrc = pwm_read_reg(PWM_REG_HRC); } pwm_write_reg(PWM_REG_CTRL, PWM_DIV|PWM_RESET); if (uV == 1000000) { pwm_write_reg(PWM_REG_LRC, 12); pwm_write_reg(PWM_REG_HRC, 10); } else { pwm_write_reg(PWM_REG_LRC, pwm_lrc); pwm_write_reg(PWM_REG_HRC, pwm_hrc); } pwm_write_reg(PWM_REG_CNTR, 0); pwm_write_reg(PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TimeEN); LOOP(10 * 1000 * LOOPS_PER_USEC); /* delay 10ms */ cru_writel(gate1, CRU_CLKGATE1_CON); }
__s32 pwm_enable(__u32 channel, __bool b_en) { __u32 tmp = 0; __hdle hdl; if(gdisp.screen[channel].lcd_cfg.lcd_pwm_used) { user_gpio_set_t gpio_info[1]; memcpy(gpio_info, &(gdisp.screen[channel].lcd_cfg.lcd_pwm), sizeof(user_gpio_set_t)); if(b_en) { gpio_info->mul_sel = 2; } else { gpio_info->mul_sel = 0; } hdl = OSAL_GPIO_Request(gpio_info, 1); OSAL_GPIO_Release(hdl, 2); } if(channel == 0) { tmp = pwm_read_reg(0x200); if(b_en) { tmp |= (1<<4); } else { tmp &= (~(1<<4)); } pwm_write_reg(0x200,tmp); } else { tmp = pwm_read_reg(0x200); if(b_en) { tmp |= (1<<19); } else { tmp &= (~(1<<19)); } pwm_write_reg(0x200,tmp); } gdisp.pwm[channel].enable = b_en; return 0; }
static void __sramfunc rk29_pwm_set_core_voltage(unsigned int uV) { u32 clk_gate2; char id = 3; //sram_printch('y'); #if 1 gate_save_soc_clk(0 | (1 << CLK_GATE_ACLK_PEIRPH % 16) | (1 << CLK_GATE_HCLK_PEIRPH % 16) | (1 << CLK_GATE_PCLK_PEIRPH % 16) , clk_gate2, CRU_CLKGATES_CON(2), 0 | (1 << ((CLK_GATE_ACLK_PEIRPH % 16) + 16)) | (1 << ((CLK_GATE_HCLK_PEIRPH % 16) + 16)) | (1 << ((CLK_GATE_PCLK_PEIRPH % 16) + 16))); #endif /* iomux pwm3 */ writel_relaxed((readl_relaxed(RK30_GRF_BASE + 0xB4) & ~(0x1<<14)) | (0x1<<14) |(0x1<<30), RK30_GRF_BASE + 0xB4);//PWM if (uV) { pwm_lrc = pwm_read_reg(id,PWM_REG_LRC); pwm_hrc = pwm_read_reg(id,PWM_REG_HRC); writel_relaxed((readl_relaxed(RK30_GRF_BASE + 0xB4) & ~(0x1<<14)) | (0x1<<30), RK30_GRF_BASE + 0xB4);//GPIO grf_writel(GPIO0_PD7_DIR_OUT, GRF_GPIO0H_DIR_ADDR); grf_writel(GPIO0_PD7_DO_HIGH, GRF_GPIO0H_DO_ADDR); grf_writel(GPIO0_PD7_EN_MASK, GRF_GPIO0H_EN_ADDR); }else { pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_RESET); pwm_write_reg(id,PWM_REG_LRC, pwm_lrc); pwm_write_reg(id,PWM_REG_HRC, pwm_hrc); pwm_write_reg(id,PWM_REG_CNTR, 0); pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TimeEN); } LOOP(10 * 1000 * LOOPS_PER_USEC); /* delay 10ms */ cru_writel(clk_gate2, CRU_CLKGATES_CON(2)); }
/* * channel: pwm channel,0/1 * pwm_info->freq: pwm freq, in hz * pwm_info->active_state: 0:low level; 1:high level */ __s32 pwm_set_para(__u32 channel, __pwm_info_t *pwm_info) { __u32 pre_scal[11][2] = { {1, 0xf}, {120, 0}, {180, 1}, {240, 2}, {360, 3}, {480, 4}, {12000, 8}, {24000, 9}, {36000, 0xa}, {48000, 0xb}, {72000, 0xc} }; __u32 pre_scal_id = 0, entire_cycle = 16, active_cycle = 12; __u32 i = 0, j = 0, tmp = 0; __u32 freq; freq = 1000000 / pwm_info->period_ns; if (freq > 366) { pre_scal_id = 0; entire_cycle = 24000000 / freq; } else { for (i = 1; i < 11; i++) { for (j = 16;; j += 16) { __u32 pwm_freq = 0; pwm_freq = 24000000 / (pre_scal[i][0] * j); if (abs(pwm_freq - freq) < abs(tmp - freq)) { tmp = pwm_freq; pre_scal_id = i; entire_cycle = j; DE_INF("pre_scal:%d, entire_cycle:%d, " "pwm_freq:%d\n", pre_scal[i][0], j, pwm_freq); DE_INF("----%d\n", tmp); } else if ((tmp < freq) && (pwm_freq < tmp)) { break; } } } } active_cycle = (pwm_info->duty_ns * entire_cycle + (pwm_info->period_ns / 2)) / pwm_info->period_ns; gdisp.pwm[channel].enable = pwm_info->enable; gdisp.pwm[channel].freq = freq; gdisp.pwm[channel].pre_scal = pre_scal[pre_scal_id][0]; gdisp.pwm[channel].active_state = pwm_info->active_state; gdisp.pwm[channel].duty_ns = pwm_info->duty_ns; gdisp.pwm[channel].period_ns = pwm_info->period_ns; gdisp.pwm[channel].entire_cycle = entire_cycle; gdisp.pwm[channel].active_cycle = active_cycle; if (channel == 0) { pwm_write_reg(0x204, ((entire_cycle - 1) << 16) | active_cycle); tmp = pwm_read_reg(0x200) & 0xffffff00; /* * bit6: gating the special clock for pwm0 * bit5: pwm0: active state is high level */ tmp |= ((1 << 6) | (pwm_info->active_state << 5) | pre_scal[pre_scal_id][1]); pwm_write_reg(0x200, tmp); } else { pwm_write_reg(0x208, ((entire_cycle - 1) << 16) | active_cycle); tmp = pwm_read_reg(0x200) & 0xff807fff; /* * bit21: gating the special clock for pwm1 * bit20: pwm1: active state is high level */ tmp |= ((1 << 21) | (pwm_info->active_state << 20) | (pre_scal[pre_scal_id][1] << 15)); pwm_write_reg(0x200, tmp); } pwm_enable(channel, pwm_info->enable); return 0; }
/* * channel: pwm channel,0/1 * pwm_info->freq: pwm freq, in hz * pwm_info->active_state: 0:low level; 1:high level */ __s32 pwm_set_para(__u32 channel, __pwm_info_t *pwm_info) { __u32 pre_scal[10] = { 120, 180, 240, 360, 480, 12000, 24000, 36000, 48000, 72000 }; __u32 pre_scal_id = 0, entire_cycle = 256, active_cycle = 192; __u32 i = 0, tmp = 0; __u32 freq; freq = 1000000 / pwm_info->period_ns; if (freq > 200000) { DE_WRN("pwm preq is large then 200khz, fix to 200khz\n"); freq = 200000; } if (freq > 781) { pre_scal_id = 0; entire_cycle = (24000000 / pre_scal[pre_scal_id] + (freq / 2)) / freq; DE_INF("pre_scal:%d, entire_cycle:%d, pwm_freq:%d\n", pre_scal[i], entire_cycle, 24000000 / pre_scal[pre_scal_id] / entire_cycle); } else { for (i = 0; i < 10; i++) { __u32 pwm_freq = 0; pwm_freq = 24000000 / (pre_scal[i] * 256); if (abs(pwm_freq - freq) < abs(tmp - freq)) { tmp = pwm_freq; pre_scal_id = i; entire_cycle = 256; DE_INF("pre_scal:%d, entire_cycle:%d, " "pwm_freq:%d\n", pre_scal[i], 256, pwm_freq); DE_INF("----%d\n", tmp); } } } active_cycle = (pwm_info->duty_ns * entire_cycle + (pwm_info->period_ns / 2)) / pwm_info->period_ns; gdisp.pwm[channel].enable = pwm_info->enable; gdisp.pwm[channel].freq = freq; gdisp.pwm[channel].pre_scal = pre_scal[pre_scal_id]; gdisp.pwm[channel].active_state = pwm_info->active_state; gdisp.pwm[channel].duty_ns = pwm_info->duty_ns; gdisp.pwm[channel].period_ns = pwm_info->period_ns; gdisp.pwm[channel].entire_cycle = entire_cycle; gdisp.pwm[channel].active_cycle = active_cycle; if (pre_scal_id >= 5) pre_scal_id += 3; if (channel == 0) { pwm_write_reg(0x204, ((entire_cycle - 1) << 16) | active_cycle); tmp = pwm_read_reg(0x200) & 0xffffff00; /* * bit6: gating the special clock for pwm0 * bit5: pwm0: active state is high level */ tmp |= (1 << 6) | (pwm_info->active_state << 5) | pre_scal_id; pwm_write_reg(0x200, tmp); } else { pwm_write_reg(0x208, ((entire_cycle - 1) << 16) | active_cycle); tmp = pwm_read_reg(0x200) & 0xff807fff; /* * bit21: gating the special clock for pwm1 * bit20: pwm1: active state is high level */ tmp |= (1 << 21) | (pwm_info->active_state << 20) | (pre_scal_id << 15); pwm_write_reg(0x200, tmp); } pwm_enable(channel, pwm_info->enable); return 0; }