From 7b4cda85a4dd1d8e5ebf9d7ebf0338e955e4f54e Mon Sep 17 00:00:00 2001 From: Dino Li Date: Fri, 3 Nov 2017 09:41:42 +0800 Subject: it83xx: pwm: support PWM_CONFIG_DSLEEP config flag With this change, we can keep a PWM channel active during low-power idle (EC deep doze). BRANCH=none BUG=none TEST=The pwm channel is function normally in deep doze mode. And tested pwm frequency setting are: 300, 250, 200, 150, 100, 50, and 10 (Hz) Change-Id: Ie94cd96e819c869bdde6d7675d8f1a6cfc627f3b Signed-off-by: Dino Li Reviewed-on: https://chromium-review.googlesource.com/752702 Reviewed-by: Randall Spangler --- board/it83xx_evb/board.c | 1 + board/it83xx_evb/board.h | 1 + chip/it83xx/pwm.c | 28 +++++++++++++++++++++------- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/board/it83xx_evb/board.c b/board/it83xx_evb/board.c index df92683ff8..2a4da1e126 100644 --- a/board/it83xx_evb/board.c +++ b/board/it83xx_evb/board.c @@ -101,6 +101,7 @@ void pd_task(void) */ const struct pwm_t pwm_channels[] = { {7, 0, 30000, PWM_PRESCALER_C4}, + {0, PWM_CONFIG_DSLEEP, 100, PWM_PRESCALER_C6}, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/it83xx_evb/board.h b/board/it83xx_evb/board.h index b843cb193f..3c7f73ae3f 100644 --- a/board/it83xx_evb/board.h +++ b/board/it83xx_evb/board.h @@ -69,6 +69,7 @@ enum pwm_channel { PWM_CH_FAN, + PWM_CH_WITH_DSLEEP_FLAG, /* Number of PWM channels */ PWM_CH_COUNT }; diff --git a/chip/it83xx/pwm.c b/chip/it83xx/pwm.c index db9f180455..a2214c127a 100644 --- a/chip/it83xx/pwm.c +++ b/chip/it83xx/pwm.c @@ -15,7 +15,7 @@ #include "util.h" #include "math_util.h" -#define PWM_CTRX_MIN 120 +#define PWM_CTRX_MIN 100 #define PWM_EC_FREQ 8000000 const struct pwm_ctrl_t pwm_ctrl_regs[] = { @@ -202,14 +202,16 @@ static int pwm_ch_freq(enum pwm_channel ch) { int actual_freq = -1, targe_freq, deviation; int pcfsr, ctr, pcfsr_sel, pcs_shift, pcs_mask; + int pwm_clk_src = (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) ? + 32768 : PWM_EC_FREQ; targe_freq = pwm_channels[ch].freq_hz; deviation = (targe_freq / 100) + 1; - for (ctr = 0xFF; ctr > PWM_CTRX_MIN; ctr--) { - pcfsr = (PWM_EC_FREQ / (ctr + 1) / targe_freq) - 1; + for (ctr = 0xFF; ctr >= PWM_CTRX_MIN; ctr--) { + pcfsr = (pwm_clk_src / (ctr + 1) / targe_freq) - 1; if (pcfsr >= 0) { - actual_freq = PWM_EC_FREQ / (ctr + 1) / (pcfsr + 1); + actual_freq = pwm_clk_src / (ctr + 1) / (pcfsr + 1); if (ABS(actual_freq - targe_freq) < deviation) break; } @@ -220,9 +222,21 @@ static int pwm_ch_freq(enum pwm_channel ch) } else { pcfsr_sel = pwm_channels[ch].pcfsr_sel; *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cycle_time = ctr; - /* ec clock 8MHz */ - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg |= - pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; + + if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) + /* + * Select 32.768KHz as PWM clock source. +] * + * NOTE: + * For pwm_channels[], the maximum supported pwm output + * signal frequency is 324 Hz (32768/(PWM_CTRX_MIN+1)). + */ + *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg &= + ~pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; + else + /* ec clock 8MHz */ + *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg |= + pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; /* pwm channel mapping */ ch = pwm_channels[ch].channel; -- cgit v1.2.1