Skip to content

Commit 41ae95a

Browse files
AngeloGioacchino Del Regnombgg
authored andcommitted
soc: mediatek: mtk-pmic-wrap: Add support for companion PMICs
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> Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Link: https://lore.kernel.org/r/20230412131216.198313-5-angelogioacchino.delregno@collabora.com Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
1 parent 2eb2730 commit 41ae95a

1 file changed

Lines changed: 59 additions & 14 deletions

File tree

drivers/soc/mediatek/mtk-pmic-wrap.c

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
/* macro for device wrapper default value */
4949
#define PWRAP_DEW_READ_TEST_VAL 0x5aa5
50+
#define PWRAP_DEW_COMP_READ_TEST_VAL 0xa55a
5051
#define PWRAP_DEW_WRITE_TEST_VAL 0xa55a
5152

5253
/* macro for manual command */
@@ -1222,12 +1223,16 @@ struct pwrap_slv_regops {
12221223
* struct pwrap_slv_type - PMIC device wrapper definitions
12231224
* @dew_regs: Device Wrapper (DeW) register offsets
12241225
* @type: PMIC Type (model)
1226+
* @comp_dew_regs: Device Wrapper (DeW) register offsets for companion device
1227+
* @comp_type: Companion PMIC Type (model)
12251228
* @regops: Register R/W ops
12261229
* @caps: Capability flags for the target device
12271230
*/
12281231
struct pwrap_slv_type {
12291232
const u32 *dew_regs;
12301233
enum pmic_type type;
1234+
const u32 *comp_dew_regs;
1235+
enum pmic_type comp_type;
12311236
const struct pwrap_slv_regops *regops;
12321237
u32 caps;
12331238
};
@@ -1548,9 +1553,12 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp)
15481553
{
15491554
int ret;
15501555
bool read_ok, tmp;
1556+
bool comp_read_ok = true;
15511557

15521558
/* Enable dual IO mode */
15531559
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
1560+
if (wrp->slave->comp_dew_regs)
1561+
pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_DIO_EN], 1);
15541562

15551563
/* Check IDLE & INIT_DONE in advance */
15561564
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)
15641572

15651573
/* Read Test */
15661574
read_ok = pwrap_pmic_read_test(wrp, wrp->slave->dew_regs, PWRAP_DEW_READ_TEST_VAL);
1567-
if (!read_ok) {
1568-
dev_err(wrp->dev, "Read failed on DIO mode.\n");
1575+
if (wrp->slave->comp_dew_regs)
1576+
comp_read_ok = pwrap_pmic_read_test(wrp, wrp->slave->comp_dew_regs,
1577+
PWRAP_DEW_COMP_READ_TEST_VAL);
1578+
if (!read_ok || !comp_read_ok) {
1579+
dev_err(wrp->dev, "Read failed on DIO mode. Main PMIC %s%s\n",
1580+
!read_ok ? "fail" : "success",
1581+
wrp->slave->comp_dew_regs && !comp_read_ok ?
1582+
", Companion PMIC fail" : "");
15691583
return -EFAULT;
15701584
}
15711585

@@ -1640,19 +1654,41 @@ static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp)
16401654
return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1;
16411655
}
16421656

1643-
static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
1657+
static bool __pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp, const u32 *dew_regs)
16441658
{
16451659
u32 rdata;
16461660
int ret;
16471661

1648-
ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
1649-
&rdata);
1662+
ret = pwrap_read(wrp, dew_regs[PWRAP_DEW_CIPHER_RDY], &rdata);
16501663
if (ret)
16511664
return false;
16521665

16531666
return rdata == 1;
16541667
}
16551668

1669+
1670+
static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
1671+
{
1672+
bool ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->dew_regs);
1673+
1674+
if (!ret)
1675+
return ret;
1676+
1677+
/* If there's any companion, wait for it to be ready too */
1678+
if (wrp->slave->comp_dew_regs)
1679+
ret = __pwrap_is_pmic_cipher_ready(wrp, wrp->slave->comp_dew_regs);
1680+
1681+
return ret;
1682+
}
1683+
1684+
static void pwrap_config_cipher(struct pmic_wrapper *wrp, const u32 *dew_regs)
1685+
{
1686+
pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1);
1687+
pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
1688+
pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
1689+
pwrap_write(wrp, dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
1690+
}
1691+
16561692
static int pwrap_init_cipher(struct pmic_wrapper *wrp)
16571693
{
16581694
int ret;
@@ -1689,10 +1725,11 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
16891725
}
16901726

16911727
/* Config cipher mode @PMIC */
1692-
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1);
1693-
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
1694-
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
1695-
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
1728+
pwrap_config_cipher(wrp, wrp->slave->dew_regs);
1729+
1730+
/* If there is any companion PMIC, configure cipher mode there too */
1731+
if (wrp->slave->comp_type > 0)
1732+
pwrap_config_cipher(wrp, wrp->slave->comp_dew_regs);
16961733

16971734
switch (wrp->slave->type) {
16981735
case PMIC_MT6397:
@@ -1754,6 +1791,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
17541791

17551792
static int pwrap_init_security(struct pmic_wrapper *wrp)
17561793
{
1794+
u32 crc_val;
17571795
int ret;
17581796

17591797
/* Enable encryption */
@@ -1762,14 +1800,21 @@ static int pwrap_init_security(struct pmic_wrapper *wrp)
17621800
return ret;
17631801

17641802
/* Signature checking - using CRC */
1765-
if (pwrap_write(wrp,
1766-
wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
1767-
return -EFAULT;
1803+
ret = pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1);
1804+
if (ret == 0 && wrp->slave->comp_dew_regs)
1805+
ret = pwrap_write(wrp, wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_EN], 0x1);
17681806

17691807
pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
17701808
pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
1771-
pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
1772-
PWRAP_SIG_ADR);
1809+
1810+
/* CRC value */
1811+
crc_val = wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL];
1812+
if (wrp->slave->comp_dew_regs)
1813+
crc_val |= wrp->slave->comp_dew_regs[PWRAP_DEW_CRC_VAL] << 16;
1814+
1815+
pwrap_writel(wrp, crc_val, PWRAP_SIG_ADR);
1816+
1817+
/* PMIC Wrapper Arbiter priority */
17731818
pwrap_writel(wrp,
17741819
wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
17751820

0 commit comments

Comments
 (0)