summaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-10 20:40:00 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-10 20:40:00 -0700
commitae46654bcff303b33facbbd04a3ad9c21d303f9b (patch)
treeb0027d47d6c949162fa6ae306f34abeb76c559a9 /drivers/soc
parent7f1b9be13a7dbe8e51ea541bbcd6c47adae39c71 (diff)
parenta48a7b6b54927159bac77735df00e5b9fc3415fb (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson: "This branch contains platform-related driver updates for ARM and ARM64. Among them: - Reset driver updates: + New API for dealing with arrays of resets + Make unimplemented {de,}assert return success on shared resets + MSDKv1 driver + Removal of obsolete Gemini reset driver + Misc updates for sunxi and Uniphier - SoC drivers: + Platform SoC driver registration on Tegra + Shuffle of Qualcomm drivers into a submenu + Allwinner A64 support for SRAM + Renesas R-Car R3 support + Power domains for Rockchip RK3366 - Misc updates and smaller fixes for TEE and memory driver subsystems" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits) firmware: arm_scpi: fix endianness of dev_id in struct dev_pstate_set soc/tegra: fuse: Add missing semi-colon soc/tegra: Restrict SoC device registration to Tegra drivers: soc: sunxi: add support for A64 and its SRAM C drivers: soc: sunxi: add support for remapping func value to reg value drivers: soc: sunxi: fix error processing on base address when claiming dt-bindings: add binding for Allwinner A64 SRAM controller and SRAM C bus: sunxi-rsb: Enable by default for ARM64 soc/tegra: Register SoC device firmware: tegra: set drvdata earlier memory: Convert to using %pOF instead of full_name soc: Convert to using %pOF instead of full_name bus: Convert to using %pOF instead of full_name firmware: Convert to using %pOF instead of full_name 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 reset: uniphier: add analog amplifiers reset control reset: uniphier: add video input subsystem reset control ...
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/amlogic/Kconfig12
-rw-r--r--drivers/soc/amlogic/Makefile1
-rw-r--r--drivers/soc/amlogic/meson-gx-socinfo.c177
-rw-r--r--drivers/soc/fsl/qbman/bman_ccsr.c10
-rw-r--r--drivers/soc/fsl/qbman/bman_portal.c8
-rw-r--r--drivers/soc/fsl/qbman/qman_ccsr.c12
-rw-r--r--drivers/soc/fsl/qbman/qman_portal.c11
-rw-r--r--drivers/soc/fsl/qe/gpio.c4
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c10
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c247
-rw-r--r--drivers/soc/qcom/Kconfig4
-rw-r--r--drivers/soc/qcom/mdt_loader.c5
-rw-r--r--drivers/soc/qcom/smsm.c3
-rw-r--r--drivers/soc/qcom/wcnss_ctrl.c1
-rw-r--r--drivers/soc/renesas/Kconfig7
-rw-r--r--drivers/soc/renesas/Makefile1
-rw-r--r--drivers/soc/renesas/r8a77995-sysc.c31
-rw-r--r--drivers/soc/renesas/rcar-rst.c5
-rw-r--r--drivers/soc/renesas/rcar-sysc.c9
-rw-r--r--drivers/soc/renesas/rcar-sysc.h1
-rw-r--r--drivers/soc/renesas/renesas-soc.c8
-rw-r--r--drivers/soc/rockchip/grf.c14
-rw-r--r--drivers/soc/rockchip/pm_domains.c32
-rw-r--r--drivers/soc/samsung/pm_domains.c10
-rw-r--r--drivers/soc/sunxi/sunxi_sram.c57
-rw-r--r--drivers/soc/tegra/Kconfig5
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c56
-rw-r--r--drivers/soc/tegra/pmc.c4
30 files changed, 588 insertions, 159 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 07fc0ac51c52..fc9e98047421 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,6 +1,7 @@
menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/actions/Kconfig"
+source "drivers/soc/amlogic/Kconfig"
source "drivers/soc/atmel/Kconfig"
source "drivers/soc/bcm/Kconfig"
source "drivers/soc/fsl/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 9241125416ba..280a6a91a9e2 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_DOVE) += dove/
obj-y += fsl/
obj-$(CONFIG_ARCH_MXC) += imx/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+obj-$(CONFIG_ARCH_MESON) += amlogic/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-y += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
new file mode 100644
index 000000000000..22acf064531f
--- /dev/null
+++ b/drivers/soc/amlogic/Kconfig
@@ -0,0 +1,12 @@
+menu "Amlogic SoC drivers"
+
+config MESON_GX_SOCINFO
+ bool "Amlogic Meson GX SoC Information driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ default ARCH_MESON
+ select SOC_BUS
+ help
+ Say yes to support decoding of Amlogic Meson GX SoC family
+ information about the type, package and version.
+
+endmenu
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
new file mode 100644
index 000000000000..3e85fc462c21
--- /dev/null
+++ b/drivers/soc/amlogic/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
new file mode 100644
index 000000000000..89f4cf507be6
--- /dev/null
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#define AO_SEC_SD_CFG8 0xe0
+#define AO_SEC_SOCINFO_OFFSET AO_SEC_SD_CFG8
+
+#define SOCINFO_MAJOR GENMASK(31, 24)
+#define SOCINFO_MINOR GENMASK(23, 16)
+#define SOCINFO_PACK GENMASK(15, 8)
+#define SOCINFO_MISC GENMASK(7, 0)
+
+static const struct meson_gx_soc_id {
+ const char *name;
+ unsigned int id;
+} soc_ids[] = {
+ { "GXBB", 0x1f },
+ { "GXTVBB", 0x20 },
+ { "GXL", 0x21 },
+ { "GXM", 0x22 },
+ { "TXL", 0x23 },
+};
+
+static const struct meson_gx_package_id {
+ const char *name;
+ unsigned int major_id;
+ unsigned int pack_id;
+} soc_packages[] = {
+ { "S905", 0x1f, 0 },
+ { "S905M", 0x1f, 0x20 },
+ { "S905D", 0x21, 0 },
+ { "S905X", 0x21, 0x80 },
+ { "S905L", 0x21, 0xc0 },
+ { "S905M2", 0x21, 0xe0 },
+ { "S912", 0x22, 0 },
+};
+
+static inline unsigned int socinfo_to_major(u32 socinfo)
+{
+ return FIELD_GET(SOCINFO_MAJOR, socinfo);
+}
+
+static inline unsigned int socinfo_to_minor(u32 socinfo)
+{
+ return FIELD_GET(SOCINFO_MINOR, socinfo);
+}
+
+static inline unsigned int socinfo_to_pack(u32 socinfo)
+{
+ return FIELD_GET(SOCINFO_PACK, socinfo);
+}
+
+static inline unsigned int socinfo_to_misc(u32 socinfo)
+{
+ return FIELD_GET(SOCINFO_MISC, socinfo);
+}
+
+static const char *socinfo_to_package_id(u32 socinfo)
+{
+ unsigned int pack = socinfo_to_pack(socinfo) & 0xf0;
+ unsigned int major = socinfo_to_major(socinfo);
+ int i;
+
+ for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
+ if (soc_packages[i].major_id == major &&
+ soc_packages[i].pack_id == pack)
+ return soc_packages[i].name;
+ }
+
+ return "Unknown";
+}
+
+static const char *socinfo_to_soc_id(u32 socinfo)
+{
+ unsigned int id = socinfo_to_major(socinfo);
+ int i;
+
+ for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
+ if (soc_ids[i].id == id)
+ return soc_ids[i].name;
+ }
+
+ return "Unknown";
+}
+
+int __init meson_gx_socinfo_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device_node *np;
+ struct regmap *regmap;
+ unsigned int socinfo;
+ struct device *dev;
+ int ret;
+
+ /* look up for chipid node */
+ np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gx-ao-secure");
+ if (!np)
+ return -ENODEV;
+
+ /* check if interface is enabled */
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ /* check if chip-id is available */
+ if (!of_property_read_bool(np, "amlogic,has-chip-id"))
+ return -ENODEV;
+
+ /* node should be a syscon */
+ regmap = syscon_node_to_regmap(np);
+ of_node_put(np);
+ if (IS_ERR(regmap)) {
+ pr_err("%s: failed to get regmap\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
+ if (ret < 0)
+ return ret;
+
+ if (!socinfo) {
+ pr_err("%s: invalid chipid value\n", __func__);
+ return -EINVAL;
+ }
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENODEV;
+
+ soc_dev_attr->family = "Amlogic Meson";
+
+ np = of_find_node_by_path("/");
+ of_property_read_string(np, "model", &soc_dev_attr->machine);
+ of_node_put(np);
+
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x",
+ socinfo_to_major(socinfo),
+ socinfo_to_minor(socinfo),
+ socinfo_to_pack(socinfo),
+ socinfo_to_misc(socinfo));
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)",
+ socinfo_to_soc_id(socinfo),
+ socinfo_to_package_id(socinfo));
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->revision);
+ kfree_const(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ return PTR_ERR(soc_dev);
+ }
+ dev = soc_device_to_device(soc_dev);
+
+ dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n",
+ soc_dev_attr->soc_id,
+ socinfo_to_major(socinfo),
+ socinfo_to_minor(socinfo),
+ socinfo_to_pack(socinfo),
+ socinfo_to_misc(socinfo));
+
+ return 0;
+}
+device_initcall(meson_gx_socinfo_init);
diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c b/drivers/soc/fsl/qbman/bman_ccsr.c
index a8e8389a6894..eaa9585c7347 100644
--- a/drivers/soc/fsl/qbman/bman_ccsr.c
+++ b/drivers/soc/fsl/qbman/bman_ccsr.c
@@ -177,8 +177,8 @@ static int fsl_bman_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
+ node);
return -ENXIO;
}
bm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
@@ -205,14 +205,14 @@ static int fsl_bman_probe(struct platform_device *pdev)
err_irq = platform_get_irq(pdev, 0);
if (err_irq <= 0) {
- dev_info(dev, "Can't get %s IRQ\n", node->full_name);
+ dev_info(dev, "Can't get %pOF IRQ\n", node);
return -ENODEV;
}
ret = devm_request_irq(dev, err_irq, bman_isr, IRQF_SHARED, "bman-err",
dev);
if (ret) {
- dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
- ret, node->full_name);
+ dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
+ ret, node);
return ret;
}
/* Disable Buffer Pool State Change */
diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c
index 8354d4dabdad..39b39c8f1399 100644
--- a/drivers/soc/fsl/qbman/bman_portal.c
+++ b/drivers/soc/fsl/qbman/bman_portal.c
@@ -103,16 +103,14 @@ static int bman_portal_probe(struct platform_device *pdev)
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CE);
if (!addr_phys[0]) {
- dev_err(dev, "Can't get %s property 'reg::CE'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
return -ENXIO;
}
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CI);
if (!addr_phys[1]) {
- dev_err(dev, "Can't get %s property 'reg::CI'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
return -ENXIO;
}
@@ -120,7 +118,7 @@ static int bman_portal_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
- dev_err(dev, "Can't get %s IRQ'\n", node->full_name);
+ dev_err(dev, "Can't get %pOF IRQ'\n", node);
return -ENXIO;
}
pcfg->irq = irq;
diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c
index 90bc40c48675..835ce947ffca 100644
--- a/drivers/soc/fsl/qbman/qman_ccsr.c
+++ b/drivers/soc/fsl/qbman/qman_ccsr.c
@@ -695,8 +695,8 @@ static int fsl_qman_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
+ node);
return -ENXIO;
}
qm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
@@ -740,15 +740,15 @@ static int fsl_qman_probe(struct platform_device *pdev)
err_irq = platform_get_irq(pdev, 0);
if (err_irq <= 0) {
- dev_info(dev, "Can't get %s property 'interrupts'\n",
- node->full_name);
+ dev_info(dev, "Can't get %pOF property 'interrupts'\n",
+ node);
return -ENODEV;
}
ret = devm_request_irq(dev, err_irq, qman_isr, IRQF_SHARED, "qman-err",
dev);
if (ret) {
- dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
- ret, node->full_name);
+ dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
+ ret, node);
return ret;
}
diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c
index adbaa30d3c5a..cbacdf4f98ed 100644
--- a/drivers/soc/fsl/qbman/qman_portal.c
+++ b/drivers/soc/fsl/qbman/qman_portal.c
@@ -237,30 +237,27 @@ static int qman_portal_probe(struct platform_device *pdev)
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CE);
if (!addr_phys[0]) {
- dev_err(dev, "Can't get %s property 'reg::CE'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
return -ENXIO;
}
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
DPAA_PORTAL_CI);
if (!addr_phys[1]) {
- dev_err(dev, "Can't get %s property 'reg::CI'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
return -ENXIO;
}
err = of_property_read_u32(node, "cell-index", &val);
if (err) {
- dev_err(dev, "Can't get %s property 'cell-index'\n",
- node->full_name);
+ dev_err(dev, "Can't get %pOF property 'cell-index'\n", node);
return err;
}
pcfg->channel = val;
pcfg->cpu = -1;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
- dev_err(dev, "Can't get %s IRQ\n", node->full_name);
+ dev_err(dev, "Can't get %pOF IRQ\n", node);
return -ENXIO;
}
pcfg->irq = irq;
diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
index 0aaf429f31d5..3b27075c21a7 100644
--- a/drivers/soc/fsl/qe/gpio.c
+++ b/drivers/soc/fsl/qe/gpio.c
@@ -304,8 +304,8 @@ static int __init qe_add_gpiochips(void)
goto err;
continue;
err:
- pr_err("%s: registration failed with status %d\n",
- np->full_name, ret);
+ pr_err("%pOF: registration failed with status %d\n",
+ np, ret);
kfree(qe_gc);
/* try others anyway */
}
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index c80a04e1b2b1..c2048382830f 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -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,
@@ -1233,8 +1233,8 @@ static int pwrap_probe(struct platform_device *pdev)
ret = of_platform_populate(np, NULL, NULL, wrp->dev);
if (ret) {
- dev_dbg(wrp->dev, "failed to create child devices at %s\n",
- np->full_name);
+ dev_dbg(wrp->dev, "failed to create child devices at %pOF\n",
+ np);
goto err_out2;
}
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index ceb2cc495cd0..e1ce8b1b5090 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -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 = {
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index d0fc331972d2..b00bccddcd3b 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -1,6 +1,8 @@
#
# QCOM Soc drivers
#
+menu "Qualcomm SoC drivers"
+
config QCOM_GLINK_SSR
tristate "Qualcomm Glink SSR driver"
depends on RPMSG
@@ -83,3 +85,5 @@ config QCOM_WCNSS_CTRL
help
Client driver for the WCNSS_CTRL SMD channel, used to download nv
firmware to a newly booted WCNSS chip.
+
+endmenu
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index bd63df0d14e0..08bd8549242a 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -178,14 +178,13 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
if (phdr->p_filesz) {
sprintf(fw_name + fw_name_len - 3, "b%02d", i);
- ret = request_firmware(&seg_fw, fw_name, dev);
+ ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
+ ptr, phdr->p_filesz);
if (ret) {
dev_err(dev, "failed to load %s\n", fw_name);
break;
}
- memcpy(ptr, seg_fw->data, seg_fw->size);
-
release_firmware(seg_fw);
}
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
index dc