Message ID | 20230403133054.319070-3-angelogioacchino.delregno@collabora.com |
---|---|
State | Accepted |
Headers | show |
Series | pwm: mtk-disp: Fix backlight configuration at boot | expand |
On 03/04/2023 15:30, AngeloGioacchino Del Regno wrote: > The DISP_PWM controller's default behavior is to always use register > double buffering: all reads/writes are then performed on shadow > registers instead of working registers and this becomes an issue > in case our chosen configuration in Linux is different from the > default (or from the one that was pre-applied by the bootloader). > > An example of broken behavior is when the controller is configured > to use shadow registers, but this driver wants to configure it > otherwise: what happens is that the .get_state() callback is called > right after registering the pwmchip and checks whether the PWM is > enabled by reading the DISP_PWM_EN register; > At this point, if shadow registers are enabled but their content > was not committed before booting Linux, we are *not* reading the > current PWM enablement status, leading to the kernel knowing that > the hardware is actually enabled when, in reality, it's not. > > The aforementioned issue emerged since this driver was fixed with > commit 0b5ef3429d8f ("pwm: mtk-disp: Fix the parameters calculated > by the enabled flag of disp_pwm") making it to read the enablement > status from the right register. > > Configure the controller in the .get_state() callback to avoid > this desync issue and get the backlight properly working again. > > Fixes: 3f2b16734914 ("pwm: mtk-disp: Implement atomic API .get_state()") > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> > --- > drivers/pwm/pwm-mtk-disp.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c > index 82b430d881a2..fe9593f968ee 100644 > --- a/drivers/pwm/pwm-mtk-disp.c > +++ b/drivers/pwm/pwm-mtk-disp.c > @@ -196,6 +196,16 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, > return err; > } > > + /* > + * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable > + * registers double buffer and manual commit to working register before > + * performing any read/write operation > + */ > + if (mdp->data->bls_debug) > + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, > + mdp->data->bls_debug_mask, > + mdp->data->bls_debug_mask); > + > rate = clk_get_rate(mdp->clk_main); > con0 = readl(mdp->base + mdp->data->con0); > con1 = readl(mdp->base + mdp->data->con1); Hi, Same test. Looks fine. Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Tested-by: Alexandre Mergnat <amergnat@baylibre.com> Regards, Alex
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 82b430d881a2..fe9593f968ee 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -196,6 +196,16 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, return err; } + /* + * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable + * registers double buffer and manual commit to working register before + * performing any read/write operation + */ + if (mdp->data->bls_debug) + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + rate = clk_get_rate(mdp->clk_main); con0 = readl(mdp->base + mdp->data->con0); con1 = readl(mdp->base + mdp->data->con1);