Commit 9da95d8f authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

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

Pull "arm: mediatek: soc updates for v4.14" from Matthias Brugger:

- add mt7623a smp support
- scpsys: reduce code duplication
- scpsys: add mt7622 support
- pmic wrapper: make of_device_ids constant

* tag 'v4.13-next-soc' of https://github.com/mbgg/linux-mediatek:
  soc: mediatek: add SCPSYS power domain driver for MediaTek MT7622 SoC
  soc: mediatek: add header files required for MT7622 SCPSYS dt-binding
  soc: mediatek: reduce code duplication of scpsys_probe across all SoCs
  dt-bindings: soc: update the binding document for SCPSYS on MediaTek MT7622 SoC
  soc: mtk-pmic-wrap: make of_device_ids const.
  ARM: mediatek: add MT7623a smp bringup code
parents 87a1cb5b 52510ee9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@ power/power_domain.txt. It provides the power domains defined in
- include/dt-bindings/power/mt8173-power.h
- include/dt-bindings/power/mt6797-power.h
- include/dt-bindings/power/mt2701-power.h
- include/dt-bindings/power/mt7622-power.h

Required properties:
- compatible: Should be one of:
	- "mediatek,mt2701-scpsys"
	- "mediatek,mt6797-scpsys"
	- "mediatek,mt7622-scpsys"
	- "mediatek,mt8173-scpsys"
- #power-domain-cells: Must be 1
- reg: Address range of the SCPSYS unit
@@ -26,6 +28,7 @@ Required properties:
                      enabled before enabling certain power domains.
	Required clocks for MT2701: "mm", "mfg", "ethif"
	Required clocks for MT6797: "mm", "mfg", "vdec"
	Required clocks for MT7622: "hif_sel"
	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"

