Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b28d78cd authored by John Crispin's avatar John Crispin Committed by Matthias Brugger
Browse files

soc: mediatek: PMIC wrap: add a slave specific struct



This patch adds a new struct pwrap_slv_type that we use to store the slave
specific data. The patch adds 2 new helper functions to access the dew
registers. The slave type is looked up via the wrappers child node.

Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
Signed-off-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
parent 25269cef
Loading
Loading
Loading
Loading
+112 −47
Original line number Original line Diff line number Diff line
@@ -69,33 +69,54 @@
					  PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
					  PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
					  PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
					  PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)


/* macro for slave device wrapper registers */
/* defines for slave device wrapper registers */
#define PWRAP_DEW_BASE			0xbc00
enum dew_regs {
#define PWRAP_DEW_EVENT_OUT_EN		(PWRAP_DEW_BASE + 0x0)
	PWRAP_DEW_BASE,
#define PWRAP_DEW_DIO_EN		(PWRAP_DEW_BASE + 0x2)
	PWRAP_DEW_DIO_EN,
#define PWRAP_DEW_EVENT_SRC_EN		(PWRAP_DEW_BASE + 0x4)
	PWRAP_DEW_READ_TEST,
#define PWRAP_DEW_EVENT_SRC		(PWRAP_DEW_BASE + 0x6)
	PWRAP_DEW_WRITE_TEST,
#define PWRAP_DEW_EVENT_FLAG		(PWRAP_DEW_BASE + 0x8)
	PWRAP_DEW_CRC_EN,
#define PWRAP_DEW_READ_TEST		(PWRAP_DEW_BASE + 0xa)
	PWRAP_DEW_CRC_VAL,
#define PWRAP_DEW_WRITE_TEST		(PWRAP_DEW_BASE + 0xc)
	PWRAP_DEW_MON_GRP_SEL,
#define PWRAP_DEW_CRC_EN		(PWRAP_DEW_BASE + 0xe)
	PWRAP_DEW_CIPHER_KEY_SEL,
#define PWRAP_DEW_CRC_VAL		(PWRAP_DEW_BASE + 0x10)
	PWRAP_DEW_CIPHER_IV_SEL,
#define PWRAP_DEW_MON_GRP_SEL		(PWRAP_DEW_BASE + 0x12)
	PWRAP_DEW_CIPHER_RDY,
#define PWRAP_DEW_MON_FLAG_SEL		(PWRAP_DEW_BASE + 0x14)
	PWRAP_DEW_CIPHER_MODE,
#define PWRAP_DEW_EVENT_TEST		(PWRAP_DEW_BASE + 0x16)
	PWRAP_DEW_CIPHER_SWRST,
#define PWRAP_DEW_CIPHER_KEY_SEL	(PWRAP_DEW_BASE + 0x18)

#define PWRAP_DEW_CIPHER_IV_SEL		(PWRAP_DEW_BASE + 0x1a)
	/* MT6397 only regs */
#define PWRAP_DEW_CIPHER_LOAD		(PWRAP_DEW_BASE + 0x1c)
	PWRAP_DEW_EVENT_OUT_EN,
#define PWRAP_DEW_CIPHER_START		(PWRAP_DEW_BASE + 0x1e)
	PWRAP_DEW_EVENT_SRC_EN,
#define PWRAP_DEW_CIPHER_RDY		(PWRAP_DEW_BASE + 0x20)
	PWRAP_DEW_EVENT_SRC,
#define PWRAP_DEW_CIPHER_MODE		(PWRAP_DEW_BASE + 0x22)
	PWRAP_DEW_EVENT_FLAG,
#define PWRAP_DEW_CIPHER_SWRST		(PWRAP_DEW_BASE + 0x24)
	PWRAP_DEW_MON_FLAG_SEL,
#define PWRAP_MT8173_DEW_CIPHER_IV0	(PWRAP_DEW_BASE + 0x26)
	PWRAP_DEW_EVENT_TEST,
#define PWRAP_MT8173_DEW_CIPHER_IV1	(PWRAP_DEW_BASE + 0x28)
	PWRAP_DEW_CIPHER_LOAD,
#define PWRAP_MT8173_DEW_CIPHER_IV2	(PWRAP_DEW_BASE + 0x2a)
	PWRAP_DEW_CIPHER_START,
#define PWRAP_MT8173_DEW_CIPHER_IV3	(PWRAP_DEW_BASE + 0x2c)
};
#define PWRAP_MT8173_DEW_CIPHER_IV4	(PWRAP_DEW_BASE + 0x2e)

