Message ID | 20230324094205.33266-5-angelogioacchino.delregno@collabora.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | MediaTek Helio X10 MT6795 - MT6331/6332 PMIC Wrapper | expand |
Le ven. 24 mars 2023 à 10:42, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> a écrit : > > Some PMICs are designed to work with a companion part, which provides > more regulators and/or companion devices such as LED controllers, > display backlight controllers, battery charging, fuel gauge, etc: > this kind of PMICs are usually present in smartphone platforms, where > tight integration is required. > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/soc/mediatek/mtk-pmic-wrap.c | 73 ++++++++++++++++++++++------ > 1 file changed, 59 insertions(+), 14 deletions(-) > > diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c > index a33a1b1820cb..366e40b802e4 100644 > --- a/drivers/soc/mediatek/mtk-pmic-wrap.c > +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c > @@ -47,6 +47,7 @@ > > /* macro for device wrapper default value */ > #define PWRAP_DEW_READ_TEST_VAL 0x5aa5 > +#define PWRAP_DEW_COMP_READ_TEST_VAL 0xa55a > #define PWRAP_DEW_WRITE_TEST_VAL 0xa55a > > /* macro for manual command */ > @@ -1222,12 +1223,16 @@ struct pwrap_slv_regops { > * struct pwrap_slv_type - PMIC device wrapper definitions > * @dew_regs: Device Wrapper (DeW) register offsets > * @type: PMIC Type (model) > + * @comp_dew_regs: Device Wrapper (DeW) register offsets for companion device > + * @comp_type: Companion PMIC Type (model) > * @regops: Register R/W ops > * @caps: Capability flags for the target device > */ > struct pwrap_slv_type { > const u32 *dew_regs; > enum pmic_type type; > + const u32 *comp_dew_regs; > + enum pmic_type comp_type; > const struct pwrap_slv_regops *regops; > u32 caps; > }; > @@ -1548,9 +1553,12 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp) > { > int ret; > bool read_ok, tmp; > + bool comp_read_ok = true; > > /* Enable dual IO mode */ > pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1); > + if (wrp->slave->comp_dew_regs) > + pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_DIO_EN], 1); > > /* Check IDLE & INIT_DONE in advance */ > ret = readx_poll_timeout(pwrap_is_fsm_idle_and_sync_idle, wrp, tmp, tmp, > @@ -1564,8 +1572,14 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp) > > /* Read Test */ > read_ok = pwrap_pmic_read_test(wrp, wrp->slave->dew_regs, PWRAP_DEW_READ_TEST_VAL); > - if (!read_ok) { > - dev_err(wrp->dev, "Read failed on DIO mode.\n"); > + if (wrp->slave->comp_dew_regs) > + comp_read_ok = pwrap_pmic_read_test(wrp, wrp->slave->comp_dew_regs, > + PWRAP_DEW_COMP_READ_TEST_VAL); > + if (!read_ok || !comp_read_ok) { > + dev_err(wrp->dev, "Read failed on DIO mode. Main PMIC %s%s\n", > + !read_ok ? "fail" : "success", > + wrp->slave->comp_dew_regs && !comp_read_ok ? > + ", Companion PMIC fail" : ""); > return -EFAULT; > } > > @@ -1640,19 +1654,41 @@ static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp) > return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1; > } > > -static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp) > +static bool __pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp, const u32 *dew_regs) > { > u32 rdata; > int ret; > > - ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY], > - &rdata); > + ret = pwrap_read(wrp, dew_regs[PWRAP_DEW_CIPHER_RDY], &rdata); > if (ret) > return false; > > return rdata == 1; > } > > + Remove this extra line please. > +static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp) > +{ > + bool ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->dew_regs); > + > + if (!ret) > + return ret; > + > + /* If there's any companion, wait for it to be ready too */ > + if (wrp->slave->comp_dew_regs) > + ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->comp_dew_regs); > + > + return ret; > +} > + > +static void pwrap_config_cipher(struct pmic_wrapper *wrp, const u32 *dew_regs) > +{ > + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1); > + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0); > + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1); > + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2); > +} > + > static int pwrap_init_cipher(struct pmic_wrapper *wrp) > { > int ret; > @@ -1689,10 +1725,11 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) > } > > /* Config cipher mode @PMIC */ > - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1); > - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0); > - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1); > - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2); > + pwrap_config_cipher(wrp, wrp->slave->dew_regs); > + > + /* If there is any companion PMIC, configure cipher mode there too */ > + if (wrp->slave->comp_type > 0) > + pwrap_config_cipher(wrp, wrp->slave->comp_dew_regs); > > switch (wrp->slave->type) { > case PMIC_MT6397: > @@ -1754,6 +1791,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) > > static int pwrap_init_security(struct pmic_wrapper *wrp) > { > + u32 crc_val; > int ret; > > /* Enable encryption */ > @@ -1762,14 +1800,21 @@ static int pwrap_init_security(struct pmic_wrapper *wrp) > return ret; > > /* Signature checking - using CRC */ > - if (pwrap_write(wrp, > - wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1)) > - return -EFAULT; > + ret = pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1); > + if (ret == 0 && wrp->slave->comp_dew_regs) > + ret = pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_EN], 0x1); > > pwrap_writel(wrp, 0x1, PWRAP_CRC_EN); > pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE); > - pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL], > - PWRAP_SIG_ADR); > + > + /* CRC value */ > + crc_val = wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL]; > + if (wrp->slave->comp_dew_regs) > + crc_val |= wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_VAL] << 16; IMHO, the number 16 should be replaced by a define even if I guess it's a simple shift value. > + > + pwrap_writel(wrp, crc_val, PWRAP_SIG_ADR); > + > + /* PMIC Wrapper Arbiter priority */ > pwrap_writel(wrp, > wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN); > > -- > 2.40.0 > Sounds good to me. Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Regards, Alex
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index a33a1b1820cb..366e40b802e4 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -47,6 +47,7 @@ /* macro for device wrapper default value */ #define PWRAP_DEW_READ_TEST_VAL 0x5aa5 +#define PWRAP_DEW_COMP_READ_TEST_VAL 0xa55a #define PWRAP_DEW_WRITE_TEST_VAL 0xa55a /* macro for manual command */ @@ -1222,12 +1223,16 @@ struct pwrap_slv_regops { * struct pwrap_slv_type - PMIC device wrapper definitions * @dew_regs: Device Wrapper (DeW) register offsets * @type: PMIC Type (model) + * @comp_dew_regs: Device Wrapper (DeW) register offsets for companion device + * @comp_type: Companion PMIC Type (model) * @regops: Register R/W ops * @caps: Capability flags for the target device */ struct pwrap_slv_type { const u32 *dew_regs; enum pmic_type type; + const u32 *comp_dew_regs; + enum pmic_type comp_type; const struct pwrap_slv_regops *regops; u32 caps; }; @@ -1548,9 +1553,12 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp) { int ret; bool read_ok, tmp; + bool comp_read_ok = true; /* Enable dual IO mode */ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1); + if (wrp->slave->comp_dew_regs) + pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_DIO_EN], 1); /* Check IDLE & INIT_DONE in advance */ ret = readx_poll_timeout(pwrap_is_fsm_idle_and_sync_idle, wrp, tmp, tmp, @@ -1564,8 +1572,14 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp) /* Read Test */ read_ok = pwrap_pmic_read_test(wrp, wrp->slave->dew_regs, PWRAP_DEW_READ_TEST_VAL); - if (!read_ok) { - dev_err(wrp->dev, "Read failed on DIO mode.\n"); + if (wrp->slave->comp_dew_regs) + comp_read_ok = pwrap_pmic_read_test(wrp, wrp->slave->comp_dew_regs, + PWRAP_DEW_COMP_READ_TEST_VAL); + if (!read_ok || !comp_read_ok) { + dev_err(wrp->dev, "Read failed on DIO mode. Main PMIC %s%s\n", + !read_ok ? "fail" : "success", + wrp->slave->comp_dew_regs && !comp_read_ok ? + ", Companion PMIC fail" : ""); return -EFAULT; } @@ -1640,19 +1654,41 @@ static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp) return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1; } -static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp) +static bool __pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp, const u32 *dew_regs) { u32 rdata; int ret; - ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY], - &rdata); + ret = pwrap_read(wrp, dew_regs[PWRAP_DEW_CIPHER_RDY], &rdata); if (ret) return false; return rdata == 1; } + +static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp) +{ + bool ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->dew_regs); + + if (!ret) + return ret; + + /* If there's any companion, wait for it to be ready too */ + if (wrp->slave->comp_dew_regs) + ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->comp_dew_regs); + + return ret; +} + +static void pwrap_config_cipher(struct pmic_wrapper *wrp, const u32 *dew_regs) +{ + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1); + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0); + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1); + pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2); +} + static int pwrap_init_cipher(struct pmic_wrapper *wrp) { int ret; @@ -1689,10 +1725,11 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) } /* Config cipher mode @PMIC */ - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1); - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0); - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1); - pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2); + pwrap_config_cipher(wrp, wrp->slave->dew_regs); + + /* If there is any companion PMIC, configure cipher mode there too */ + if (wrp->slave->comp_type > 0) + pwrap_config_cipher(wrp, wrp->slave->comp_dew_regs); switch (wrp->slave->type) { case PMIC_MT6397: @@ -1754,6 +1791,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) static int pwrap_init_security(struct pmic_wrapper *wrp) { + u32 crc_val; int ret; /* Enable encryption */ @@ -1762,14 +1800,21 @@ static int pwrap_init_security(struct pmic_wrapper *wrp) return ret; /* Signature checking - using CRC */ - if (pwrap_write(wrp, - wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1)) - return -EFAULT; + ret = pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1); + if (ret == 0 && wrp->slave->comp_dew_regs) + ret = pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_EN], 0x1); pwrap_writel(wrp, 0x1, PWRAP_CRC_EN); pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE); - pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL], - PWRAP_SIG_ADR); + + /* CRC value */ + crc_val = wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL]; + if (wrp->slave->comp_dew_regs) + crc_val |= wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_VAL] << 16; + + pwrap_writel(wrp, crc_val, PWRAP_SIG_ADR); + + /* PMIC Wrapper Arbiter priority */ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
Some PMICs are designed to work with a companion part, which provides more regulators and/or companion devices such as LED controllers, display backlight controllers, battery charging, fuel gauge, etc: this kind of PMICs are usually present in smartphone platforms, where tight integration is required. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/soc/mediatek/mtk-pmic-wrap.c | 73 ++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 14 deletions(-)