Commit 9855b3db authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'v4.14-next-soc' of https://github.com/mbgg/linux-mediatek into next/drivers

Pull "Mediatek: soc driver updates for v4.15" from Matthias Brugger:

- add 32 bit read/write support to pwrap
- add mt7622 support to pwrap
- test build all mediatek soc drivers
- fix compiler issues
- clean up Kconfig description

* tag 'v4.14-next-soc' of https://github.com/mbgg/linux-mediatek:
  soc: mediatek: pwrap: fix fatal compiler error
  soc: mediatek: pwrap: fix compiler errors
  arm64: mediatek: cleanup message for platform selection
  soc: Allow test-building of MediaTek drivers
  soc: mediatek: place Kconfig for all SoC drivers under menu
  soc: mediatek: pwrap: add support for MT7622 SoC
  soc: mediatek: pwrap: add common way for setup CS timing extenstion
  soc: mediatek: pwrap: add MediaTek MT6380 as one slave of pwrap
  soc: mediatek: pwrap: refactor pwrap_init for the various PMIC types
  soc: mediatek: pwrap: add pwrap_write32 for writing in 32-bit mode
  soc: mediatek: pwrap: add pwrap_read32 for reading in 32-bit mode
  dt-bindings: arm: mediatek: add MT7622 string to the PMIC wrapper doc
  ARM: mediatek: Cocci spatch "of_table"
  soc: mediatek: pwrap: fixup warnings from coding style