#define PWRAP_MT8173_DEW_CIPHER_IV5	(PWRAP_DEW_BASE + 0x30)
static const u32 mt6397_regs[] = {
	[PWRAP_DEW_BASE] =		0xbc00,
	[PWRAP_DEW_EVENT_OUT_EN] =	0xbc00,
	[PWRAP_DEW_DIO_EN] =		0xbc02,
	[PWRAP_DEW_EVENT_SRC_EN] =	0xbc04,
	[PWRAP_DEW_EVENT_SRC] =		0xbc06,
	[PWRAP_DEW_EVENT_FLAG] =	0xbc08,
	[PWRAP_DEW_READ_TEST] =		0xbc0a,
	[PWRAP_DEW_WRITE_TEST] =	0xbc0c,
	[PWRAP_DEW_CRC_EN] =		0xbc0e,
	[PWRAP_DEW_CRC_VAL] =		0xbc10,
	[PWRAP_DEW_MON_GRP_SEL] =	0xbc12,
	[PWRAP_DEW_MON_FLAG_SEL] =	0xbc14,
	[PWRAP_DEW_EVENT_TEST] =	0xbc16,
	[PWRAP_DEW_CIPHER_KEY_SEL] =	0xbc18,
	[PWRAP_DEW_CIPHER_IV_SEL] =	0xbc1a,
	[PWRAP_DEW_CIPHER_LOAD] =	0xbc1c,
	[PWRAP_DEW_CIPHER_START] =	0xbc1e,
	[PWRAP_DEW_CIPHER_RDY] =	0xbc20,
	[PWRAP_DEW_CIPHER_MODE] =	0xbc22,
	[PWRAP_DEW_CIPHER_SWRST] =	0xbc24,
};


enum pwrap_regs {
enum pwrap_regs {
	PWRAP_MUX_SEL,
	PWRAP_MUX_SEL,
@@ -349,16 +370,26 @@ static int mt8135_regs[] = {
	[PWRAP_DCM_DBC_PRD] =		0x160,
	[PWRAP_DCM_DBC_PRD] =		0x160,
};
};


enum pmic_type {
	PMIC_MT6397,
};

enum pwrap_type {
enum pwrap_type {
	PWRAP_MT8135,
	PWRAP_MT8135,
	PWRAP_MT8173,
	PWRAP_MT8173,
};
};


struct pwrap_slv_type {
	const u32 *dew_regs;
	enum pmic_type type;
};

struct pmic_wrapper {
struct pmic_wrapper {
	struct device *dev;
	struct device *dev;
	void __iomem *base;
	void __iomem *base;
	struct regmap *regmap;
	struct regmap *regmap;
	const struct pmic_wrapper_type *master;
	const struct pmic_wrapper_type *master;
	const struct pwrap_slv_type *slave;
	struct clk *clk_spi;
	struct clk *clk_spi;
	struct clk *clk_wrap;
	struct clk *clk_wrap;
	struct reset_control *rstc;
	struct reset_control *rstc;
@@ -544,7 +575,8 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)


	for (i = 0; i < 4; i++) {
	for (i = 0; i < 4; i++) {
		pwrap_writel(wrp, i, PWRAP_SIDLY);
		pwrap_writel(wrp, i, PWRAP_SIDLY);
		pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
		pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST],
			   &rdata);
		if (rdata == PWRAP_DEW_READ_TEST_VAL) {
		if (rdata == PWRAP_DEW_READ_TEST_VAL) {
			dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
			dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
			pass |= 1 << i;
			pass |= 1 << i;
@@ -593,7 +625,8 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
	u32 rdata;
	u32 rdata;
	int ret;
	int ret;


	ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
	ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
			 &rdata);
	if (ret)
	if (ret)
		return 0;
		return 0;


@@ -621,12 +654,12 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
	}
	}


	/* Config cipher mode @PMIC */
	/* Config cipher mode @PMIC */
	pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1);
	pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
	pwrap_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
	pwrap_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
	pwrap_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
	pwrap_write(wrp, PWRAP_DEW_CIPHER_START, 0x1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);


	/* wait for cipher data ready@AP */
	/* wait for cipher data ready@AP */
	ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
	ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