Optional properties:
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ static void __init mediatek_timer_init(void)

	if (of_machine_is_compatible("mediatek,mt6589") ||
	    of_machine_is_compatible("mediatek,mt7623") ||
	    of_machine_is_compatible("mediatek,mt7623a") ||
	    of_machine_is_compatible("mediatek,mt8135") ||
	    of_machine_is_compatible("mediatek,mt8127")) {
		/* turn on GPT6 which ungates arch timer clocks */
@@ -49,6 +50,7 @@ static const char * const mediatek_board_dt_compat[] = {
	"mediatek,mt6589",
	"mediatek,mt6592",
	"mediatek,mt7623",
	"mediatek,mt7623a",
	"mediatek,mt8127",
	"mediatek,mt8135",
	NULL,
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
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;
+3 −3
Original line number Diff line number Diff line
@@ -1067,7 +1067,7 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
	.init_soc_specific = pwrap_mt2701_init_soc_specific,
};

static struct pmic_wrapper_type pwrap_mt8135 = {
static const struct pmic_wrapper_type pwrap_mt8135 = {
	.regs = mt8135_regs,
	.type = PWRAP_MT8135,
	.arb_en_all = 0x1ff,
@@ -1079,7 +1079,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
	.init_soc_specific = pwrap_mt8135_init_soc_specific,
};

static struct pmic_wrapper_type pwrap_mt8173 = {
static const struct pmic_wrapper_type pwrap_mt8173 = {
	.regs = mt8173_regs,
	.type = PWRAP_MT8173,
	.arb_en_all = 0x3f,
@@ -1091,7 +1091,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
	.init_soc_specific = pwrap_mt8173_init_soc_specific,
};

static struct of_device_id of_pwrap_match_tbl[] = {
static const struct of_device_id of_pwrap_match_tbl[] = {
	{
		.compatible = "mediatek,mt2701-pwrap",
		.data = &pwrap_mt2701,
+147 −100
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <dt-bindings/power/mt2701-power.h>
#include <dt-bindings/power/mt6797-power.h>
#include <dt-bindings/power/mt7622-power.h>
#include <dt-bindings/power/mt8173-power.h>

#define SPM_VDE_PWR_CON			0x0210
@@ -39,6 +40,11 @@
#define SPM_MFG_2D_PWR_CON		0x02c0
#define SPM_MFG_ASYNC_PWR_CON		0x02c4
#define SPM_USB_PWR_CON			0x02cc
#define SPM_ETHSYS_PWR_CON		0x02e0	/* MT7622 */
#define SPM_HIF0_PWR_CON		0x02e4	/* MT7622 */
#define SPM_HIF1_PWR_CON		0x02e8	/* MT7622 */
#define SPM_WB_PWR_CON			0x02ec	/* MT7622 */


#define SPM_PWR_STATUS			0x060c
#define SPM_PWR_STATUS_2ND		0x0610
@@ -64,6 +70,10 @@
#define PWR_STATUS_MFG_ASYNC		BIT(23)
#define PWR_STATUS_AUDIO		BIT(24)
#define PWR_STATUS_USB			BIT(25)
#define PWR_STATUS_ETHSYS		BIT(24)	/* MT7622 */
#define PWR_STATUS_HIF0			BIT(25)	/* MT7622 */
#define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
#define PWR_STATUS_WB			BIT(27)	/* MT7622 */

enum clk_id {
	CLK_NONE,
@@ -73,6 +83,7 @@ enum clk_id {
	CLK_VENC_LT,
	CLK_ETHIF,
	CLK_VDEC,
	CLK_HIFSEL,
	CLK_MAX,
};

@@ -84,6 +95,7 @@ static const char * const clk_names[] = {
	"venc_lt",
	"ethif",
	"vdec",
	"hif_sel",
	NULL,
};

@@ -124,6 +136,19 @@ struct scp {
	struct scp_ctrl_reg ctrl_reg;
};

struct scp_subdomain {
	int origin;
	int subdomain;
};

struct scp_soc_data {
	const struct scp_domain_data *domains;
	int num_domains;
	const struct scp_subdomain *subdomains;
	int num_subdomains;
	const struct scp_ctrl_reg regs;
};

static int scpsys_domain_is_on(struct scp_domain *scpd)
{
	struct scp *scp = scpd->scp;
@@ -357,7 +382,7 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)

static struct scp *init_scp(struct platform_device *pdev,
			const struct scp_domain_data *scp_domain_data, int num,
			struct scp_ctrl_reg *scp_ctrl_reg)
			const struct scp_ctrl_reg *scp_ctrl_reg)
{
	struct genpd_onecell_data *pd_data;
	struct resource *res;
@@ -565,26 +590,6 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
	},
};

#define NUM_DOMAINS_MT2701	ARRAY_SIZE(scp_domain_data_mt2701)

static int __init scpsys_probe_mt2701(struct platform_device *pdev)
{
	struct scp *scp;
	struct scp_ctrl_reg scp_reg;

	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;

	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
		       &scp_reg);
	if (IS_ERR(scp))
		return PTR_ERR(scp);

	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);

	return 0;
}

/*
 * MT6797 power domain support
 */
@@ -649,51 +654,62 @@ static const struct scp_domain_data scp_domain_data_mt6797[] = {
	},
};

#define NUM_DOMAINS_MT6797	ARRAY_SIZE(scp_domain_data_mt6797)
#define SPM_PWR_STATUS_MT6797		0x0180
#define SPM_PWR_STATUS_2ND_MT6797	0x0184

static int __init scpsys_probe_mt6797(struct platform_device *pdev)
{
	struct scp *scp;
	struct genpd_onecell_data *pd_data;
	int ret;
	struct scp_ctrl_reg scp_reg;

	scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;

	scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797,
		       &scp_reg);
	if (IS_ERR(scp))
		return PTR_ERR(scp);

	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797);

	pd_data = &scp->pd_data;

	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
				     pd_data->domains[MT6797_POWER_DOMAIN_VDEC]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);

	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
				     pd_data->domains[MT6797_POWER_DOMAIN_ISP]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);

	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
				     pd_data->domains[MT6797_POWER_DOMAIN_VENC]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
static const struct scp_subdomain scp_subdomain_mt6797[] = {
	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
};

	ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
				     pd_data->domains[MT6797_POWER_DOMAIN_MJC]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
