Commit 11c9dff0 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'v4.15-next-soc' of...

Merge tag 'v4.15-next-soc' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into next/soc

Pull "arm: Updates for soc driver for v4.15-next" from Matthias Brugger:

- change kconfig entry for armv7 SoCs to be more generic
- add support for mt2701 scpsys driver
  binding documentation
  extend driver to allow the bus protection to overwrite the register

* tag 'v4.15-next-soc' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux:
  soc: mediatek: add MT2712 scpsys support
  soc: mediatek: add dependent clock jpgdec/audio for scpsys
  soc: mediatek: extend bus protection API
  dt-bindings: soc: add MT2712 power dt-bindings
  ARM: mediatek: use more generic prompts for SoCs with ARMv7
parents a3dc838d fdac5f4d
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/mt2712-power.h
- include/dt-bindings/power/mt7622-power.h

Required properties:
- compatible: Should be one of:
	- "mediatek,mt2701-scpsys"
	- "mediatek,mt2712-scpsys"
	- "mediatek,mt6797-scpsys"
	- "mediatek,mt7622-scpsys"
	- "mediatek,mt8173-scpsys"
@@ -27,6 +29,7 @@ Required properties:
                      These are clocks which hardware needs to be
                      enabled before enabling certain power domains.
	Required clocks for MT2701: "mm", "mfg", "ethif"
	Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec"
	Required clocks for MT6797: "mm", "mfg", "vdec"
	Required clocks for MT7622: "hif_sel"
	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
+1 −1
Original line number Diff line number Diff line
menuconfig ARCH_MEDIATEK
	bool "Mediatek MT65xx & MT81xx SoC"
	bool "MediaTek SoC Support"
	depends on ARCH_MULTI_V7
	select ARM_GIC
	select PINCTRL
+22 −4
Original line number Diff line number Diff line
@@ -19,23 +19,33 @@

#define INFRA_TOPAXI_PROTECTEN		0x0220
#define INFRA_TOPAXI_PROTECTSTA1	0x0228
#define INFRA_TOPAXI_PROTECTEN_SET	0x0260
#define INFRA_TOPAXI_PROTECTEN_CLR	0x0264

/**
 * mtk_infracfg_set_bus_protection - enable bus protection
 * @regmap: The infracfg regmap
 * @mask: The mask containing the protection bits to be enabled.
 * @reg_update: The boolean flag determines to set the protection bits
 *              by regmap_update_bits with enable register(PROTECTEN) or
 *              by regmap_write with set register(PROTECTEN_SET).
 *
 * This function enables the bus protection bits for disabled power
 * domains so that the system does not hang when some unit accesses the
 * bus while in power down.
 */
int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
		bool reg_update)
{
	unsigned long expired;
	u32 val;
	int ret;

	regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask);
	if (reg_update)
		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
				mask);
	else
		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);

	expired = jiffies + HZ;

@@ -59,16 +69,24 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
 * mtk_infracfg_clear_bus_protection - disable bus protection
 * @regmap: The infracfg regmap
 * @mask: The mask containing the protection bits to be disabled.
 * @reg_update: The boolean flag determines to clear the protection bits
 *              by regmap_update_bits with enable register(PROTECTEN) or
 *              by regmap_write with clear register(PROTECTEN_CLR).
 *
 * This function disables the bus protection bits previously enabled with
 * mtk_infracfg_set_bus_protection.
 */
int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)

int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
		bool reg_update)
{
	unsigned long expired;
	int ret;

	if (reg_update)
		regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
	else
		regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);

	expired = jiffies + HZ;

+125 −15
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/soc/mediatek/infracfg.h>