@@ -643,7 +676,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
	}
	}


	/* wait for cipher mode idle */
	/* wait for cipher mode idle */
	pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_MODE], 0x1);
	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
	if (ret) {
	if (ret) {
		dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
		dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
@@ -653,8 +686,10 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
	pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE);
	pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE);


	/* Write Test */
	/* Write Test */
	if (pwrap_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) ||
	if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
	    pwrap_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) ||
			PWRAP_DEW_WRITE_TEST_VAL) ||
	    pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
		       &rdata) ||
	    (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
	    (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
		dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
		dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
		return -EFAULT;
		return -EFAULT;
@@ -677,8 +712,10 @@ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
	writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
	writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);


	/* enable PMIC event out and sources */
	/* enable PMIC event out and sources */
	if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
	if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
		pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
			0x1) ||
	    pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
			0xffff)) {
		dev_err(wrp->dev, "enable dewrap fail\n");
		dev_err(wrp->dev, "enable dewrap fail\n");
		return -EFAULT;
		return -EFAULT;
	}
	}
@@ -689,8 +726,10 @@ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
{
{
	/* PMIC_DEWRAP enables */
	/* PMIC_DEWRAP enables */
	if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
	if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
		pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
			0x1) ||
	    pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
			0xffff)) {
		dev_err(wrp->dev, "enable dewrap fail\n");
		dev_err(wrp->dev, "enable dewrap fail\n");
		return -EFAULT;
		return -EFAULT;
	}
	}
@@ -734,7 +773,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
		return ret;
		return ret;


	/* Enable dual IO mode */
	/* Enable dual IO mode */
	pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1);
	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);


	/* Check IDLE & INIT_DONE in advance */
	/* Check IDLE & INIT_DONE in advance */
	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
@@ -746,7 +785,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
	pwrap_writel(wrp, 1, PWRAP_DIO_EN);
	pwrap_writel(wrp, 1, PWRAP_DIO_EN);


	/* Read Test */
	/* Read Test */
	pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
	pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
	if (rdata != PWRAP_DEW_READ_TEST_VAL) {
	if (rdata != PWRAP_DEW_READ_TEST_VAL) {
		dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
		dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
				PWRAP_DEW_READ_TEST_VAL, rdata);
				PWRAP_DEW_READ_TEST_VAL, rdata);
@@ -759,12 +798,13 @@ static int pwrap_init(struct pmic_wrapper *wrp)
		return ret;
		return ret;


	/* Signature checking - using CRC */
	/* Signature checking - using CRC */
	if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
	if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
		return -EFAULT;
		return -EFAULT;


	pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
	pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
	pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
	pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
	pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
	pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
		     PWRAP_SIG_ADR);
	pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
	pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);


	if (wrp->master->type == PWRAP_MT8135)
	if (wrp->master->type == PWRAP_MT8135)
@@ -818,6 +858,21 @@ static const struct regmap_config pwrap_regmap_config = {
	.max_register = 0xffff,
	.max_register = 0xffff,
};
};


static const struct pwrap_slv_type pmic_mt6397 = {
	.dew_regs = mt6397_regs,
	.type = PMIC_MT6397,
};

static const struct of_device_id of_slave_match_tbl[] = {
	{
		.compatible = "mediatek,mt6397",
		.data = &pmic_mt6397,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, of_slave_match_tbl);

static struct pmic_wrapper_type pwrap_mt8135 = {
static struct pmic_wrapper_type pwrap_mt8135 = {
	.regs = mt8135_regs,
	.regs = mt8135_regs,
	.type = PWRAP_MT8135,
	.type = PWRAP_MT8135,
@@ -862,8 +917,17 @@ static int pwrap_probe(struct platform_device *pdev)
	struct device_node *np = pdev->dev.of_node;
	struct device_node *np = pdev->dev.of_node;
	const struct of_device_id *of_id =
	const struct of_device_id *of_id =
		of_match_device(of_pwrap_match_tbl, &pdev->dev);
		of_match_device(of_pwrap_match_tbl, &pdev->dev);
	const struct of_device_id *of_slave_id = NULL;
	struct resource *res;
	struct resource *res;


	if (pdev->dev.of_node->child)
		of_slave_id = of_match_node(of_slave_match_tbl,
					    pdev->dev.of_node->child);
	if (!of_slave_id) {
		dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n");
		return -EINVAL;
	}

	wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
	wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
	if (!wrp)
	if (!wrp)
		return -ENOMEM;
		return -ENOMEM;
@@ -871,6 +935,7 @@ static int pwrap_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, wrp);
	platform_set_drvdata(pdev, wrp);


	wrp->master = of_id->data;
	wrp->master = of_id->data;
	wrp->slave = of_slave_id->data;
	wrp->dev = &pdev->dev;
	wrp->dev = &pdev->dev;


	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");