/*
 * MT7622 power domain support
 */

	return 0;
}
static const struct scp_domain_data scp_domain_data_mt7622[] = {
	[MT7622_POWER_DOMAIN_ETHSYS] = {
		.name = "ethsys",
		.sta_mask = PWR_STATUS_ETHSYS,
		.ctl_offs = SPM_ETHSYS_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
		.clk_id = {CLK_NONE},
		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
		.active_wakeup = true,
	},
	[MT7622_POWER_DOMAIN_HIF0] = {
		.name = "hif0",
		.sta_mask = PWR_STATUS_HIF0,
		.ctl_offs = SPM_HIF0_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
		.clk_id = {CLK_HIFSEL},
		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
		.active_wakeup = true,
	},
	[MT7622_POWER_DOMAIN_HIF1] = {
		.name = "hif1",
		.sta_mask = PWR_STATUS_HIF1,
		.ctl_offs = SPM_HIF1_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
		.clk_id = {CLK_HIFSEL},
		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
		.active_wakeup = true,
	},
	[MT7622_POWER_DOMAIN_WB] = {
		.name = "wb",
		.sta_mask = PWR_STATUS_WB,
		.ctl_offs = SPM_WB_PWR_CON,
		.sram_pdn_bits = 0,
		.sram_pdn_ack_bits = 0,
		.clk_id = {CLK_NONE},
		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
		.active_wakeup = true,
	},
};

/*
 * MT8173 power domain support
@@ -789,39 +805,50 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = {
	},
};

#define NUM_DOMAINS_MT8173	ARRAY_SIZE(scp_domain_data_mt8173)

static int __init scpsys_probe_mt8173(struct platform_device *pdev)
{
	struct scp *scp;
	struct genpd_onecell_data *pd_data;
	int ret;
	struct scp_ctrl_reg scp_reg;

	scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
	scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;

	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
		       &scp_reg);
	if (IS_ERR(scp))
		return PTR_ERR(scp);

	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
static const struct scp_subdomain scp_subdomain_mt8173[] = {
	{MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
	{MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
};

	pd_data = &scp->pd_data;
static const struct scp_soc_data mt2701_data = {
	.domains = scp_domain_data_mt2701,
	.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
};

	ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
		pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
static const struct scp_soc_data mt6797_data = {
	.domains = scp_domain_data_mt6797,
	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
	.subdomains = scp_subdomain_mt6797,
	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
	}
};

	ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
		pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
	if (ret && IS_ENABLED(CONFIG_PM))
		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
static const struct scp_soc_data mt7622_data = {
	.domains = scp_domain_data_mt7622,
	.num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
};

	return 0;
static const struct scp_soc_data mt8173_data = {
	.domains = scp_domain_data_mt8173,
	.num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
	.subdomains = scp_subdomain_mt8173,
	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
};

/*
 * scpsys driver init
@@ -830,13 +857,16 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
static const struct of_device_id of_scpsys_match_tbl[] = {
	{
		.compatible = "mediatek,mt2701-scpsys",
		.data = scpsys_probe_mt2701,
		.data = &mt2701_data,
	}, {
		.compatible = "mediatek,mt6797-scpsys",
		.data = scpsys_probe_mt6797,
		.data = &mt6797_data,
	}, {
		.compatible = "mediatek,mt7622-scpsys",
		.data = &mt7622_data,
	}, {
		.compatible = "mediatek,mt8173-scpsys",
		.data = scpsys_probe_mt8173,
		.data = &mt8173_data,
	}, {
		/* sentinel */
	}
@@ -844,16 +874,33 @@ static const struct of_device_id of_scpsys_match_tbl[] = {

static int scpsys_probe(struct platform_device *pdev)
{
	int (*probe)(struct platform_device *);
	const struct of_device_id *of_id;
	const struct of_device_id *match;
	const struct scp_subdomain *sd;
	const struct scp_soc_data *soc;
	struct scp *scp;
	struct genpd_onecell_data *pd_data;
	int i, ret;

	of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
	if (!of_id || !of_id->data)
		return -EINVAL;
	match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
	soc = (const struct scp_soc_data *)match->data;

	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
	if (IS_ERR(scp))
		return PTR_ERR(scp);

	probe = of_id->data;
	mtk_register_power_domains(pdev, scp, soc->num_domains);

	return probe(pdev);
	pd_data = &scp->pd_data;

	for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
		ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
					     pd_data->domains[sd->subdomain]);
		if (ret && IS_ENABLED(CONFIG_PM))
			dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
				ret);
	}

	return 0;
}

static struct platform_driver scpsys_drv = {
Loading