#include <dt-bindings/power/mt2701-power.h>
#include <dt-bindings/power/mt2712-power.h>
#include <dt-bindings/power/mt6797-power.h>
#include <dt-bindings/power/mt7622-power.h>
#include <dt-bindings/power/mt8173-power.h>
@@ -32,7 +33,7 @@
#define SPM_DIS_PWR_CON			0x023c
#define SPM_CONN_PWR_CON		0x0280
#define SPM_VEN2_PWR_CON		0x0298
#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173 */
#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173, MT2712 */
#define SPM_BDP_PWR_CON			0x029c	/* MT2701 */
#define SPM_ETH_PWR_CON			0x02a0
#define SPM_HIF_PWR_CON			0x02a4
@@ -40,12 +41,12 @@
#define SPM_MFG_2D_PWR_CON		0x02c0
#define SPM_MFG_ASYNC_PWR_CON		0x02c4
#define SPM_USB_PWR_CON			0x02cc
#define SPM_USB2_PWR_CON		0x02d4	/* MT2712 */
#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,12 +65,13 @@
#define PWR_STATUS_ETH			BIT(15)
#define PWR_STATUS_HIF			BIT(16)
#define PWR_STATUS_IFR_MSC		BIT(17)
#define PWR_STATUS_USB2			BIT(19)	/* MT2712 */
#define PWR_STATUS_VENC_LT		BIT(20)
#define PWR_STATUS_VENC			BIT(21)
#define PWR_STATUS_MFG_2D		BIT(22)
#define PWR_STATUS_MFG_ASYNC		BIT(23)
#define PWR_STATUS_AUDIO		BIT(24)
#define PWR_STATUS_USB			BIT(25)
#define PWR_STATUS_MFG_2D		BIT(22)	/* MT8173 */
#define PWR_STATUS_MFG_ASYNC		BIT(23)	/* MT8173 */
#define PWR_STATUS_AUDIO		BIT(24)	/* MT8173, MT2712 */
#define PWR_STATUS_USB			BIT(25)	/* MT8173, MT2712 */
#define PWR_STATUS_ETHSYS		BIT(24)	/* MT7622 */
#define PWR_STATUS_HIF0			BIT(25)	/* MT7622 */
#define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
@@ -84,6 +86,8 @@ enum clk_id {
	CLK_ETHIF,
	CLK_VDEC,
	CLK_HIFSEL,
	CLK_JPGDEC,
	CLK_AUDIO,
	CLK_MAX,
};

@@ -96,10 +100,12 @@ static const char * const clk_names[] = {
	"ethif",
	"vdec",
	"hif_sel",
	"jpgdec",
	"audio",
	NULL,
};

#define MAX_CLKS	2
#define MAX_CLKS	3

struct scp_domain_data {
	const char *name;
@@ -134,6 +140,7 @@ struct scp {
	void __iomem *base;
	struct regmap *infracfg;
	struct scp_ctrl_reg ctrl_reg;
	bool bus_prot_reg_update;
};

struct scp_subdomain {
@@ -147,6 +154,7 @@ struct scp_soc_data {
	const struct scp_subdomain *subdomains;
	int num_subdomains;
	const struct scp_ctrl_reg regs;
	bool bus_prot_reg_update;
};

static int scpsys_domain_is_on(struct scp_domain *scpd)
@@ -254,7 +262,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)

	if (scpd->data->bus_prot_mask) {
		ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
				scpd->data->bus_prot_mask);
				scpd->data->bus_prot_mask,
				scp->bus_prot_reg_update);
		if (ret)
			goto err_pwr_ack;
	}
@@ -289,7 +298,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)

	if (scpd->data->bus_prot_mask) {
		ret = mtk_infracfg_set_bus_protection(scp->infracfg,
				scpd->data->bus_prot_mask);
				scpd->data->bus_prot_mask,
				scp->bus_prot_reg_update);
		if (ret)
			goto out;
	}
@@ -371,7 +381,8 @@ 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,
			const struct scp_ctrl_reg *scp_ctrl_reg)
			const struct scp_ctrl_reg *scp_ctrl_reg,
			bool bus_prot_reg_update)
{
	struct genpd_onecell_data *pd_data;
	struct resource *res;
@@ -386,6 +397,8 @@ static struct scp *init_scp(struct platform_device *pdev,
	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;

	scp->bus_prot_reg_update = bus_prot_reg_update;

	scp->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -580,6 +593,85 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
	},
};

/*
 * MT2712 power domain support
 */
