Merge "arm64: defconfig: Add pwm support for NIOBE"

This commit is contained in:
QCTECMDR Service 2024-08-27 00:38:53 -07:00 committed by Gerrit - the friendly Code Review server
commit 1b7462b00f
3 changed files with 56 additions and 23 deletions

View File

@ -120,6 +120,7 @@ CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE=m
CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_DEFAULT=y
CONFIG_POWER_RESET_QCOM_PON=m
CONFIG_POWER_RESET_QCOM_REBOOT_REASON=m
CONFIG_PWM_QCOM=m
CONFIG_PWM_QTI_LPG=m
CONFIG_QCOM_AOSS_QMP=m
CONFIG_QCOM_BALANCE_ANON_FILE_RECLAIM=y

View File

@ -29,8 +29,11 @@
#define PWM_CYC_CFG 0xC
#define PWM_UPDATE 0x10
#define PWM_PERIOD_CNT 0x14
#define PWM_RESET 0x18
#define PWM_FRAME_POLARITY_BIT 0
#define PWM_FRAME_POLARITY_BIT BIT(0)
#define PWM_FRAME_ROLLOVER_CNT_BIT BIT(4)
#define PWM_FRAME_RESET_BIT BIT(0)
enum {
ENABLE_STATUS0,
@ -42,6 +45,8 @@ enum {
struct pdm_pwm_priv_data {
unsigned int max_channels;
const u16 *status_reg_offsets;
bool pwm_reset_support;
bool pwm_cnt_rollover;
};
/*
@ -54,6 +59,7 @@ struct pdm_pwm_priv_data {
* @current_freq: Current frequency of frame.
* @freq_set: This bool flag is responsible for setting period once per frame.
* @mutex: mutex lock per frame.
* @cnt_rollover_en: This bool flag is used to set rollover bit per frame.
*/
struct pdm_pwm_frames {
u32 frame_id;
@ -66,6 +72,7 @@ struct pdm_pwm_frames {
bool freq_set;
struct mutex frame_lock; /* PWM per frame lock */
struct pdm_pwm_chip *pwm_chip;
bool cnt_rollover_en;
};
/*
@ -100,8 +107,11 @@ static int __pdm_pwm_calc_pwm_frequency(struct pdm_pwm_chip *chip,
unsigned long cyc_cfg, freq;
int ret;
/* PWM client could set the period only once, due to HW limitation. */
if (chip->frames[hw_idx].freq_set)
/*
* PWM client can set the period only once if the HW version does
* not support reset functionality.
*/
if (chip->frames[hw_idx].freq_set && !chip->priv_data->pwm_reset_support)
return 0;
freq = PERIOD_TO_HZ(period_ns);
@ -167,18 +177,34 @@ static int pdm_pwm_config(struct pdm_pwm_chip *chip, u32 hw_idx,
mutex_lock(&chip->frames[hw_idx].frame_lock);
/*
* Set the counter rollover enable bit, so that counter doesn't get stuck
* in period change configuration.
*/
if (chip->priv_data->pwm_cnt_rollover && !chip->frames[hw_idx].cnt_rollover_en) {
regmap_update_bits(chip->regmap, chip->frames[hw_idx].reg_offset + PWM_CTL0,
PWM_FRAME_ROLLOVER_CNT_BIT, PWM_FRAME_ROLLOVER_CNT_BIT);
chip->frames[hw_idx].cnt_rollover_en = true;
}
ret = __pdm_pwm_calc_pwm_frequency(chip, current_period, hw_idx);
if (ret)
goto out;
if (chip->frames[hw_idx].current_period_ns != period_ns) {
pr_err("Period cannot be updated, calculating dutycycle on old period\n");
current_period = chip->frames[hw_idx].current_period_ns;
if (chip->priv_data->pwm_reset_support)
regmap_update_bits(chip->regmap,
chip->frames[hw_idx].reg_offset + PWM_RESET,
PWM_FRAME_RESET_BIT, PWM_FRAME_RESET_BIT);
else {
pr_err("Period cannot be updated, calculating dutycycle on old period\n");
current_period = chip->frames[hw_idx].current_period_ns;
}
}
if (chip->frames[hw_idx].polarity != polarity) {
regmap_update_bits(chip->regmap, chip->frames[hw_idx].reg_offset
+ PWM_CTL0, BIT(PWM_FRAME_POLARITY_BIT), polarity);
+ PWM_CTL0, PWM_FRAME_POLARITY_BIT, polarity);
chip->frames[hw_idx].polarity = polarity;
}
@ -220,21 +246,6 @@ static int pdm_pwm_config(struct pdm_pwm_chip *chip, u32 hw_idx,
return ret;
}
static void pdm_pwm_free(struct pwm_chip *pwm_chip, struct pwm_device *pwm)
{
struct pdm_pwm_chip *chip = container_of(pwm_chip,
struct pdm_pwm_chip, pwm_chip);
u32 hw_idx = pwm->hwpwm;
mutex_lock(&chip->lock);
chip->frames[hw_idx].freq_set = false;
chip->frames[hw_idx].current_period_ns = 0;
chip->frames[hw_idx].current_duty_ns = 0;
mutex_unlock(&chip->lock);
}
static int pdm_pwm_enable(struct pdm_pwm_chip *chip, struct pwm_device *pwm)
{
u32 ret, val;
@ -305,7 +316,7 @@ static int pdm_pwm_apply(struct pwm_chip *pwm_chip, struct pwm_device *pwm,
pwm_get_state(pwm, &curr_state);
if (state->period < curr_state.period)
if (state->period < curr_state.period && !chip->priv_data->pwm_reset_support)
return -EINVAL;
if (state->period != curr_state.period ||
@ -331,6 +342,24 @@ static int pdm_pwm_apply(struct pwm_chip *pwm_chip, struct pwm_device *pwm,
return 0;
}
static void pdm_pwm_free(struct pwm_chip *pwm_chip, struct pwm_device *pwm)
{
struct pdm_pwm_chip *chip = container_of(pwm_chip,
struct pdm_pwm_chip, pwm_chip);
u32 hw_idx = pwm->hwpwm;
mutex_lock(&chip->lock);
chip->frames[hw_idx].freq_set = false;
chip->frames[hw_idx].current_period_ns = 0;
chip->frames[hw_idx].current_duty_ns = 0;
chip->frames[hw_idx].cnt_rollover_en = false;
mutex_unlock(&chip->lock);
pdm_pwm_disable(chip, pwm);
}
static const struct pwm_ops pdm_pwm_ops = {
.apply = pdm_pwm_apply,
.free = pdm_pwm_free,
@ -465,7 +494,7 @@ static int get_polarity(struct seq_file *m, void *unused)
u32 temp;
regmap_read(chip->regmap, frame->reg_offset + PWM_CTL0, &temp);
if (BIT(PWM_FRAME_POLARITY_BIT) & temp)
if (PWM_FRAME_POLARITY_BIT & temp)
seq_puts(m, "PWM_POLARITY_INVERSED\n");
else
seq_puts(m, "PWM_POLARITY_NORMAL\n");
@ -672,6 +701,8 @@ static struct pdm_pwm_priv_data pdm_pwm_v2_reg_offsets = {
[ENABLE_STATUS0] = 0xc,
[ENABLE_STATUS1] = 0x10,
},
.pwm_reset_support = true,
.pwm_cnt_rollover = true,
};
static const struct of_device_id pdm_pwm_of_match[] = {

View File

@ -99,6 +99,7 @@ def define_niobe():
"drivers/power/reset/reboot-mode.ko",
"drivers/power/supply/qti_battery_charger.ko",
"drivers/powercap/qti_epm_hardware.ko",
"drivers/pwm/pwm-qcom.ko",
"drivers/pwm/pwm-qti-lpg.ko",
"drivers/regulator/ap72200-regulator.ko",
"drivers/regulator/debug-regulator.ko",