mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 13:58:46 +00:00
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>
This commit is contained in:
parent
2eb2730234
commit
41ae95aaa0
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user