static const struct scp_domain_data scp_domain_data_mt2712[] = {
	[MT2712_POWER_DOMAIN_MM] = {
		.name = "mm",
		.sta_mask = PWR_STATUS_DISP,
		.ctl_offs = SPM_DIS_PWR_CON,
		.sram_pdn_bits = GENMASK(8, 8),
		.sram_pdn_ack_bits = GENMASK(12, 12),
		.clk_id = {CLK_MM},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_VDEC] = {
		.name = "vdec",
		.sta_mask = PWR_STATUS_VDEC,
		.ctl_offs = SPM_VDE_PWR_CON,
		.sram_pdn_bits = GENMASK(8, 8),
		.sram_pdn_ack_bits = GENMASK(12, 12),
		.clk_id = {CLK_MM, CLK_VDEC},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_VENC] = {
		.name = "venc",
		.sta_mask = PWR_STATUS_VENC,
		.ctl_offs = SPM_VEN_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
		.clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_ISP] = {
		.name = "isp",
		.sta_mask = PWR_STATUS_ISP,
		.ctl_offs = SPM_ISP_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(13, 12),
		.clk_id = {CLK_MM},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_AUDIO] = {
		.name = "audio",
		.sta_mask = PWR_STATUS_AUDIO,
		.ctl_offs = SPM_AUDIO_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
		.clk_id = {CLK_AUDIO},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_USB] = {
		.name = "usb",
		.sta_mask = PWR_STATUS_USB,
		.ctl_offs = SPM_USB_PWR_CON,
		.sram_pdn_bits = GENMASK(10, 8),
		.sram_pdn_ack_bits = GENMASK(14, 12),
		.clk_id = {CLK_NONE},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_USB2] = {
		.name = "usb2",
		.sta_mask = PWR_STATUS_USB2,
		.ctl_offs = SPM_USB2_PWR_CON,
		.sram_pdn_bits = GENMASK(10, 8),
		.sram_pdn_ack_bits = GENMASK(14, 12),
		.clk_id = {CLK_NONE},
		.active_wakeup = true,
	},
	[MT2712_POWER_DOMAIN_MFG] = {
		.name = "mfg",
		.sta_mask = PWR_STATUS_MFG,
		.ctl_offs = SPM_MFG_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(19, 16),
		.clk_id = {CLK_MFG},
		.bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
		.active_wakeup = true,
	},
};

/*
 * MT6797 power domain support
 */
@@ -806,7 +898,18 @@ static const struct scp_soc_data mt2701_data = {
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
	},
	.bus_prot_reg_update = true,
};

static const struct scp_soc_data mt2712_data = {
	.domains = scp_domain_data_mt2712,
	.num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	},
	.bus_prot_reg_update = false,
};

static const struct scp_soc_data mt6797_data = {
@@ -817,7 +920,8 @@ static const struct scp_soc_data mt6797_data = {
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
	}
	},
	.bus_prot_reg_update = true,
};

static const struct scp_soc_data mt7622_data = {
@@ -826,7 +930,8 @@ static const struct scp_soc_data mt7622_data = {
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
	},
	.bus_prot_reg_update = true,
};

static const struct scp_soc_data mt8173_data = {
@@ -837,7 +942,8 @@ static const struct scp_soc_data mt8173_data = {
	.regs = {
		.pwr_sta_offs = SPM_PWR_STATUS,
		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
	}
	},
	.bus_prot_reg_update = true,
};

/*
@@ -848,6 +954,9 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
	{
		.compatible = "mediatek,mt2701-scpsys",
		.data = &mt2701_data,
	}, {
		.compatible = "mediatek,mt2712-scpsys",
		.data = &mt2712_data,
	}, {
		.compatible = "mediatek,mt6797-scpsys",
		.data = &mt6797_data,
@@ -874,7 +983,8 @@ static int scpsys_probe(struct platform_device *pdev)
	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);
	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
			soc->bus_prot_reg_update);
	if (IS_ERR(scp))
		return PTR_ERR(scp);

+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
 */

#ifndef _DT_BINDINGS_POWER_MT2712_POWER_H
#define _DT_BINDINGS_POWER_MT2712_POWER_H

#define MT2712_POWER_DOMAIN_MM		0
#define MT2712_POWER_DOMAIN_VDEC	1
#define MT2712_POWER_DOMAIN_VENC	2
#define MT2712_POWER_DOMAIN_ISP		3
#define MT2712_POWER_DOMAIN_AUDIO	4
#define MT2712_POWER_DOMAIN_USB		5
#define MT2712_POWER_DOMAIN_USB2	6
#define MT2712_POWER_DOMAIN_MFG		7

#endif /* _DT_BINDINGS_POWER_MT2712_POWER_H */
Loading