parents 84cbda2f f32fbbad
......@@ -19,6 +19,7 @@ IP Pairing
Required properties in pwrap device node.
- compatible:
"mediatek,mt2701-pwrap" for MT2701/7623 SoCs
"mediatek,mt7622-pwrap" for MT7622 SoCs
"mediatek,mt8135-pwrap" for MT8135 SoCs
"mediatek,mt8173-pwrap" for MT8173 SoCs
- interrupts: IRQ for pwrap in SOC
......@@ -36,9 +37,12 @@ Required properties in pwrap device node.
- clocks: Must contain an entry for each entry in clock-names.
Optional properities:
- pmic: Mediatek PMIC MFD is the child device of pwrap
- pmic: Using either MediaTek PMIC MFD as the child device of pwrap
See the following for child node definitions:
Documentation/devicetree/bindings/mfd/mt6397.txt
or the regulator-only device as the child device of pwrap, such as MT6380.
See the following definitions for such kinds of devices.
Documentation/devicetree/bindings/regulator/mt6380-regulator.txt
Example:
pwrap: pwrap@1000f000 {
......
......@@ -54,12 +54,14 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
{ .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
{ .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
{ .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot },
{},
};
static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
{ .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot },
{ .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot },
{ .compatible = "mediatek,mt7623a", .data = &mtk_mt7623_boot },
{},
};
static void __iomem *mtk_smp_base;
......
......@@ -91,12 +91,13 @@ config ARCH_HISI
This enables support for Hisilicon ARMv8 SoC family
config ARCH_MEDIATEK
bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
bool "MediaTek SoC Family"
select ARM_GIC
select PINCTRL
select MTK_TIMER
help
Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
This enables support for MediaTek MT27xx, MT65xx, MT76xx
& MT81xx ARMv8 SoCs
config ARCH_MESON
bool "Amlogic Platforms"
......
......@@ -10,7 +10,7 @@ obj-$(CONFIG_MACH_DOVE) += dove/
obj-y += fsl/
obj-$(CONFIG_ARCH_MXC) += imx/
obj-$(CONFIG_SOC_XWAY) += lantiq/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-y += mediatek/
obj-$(CONFIG_ARCH_MESON) += amlogic/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-y += renesas/
......
#
# MediaTek SoC drivers
#
menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
select REGMAP
help
Say yes here to add support for the MediaTek INFRACFG controller. The
......@@ -12,7 +14,6 @@ config MTK_INFRACFG
config MTK_PMIC_WRAP
tristate "MediaTek PMIC Wrapper Support"
depends on ARCH_MEDIATEK
depends on RESET_CONTROLLER
select REGMAP
help
......@@ -22,7 +23,6 @@ config MTK_PMIC_WRAP
config MTK_SCPSYS
bool "MediaTek SCPSYS Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
default ARCH_MEDIATEK
select REGMAP
select MTK_INFRACFG
......@@ -30,3 +30,5 @@ config MTK_SCPSYS
help
Say yes here to add support for the MediaTek SCPSYS power domain
driver.
endmenu
......@@ -70,6 +70,12 @@
PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
/* Group of bits used for shown slave capability */
#define PWRAP_SLV_CAP_SPI BIT(0)
#define PWRAP_SLV_CAP_DUALIO BIT(1)
#define PWRAP_SLV_CAP_SECURITY BIT(2)
#define HAS_CAP(_c, _x) (((_c) & (_x)) == (_x))
/* defines for slave device wrapper registers */
enum dew_regs {
PWRAP_DEW_BASE,
......@@ -208,6 +214,36 @@ enum pwrap_regs {
PWRAP_ADC_RDATA_ADDR1,
PWRAP_ADC_RDATA_ADDR2,
/* MT7622 only regs */
PWRAP_EINT_STA0_ADR,
PWRAP_EINT_STA1_ADR,
PWRAP_STA,
PWRAP_CLR,
PWRAP_DVFS_ADR8,
PWRAP_DVFS_WDATA8,
PWRAP_DVFS_ADR9,
PWRAP_DVFS_WDATA9,
PWRAP_DVFS_ADR10,
PWRAP_DVFS_WDATA10,
PWRAP_DVFS_ADR11,
PWRAP_DVFS_WDATA11,
PWRAP_DVFS_ADR12,
PWRAP_DVFS_WDATA12,
PWRAP_DVFS_ADR13,
PWRAP_DVFS_WDATA13,
PWRAP_DVFS_ADR14,
PWRAP_DVFS_WDATA14,
PWRAP_DVFS_ADR15,
PWRAP_DVFS_WDATA15,
PWRAP_EXT_CK,
PWRAP_ADC_RDATA_ADDR,
PWRAP_GPS_STA,
PWRAP_SW_RST,
PWRAP_DVFS_STEP_CTRL0,
PWRAP_DVFS_STEP_CTRL1,
PWRAP_DVFS_STEP_CTRL2,
PWRAP_SPI2_CTRL,
/* MT8135 only regs */
PWRAP_CSHEXT,
PWRAP_EVENT_IN_EN,
......@@ -330,6 +366,118 @@ static int mt2701_regs[] = {
[PWRAP_ADC_RDATA_ADDR2] = 0x154,
};
static int mt7622_regs[] = {
[PWRAP_MUX_SEL] = 0x0,
[PWRAP_WRAP_EN] = 0x4,
[PWRAP_DIO_EN] = 0x8,
[PWRAP_SIDLY] = 0xC,
[PWRAP_RDDMY] = 0x10,
[PWRAP_SI_CK_CON] = 0x14,
[PWRAP_CSHEXT_WRITE] = 0x18,
[PWRAP_CSHEXT_READ] = 0x1C,
[PWRAP_CSLEXT_START] = 0x20,
[PWRAP_CSLEXT_END] = 0x24,
[PWRAP_STAUPD_PRD] = 0x28,
[PWRAP_STAUPD_GRPEN] = 0x2C,
[PWRAP_EINT_STA0_ADR] = 0x30,
[PWRAP_EINT_STA1_ADR] = 0x34,
[PWRAP_STA] = 0x38,
[PWRAP_CLR] = 0x3C,
[PWRAP_STAUPD_MAN_TRIG] = 0x40,
[PWRAP_STAUPD_STA] = 0x44,
[PWRAP_WRAP_STA] = 0x48,
[PWRAP_HARB_INIT] = 0x4C,
[PWRAP_HARB_HPRIO] = 0x50,
[PWRAP_HIPRIO_ARB_EN] = 0x54,
[PWRAP_HARB_STA0] = 0x58,
[PWRAP_HARB_STA1] = 0x5C,
[PWRAP_MAN_EN] = 0x60,
[PWRAP_MAN_CMD] = 0x64,
[PWRAP_MAN_RDATA] = 0x68,
[PWRAP_MAN_VLDCLR] = 0x6C,
[PWRAP_WACS0_EN] = 0x70,
[PWRAP_INIT_DONE0] = 0x74,
[PWRAP_WACS0_CMD] = 0x78,
[PWRAP_WACS0_RDATA] = 0x7C,
[PWRAP_WACS0_VLDCLR] = 0x80,
[PWRAP_WACS1_EN] = 0x84,
[PWRAP_INIT_DONE1] = 0x88,
[PWRAP_WACS1_CMD] = 0x8C,
[PWRAP_WACS1_RDATA] = 0x90,
[PWRAP_WACS1_VLDCLR] = 0x94,
[PWRAP_WACS2_EN] = 0x98,
[PWRAP_INIT_DONE2] = 0x9C,
[PWRAP_WACS2_CMD] = 0xA0,
[PWRAP_WACS2_RDATA] = 0xA4,
[PWRAP_WACS2_VLDCLR] = 0xA8,
[PWRAP_INT_EN] = 0xAC,
[PWRAP_INT_FLG_RAW] = 0xB0,
[PWRAP_INT_FLG] = 0xB4,
[PWRAP_INT_CLR] = 0xB8,
[PWRAP_SIG_ADR] = 0xBC,
[PWRAP_SIG_MODE] = 0xC0,
[PWRAP_SIG_VALUE] = 0xC4,
[PWRAP_SIG_ERRVAL] = 0xC8,
[PWRAP_CRC_EN] = 0xCC,
[PWRAP_TIMER_EN] = 0xD0,
[PWRAP_TIMER_STA] = 0xD4,
[PWRAP_WDT_UNIT] = 0xD8,
[PWRAP_WDT_SRC_EN] = 0xDC,
[PWRAP_WDT_FLG] = 0xE0,
[PWRAP_DEBUG_INT_SEL] = 0xE4,
[PWRAP_DVFS_ADR0] = 0xE8,
[PWRAP_DVFS_WDATA0] = 0xEC,
[PWRAP_DVFS_ADR1] = 0xF0,
[PWRAP_DVFS_WDATA1] = 0xF4,
[PWRAP_DVFS_ADR2] = 0xF8,
[PWRAP_DVFS_WDATA2] = 0xFC,
[PWRAP_DVFS_ADR3] = 0x100,
[PWRAP_DVFS_WDATA3] = 0x104,
[PWRAP_DVFS_ADR4] = 0x108,
[PWRAP_DVFS_WDATA4] = 0x10C,
[PWRAP_DVFS_ADR5] = 0x110,
[PWRAP_DVFS_WDATA5] = 0x114,
[PWRAP_DVFS_ADR6] = 0x118,
[PWRAP_DVFS_WDATA6] = 0x11C,
[PWRAP_DVFS_ADR7] = 0x120,
[PWRAP_DVFS_WDATA7] = 0x124,
[PWRAP_DVFS_ADR8] = 0x128,
[PWRAP_DVFS_WDATA8] = 0x12C,
[PWRAP_DVFS_ADR9] = 0x130,
[PWRAP_DVFS_WDATA9] = 0x134,
[PWRAP_DVFS_ADR10] = 0x138,
[PWRAP_DVFS_WDATA10] = 0x13C,
[PWRAP_DVFS_ADR11] = 0x140,
[PWRAP_DVFS_WDATA11] = 0x144,
[PWRAP_DVFS_ADR12] = 0x148,
[PWRAP_DVFS_WDATA12] = 0x14C,
[PWRAP_DVFS_ADR13] = 0x150,
[PWRAP_DVFS_WDATA13] = 0x154,
[PWRAP_DVFS_ADR14] = 0x158,
[PWRAP_DVFS_WDATA14] = 0x15C,
[PWRAP_DVFS_ADR15] = 0x160,
[PWRAP_DVFS_WDATA15] = 0x164,
[PWRAP_SPMINF_STA] = 0x168,
[PWRAP_CIPHER_KEY_SEL] = 0x16C,
[PWRAP_CIPHER_IV_SEL] = 0x170,
[PWRAP_CIPHER_EN] = 0x174,
[PWRAP_CIPHER_RDY] = 0x178,
[PWRAP_CIPHER_MODE] = 0x17C,
[PWRAP_CIPHER_SWRST] = 0x180,
[PWRAP_DCM_EN] = 0x184,
[PWRAP_DCM_DBC_PRD] = 0x188,
[PWRAP_EXT_CK] = 0x18C,
[PWRAP_ADC_CMD_ADDR] = 0x190,
[PWRAP_PWRAP_ADC_CMD] = 0x194,
[PWRAP_ADC_RDATA_ADDR] = 0x198,
[PWRAP_GPS_STA] = 0x19C,
[PWRAP_SW_RST] = 0x1A0,
[PWRAP_DVFS_STEP_CTRL0] = 0x238,
[PWRAP_DVFS_STEP_CTRL1] = 0x23C,
[PWRAP_DVFS_STEP_CTRL2] = 0x240,
[PWRAP_SPI2_CTRL] = 0x244,
};
static int mt8173_regs[] = {
[PWRAP_MUX_SEL] = 0x0,
[PWRAP_WRAP_EN] = 0x4,
......@@ -487,18 +635,31 @@ static int mt8135_regs[] = {
enum pmic_type {
PMIC_MT6323,
PMIC_MT6380,
PMIC_MT6397,
};
enum pwrap_type {
PWRAP_MT2701,
PWRAP_MT7622,
PWRAP_MT8135,
PWRAP_MT8173,
};
struct pmic_wrapper;
struct pwrap_slv_type {
const u32 *dew_regs;
enum pmic_type type;
const struct regmap_config *regmap;
/* Flags indicating the capability for the target slave */
u32 caps;
/*
* pwrap operations are highly associated with the PMIC types,
* so the pointers added increases flexibility allowing determination
* which type is used by the detection through device tree.
*/
int (*pwrap_read)(struct pmic_wrapper *wrp, u32 adr, u32 *rdata);
int (*pwrap_write)(struct pmic_wrapper *wrp, u32 adr, u32 wdata);
};
struct pmic_wrapper {
......@@ -522,7 +683,7 @@ struct pmic_wrapper_type {
u32 int_en_all;
u32 spi_w;
u32 wdt_src;
int has_bridge:1;
unsigned int has_bridge:1;
int (*init_reg_clock)(struct pmic_wrapper *wrp);
int (*init_soc_specific)(struct pmic_wrapper *wrp);
};
......@@ -593,7 +754,7 @@ static int pwrap_wait_for_state(struct pmic_wrapper *wrp,
} while (1);
}
static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
static int pwrap_read16(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
{
int ret;
......@@ -603,35 +764,102 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
return ret;
}
pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
PWRAP_WACS2_CMD);
pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD);
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr);
if (ret)
return ret;
*rdata = PWRAP_GET_WACS_RDATA(pwrap_readl(wrp, PWRAP_WACS2_RDATA));
pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
return 0;
}
static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
static int pwrap_read32(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
{
int ret;
int ret, msb;
*rdata = 0;
for (msb = 0; msb < 2; msb++) {
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
if (ret) {
pwrap_leave_fsm_vldclr(wrp);
return ret;
}
pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD);
pwrap_writel(wrp, ((msb << 30) | (adr << 16)),
PWRAP_WACS2_CMD);
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr);
if (ret)
return ret;
*rdata = PWRAP_GET_WACS_RDATA(pwrap_readl(wrp, PWRAP_WACS2_RDATA));
*rdata += (PWRAP_GET_WACS_RDATA(pwrap_readl(wrp,
PWRAP_WACS2_RDATA)) << (16 * msb));
pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
}
return 0;
}
static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
{
return wrp->slave->pwrap_read(wrp, adr, rdata);
}
static int pwrap_write16(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
{
int ret;
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
if (ret) {
pwrap_leave_fsm_vldclr(wrp);
return ret;
}
pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
PWRAP_WACS2_CMD);
return 0;
}
static int pwrap_write32(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
{
int ret, msb, rdata;
for (msb = 0; msb < 2; msb++) {
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
if (ret) {
pwrap_leave_fsm_vldclr(wrp);
return ret;
}
pwrap_writel(wrp, (1 << 31) | (msb << 30) | (adr << 16) |
((wdata >> (msb * 16)) & 0xffff),
PWRAP_WACS2_CMD);
/*
* The pwrap_read operation is the requirement of hardware used
* for the synchronization between two successive 16-bit
* pwrap_writel operations composing one 32-bit bus writing.
* Otherwise, we'll find the result fails on the lower 16-bit
* pwrap writing.
*/
if (!msb)
pwrap_read(wrp, adr, &rdata);
}
return 0;
}
static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
{
return wrp->slave->pwrap_write(wrp, adr, wdata);
}
static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata)
{
return pwrap_read(context, adr, rdata);
......@@ -711,23 +939,75 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
return 0;
}
static int pwrap_mt8135_init_reg_clock(struct pmic_wrapper *wrp)
static int pwrap_init_dual_io(struct pmic_wrapper *wrp)
{
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
int ret;
u32 rdata;
/* Enable dual IO mode */
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
/* Check IDLE & INIT_DONE in advance */
ret = pwrap_wait_for_state(wrp,
pwrap_is_fsm_idle_and_sync_idle);
if (ret) {
dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
return ret;
}
pwrap_writel(wrp, 1, PWRAP_DIO_EN);
/* Read Test */
pwrap_read(wrp,
wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
if (rdata != PWRAP_DEW_READ_TEST_VAL) {
dev_err(wrp->dev,
"Read failed on DIO mode: 0x%04x!=0x%04x\n",
PWRAP_DEW_READ_TEST_VAL, rdata);
return -EFAULT;
}
return 0;
}
static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
/*
* pwrap_init_chip_select_ext is used to configure CS extension time for each
* phase during data transactions on the pwrap bus.
*/
static void pwrap_init_chip_select_ext(struct pmic_wrapper *wrp, u8 hext_write,
u8 hext_read, u8 lext_start,
u8 lext_end)
{
pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
/*
* After finishing a write and read transaction, extends CS high time
* to be at least xT of BUS CLK as hext_write and hext_read specifies
* respectively.
*/
pwrap_writel(wrp, hext_write, PWRAP_CSHEXT_WRITE);
pwrap_writel(wrp, hext_read, PWRAP_CSHEXT_READ);
/*
* Extends CS low time after CSL and before CSH command to be at
* least xT of BUS CLK as lext_start and lext_end specifies
* respectively.
*/
pwrap_writel(wrp, lext_start, PWRAP_CSLEXT_START);
pwrap_writel(wrp, lext_end, PWRAP_CSLEXT_END);
}
static int pwrap_common_init_reg_clock(struct pmic_wrapper *wrp)
{
switch (wrp->master->type) {
case PWRAP_MT8173:
pwrap_init_chip_select_ext(wrp, 0, 4, 2, 2);
break;
case PWRAP_MT8135:
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
pwrap_init_chip_select_ext(wrp, 0, 4, 0, 0);
break;
default:
break;
}
return 0;
}
......@@ -737,20 +1017,16 @@ static int pwrap_mt2701_init_reg_clock(struct pmic_wrapper *wrp)
switch (wrp->slave->type) {
case PMIC_MT6397:
pwrap_writel(wrp, 0xc, PWRAP_RDDMY);
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE);
pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
pwrap_init_chip_select_ext(wrp, 4, 0, 2, 2);
break;
case PMIC_MT6323:
pwrap_writel(wrp, 0x8, PWRAP_RDDMY);
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_RDDMY_NO],
0x8);
pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE);
pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
pwrap_init_chip_select_ext(wrp, 5, 0, 2, 2);
break;
default:
break;
}
......@@ -794,6 +1070,9 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
case PWRAP_MT8173:
pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
break;
case PWRAP_MT7622:
pwrap_writel(wrp, 0, PWRAP_CIPHER_EN);
break;
}
/* Config cipher mode @PMIC */
......@@ -815,6 +1094,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
0x1);
break;
default:
break;
}
/* wait for cipher data ready@AP */
......@@ -827,7 +1108,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
/* wait for cipher data ready@PMIC */
ret = pwrap_wait_for_state(wrp, pwrap_is_pmic_cipher_ready);
if (ret) {
dev_err(wrp->dev, "timeout waiting for cipher data ready@PMIC\n");
dev_err(wrp->dev,
"timeout waiting for cipher data ready@PMIC\n");
return ret;
}
......@@ -854,6 +1136,30 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
return 0;
}
static int pwrap_init_security(struct pmic_wrapper *wrp)
{
int ret;
/* Enable encryption */
ret = pwrap_init_cipher(wrp);
if (ret)
return ret;
/* Signature checking - using CRC */
if (pwrap_write(wrp,
wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
return -EFAULT;
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);
pwrap_writel(wrp,
wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
return 0;
}
static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
{
/* enable pwrap events and pwrap bridge in AP side */
......@@ -911,10 +1217,18 @@ static int pwrap_mt2701_init_soc_specific(struct pmic_wrapper *wrp)
return 0;
}
static int pwrap_mt7622_init_soc_specific(struct pmic_wrapper *wrp)
{
pwrap_writel(wrp, 0, PWRAP_STAUPD_PRD);
/* enable 2wire SPI master */
pwrap_writel(wrp, 0x8000000, PWRAP_SPI2_CTRL);
return 0;
}
static int pwrap_init(struct pmic_wrapper *wrp)
{
int ret;
u32 rdata;
reset_control_reset(wrp->rstc);
if (wrp->rstc_bridge)
......@@ -926,10 +1240,12 @@ static int pwrap_init(struct pmic_wrapper *wrp)
pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
}
if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SPI)) {
/* Reset SPI slave */
ret = pwrap_reset_spislave(wrp);
if (ret)
return ret;
}
pwrap_writel(wrp, 1, PWRAP_WRAP_EN);
......@@ -941,45 +1257,26 @@ static int pwrap_init(struct pmic_wrapper *wrp)
if (ret)
return ret;
if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SPI)) {
/* Setup serial input delay */
ret = pwrap_init_sidly(wrp);
if (ret)
return ret;
/* Enable dual IO mode */
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
/* Check IDLE & INIT_DONE in advance */
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
if (ret) {
dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
return ret;
}
pwrap_writel(wrp, 1, PWRAP_DIO_EN);
/* Read Test */
pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
if (rdata != PWRAP_DEW_READ_TEST_VAL) {
dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
PWRAP_DEW_READ_TEST_VAL, rdata);
return -EFAULT;
if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_DUALIO)) {
/* Enable dual I/O mode */
ret = pwrap_init_dual_io(wrp);
if (ret)
return ret;
}
/* Enable encryption */
ret = pwrap_init_cipher(wrp);
if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SECURITY)) {
/* Enable security on bus */
ret = pwrap_init_security(wrp);
if (ret)
return ret;
/* Signature checking - using CRC */
if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
return -EFAULT;
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);
pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
}
if (wrp->master->type == PWRAP_MT8135)
pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
......@@ -1023,7 +1320,7 @@ static irqreturn_t pwrap_interrupt(int irqno, void *dev_id)
return IRQ_HANDLED;
}
static const struct regmap_config pwrap_regmap_config = {
static const struct regmap_config pwrap_regmap_config16 = {
.reg_bits = 16,
.val_bits = 16,
.reg_stride = 2,
......@@ -1032,20 +1329,54 @@ static const struct regmap_config pwrap_regmap_config = {
.max_register = 0xffff,
};
static const struct regmap_config pwrap_regmap_config32 = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.reg_read = pwrap_regmap_read,
.reg_write = pwrap_regmap_write,
.max_register = 0xffff,
};
static const struct pwrap_slv_type pmic_mt6323 = {
.dew_regs = mt6323_regs,
.type = PMIC_MT6323,
.regmap = &pwrap_regmap_config16,
.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
PWRAP_SLV_CAP_SECURITY,
.pwrap_read = pwrap_read16,
.pwrap_write = pwrap_write16,
};
static const struct pwrap_slv_type pmic_mt6380 = {
.dew_regs = NULL,
.type = PMIC_MT6380,
.regmap = &pwrap_regmap_config32,
.caps = 0,
.pwrap_read = pwrap_read32,
.pwrap_write = pwrap_write32,
};
static const struct pwrap_slv_type pmic_mt6397 = {
.dew_regs = mt6397_regs,
.type = PMIC_MT6397,
.regmap = &pwrap_regmap_config16,
.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
PWRAP_SLV_CAP_SECURITY,
.pwrap_read = pwrap_read16,
.pwrap_write = pwrap_write16,
};
static const struct of_device_id of_slave_match_tbl[] = {
{
.compatible = "mediatek,mt6323",
.data = &pmic_mt6323,
}, {
/* The MT6380 PMIC only implements a regulator, so we bind it
* directly instead of using a MFD.
*/
.compatible = "mediatek,mt6380-regulator",
.data = &pmic_mt6380,
}, {
.compatible = "mediatek,mt6397",
.data = &pmic_mt6397,
......@@ -1067,6 +1398,18 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
.init_soc_specific = pwrap_mt2701_init_soc_specific,
};
static const struct pmic_wrapper_type pwrap_mt7622 = {
.regs = mt7622_regs,
.type = PWRAP_MT7622,
.arb_en_all = 0xff,
.int_en_all = ~(u32)BIT(31),
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
.has_bridge = 0,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt7622_init_soc_specific,
};
static const struct pmic_wrapper_type pwrap_mt8135 = {
.regs = mt8135_regs,
.type = PWRAP_MT8135,
......@@ -1075,7 +1418,7 @@ static const struct pmic_wrapper_type pwrap_mt8135 = {
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
.has_bridge = 1,
.init_reg_clock = pwrap_mt8135_init_reg_clock,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt8135_init_soc_specific,
};
......@@ -1087,7 +1430,7 @@ static const struct pmic_wrapper_type pwrap_mt8173 = {
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
.has_bridge = 0,
.init_reg_clock = pwrap_mt8173_init_reg_clock,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt8173_init_soc_specific,
};
......@@ -1095,6 +1438,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
{
.compatible = "mediatek,mt2701-pwrap",
.data = &pwrap_mt2701,
}, {
.compatible = "mediatek,mt7622-pwrap",
.data = &pwrap_mt7622,
}, {
.compatible = "mediatek,mt8135-pwrap",
.data = &pwrap_mt8135,
......@@ -1159,23 +1505,27 @@ static int pwrap_probe(struct platform_device *pdev)
if (IS_ERR(wrp->bridge_base))
return PTR_ERR(wrp->bridge_base);
wrp->rstc_bridge = devm_reset_control_get(wrp->dev, "pwrap-bridge");
wrp->rstc_bridge = devm_reset_control_get(wrp->dev,
"pwrap-bridge");
if (IS_ERR(wrp->rstc_bridge)) {
ret = PTR_ERR(wrp->rstc_bridge);
dev_dbg(wrp->dev, "cannot get pwrap-bridge reset: %d\n", ret);
dev_dbg(wrp->dev,
"cannot get pwrap-bridge reset: %d\n", ret);
return ret;
}
}
wrp->clk_spi = devm_clk_get(wrp->dev, "spi");
if (IS_ERR(wrp->clk_spi)) {
dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_spi));
dev_dbg(wrp->dev, "failed to get clock: %ld\n",
PTR_ERR(wrp->clk_spi));
return PTR_ERR(wrp->clk_spi);
}
wrp->clk_wrap = devm_clk_get(wrp->dev, "wrap");
if (IS_ERR(wrp->clk_wrap)) {
dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_wrap));
dev_dbg(wrp->dev, "failed to get clock: %ld\n",
PTR_ERR(wrp->clk_wrap));
return PTR_ERR(wrp->clk_wrap);
}
......@@ -1220,12 +1570,13 @@ static int pwrap_probe(struct platform_device *pdev)
pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt,
IRQF_TRIGGER_HIGH,
"mt-pmic-pwrap", wrp);
if (ret)
goto err_out2;
wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, &pwrap_regmap_config);
wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, wrp->slave->regmap);
if (IS_ERR(wrp->regmap)) {
ret = PTR_ERR(wrp->regmap);
goto err_out2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment