aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-29 15:16:01 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-29 15:16:01 -0700
commitb22b6beae6116e3a9c46ced312c626f6737a3fa6 (patch)
treec92228669e0444d91fd1445bc562351fd69b58cc /drivers/soc
parentMerge tag 'armsoc-defconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc (diff)
parentMerge tag 'tegra-for-4.20-firmware-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers (diff)
downloadlinux-dev-b22b6beae6116e3a9c46ced312c626f6737a3fa6.tar.xz
linux-dev-b22b6beae6116e3a9c46ced312c626f6737a3fa6.zip
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Arnd Bergmann: "The most noteworthy SoC driver changes this time include: - The TEE subsystem gains an in-kernel interface to access the TEE from device drivers. - The reset controller subsystem gains a driver for the Qualcomm Snapdragon 845 Power Domain Controller. - The Xilinx Zynq platform now has a firmware interface for its platform management unit. This contains a firmware "ioctl" interface that was a little controversial at first, but the version we merged solved that by not exposing arbitrary firmware calls to user space. - The Amlogic Meson platform gains a "canvas" driver that is used for video processing and shared between different high-level drivers. The rest is more of the usual, mostly related to SoC specific power management support and core drivers in drivers/soc: - Several Renesas SoCs (RZ/G1N, RZ/G2M, R-Car V3M, RZ/A2M) gain new features related to power and reset control. - The Mediatek mt8183 and mt6765 SoC platforms gain support for their respective power management chips. - A new driver for NXP i.MX8, which need a firmware interface for power management. - The SCPI firmware interface now contains support estimating power usage of performance states - The NVIDIA Tegra "pmc" driver gains a few new features, in particular a pinctrl interface for configuring the pads. - Lots of small changes for Qualcomm, in particular the "smem" device driver. - Some cleanups for the TI OMAP series related to their sysc controller. Additional cleanups and bugfixes in SoC specific drivers include the Meson, Keystone, NXP, AT91, Sunxi, Actions, and Tegra platforms" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (129 commits) firmware: tegra: bpmp: Implement suspend/resume support drivers: clk: Add ZynqMP clock driver dt-bindings: clock: Add bindings for ZynqMP clock driver firmware: xilinx: Add zynqmp IOCTL API for device control Documentation: xilinx: Add documentation for eemi APIs MAINTAINERS: imx: include drivers/firmware/imx path firmware: imx: add misc svc support firmware: imx: add SCU firmware driver support reset: Fix potential use-after-free in __of_reset_control_get() dt-bindings: arm: fsl: add scu binding doc soc: fsl: qbman: add interrupt coalesce changing APIs soc: fsl: bman_portals: defer probe after bman's probe soc: fsl: qbman: Use last response to determine valid bit soc: fsl: qbman: Add 64 bit DMA addressing requirement to QBMan soc: fsl: qbman: replace CPU 0 with any online CPU in hotplug handlers soc: fsl: qbman: Check if CPU is offline when initializing portals reset: qcom: PDC Global (Power Domain Controller) reset controller dt-bindings: reset: Add PDC Global binding for SDM845 SoCs reset: Grammar s/more then once/more than once/ bus: ti-sysc: Just use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS ...
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/Makefile2
-rw-r--r--drivers/soc/actions/Kconfig2
-rw-r--r--drivers/soc/actions/Makefile2
-rw-r--r--drivers/soc/actions/owl-sps-helper.c6
-rw-r--r--drivers/soc/actions/owl-sps.c64
-rw-r--r--drivers/soc/amlogic/Kconfig7
-rw-r--r--drivers/soc/amlogic/Makefile1
-rw-r--r--drivers/soc/amlogic/meson-canvas.c185
-rw-r--r--drivers/soc/fsl/dpio/dpio-driver.c3
-rw-r--r--drivers/soc/fsl/qbman/Kconfig2
-rw-r--r--drivers/soc/fsl/qbman/bman.c6
-rw-r--r--drivers/soc/fsl/qbman/bman_portal.c14
-rw-r--r--drivers/soc/fsl/qbman/dpaa_sys.h20
-rw-r--r--drivers/soc/fsl/qbman/qman.c53
-rw-r--r--drivers/soc/fsl/qbman/qman_portal.c6
-rw-r--r--drivers/soc/fsl/qe/qe.c6
-rw-r--r--drivers/soc/imx/gpc.c26
-rw-r--r--drivers/soc/imx/gpcv2.c100
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c519
-rw-r--r--drivers/soc/qcom/Kconfig21
-rw-r--r--drivers/soc/qcom/apr.c4
-rw-r--r--drivers/soc/qcom/llcc-slice.c74
-rw-r--r--drivers/soc/qcom/rmtfs_mem.c5
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c2
-rw-r--r--drivers/soc/qcom/smem.c174
-rw-r--r--drivers/soc/qcom/spm.c3
-rw-r--r--drivers/soc/qcom/wcnss_ctrl.c2
-rw-r--r--drivers/soc/renesas/Kconfig19
-rw-r--r--drivers/soc/renesas/Makefile2
-rw-r--r--drivers/soc/renesas/r8a7743-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7745-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a774a1-sysc.c45
-rw-r--r--drivers/soc/renesas/r8a774c0-sysc.c68
-rw-r--r--drivers/soc/renesas/r8a7779-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7790-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7791-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7792-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7794-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7795-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a7796-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a77970-sysc.c5
-rw-r--r--drivers/soc/renesas/r8a77995-sysc.c5
-rw-r--r--drivers/soc/renesas/rcar-rst.c11
-rw-r--r--drivers/soc/renesas/rcar-sysc.c13
-rw-r--r--drivers/soc/renesas/rcar-sysc.h9
-rw-r--r--drivers/soc/renesas/renesas-soc.c100
-rw-r--r--drivers/soc/tegra/pmc.c513
-rw-r--r--drivers/soc/ti/knav_dma.c4
-rw-r--r--drivers/soc/ti/knav_qmss.h6
49 files changed, 1590 insertions, 564 deletions
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 113e884697fd..446166ba0bec 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,7 +18,7 @@ obj-y += qcom/
obj-y += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_SOC_SAMSUNG) += samsung/
-obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+obj-y += sunxi/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_SOC_TI) += ti/
obj-$(CONFIG_ARCH_U8500) += ux500/
diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig
index 9d68b5a771c3..1a0b9649efb4 100644
--- a/drivers/soc/actions/Kconfig
+++ b/drivers/soc/actions/Kconfig
@@ -10,7 +10,7 @@ config OWL_PM_DOMAINS
select PM_GENERIC_DOMAINS
help
Say 'y' here to enable support for Smart Power System (SPS)
- power-gating on Actions Semiconductor S500 SoC.
+ power-gating on Actions Semiconductor S500, S700 and S900 SoCs.
If unsure, say 'n'.
endif
diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile
index 1e101b06bab1..4db9e7b050e5 100644
--- a/drivers/soc/actions/Makefile
+++ b/drivers/soc/actions/Makefile
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o
obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c
index 9d7a2c2b44ec..291a206d6f04 100644
--- a/drivers/soc/actions/owl-sps-helper.c
+++ b/drivers/soc/actions/owl-sps-helper.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Actions Semi Owl Smart Power System (SPS) shared helpers
*
@@ -5,11 +6,6 @@
* Author: Actions Semi, Inc.
*
* Copyright (c) 2017 Andreas Färber
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
*/
#include <linux/delay.h>
diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c
index 032921d8d41f..73a9e0bb7e8e 100644
--- a/drivers/soc/actions/owl-sps.c
+++ b/drivers/soc/actions/owl-sps.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Actions Semi Owl Smart Power System (SPS)
*
@@ -5,11 +6,6 @@
* Author: Actions Semi, Inc.
*
* Copyright (c) 2017 Andreas Färber
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
*/
#include <linux/of_address.h>
@@ -18,6 +14,7 @@
#include <linux/soc/actions/owl-sps.h>
#include <dt-bindings/power/owl-s500-powergate.h>
#include <dt-bindings/power/owl-s700-powergate.h>
+#include <dt-bindings/power/owl-s900-powergate.h>
struct owl_sps_domain_info {
const char *name;
@@ -244,9 +241,66 @@ static const struct owl_sps_info s700_sps_info = {
.domains = s700_sps_domains,
};
+static const struct owl_sps_domain_info s900_sps_domains[] = {
+ [S900_PD_GPU_B] = {
+ .name = "GPU_B",
+ .pwr_bit = 3,
+ },
+ [S900_PD_VCE] = {
+ .name = "VCE",
+ .pwr_bit = 4,
+ },
+ [S900_PD_SENSOR] = {
+ .name = "SENSOR",
+ .pwr_bit = 5,
+ },
+ [S900_PD_VDE] = {
+ .name = "VDE",
+ .pwr_bit = 6,
+ },
+ [S900_PD_HDE] = {
+ .name = "HDE",
+ .pwr_bit = 7,
+ },
+ [S900_PD_USB3] = {
+ .name = "USB3",
+ .pwr_bit = 8,
+ },
+ [S900_PD_DDR0] = {
+ .name = "DDR0",
+ .pwr_bit = 9,
+ },
+ [S900_PD_DDR1] = {
+ .name = "DDR1",
+ .pwr_bit = 10,
+ },
+ [S900_PD_DE] = {
+ .name = "DE",
+ .pwr_bit = 13,
+ },
+ [S900_PD_NAND] = {
+ .name = "NAND",
+ .pwr_bit = 14,
+ },
+ [S900_PD_USB2_H0] = {
+ .name = "USB2_H0",
+ .pwr_bit = 15,
+ },
+ [S900_PD_USB2_H1] = {
+ .name = "USB2_H1",
+ .pwr_bit = 16,
+ },
+};
+
+static const struct owl_sps_info s900_sps_info = {
+ .num_domains = ARRAY_SIZE(s900_sps_domains),
+ .domains = s900_sps_domains,
+};
+
static const struct of_device_id owl_sps_of_matches[] = {
{ .compatible = "actions,s500-sps", .data = &s500_sps_info },
{ .compatible = "actions,s700-sps", .data = &s700_sps_info },
+ { .compatible = "actions,s900-sps", .data = &s900_sps_info },
{ }
};
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
index b04f6e4aedbc..2f282b472912 100644
--- a/drivers/soc/amlogic/Kconfig
+++ b/drivers/soc/amlogic/Kconfig
@@ -1,5 +1,12 @@
menu "Amlogic SoC drivers"
+config MESON_CANVAS
+ tristate "Amlogic Meson Canvas driver"
+ depends on ARCH_MESON || COMPILE_TEST
+ default n
+ help
+ Say yes to support the canvas IP for Amlogic SoCs.
+
config MESON_GX_SOCINFO
bool "Amlogic Meson GX SoC Information driver"
depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
index 8fa321893928..0ab16d35ac36 100644
--- a/drivers/soc/amlogic/Makefile
+++ b/drivers/soc/amlogic/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c
new file mode 100644
index 000000000000..fce33ca76bb6
--- /dev/null
+++ b/drivers/soc/amlogic/meson-canvas.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2014 Endless Mobile
+ */
+
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/soc/amlogic/meson-canvas.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define NUM_CANVAS 256
+
+/* DMC Registers */
+#define DMC_CAV_LUT_DATAL 0x00
+ #define CANVAS_WIDTH_LBIT 29
+ #define CANVAS_WIDTH_LWID 3
+#define DMC_CAV_LUT_DATAH 0x04
+ #define CANVAS_WIDTH_HBIT 0
+ #define CANVAS_HEIGHT_BIT 9
+ #define CANVAS_WRAP_BIT 22
+ #define CANVAS_BLKMODE_BIT 24
+ #define CANVAS_ENDIAN_BIT 26
+#define DMC_CAV_LUT_ADDR 0x08
+ #define CANVAS_LUT_WR_EN BIT(9)
+ #define CANVAS_LUT_RD_EN BIT(8)
+
+struct meson_canvas {
+ struct device *dev;
+ void __iomem *reg_base;
+ spinlock_t lock; /* canvas device lock */
+ u8 used[NUM_CANVAS];
+};
+
+static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val)
+{
+ writel_relaxed(val, canvas->reg_base + reg);
+}
+
+static u32 canvas_read(struct meson_canvas *canvas, u32 reg)
+{
+ return readl_relaxed(canvas->reg_base + reg);
+}
+
+struct meson_canvas *meson_canvas_get(struct device *dev)
+{
+ struct device_node *canvas_node;
+ struct platform_device *canvas_pdev;
+
+ canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0);
+ if (!canvas_node)
+ return ERR_PTR(-ENODEV);
+
+ canvas_pdev = of_find_device_by_node(canvas_node);
+ if (!canvas_pdev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return dev_get_drvdata(&canvas_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(meson_canvas_get);
+
+int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
+ u32 addr, u32 stride, u32 height,
+ unsigned int wrap,
+ unsigned int blkmode,
+ unsigned int endian)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ if (!canvas->used[canvas_index]) {
+ dev_err(canvas->dev,
+ "Trying to setup non allocated canvas %u\n",
+ canvas_index);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ return -EINVAL;
+ }
+
+ canvas_write(canvas, DMC_CAV_LUT_DATAL,
+ ((addr + 7) >> 3) |
+ (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
+
+ canvas_write(canvas, DMC_CAV_LUT_DATAH,
+ ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
+ CANVAS_WIDTH_HBIT) |
+ (height << CANVAS_HEIGHT_BIT) |
+ (wrap << CANVAS_WRAP_BIT) |
+ (blkmode << CANVAS_BLKMODE_BIT) |
+ (endian << CANVAS_ENDIAN_BIT));
+
+ canvas_write(canvas, DMC_CAV_LUT_ADDR,
+ CANVAS_LUT_WR_EN | canvas_index);
+
+ /* Force a read-back to make sure everything is flushed. */
+ canvas_read(canvas, DMC_CAV_LUT_DATAH);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_config);
+
+int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index)
+{
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ for (i = 0; i < NUM_CANVAS; ++i) {
+ if (!canvas->used[i]) {
+ canvas->used[i] = 1;
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ *canvas_index = i;
+ return 0;
+ }
+ }
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ dev_err(canvas->dev, "No more canvas available\n");
+ return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_alloc);
+
+int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&canvas->lock, flags);
+ if (!canvas->used[canvas_index]) {
+ dev_err(canvas->dev,
+ "Trying to free unused canvas %u\n", canvas_index);
+ spin_unlock_irqrestore(&canvas->lock, flags);
+ return -EINVAL;
+ }
+ canvas->used[canvas_index] = 0;
+ spin_unlock_irqrestore(&canvas->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_free);
+
+static int meson_canvas_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct meson_canvas *canvas;
+ struct device *dev = &pdev->dev;
+
+ canvas = devm_kzalloc(dev, sizeof(*canvas), GFP_KERNEL);
+ if (!canvas)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ canvas->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(canvas->reg_base))
+ return PTR_ERR(canvas->reg_base);
+
+ canvas->dev = dev;
+ spin_lock_init(&canvas->lock);
+ dev_set_drvdata(dev, canvas);
+
+ return 0;
+}
+
+static const struct of_device_id canvas_dt_match[] = {
+ { .compatible = "amlogic,canvas" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, canvas_dt_match);
+
+static struct platform_driver meson_canvas_driver = {
+ .probe = meson_canvas_probe,
+ .driver = {
+ .name = "amlogic-canvas",
+ .of_match_table = canvas_dt_match,
+ },
+};
+module_platform_driver(meson_canvas_driver);
+
+MODULE_DESCRIPTION("Amlogic Canvas driver");
+MODULE_AUTHOR("Maxime Jourdan <mjourdan@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c
index b60b77bfaffa..e58fcc9096e8 100644
--- a/drivers/soc/fsl/dpio/dpio-driver.c
+++ b/drivers/soc/fsl/dpio/dpio-driver.c
@@ -50,13 +50,10 @@ static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
{
- struct dpio_priv *priv;
int error;
struct fsl_mc_device_irq *irq;
cpumask_t mask;
- priv = dev_get_drvdata(&dpio_dev->dev);
-
irq = dpio_dev->irqs[0];
error = devm_request_irq(&dpio_dev->dev,
irq->msi_desc->irq,
diff --git a/drivers/soc/fsl/qbman/Kconfig b/drivers/soc/fsl/qbman/Kconfig
index d570cb5fd381..b0943e541796 100644
--- a/drivers/soc/fsl/qbman/Kconfig
+++ b/drivers/soc/fsl/qbman/Kconfig
@@ -1,6 +1,6 @@
menuconfig FSL_DPAA
bool "QorIQ DPAA1 framework support"
- depends on (FSL_SOC_BOOKE || ARCH_LAYERSCAPE)
+ depends on ((FSL_SOC_BOOKE || ARCH_LAYERSCAPE) && ARCH_DMA_ADDR_T_64BIT)
select GENERIC_ALLOCATOR
help
The Freescale Data Path Acceleration Architecture (DPAA) is a set of
diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c
index f9485cedc648..f84ab596bde8 100644
--- a/drivers/soc/fsl/qbman/bman.c
+++ b/drivers/soc/fsl/qbman/bman.c
@@ -562,11 +562,9 @@ static int bman_create_portal(struct bman_portal *portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
- if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
- irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
- dev_err(c->dev, "irq_set_affinity() failed\n");
+
+ if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
goto fail_affinity;
- }
/* Need RCR to be empty before continuing */
ret = bm_rcr_get_fill(p);
diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c
index 2f71f7df3465..2c95cf59f3e7 100644
--- a/drivers/soc/fsl/qbman/bman_portal.c
+++ b/drivers/soc/fsl/qbman/bman_portal.c
@@ -65,7 +65,9 @@ static int bman_offline_cpu(unsigned int cpu)
if (!pcfg)
return 0;
- irq_set_affinity(pcfg->irq, cpumask_of(0));
+ /* use any other online CPU */
+ cpu = cpumask_any_but(cpu_online_mask, cpu);
+ irq_set_affinity(pcfg->irq, cpumask_of(cpu));
return 0;
}
@@ -91,7 +93,15 @@ static int bman_portal_probe(struct platform_device *pdev)
struct device_node *node = dev->of_node;
struct bm_portal_config *pcfg;
struct resource *addr_phys[2];
- int irq, cpu;
+ int irq, cpu, err;
+
+ err = bman_is_probed();
+ if (!err)
+ return -EPROBE_DEFER;
+ if (err < 0) {
+ dev_err(&pdev->dev, "failing probe due to bman probe error\n");
+ return -ENODEV;
+ }
pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
if (!pcfg)
diff --git a/drivers/soc/fsl/qbman/dpaa_sys.h b/drivers/soc/fsl/qbman/dpaa_sys.h
index 9f379000da85..ae8afa552b1e 100644
--- a/drivers/soc/fsl/qbman/dpaa_sys.h
+++ b/drivers/soc/fsl/qbman/dpaa_sys.h
@@ -111,4 +111,24 @@ int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
#define QBMAN_MEMREMAP_ATTR MEMREMAP_WC
#endif
+static inline int dpaa_set_portal_irq_affinity(struct device *dev,
+ int irq, int cpu)
+{
+ int ret = 0;
+
+ if (!irq_can_set_affinity(irq)) {
+ dev_err(dev, "unable to set IRQ affinity\n");
+ return -EINVAL;
+ }
+
+ if (cpu == -1 || !cpu_online(cpu))
+ cpu = cpumask_any(cpu_online_mask);
+
+ ret = irq_set_affinity(irq, cpumask_of(cpu));
+ if (ret)
+ dev_err(dev, "irq_set_affinity() on CPU %d failed\n", cpu);
+
+ return ret;
+}
+
#endif /* __DPAA_SYS_H */
diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 8cc015183043..5ce24718c2fd 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -850,12 +850,24 @@ static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
static inline int qm_mc_init(struct qm_portal *portal)
{
+ u8 rr0, rr1;
struct qm_mc *mc = &portal->mc;
mc->cr = portal->addr.ce + QM_CL_CR;
mc->rr = portal->addr.ce + QM_CL_RR0;
- mc->rridx = (mc->cr->_ncw_verb & QM_MCC_VERB_VBIT)
- ? 0 : 1;
+ /*
+ * The expected valid bit polarity for the next CR command is 0
+ * if RR1 contains a valid response, and is 1 if RR0 contains a
+ * valid response. If both RR contain all 0, this indicates either
+ * that no command has been executed since reset (in which case the
+ * expected valid bit polarity is 1)
+ */
+ rr0 = mc->rr->verb;
+ rr1 = (mc->rr+1)->verb;
+ if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
+ mc->rridx = 1;
+ else
+ mc->rridx = 0;
mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
#ifdef CONFIG_FSL_DPAA_CHECKING
mc->state = qman_mc_idle;
@@ -1000,6 +1012,37 @@ static inline void put_affine_portal(void)
static struct workqueue_struct *qm_portal_wq;
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+{
+ if (!portal)
+ return;
+
+ qm_dqrr_set_ithresh(&portal->p, ithresh);
+ portal->p.dqrr.ithresh = ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_set_ithresh);
+
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
+{
+ if (portal && ithresh)
+ *ithresh = portal->p.dqrr.ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_get_ithresh);
+
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
+{
+ if (portal && iperiod)
+ *iperiod = qm_in(&portal->p, QM_REG_ITPR);
+}
+EXPORT_SYMBOL(qman_portal_get_iperiod);
+
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+{
+ if (portal)
+ qm_out(&portal->p, QM_REG_ITPR, iperiod);
+}
+EXPORT_SYMBOL(qman_portal_set_iperiod);
+
int qman_wq_alloc(void)
{
qm_portal_wq = alloc_workqueue("qman_portal_wq", 0, 1);
@@ -1210,11 +1253,9 @@ static int qman_create_portal(struct qman_portal *portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
- if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
- irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
- dev_err(c->dev, "irq_set_affinity() failed\n");
+
+ if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
goto fail_affinity;
- }
/* Need EQCR to be empty before continuing */
isdr &= ~QM_PIRQ_EQCI;
diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c
index 3e9391d117c5..661c9b234d32 100644
--- a/drivers/soc/fsl/qbman/qman_portal.c
+++ b/drivers/soc/fsl/qbman/qman_portal.c
@@ -195,8 +195,10 @@ static int qman_offline_cpu(unsigned int cpu)
if (p) {
pcfg = qman_get_qm_portal_config(p);
if (pcfg) {
- irq_set_affinity(pcfg->irq, cpumask_of(0));
- qman_portal_update_sdest(pcfg, 0);
+ /* select any other online CPU */
+ cpu = cpumask_any_but(cpu_online_mask, cpu);
+ irq_set_affinity(pcfg->irq, cpumask_of(cpu));
+ qman_portal_update_sdest(pcfg, cpu);
}
}
return 0;
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 2ef6fc6487c1..612d9c551be5 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -588,11 +588,7 @@ struct qe_firmware_info *qe_get_firmware_info(void)
}
/* Find the 'firmware' child node */
- for_each_child_of_node(qe, fw) {
- if (strcmp(fw->name, "firmware") == 0)
- break;
- }
-
+ fw = of_get_child_by_name(qe, "firmware");
of_node_put(qe);
/* Did we find the 'firmware' node? */
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index b3da635970ea..aa3729ecaa9e 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -1,13 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
* Copyright 2011-2013 Freescale Semiconductor, Inc.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
@@ -69,7 +63,7 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
u32 val;
/* Read ISO and ISO2SW power down delays */
- regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
+ regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PDNSCR_OFFS, &val);
iso = val & 0x3f;
iso2sw = (val >> 8) & 0x3f;
@@ -247,6 +241,7 @@ builtin_platform_driver(imx_pgc_power_domain_driver)
#define GPC_PGC_DOMAIN_ARM 0
#define GPC_PGC_DOMAIN_PU 1
#define GPC_PGC_DOMAIN_DISPLAY 2
+#define GPC_PGC_DOMAIN_PCI 3
static struct genpd_power_state imx6_pm_domain_pu_state = {
.power_off_latency_ns = 25000,
@@ -254,12 +249,13 @@ static struct genpd_power_state imx6_pm_domain_pu_state = {
};
static struct imx_pm_domain imx_gpc_domains[] = {
- {
+ [GPC_PGC_DOMAIN_ARM] {
.base = {
.name = "ARM",
.flags = GENPD_FLAG_ALWAYS_ON,
},
- }, {
+ },
+ [GPC_PGC_DOMAIN_PU] {
.base = {
.name = "PU",
.power_off = imx6_pm_domain_power_off,
@@ -269,7 +265,8 @@ static struct imx_pm_domain imx_gpc_domains[] = {
},
.reg_offs = 0x260,
.cntr_pdn_bit = 0,
- }, {
+ },
+ [GPC_PGC_DOMAIN_DISPLAY] {
.base = {
.name = "DISPLAY",
.power_off = imx6_pm_domain_power_off,
@@ -277,7 +274,8 @@ static struct imx_pm_domain imx_gpc_domains[] = {
},
.reg_offs = 0x240,
.cntr_pdn_bit = 4,
- }, {
+ },
+ [GPC_PGC_DOMAIN_PCI] {
.base = {
.name = "PCI",
.power_off = imx6_pm_domain_power_off,
@@ -348,8 +346,8 @@ static const struct regmap_config imx_gpc_regmap_config = {
};
static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
- &imx_gpc_domains[0].base,
- &imx_gpc_domains[1].base,
+ &imx_gpc_domains[GPC_PGC_DOMAIN_ARM].base,
+ &imx_gpc_domains[GPC_PGC_DOMAIN_PU].base,
};
static struct genpd_onecell_data imx_gpc_onecell_data = {
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 6ef18cf8f243..e7b5994fee9d 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017 Impinj, Inc
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
@@ -5,29 +6,23 @@
* Based on the code of analogus driver:
*
* Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <dt-bindings/power/imx7-power.h>
-#define GPC_LPCR_A7_BSC 0x000
+#define GPC_LPCR_A_CORE_BSC 0x000
#define GPC_PGC_CPU_MAPPING 0x0ec
-#define USB_HSIC_PHY_A7_DOMAIN BIT(6)
-#define USB_OTG2_PHY_A7_DOMAIN BIT(5)
-#define USB_OTG1_PHY_A7_DOMAIN BIT(4)
-#define PCIE_PHY_A7_DOMAIN BIT(3)
-#define MIPI_PHY_A7_DOMAIN BIT(2)
+#define USB_HSIC_PHY_A_CORE_DOMAIN BIT(6)
+#define USB_OTG2_PHY_A_CORE_DOMAIN BIT(5)
+#define USB_OTG1_PHY_A_CORE_DOMAIN BIT(4)
+#define PCIE_PHY_A_CORE_DOMAIN BIT(3)
+#define MIPI_PHY_A_CORE_DOMAIN BIT(2)
#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
#define GPC_PU_PGC_SW_PDN_REQ 0x104
@@ -53,7 +48,7 @@
#define GPC_PGC_CTRL_PCR BIT(0)
-struct imx7_pgc_domain {
+struct imx_pgc_domain {
struct generic_pm_domain genpd;
struct regmap *regmap;
struct regulator *regulator;
@@ -69,11 +64,16 @@ struct imx7_pgc_domain {
struct device *dev;
};
-static int imx7_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
+struct imx_pgc_domain_data {
+ const struct imx_pgc_domain *domains;
+ size_t domains_num;
+};
+
+static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
bool on)
{
- struct imx7_pgc_domain *domain = container_of(genpd,
- struct imx7_pgc_domain,
+ struct imx_pgc_domain *domain = container_of(genpd,
+ struct imx_pgc_domain,
genpd);
unsigned int offset = on ?
GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ;
@@ -150,24 +150,24 @@ unmap:
return ret;
}
-static int imx7_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
+static int imx_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
{
- return imx7_gpc_pu_pgc_sw_pxx_req(genpd, true);
+ return imx_gpc_pu_pgc_sw_pxx_req(genpd, true);
}
-static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
+static int imx_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
{
- return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false);
+ return imx_gpc_pu_pgc_sw_pxx_req(genpd, false);
}
-static const struct imx7_pgc_domain imx7_pgc_domains[] = {
+static const struct imx_pgc_domain imx7_pgc_domains[] = {
[IMX7_POWER_DOMAIN_MIPI_PHY] = {
.genpd = {
.name = "mipi-phy",
},
.bits = {
.pxx = MIPI_PHY_SW_Pxx_REQ,
- .map = MIPI_PHY_A7_DOMAIN,
+ .map = MIPI_PHY_A_CORE_DOMAIN,
},
.voltage = 1000000,
.pgc = PGC_MIPI,
@@ -179,7 +179,7 @@ static const struct imx7_pgc_domain imx7_pgc_domains[] = {
},
.bits = {
.pxx = PCIE_PHY_SW_Pxx_REQ,
- .map = PCIE_PHY_A7_DOMAIN,
+ .map = PCIE_PHY_A_CORE_DOMAIN,
},
.voltage = 1000000,
.pgc = PGC_PCIE,
@@ -191,16 +191,21 @@ static const struct imx7_pgc_domain imx7_pgc_domains[] = {
},
.bits = {
.pxx = USB_HSIC_PHY_SW_Pxx_REQ,
- .map = USB_HSIC_PHY_A7_DOMAIN,
+ .map = USB_HSIC_PHY_A_CORE_DOMAIN,
},
.voltage = 1200000,
.pgc = PGC_USB_HSIC,
},
};
-static int imx7_pgc_domain_probe(struct platform_device *pdev)
+static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
+ .domains = imx7_pgc_domains,
+ .domains_num = ARRAY_SIZE(imx7_pgc_domains),
+};
+
+static int imx_pgc_domain_probe(struct platform_device *pdev)
{
- struct imx7_pgc_domain *domain = pdev->dev.platform_data;
+ struct imx_pgc_domain *domain = pdev->dev.platform_data;
int ret;
domain->dev = &pdev->dev;
@@ -233,9 +238,9 @@ static int imx7_pgc_domain_probe(struct platform_device *pdev)
return ret;
}
-static int imx7_pgc_domain_remove(struct platform_device *pdev)
+static int imx_pgc_domain_remove(struct platform_device *pdev)
{
- struct imx7_pgc_domain *domain = pdev->dev.platform_data;
+ struct imx_pgc_domain *domain = pdev->dev.platform_data;
of_genpd_del_provider(domain->dev->of_node);
pm_genpd_remove(&domain->genpd);
@@ -243,25 +248,26 @@ static int imx7_pgc_domain_remove(struct platform_device *pdev)
return 0;
}
-static const struct platform_device_id imx7_pgc_domain_id[] = {
- { "imx7-pgc-domain", },
+static const struct platform_device_id imx_pgc_domain_id[] = {
+ { "imx-pgc-domain", },
{ },
};
-static struct platform_driver imx7_pgc_domain_driver = {
+static struct platform_driver imx_pgc_domain_driver = {
.driver = {
- .name = "imx7-pgc",
+ .name = "imx-pgc",
},
- .probe = imx7_pgc_domain_probe,
- .remove = imx7_pgc_domain_remove,
- .id_table = imx7_pgc_domain_id,
+ .probe = imx_pgc_domain_probe,
+ .remove = imx_pgc_domain_remove,
+ .id_table = imx_pgc_domain_id,
};
-builtin_platform_driver(imx7_pgc_domain_driver)
+builtin_platform_driver(imx_pgc_domain_driver)
static int imx_gpcv2_probe(struct platform_device *pdev)
{
+ static const struct imx_pgc_domain_data *domain_data;
static const struct regmap_range yes_ranges[] = {
- regmap_reg_range(GPC_LPCR_A7_BSC,
+ regmap_reg_range(GPC_LPCR_A_CORE_BSC,
GPC_M4_PU_PDN_FLG),
regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI),
GPC_PGC_SR(PGC_MIPI)),
@@ -307,9 +313,11 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
return ret;
}
+ domain_data = of_device_get_match_data(&pdev->dev);
+
for_each_child_of_node(pgc_np, np) {
struct platform_device *pd_pdev;
- struct imx7_pgc_domain *domain;
+ struct imx_pgc_domain *domain;
u32 domain_index;
ret = of_property_read_u32(np, "reg", &domain_index);
@@ -319,14 +327,14 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
return ret;
}
- if (domain_index >= ARRAY_SIZE(imx7_pgc_domains)) {
+ if (domain_index >= domain_data->domains_num) {
dev_warn(dev,
"Domain index %d is out of bounds\n",
domain_index);
continue;
}
- pd_pdev = platform_device_alloc("imx7-pgc-domain",
+ pd_pdev = platform_device_alloc("imx-pgc-domain",
domain_index);
if (!pd_pdev) {
dev_err(dev, "Failed to allocate platform device\n");
@@ -335,8 +343,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
}
ret = platform_device_add_data(pd_pdev,
- &imx7_pgc_domains[domain_index],
- sizeof(imx7_pgc_domains[domain_index]));
+ &domain_data->domains[domain_index],
+ sizeof(domain_data->domains[domain_index]));
if (ret) {
platform_device_put(pd_pdev);
of_node_put(np);
@@ -345,8 +353,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
domain = pd_pdev->dev.platform_data;
domain->regmap = regmap;
- domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req;
- domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req;
+ domain->genpd.power_on = imx_gpc_pu_pgc_sw_pup_req;
+ domain->genpd.power_off = imx_gpc_pu_pgc_sw_pdn_req;
pd_pdev->dev.parent = dev;
pd_pdev->dev.of_node = np;
@@ -363,7 +371,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
}
static const struct of_device_id imx_gpcv2_dt_ids[] = {
- { .compatible = "fsl,imx7d-gpc" },
+ { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
{ }
};
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 4e931fdf4d09..8236a6c87e19 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -76,6 +76,13 @@
#define PWRAP_SLV_CAP_SECURITY BIT(2)
#define HAS_CAP(_c, _x) (((_c) & (_x)) == (_x))
+/* Group of bits used for shown pwrap capability */
+#define PWRAP_CAP_BRIDGE BIT(0)
+#define PWRAP_CAP_RESET BIT(1)
+#define PWRAP_CAP_DCM BIT(2)
+#define PWRAP_CAP_INT1_EN BIT(3)
+#define PWRAP_CAP_WDT_SRC1 BIT(4)
+
/* defines for slave device wrapper registers */
enum dew_regs {
PWRAP_DEW_BASE,
@@ -91,6 +98,27 @@ enum dew_regs {
PWRAP_DEW_CIPHER_MODE,
PWRAP_DEW_CIPHER_SWRST,
+ /* MT6323 only regs */
+ PWRAP_DEW_CIPHER_EN,
+ PWRAP_DEW_RDDMY_NO,
+
+ /* MT6358 only regs */
+ PWRAP_SMT_CON1,
+ PWRAP_DRV_CON1,
+ PWRAP_FILTER_CON0,
+ PWRAP_GPIO_PULLEN0_CLR,
+ PWRAP_RG_SPI_CON0,
+ PWRAP_RG_SPI_RECORD0,
+ PWRAP_RG_SPI_CON2,
+ PWRAP_RG_SPI_CON3,
+ PWRAP_RG_SPI_CON4,
+ PWRAP_RG_SPI_CON5,
+ PWRAP_RG_SPI_CON6,
+ PWRAP_RG_SPI_CON7,
+ PWRAP_RG_SPI_CON8,
+ PWRAP_RG_SPI_CON13,
+ PWRAP_SPISLV_KEY,
+
/* MT6397 only regs */
PWRAP_DEW_EVENT_OUT_EN,
PWRAP_DEW_EVENT_SRC_EN,
@@ -100,10 +128,6 @@ enum dew_regs {
PWRAP_DEW_EVENT_TEST,
PWRAP_DEW_CIPHER_LOAD,
PWRAP_DEW_CIPHER_START,
-
- /* MT6323 only regs */
- PWRAP_DEW_CIPHER_EN,
- PWRAP_DEW_RDDMY_NO,
};
static const u32 mt6323_regs[] = {
@@ -123,6 +147,64 @@ static const u32 mt6323_regs[] = {
[PWRAP_DEW_RDDMY_NO] = 0x01a4,
};
+static const u32 mt6351_regs[] = {
+ [PWRAP_DEW_DIO_EN] = 0x02F2,
+ [PWRAP_DEW_READ_TEST] = 0x02F4,
+ [PWRAP_DEW_WRITE_TEST] = 0x02F6,
+ [PWRAP_DEW_CRC_EN] = 0x02FA,
+ [PWRAP_DEW_CRC_VAL] = 0x02FC,
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x0300,
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x0302,
+ [PWRAP_DEW_CIPHER_EN] = 0x0304,
+ [PWRAP_DEW_CIPHER_RDY] = 0x0306,
+ [PWRAP_DEW_CIPHER_MODE] = 0x0308,
+ [PWRAP_DEW_CIPHER_SWRST] = 0x030A,
+ [PWRAP_DEW_RDDMY_NO] = 0x030C,
+};
+
+static const u32 mt6357_regs[] = {
+ [PWRAP_DEW_DIO_EN] = 0x040A,
+ [PWRAP_DEW_READ_TEST] = 0x040C,
+ [PWRAP_DEW_WRITE_TEST] = 0x040E,
+ [PWRAP_DEW_CRC_EN] = 0x0412,
+ [PWRAP_DEW_CRC_VAL] = 0x0414,
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x0418,
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x041A,
+ [PWRAP_DEW_CIPHER_EN] = 0x041C,
+ [PWRAP_DEW_CIPHER_RDY] = 0x041E,
+ [PWRAP_DEW_CIPHER_MODE] = 0x0420,
+ [PWRAP_DEW_CIPHER_SWRST] = 0x0422,
+ [PWRAP_DEW_RDDMY_NO] = 0x0424,
+};
+
+static const u32 mt6358_regs[] = {
+ [PWRAP_SMT_CON1] = 0x0030,
+ [PWRAP_DRV_CON1] = 0x0038,
+ [PWRAP_FILTER_CON0] = 0x0040,
+ [PWRAP_GPIO_PULLEN0_CLR] = 0x0098,
+ [PWRAP_RG_SPI_CON0] = 0x0408,
+ [PWRAP_RG_SPI_RECORD0] = 0x040a,
+ [PWRAP_DEW_DIO_EN] = 0x040c,
+ [PWRAP_DEW_READ_TEST] = 0x040e,
+ [PWRAP_DEW_WRITE_TEST] = 0x0410,
+ [PWRAP_DEW_CRC_EN] = 0x0414,
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x041a,
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x041c,
+ [PWRAP_DEW_CIPHER_EN] = 0x041e,
+ [PWRAP_DEW_CIPHER_RDY] = 0x0420,
+ [PWRAP_DEW_CIPHER_MODE] = 0x0422,
+ [PWRAP_DEW_CIPHER_SWRST] = 0x0424,
+ [PWRAP_RG_SPI_CON2] = 0x0432,
+ [PWRAP_RG_SPI_CON3] = 0x0434,
+ [PWRAP_RG_SPI_CON4] = 0x0436,
+ [PWRAP_RG_SPI_CON5] = 0x0438,
+ [PWRAP_RG_SPI_CON6] = 0x043a,
+ [PWRAP_RG_SPI_CON7] = 0x043c,
+ [PWRAP_RG_SPI_CON8] = 0x043e,
+ [PWRAP_RG_SPI_CON13] = 0x0448,
+ [PWRAP_SPISLV_KEY] = 0x044a,
+};
+
static const u32 mt6397_regs[] = {
[PWRAP_DEW_BASE] = 0xbc00,
[PWRAP_DEW_EVENT_OUT_EN] = 0xbc00,
@@ -146,21 +228,6 @@ static const u32 mt6397_regs[] = {
[PWRAP_DEW_CIPHER_SWRST] = 0xbc24,
};
-static const u32 mt6351_regs[] = {
- [PWRAP_DEW_DIO_EN] = 0x02F2,
- [PWRAP_DEW_READ_TEST] = 0x02F4,
- [PWRAP_DEW_WRITE_TEST] = 0x02F6,
- [PWRAP_DEW_CRC_EN] = 0x02FA,
- [PWRAP_DEW_CRC_VAL] = 0x02FC,
- [PWRAP_DEW_CIPHER_KEY_SEL] = 0x0300,
- [PWRAP_DEW_CIPHER_IV_SEL] = 0x0302,
- [PWRAP_DEW_CIPHER_EN] = 0x0304,
- [PWRAP_DEW_CIPHER_RDY] = 0x0306,
- [PWRAP_DEW_CIPHER_MODE] = 0x0308,
- [PWRAP_DEW_CIPHER_SWRST] = 0x030A,
- [PWRAP_DEW_RDDMY_NO] = 0x030C,
-};
-
enum pwrap_regs {
PWRAP_MUX_SEL,
PWRAP_WRAP_EN,
@@ -221,6 +288,8 @@ enum pwrap_regs {
PWRAP_CIPHER_SWRST,
PWRAP_DCM_EN,
PWRAP_DCM_DBC_PRD,
+ PWRAP_EINT_STA0_ADR,
+ PWRAP_EINT_STA1_ADR,
/* MT2701 only regs */
PWRAP_ADC_CMD_ADDR,
@@ -230,8 +299,6 @@ enum pwrap_regs {
PWRAP_ADC_RDATA_ADDR2,
/* MT7622 only regs */
- PWRAP_EINT_STA0_ADR,
- PWRAP_EINT_STA1_ADR,
PWRAP_STA,
PWRAP_CLR,
PWRAP_DVFS_ADR8,
@@ -293,6 +360,27 @@ enum pwrap_regs {
PWRAP_DVFS_WDATA7,
PWRAP_SPMINF_STA,
PWRAP_CIPHER_EN,
+
+ /* MT8183 only regs */
+ PWRAP_SI_SAMPLE_CTRL,
+ PWRAP_CSLEXT_WRITE,
+ PWRAP_CSLEXT_READ,
+ PWRAP_EXT_CK_WRITE,
+ PWRAP_STAUPD_CTRL,
+ PWRAP_WACS_P2P_EN,
+ PWRAP_INIT_DONE_P2P,
+ PWRAP_WACS_MD32_EN,
+ PWRAP_INIT_DONE_MD32,
+ PWRAP_INT1_EN,
+ PWRAP_INT1_FLG,
+ PWRAP_INT1_CLR,
+ PWRAP_WDT_SRC_EN_1,
+ PWRAP_INT_GPS_AUXADC_CMD_ADDR,
+ PWRAP_INT_GPS_AUXADC_CMD,
+ PWRAP_INT_GPS_AUXADC_RDATA_ADDR,
+ PWRAP_EXT_GPS_AUXADC_RDATA_ADDR,
+ PWRAP_GPSINF_0_STA,
+ PWRAP_GPSINF_1_STA,
};
static int mt2701_regs[] = {
@@ -381,6 +469,38 @@ static int mt2701_regs[] = {
[PWRAP_ADC_RDATA_ADDR2] = 0x154,
};
+static int mt6765_regs[] = {
+ [PWRAP_MUX_SEL] = 0x0,
+ [PWRAP_WRAP_EN] = 0x4,
+ [PWRAP_DIO_EN] = 0x8,
+ [PWRAP_RDDMY] = 0x20,
+ [PWRAP_CSHEXT_WRITE] = 0x24,
+ [PWRAP_CSHEXT_READ] = 0x28,
+ [PWRAP_CSLEXT_START] = 0x2C,
+ [PWRAP_CSLEXT_END] = 0x30,
+ [PWRAP_STAUPD_PRD] = 0x3C,
+ [PWRAP_HARB_HPRIO] = 0x68,
+ [PWRAP_HIPRIO_ARB_EN] = 0x6C,
+ [PWRAP_MAN_EN] = 0x7C,
+ [PWRAP_MAN_CMD] = 0x80,
+ [PWRAP_WACS0_EN] = 0x8C,
+ [PWRAP_WACS1_EN] = 0x94,
+ [PWRAP_WACS2_EN] = 0x9C,
+ [PWRAP_INIT_DONE2] = 0xA0,
+ [PWRAP_WACS2_CMD] = 0xC20,
+ [PWRAP_WACS2_RDATA] = 0xC24,
+ [PWRAP_WACS2_VLDCLR] = 0xC28,
+ [PWRAP_INT_EN] = 0xB4,
+ [PWRAP_INT_FLG_RAW] = 0xB8,
+ [PWRAP_INT_FLG] = 0xBC,
+ [PWRAP_INT_CLR] = 0xC0,
+ [PWRAP_TIMER_EN] = 0xE8,
+ [PWRAP_WDT_UNIT] = 0xF0,
+ [PWRAP_WDT_SRC_EN] = 0xF4,
+ [PWRAP_DCM_EN] = 0x1DC,
+ [PWRAP_DCM_DBC_PRD] = 0x1E0,
+};
+
static int mt6797_regs[] = {
[PWRAP_MUX_SEL] = 0x0,
[PWRAP_WRAP_EN] = 0x4,
@@ -526,6 +646,79 @@ static int mt7622_regs[] = {
[PWRAP_SPI2_CTRL] = 0x244,
};
+static int mt8135_regs[] = {
+ [PWRAP_MUX_SEL] = 0x0,
+ [PWRAP_WRAP_EN] = 0x4,
+ [PWRAP_DIO_EN] = 0x8,
+ [PWRAP_SIDLY] = 0xc,
+ [PWRAP_CSHEXT] = 0x10,
+ [PWRAP_CSHEXT_WRITE] = 0x14,
+ [PWRAP_CSHEXT_READ] = 0x18,
+ [PWRAP_CSLEXT_START] = 0x1c,
+ [PWRAP_CSLEXT_END] = 0x20,
+ [PWRAP_STAUPD_PRD] = 0x24,
+ [PWRAP_STAUPD_GRPEN] = 0x28,
+ [PWRAP_STAUPD_MAN_TRIG] = 0x2c,
+ [PWRAP_STAUPD_STA] = 0x30,
+ [PWRAP_EVENT_IN_EN] = 0x34,
+ [PWRAP_EVENT_DST_EN] = 0x38,
+ [PWRAP_WRAP_STA] = 0x3c,
+ [PWRAP_RRARB_INIT] = 0x40,
+ [PWRAP_RRARB_EN] = 0x44,
+ [PWRAP_RRARB_STA0] = 0x48,
+ [PWRAP_RRARB_STA1] = 0x4c,
+ [PWRAP_HARB_INIT] = 0x50,
+ [PWRAP_HARB_HPRIO] = 0x54,
+ [PWRAP_HIPRIO_ARB_EN] = 0x58,
+ [PWRAP_HARB_STA0] = 0x5c,
+ [PWRAP_HARB_STA1] = 0x60,
+ [PWRAP_MAN_EN] = 0x64,
+ [PWRAP_MAN_CMD] = 0x68,
+ [PWRAP_MAN_RDATA] = 0x6c,
+ [PWRAP_MAN_VLDCLR] = 0x70,
+ [PWRAP_WACS0_EN] = 0x74,
+ [PWRAP_INIT_DONE0] = 0x78,
+ [PWRAP_WACS0_CMD] = 0x7c,
+ [PWRAP_WACS0_RDATA] = 0x80,
+ [PWRAP_WACS0_VLDCLR] = 0x84,
+ [PWRAP_WACS1_EN] = 0x88,
+ [PWRAP_INIT_DONE1] = 0x8c,
+ [PWRAP_WACS1_CMD] = 0x90,
+ [PWRAP_WACS1_RDATA] = 0x94,
+ [PWRAP_WACS1_VLDCLR] = 0x98,
+ [PWRAP_WACS2_EN] = 0x9c,
+ [PWRAP_INIT_DONE2] = 0xa0,
+ [PWRAP_WACS2_CMD] = 0xa4,
+ [PWRAP_WACS2_RDATA] = 0xa8,
+ [PWRAP_WACS2_VLDCLR] = 0xac,
+ [PWRAP_INT_EN] = 0xb0,
+ [PWRAP_INT_FLG_RAW] = 0xb4,
+ [PWRAP_INT_FLG] = 0xb8,
+ [PWRAP_INT_CLR] = 0xbc,
+ [PWRAP_SIG_ADR] = 0xc0,
+ [PWRAP_SIG_MODE] = 0xc4,
+ [PWRAP_SIG_VALUE] = 0xc8,
+ [PWRAP_SIG_ERRVAL] = 0xcc,
+ [PWRAP_CRC_EN] = 0xd0,
+ [PWRAP_EVENT_STA] = 0xd4,
+ [PWRAP_EVENT_STACLR] = 0xd8,
+ [PWRAP_TIMER_EN] = 0xdc,
+ [PWRAP_TIMER_STA] = 0xe0,
+ [PWRAP_WDT_UNIT] = 0xe4,
+ [PWRAP_WDT_SRC_EN] = 0xe8,
+ [PWRAP_WDT_FLG] = 0xec,
+ [PWRAP_DEBUG_INT_SEL] = 0xf0,
+ [PWRAP_CIPHER_KEY_SEL] = 0x134,
+ [PWRAP_CIPHER_IV_SEL] = 0x138,
+ [PWRAP_CIPHER_LOAD] = 0x13c,
+ [PWRAP_CIPHER_START] = 0x140,
+ [PWRAP_CIPHER_RDY] = 0x144,
+ [PWRAP_CIPHER_MODE] = 0x148,
+ [PWRAP_CIPHER_SWRST] = 0x14c,
+ [PWRAP_DCM_EN] = 0x15c,
+ [PWRAP_DCM_DBC_PRD] = 0x160,
+};
+
static int mt8173_regs[] = {
[PWRAP_MUX_SEL] = 0x0,
[PWRAP_WRAP_EN] = 0x4,
@@ -608,92 +801,74 @@ static int mt8173_regs[] = {
[PWRAP_DCM_DBC_PRD] = 0x148,
};
-static int mt8135_regs[] = {
- [PWRAP_MUX_SEL] = 0x0,
- [PWRAP_WRAP_EN] = 0x4,
- [PWRAP_DIO_EN] = 0x8,
- [PWRAP_SIDLY] = 0xc,
- [PWRAP_CSHEXT] = 0x10,
- [PWRAP_CSHEXT_WRITE] = 0x14,
- [PWRAP_CSHEXT_READ] = 0x18,
- [PWRAP_CSLEXT_START] = 0x1c,
- [PWRAP_CSLEXT_END] = 0x20,
- [PWRAP_STAUPD_PRD] = 0x24,
- [PWRAP_STAUPD_GRPEN] = 0x28,
- [PWRAP_STAUPD_MAN_TRIG] = 0x2c,
- [PWRAP_STAUPD_STA] = 0x30,
- [PWRAP_EVENT_IN_EN] = 0x34,
- [PWRAP_EVENT_DST_EN] = 0x38,
- [PWRAP_WRAP_STA] = 0x3c,
- [PWRAP_RRARB_INIT] = 0x40,
- [PWRAP_RRARB_EN] = 0x44,
- [PWRAP_RRARB_STA0] = 0x48,
- [PWRAP_RRARB_STA1] = 0x4c,
- [PWRAP_HARB_INIT] = 0x50,
- [PWRAP_HARB_HPRIO] = 0x54,
- [PWRAP_HIPRIO_ARB_EN] = 0x58,
- [PWRAP_HARB_STA0] = 0x5c,
- [PWRAP_HARB_STA1] = 0x60,
- [PWRAP_MAN_EN] = 0x64,
- [PWRAP_MAN_CMD] = 0x68,
- [PWRAP_MAN_RDATA] = 0x6c,
- [PWRAP_MAN_VLDCLR] = 0x70,
- [PWRAP_WACS0_EN] = 0x74,
- [PWRAP_INIT_DONE0] = 0x78,
- [PWRAP_WACS0_CMD] = 0x7c,
- [PWRAP_WACS0_RDATA] = 0x80,
- [PWRAP_WACS0_VLDCLR] = 0x84,
- [PWRAP_WACS1_EN] = 0x88,
- [PWRAP_INIT_DONE1] = 0x8c,
- [PWRAP_WACS1_CMD] = 0x90,
- [PWRAP_WACS1_RDATA] = 0x94,
- [PWRAP_WACS1_VLDCLR] = 0x98,
- [PWRAP_WACS2_EN] = 0x9c,
- [PWRAP_INIT_DONE2] = 0xa0,
- [PWRAP_WACS2_CMD] = 0xa4,
- [PWRAP_WACS2_RDATA] = 0xa8,
- [PWRAP_WACS2_VLDCLR] = 0xac,
- [PWRAP_INT_EN] = 0xb0,
- [PWRAP_INT_FLG_RAW] = 0xb4,
- [PWRAP_INT_FLG] = 0xb8,
- [PWRAP_INT_CLR] = 0xbc,
- [PWRAP_SIG_ADR] = 0xc0,
- [PWRAP_SIG_MODE] = 0xc4,
- [PWRAP_SIG_VALUE] = 0xc8,
- [PWRAP_SIG_ERRVAL] = 0xcc,
- [PWRAP_CRC_EN] = 0xd0,
- [PWRAP_EVENT_STA] = 0xd4,
- [PWRAP_EVENT_STACLR] = 0xd8,
- [PWRAP_TIMER_EN] = 0xdc,
- [PWRAP_TIMER_STA] = 0xe0,
- [PWRAP_WDT_UNIT] = 0xe4,
- [PWRAP_WDT_SRC_EN] = 0xe8,
- [PWRAP_WDT_FLG] = 0xec,
- [PWRAP_DEBUG_INT_SEL] = 0xf0,
- [PWRAP_CIPHER_KEY_SEL] = 0x134,
- [PWRAP_CIPHER_IV_SEL] = 0x138,
- [PWRAP_CIPHER_LOAD] = 0x13c,
- [PWRAP_CIPHER_START] = 0x140,
- [PWRAP_CIPHER_RDY] = 0x144,
- [PWRAP_CIPHER_MODE] = 0x148,
- [PWRAP_CIPHER_SWRST] = 0x14c,
- [PWRAP_DCM_EN] = 0x15c,
- [PWRAP_DCM_DBC_PRD] = 0x160,
+static int mt8183_regs[] = {
+ [PWRAP_MUX_SEL] = 0x0,
+ [PWRAP_WRAP_EN] = 0x4,
+ [PWRAP_DIO_EN] = 0x8,
+ [PWRAP_SI_SAMPLE_CTRL] = 0xC,
+ [PWRAP_RDDMY] = 0x14,
+ [PWRAP_CSHEXT_WRITE] = 0x18,
+ [PWRAP_CSHEXT_READ] = 0x1C,
+ [PWRAP_CSLEXT_WRITE] = 0x20,
+ [PWRAP_CSLEXT_READ] = 0x24,
+ [PWRAP_EXT_CK_WRITE] = 0x28,
+ [PWRAP_STAUPD_CTRL] = 0x30,
+ [PWRAP_STAUPD_GRPEN] = 0x34,
+ [PWRAP_EINT_STA0_ADR] = 0x38,
+ [PWRAP_HARB_HPRIO] = 0x5C,
+ [PWRAP_HIPRIO_ARB_EN] = 0x60,
+ [PWRAP_MAN_EN] = 0x70,
+ [PWRAP_MAN_CMD] = 0x74,
+ [PWRAP_WACS0_EN] = 0x80,
+ [PWRAP_INIT_DONE0] = 0x84,
+ [PWRAP_WACS1_EN] = 0x88,
+ [PWRAP_INIT_DONE1] = 0x8C,
+ [PWRAP_WACS2_EN] = 0x90,
+ [PWRAP_INIT_DONE2] = 0x94,
+ [PWRAP_WACS_P2P_EN] = 0xA0,
+ [PWRAP_INIT_DONE_P2P] = 0xA4,
+ [PWRAP_WACS_MD32_EN] = 0xA8,
+ [PWRAP_INIT_DONE_MD32] = 0xAC,
+ [PWRAP_INT_EN] = 0xB0,
+ [PWRAP_INT_FLG] = 0xB8,
+ [PWRAP_INT_CLR] = 0xBC,
+ [PWRAP_INT1_EN] = 0xC0,
+ [PWRAP_INT1_FLG] = 0xC8,
+ [PWRAP_INT1_CLR] = 0xCC,
+ [PWRAP_SIG_ADR] = 0xD0,
+ [PWRAP_CRC_EN] = 0xE0,
+ [PWRAP_TIMER_EN] = 0xE4,
+ [PWRAP_WDT_UNIT] = 0xEC,
+ [PWRAP_WDT_SRC_EN] = 0xF0,
+ [PWRAP_WDT_SRC_EN_1] = 0xF4,
+ [PWRAP_INT_GPS_AUXADC_CMD_ADDR] = 0x1DC,
+ [PWRAP_INT_GPS_AUXADC_CMD] = 0x1E0,
+ [PWRAP_INT_GPS_AUXADC_RDATA_ADDR] = 0x1E4,
+ [PWRAP_EXT_GPS_AUXADC_RDATA_ADDR] = 0x1E8,
+ [PWRAP_GPSINF_0_STA] = 0x1EC,
+ [PWRAP_GPSINF_1_STA] = 0x1F0,
+ [PWRAP_WACS2_CMD] = 0xC20,
+ [PWRAP_WACS2_RDATA] = 0xC24,
+ [PWRAP_WACS2_VLDCLR] = 0xC28,
};
enum pmic_type {
PMIC_MT6323,
PMIC_MT6351,
+ PMIC_MT6357,
+ PMIC_MT6358,
PMIC_MT6380,
PMIC_MT6397,
};
enum pwrap_type {
PWRAP_MT2701,
+ PWRAP_MT6765,
PWRAP_MT6797,
PWRAP_MT7622,
PWRAP_MT8135,
PWRAP_MT8173,
+ PWRAP_MT8183,
};
struct pmic_wrapper;
@@ -731,9 +906,11 @@ struct pmic_wrapper_type {
enum pwrap_type type;
u32 arb_en_all;
u32 int_en_all;
+ u32 int1_en_all;
u32 spi_w;
u32 wdt_src;
- unsigned int has_bridge:1;
+ /* Flags indicating the capability for the target pwrap */
+ u32 caps;
int (*init_reg_clock)(struct pmic_wrapper *wrp);
int (*init_soc_specific)(struct pmic_wrapper *wrp);
};
@@ -1096,7 +1273,7 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
&rdata);
if (ret)
- return 0;
+ return false;
return rdata == 1;
}
@@ -1117,6 +1294,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
break;
case PWRAP_MT2701:
+ case PWRAP_MT6765:
case PWRAP_MT6797:
case PWRAP_MT8173:
pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
@@ -1124,6 +1302,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
case PWRAP_MT7622:
pwrap_writel(wrp, 0, PWRAP_CIPHER_EN);
break;
+ case PWRAP_MT8183:
+ break;
}
/* Config cipher mode @PMIC */
@@ -1141,6 +1321,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
break;
case PMIC_MT6323:
case PMIC_MT6351:
+ case PMIC_MT6357:
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
0x1);
break;
@@ -1276,6 +1457,23 @@ static int pwrap_mt7622_init_soc_specific(struct pmic_wrapper *wrp)
return 0;
}
+static int pwrap_mt8183_init_soc_specific(struct pmic_wrapper *wrp)
+{
+ pwrap_writel(wrp, 0xf5, PWRAP_STAUPD_GRPEN);
+
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1);
+ pwrap_writel(wrp, 1, PWRAP_CRC_EN);
+ pwrap_writel(wrp, 0x416, PWRAP_SIG_ADR);
+ pwrap_writel(wrp, 0x42e, PWRAP_EINT_STA0_ADR);
+
+ pwrap_writel(wrp, 1, PWRAP_WACS_P2P_EN);
+ pwrap_writel(wrp, 1, PWRAP_WACS_MD32_EN);
+ pwrap_writel(wrp, 1, PWRAP_INIT_DONE_P2P);
+ pwrap_writel(wrp, 1, PWRAP_INIT_DONE_MD32);
+
+ return 0;
+}
+
static int pwrap_init(struct pmic_wrapper *wrp)
{
int ret;
@@ -1348,7 +1546,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
pwrap_writel(wrp, 1, PWRAP_INIT_DONE0);
pwrap_writel(wrp, 1, PWRAP_INIT_DONE1);
- if (wrp->master->has_bridge) {
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) {
writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE3);
writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE4);
}
@@ -1362,11 +1560,15 @@ static irqreturn_t pwrap_interrupt(int irqno, void *dev_id)
struct pmic_wrapper *wrp = dev_id;
rdata = pwrap_readl(wrp, PWRAP_INT_FLG);
-
dev_err(wrp->dev, "unexpected interrupt int=0x%x\n", rdata);
-
pwrap_writel(wrp, 0xffffffff, PWRAP_INT_CLR);
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN)) {
+ rdata = pwrap_readl(wrp, PWRAP_INT1_FLG);
+ dev_err(wrp->dev, "unexpected interrupt int1=0x%x\n", rdata);
+ pwrap_writel(wrp, 0xffffffff, PWRAP_INT1_CLR);
+ }
+
return IRQ_HANDLED;
}
@@ -1398,6 +1600,33 @@ static const struct pwrap_slv_type pmic_mt6323 = {
.pwrap_write = pwrap_write16,
};
+static const struct pwrap_slv_type pmic_mt6351 = {
+ .dew_regs = mt6351_regs,
+ .type = PMIC_MT6351,
+ .regmap = &pwrap_regmap_config16,
+ .caps = 0,
+ .pwrap_read = pwrap_read16,
+ .pwrap_write = pwrap_write16,
+};
+
+static const struct pwrap_slv_type pmic_mt6357 = {
+ .dew_regs = mt6357_regs,
+ .type = PMIC_MT6357,
+ .regmap = &pwrap_regmap_config16,
+ .caps = 0,
+ .pwrap_read = pwrap_read16,
+ .pwrap_write = pwrap_write16,
+};
+
+static const struct pwrap_slv_type pmic_mt6358 = {
+ .dew_regs = mt6358_regs,
+ .type = PMIC_MT6358,
+ .regmap = &pwrap_regmap_config16,
+ .caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO,
+ .pwrap_read = pwrap_read16,
+ .pwrap_write = pwrap_write16,
+};
+
static const struct pwrap_slv_type pmic_mt6380 = {
.dew_regs = NULL,
.type = PMIC_MT6380,
@@ -1417,20 +1646,20 @@ static const struct pwrap_slv_type pmic_mt6397 = {
.pwrap_write = pwrap_write16,
};
-static const struct pwrap_slv_type pmic_mt6351 = {
- .dew_regs = mt6351_regs,
- .type = PMIC_MT6351,
- .regmap = &pwrap_regmap_config16,
- .caps = 0,
- .pwrap_read = pwrap_read16,
- .pwrap_write = pwrap_write16,
-};
-
static const struct of_device_id of_slave_match_tbl[] = {
{
.compatible = "mediatek,mt6323",
.data = &pmic_mt6323,
}, {
+ .compatible = "mediatek,mt6351",
+ .data = &pmic_mt6351,
+ }, {
+ .compatible = "mediatek,mt6357",
+ .data = &pmic_mt6357,
+ }, {
+ .compatible = "mediatek,mt6358",
+ .data = &pmic_mt6358,
+ }, {
/* The MT6380 PMIC only implements a regulator, so we bind it
* directly instead of using a MFD.
*/
@@ -1440,9 +1669,6 @@ static const struct of_device_id of_slave_match_tbl[] = {
.compatible = "mediatek,mt6397",
.data = &pmic_mt6397,
}, {
- .compatible = "mediatek,mt6351",
- .data = &pmic_mt6351,
- }, {
/* sentinel */
}
};
@@ -1453,21 +1679,35 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
.type = PWRAP_MT2701,
.arb_en_all = 0x3f,
.int_en_all = ~(u32)(BIT(31) | BIT(2)),
+ .int1_en_all = 0,
.spi_w = PWRAP_MAN_CMD_SPI_WRITE_NEW,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
- .has_bridge = 0,
+ .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
.init_reg_clock = pwrap_mt2701_init_reg_clock,
.init_soc_specific = pwrap_mt2701_init_soc_specific,
};
+static const struct pmic_wrapper_type pwrap_mt6765 = {
+ .regs = mt6765_regs,
+ .type = PWRAP_MT6765,
+ .arb_en_all = 0x3fd35,
+ .int_en_all = 0xffffffff,
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+ .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
+ .init_reg_clock = pwrap_common_init_reg_clock,
+ .init_soc_specific = NULL,
+};
+
static const struct pmic_wrapper_type pwrap_mt6797 = {
.regs = mt6797_regs,
.type = PWRAP_MT6797,
.arb_en_all = 0x01fff,
.int_en_all = 0xffffffc6,
+ .int1_en_all = 0,
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
- .has_bridge = 0,
+ .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = NULL,
};
@@ -1477,9 +1717,10 @@ static const struct pmic_wrapper_type pwrap_mt7622 = {
.type = PWRAP_MT7622,
.arb_en_all = 0xff,
.int_en_all = ~(u32)BIT(31),
+ .int1_en_all = 0,
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
- .has_bridge = 0,
+ .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt7622_init_soc_specific,
};
@@ -1489,9 +1730,10 @@ static const struct pmic_wrapper_type pwrap_mt8135 = {
.type = PWRAP_MT8135,
.arb_en_all = 0x1ff,
.int_en_all = ~(u32)(BIT(31) | BIT(1)),
+ .int1_en_all = 0,
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
- .has_bridge = 1,
+ .caps = PWRAP_CAP_BRIDGE | PWRAP_CAP_RESET | PWRAP_CAP_DCM,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt8135_init_soc_specific,
};
@@ -1501,18 +1743,35 @@ static const struct pmic_wrapper_type pwrap_mt8173 = {
.type = PWRAP_MT8173,
.arb_en_all = 0x3f,
.int_en_all = ~(u32)(BIT(31) | BIT(1)),
+ .int1_en_all = 0,
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
.wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
- .has_bridge = 0,
+ .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
.init_reg_clock = pwrap_common_init_reg_clock,
.init_soc_specific = pwrap_mt8173_init_soc_specific,
};
+static const struct pmic_wrapper_type pwrap_mt8183 = {
+ .regs = mt8183_regs,
+ .type = PWRAP_MT8183,
+ .arb_en_all = 0x3fa75,
+ .int_en_all = 0xffffffff,
+ .int1_en_all = 0xeef7ffff,
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+ .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_WDT_SRC1,
+ .init_reg_clock = pwrap_common_init_reg_clock,
+ .init_soc_specific = pwrap_mt8183_init_soc_specific,
+};
+
static const struct of_device_id of_pwrap_match_tbl[] = {
{
.compatible = "mediatek,mt2701-pwrap",
.data = &pwrap_mt2701,
}, {
+ .compatible = "mediatek,mt6765-pwrap",
+ .data = &pwrap_mt6765,
+ }, {
.compatible = "mediatek,mt6797-pwrap",
.data = &pwrap_mt6797,
}, {
@@ -1525,6 +1784,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
.compatible = "mediatek,mt8173-pwrap",
.data = &pwrap_mt8173,
}, {
+ .compatible = "mediatek,mt8183-pwrap",
+ .data = &pwrap_mt8183,
+ }, {
/* sentinel */
}
};
@@ -1561,14 +1823,16 @@ static int pwrap_probe(struct platform_device *pdev)
if (IS_ERR(wrp->base))
return PTR_ERR(wrp->base);
- wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
- if (IS_ERR(wrp->rstc)) {
- ret = PTR_ERR(wrp->rstc);
- dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
- return ret;
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_RESET)) {
+ wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
+ if (IS_ERR(wrp->rstc)) {
+ ret = PTR_ERR(wrp->rstc);
+ dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
+ return ret;
+ }
}
- if (wrp->master->has_bridge) {
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"pwrap-bridge");
wrp->bridge_base = devm_ioremap_resource(wrp->dev, res);
@@ -1608,8 +1872,10 @@ static int pwrap_probe(struct platform_device *pdev)
goto err_out1;
/* Enable internal dynamic clock */
- pwrap_writel(wrp, 1, PWRAP_DCM_EN);
- pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_DCM)) {
+ pwrap_writel(wrp, 1, PWRAP_DCM_EN);
+ pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+ }
/*
* The PMIC could already be initialized by the bootloader.
@@ -1636,8 +1902,17 @@ static int pwrap_probe(struct platform_device *pdev)
* so STAUPD of WDT_SRC which should be turned off
*/
pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN);
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_WDT_SRC1))
+ pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN_1);
+
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
+ /*
+ * We add INT1 interrupt to handle starvation and request exception
+ * If we support it, we should enable it here.
+ */
+ if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN))
+ pwrap_writel(wrp, wrp->master->int1_en_all, PWRAP_INT1_EN);
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt,
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 41986d96f24b..684cb51694d1 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -33,7 +33,7 @@ config QCOM_GLINK_SSR
config QCOM_GSBI
tristate "QCOM General Serial Bus Interface"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM || COMPILE_TEST
select MFD_SYSCON
help
Say y here to enable GSBI support. The GSBI provides control
@@ -42,7 +42,7 @@ config QCOM_GSBI
config QCOM_LLCC
tristate "Qualcomm Technologies, Inc. LLCC driver"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM || COMPILE_TEST
help
Qualcomm Technologies, Inc. platform specific
Last Level Cache Controller(LLCC) driver. This provides interfaces
@@ -73,7 +73,8 @@ config QCOM_PM
config QCOM_QMI_HELPERS
tristate
- depends on (ARCH_QCOM || COMPILE_TEST) && NET
+ depends on ARCH_QCOM || COMPILE_TEST
+ depends on NET
help
Helper library for handling QMI encoded messages. QMI encoded
messages are used in communication between the majority of QRTR
@@ -94,7 +95,7 @@ config QCOM_RMTFS_MEM
config QCOM_RPMH
bool "Qualcomm RPM-Hardened (RPMH) Communication"
- depends on ARCH_QCOM && ARM64 && OF || COMPILE_TEST
+ depends on ARCH_QCOM && ARM64 || COMPILE_TEST
help
Support for communication with the hardened-RPM blocks in
Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an
@@ -104,7 +105,7 @@ config QCOM_RPMH
config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM || COMPILE_TEST
depends on HWSPINLOCK
help
Say y here to enable support for the Qualcomm Shared Memory Manager.
@@ -113,8 +114,8 @@ config QCOM_SMEM
config QCOM_SMD_RPM
tristate "Qualcomm Resource Power Manager (RPM) over SMD"
- depends on ARCH_QCOM
- depends on RPMSG && OF
+ depends on ARCH_QCOM || COMPILE_TEST
+ depends on RPMSG
help
If you say yes to this option, support will be included for the
Resource Power Manager system found in the Qualcomm 8974 based
@@ -134,6 +135,7 @@ config QCOM_SMP2P
depends on MAILBOX
depends on QCOM_SMEM
select QCOM_SMEM_STATE
+ select IRQ_DOMAIN
help
Say yes here to support the Qualcomm Shared Memory Point to Point
protocol.
@@ -142,13 +144,14 @@ config QCOM_SMSM
tristate "Qualcomm Shared Memory State Machine"
depends on QCOM_SMEM
select QCOM_SMEM_STATE
+ select IRQ_DOMAIN
help
Say yes here to support the Qualcomm Shared Memory State Machine.
The state machine is represented by bits in shared memory.
config QCOM_WCNSS_CTRL
tristate "Qualcomm WCNSS control driver"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM || COMPILE_TEST
depends on RPMSG
help
Client driver for the WCNSS_CTRL SMD channel, used to download nv
@@ -156,7 +159,7 @@ config QCOM_WCNSS_CTRL
config QCOM_APR
tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
- depends on ARCH_QCOM
+ depends on ARCH_QCOM || COMPILE_TEST
depends on RPMSG
help
Enable APR IPC protocol support between
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index 4bda793ba6ae..74f8b9607daa 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -87,7 +87,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
}
if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) {
- dev_err(apr->dev, "APR: Wrong paket size\n");
+ dev_err(apr->dev, "APR: Wrong packet size\n");
return -EINVAL;
}
@@ -221,7 +221,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
if (np)
snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
else
- strncpy(adev->name, id->name, APR_NAME_SIZE);
+ strscpy(adev->name, id->name, APR_NAME_SIZE);
dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
id->domain_id, id->svc_id);
diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c
index 54063a31132f..192ca761b2cb 100644
--- a/drivers/soc/qcom/llcc-slice.c
+++ b/drivers/soc/qcom/llcc-slice.c
@@ -13,6 +13,7 @@
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/soc/qcom/llcc-qcom.h>
@@ -106,22 +107,24 @@ static int llcc_update_act_ctrl(u32 sid,
u32 slice_status;
int ret;
- act_ctrl_reg = drv_data->bcast_off + LLCC_TRP_ACT_CTRLn(sid);
- status_reg = drv_data->bcast_off + LLCC_TRP_STATUSn(sid);
+ act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
+ status_reg = LLCC_TRP_STATUSn(sid);
/* Set the ACTIVE trigger */
act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
- ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
+ ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
+ act_ctrl_reg_val);
if (ret)
return ret;
/* Clear the ACTIVE trigger */
act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
- ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
+ ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
+ act_ctrl_reg_val);
if (ret)
return ret;
- ret = regmap_read_poll_timeout(drv_data->regmap, status_reg,
+ ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
slice_status, !(slice_status & status),
0, LLCC_STATUS_READ_DELAY);
return ret;
@@ -223,19 +226,16 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
u32 attr0_val;
u32 max_cap_cacheline;
u32 sz;
- int ret;
+ int ret = 0;
const struct llcc_slice_config *llcc_table;
struct llcc_slice_desc desc;
- u32 bcast_off = drv_data->bcast_off;
sz = drv_data->cfg_size;
llcc_table = drv_data->cfg;
for (i = 0; i < sz; i++) {
- attr1_cfg = bcast_off +
- LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
- attr0_cfg = bcast_off +
- LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
+ attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
+ attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
attr1_val = llcc_table[i].cache_mode;
attr1_val |= llcc_table[i].probe_target_ways <<
@@ -260,10 +260,12 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
- ret = regmap_write(drv_data->regmap, attr1_cfg, attr1_val);
+ ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
+ attr1_val);
if (ret)
return ret;
- ret = regmap_write(drv_data->regmap, attr0_cfg, attr0_val);
+ ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
+ attr0_val);
if (ret)
return ret;
if (llcc_table[i].activate_on_init) {
@@ -279,24 +281,37 @@ int qcom_llcc_probe(struct platform_device *pdev,
{
u32 num_banks;
struct device *dev = &pdev->dev;
- struct resource *res;
- void __iomem *base;
+ struct resource *llcc_banks_res, *llcc_bcast_res;
+ void __iomem *llcc_banks_base, *llcc_bcast_base;
int ret, i;
+ struct platform_device *llcc_edac;
drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
if (!drv_data)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(base))
- return PTR_ERR(base);
+ llcc_banks_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "llcc_base");
+ llcc_banks_base = devm_ioremap_resource(&pdev->dev, llcc_banks_res);
+ if (IS_ERR(llcc_banks_base))
+ return PTR_ERR(llcc_banks_base);
- drv_data->regmap = devm_regmap_init_mmio(dev, base,
- &llcc_regmap_config);
+ drv_data->regmap = devm_regmap_init_mmio(dev, llcc_banks_base,
+ &llcc_regmap_config);
if (IS_ERR(drv_data->regmap))
return PTR_ERR(drv_data->regmap);
+ llcc_bcast_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "llcc_broadcast_base");
+ llcc_bcast_base = devm_ioremap_resource(&pdev->dev, llcc_bcast_res);
+ if (IS_ERR(llcc_bcast_base))
+ return PTR_ERR(llcc_bcast_base);
+
+ drv_data->bcast_regmap = devm_regmap_init_mmio(dev, llcc_bcast_base,
+ &llcc_regmap_config);
+ if (IS_ERR(drv_data->bcast_regmap))
+ return PTR_ERR(drv_data->bcast_regmap);
+
ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
&num_banks);
if (ret)
@@ -318,8 +333,6 @@ int qcom_llcc_probe(struct platform_device *pdev,
for (i = 0; i < num_banks; i++)
drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
- drv_data->bcast_off = num_banks * BANK_OFFSET_STRIDE;
-
drv_data->bitmap = devm_kcalloc(dev,
BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
GFP_KERNEL);
@@ -331,7 +344,20 @@ int qcom_llcc_probe(struct platform_device *pdev,
mutex_init(&drv_data->lock);
platform_set_drvdata(pdev, drv_data);
- return qcom_llcc_cfg_program(pdev);
+ ret = qcom_llcc_cfg_program(pdev);
+ if (ret)
+ return ret;
+
+ drv_data->ecc_irq = platform_get_irq(pdev, 0);
+ if (drv_data->ecc_irq >= 0) {
+ llcc_edac = platform_device_register_data(&pdev->dev,
+ "qcom_llcc_edac", -1, drv_data,
+ sizeof(*drv_data));
+ if (IS_ERR(llcc_edac))
+ dev_err(dev, "Failed to register llcc edac driver\n");
+ }
+
+ return ret;
}
EXPORT_SYMBOL_GPL(qcom_llcc_probe);
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
index 8a3678c2e83c..97bb5989aa21 100644
--- a/drivers/soc/qcom/rmtfs_mem.c
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -212,6 +212,11 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to parse qcom,vmid\n");
goto remove_cdev;
} else if (!ret) {
+ if (!qcom_scm_is_available()) {
+ ret = -EPROBE_DEFER;
+ goto remove_cdev;
+ }
+
perms[0].vmid = QCOM_SCM_VMID_HLOS;
perms[0].perm = QCOM_SCM_PERM_RW;
perms[1].vmid = vmid;
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index ee75da66d64b..75bd9a83aef0 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -121,6 +121,7 @@ static int tcs_invalidate(struct rsc_drv *drv, int type)
return -EAGAIN;
}
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
+ write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, m, 0);
}
bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
spin_unlock(&tcs->lock);
@@ -239,6 +240,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
skip:
/* Reclaim the TCS */
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
+ write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0);
write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
spin_lock(&drv->lock);
clear_bit(i, drv->tcs_in_use);
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index bf4bd71ab53f..f80d040601fd 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
+#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smem.h>
@@ -277,7 +278,7 @@ struct qcom_smem {
u32 item_count;
unsigned num_regions;
- struct smem_region regions[0];
+ struct smem_region regions[];
};
static void *
@@ -489,7 +490,7 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
size_t *size)
{
struct smem_header *header;
- struct smem_region *area;
+ struct smem_region *region;
struct smem_global_entry *entry;
u32 aux_base;
unsigned i;
@@ -502,12 +503,12 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
for (i = 0; i < smem->num_regions; i++) {
- area = &smem->regions[i];
+ region = &smem->regions[i];
- if (area->aux_base == aux_base || !aux_base) {
+ if (region->aux_base == aux_base || !aux_base) {
if (size != NULL)
*size = le32_to_cpu(entry->size);
- return area->virt_base + le32_to_cpu(entry->offset);
+ return region->virt_base + le32_to_cpu(entry->offset);
}
}
@@ -722,12 +723,59 @@ static u32 qcom_smem_get_item_count(struct qcom_smem *smem)
return le16_to_cpu(info->num_items);
}
+/*
+ * Validate the partition header for a partition whose partition
+ * table entry is supplied. Returns a pointer to its header if
+ * valid, or a null pointer otherwise.
+ */
+static struct smem_partition_header *
+qcom_smem_partition_header(struct qcom_smem *smem,
+ struct smem_ptable_entry *entry, u16 host0, u16 host1)
+{
+ struct smem_partition_header *header;
+ u32 size;
+
+ header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+
+ if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
+ dev_err(smem->dev, "bad partition magic %02x %02x %02x %02x\n",
+ header->magic[0], header->magic[1],
+ header->magic[2], header->magic[3]);
+ return NULL;
+ }
+
+ if (host0 != le16_to_cpu(header->host0)) {
+ dev_err(smem->dev, "bad host0 (%hu != %hu)\n",
+ host0, le16_to_cpu(header->host0));
+ return NULL;
+ }
+ if (host1 != le16_to_cpu(header->host1)) {
+ dev_err(smem->dev, "bad host1 (%hu != %hu)\n",
+ host1, le16_to_cpu(header->host1));
+ return NULL;
+ }
+
+ size = le32_to_cpu(header->size);
+ if (size != le32_to_cpu(entry->size)) {
+ dev_err(smem->dev, "bad partition size (%u != %u)\n",
+ size, le32_to_cpu(entry->size));
+ return NULL;
+ }
+
+ if (le32_to_cpu(header->offset_free_uncached) > size) {
+ dev_err(smem->dev, "bad partition free uncached (%u > %u)\n",
+ le32_to_cpu(header->offset_free_uncached), size);
+ return NULL;
+ }
+
+ return header;
+}
+
static int qcom_smem_set_global_partition(struct qcom_smem *smem)
{
struct smem_partition_header *header;
struct smem_ptable_entry *entry;
struct smem_ptable *ptable;
- u32 host0, host1, size;
bool found = false;
int i;
@@ -742,10 +790,15 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
entry = &ptable->entry[i];
- host0 = le16_to_cpu(entry->host0);
- host1 = le16_to_cpu(entry->host1);
+ if (!le32_to_cpu(entry->offset))
+ continue;
+ if (!le32_to_cpu(entry->size))
+ continue;
+
+ if (le16_to_cpu(entry->host0) != SMEM_GLOBAL_HOST)
+ continue;
- if (host0 == SMEM_GLOBAL_HOST && host0 == host1) {
+ if (le16_to_cpu(entry->host1) == SMEM_GLOBAL_HOST) {
found = true;
break;
}
@@ -756,36 +809,10 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
return -EINVAL;
}
- if (!le32_to_cpu(entry->offset) || !le32_to_cpu(entry->size)) {
- dev_err(smem->dev, "Invalid entry for global partition\n");
+ header = qcom_smem_partition_header(smem, entry,
+ SMEM_GLOBAL_HOST, SMEM_GLOBAL_HOST);
+ if (!header)
return -EINVAL;
- }
-
- header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
- host0 = le16_to_cpu(header->host0);
- host1 = le16_to_cpu(header->host1);
-
- if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
- dev_err(smem->dev, "Global partition has invalid magic\n");
- return -EINVAL;
- }
-
- if (host0 != SMEM_GLOBAL_HOST && host1 != SMEM_GLOBAL_HOST) {
- dev_err(smem->dev, "Global partition hosts are invalid\n");
- return -EINVAL;
- }
-
- if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
- dev_err(smem->dev, "Global partition has invalid size\n");
- return -EINVAL;
- }
-
- size = le32_to_cpu(header->offset_free_uncached);
- if (size > le32_to_cpu(header->size)) {
- dev_err(smem->dev,
- "Global partition has invalid free pointer\n");
- return -EINVAL;
- }
smem->global_partition = header;
smem->global_cacheline = le32_to_cpu(entry->cacheline);
@@ -793,14 +820,14 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
return 0;
}
-static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
- unsigned int local_host)
+static int
+qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
{
struct smem_partition_header *header;
struct smem_ptable_entry *entry;
struct smem_ptable *ptable;
unsigned int remote_host;
- u32 host0, host1;
+ u16 host0, host1;
int i;
ptable = qcom_smem_get_ptable(smem);
@@ -809,71 +836,33 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
entry = &ptable->entry[i];
- host0 = le16_to_cpu(entry->host0);
- host1 = le16_to_cpu(entry->host1);
-
- if (host0 != local_host && host1 != local_host)
- continue;
-
if (!le32_to_cpu(entry->offset))
continue;
-
if (!le32_to_cpu(entry->size))
continue;
+ host0 = le16_to_cpu(entry->host0);
+ host1 = le16_to_cpu(entry->host1);
if (host0 == local_host)
remote_host = host1;
- else
+ else if (host1 == local_host)
remote_host = host0;
+ else
+ continue;
if (remote_host >= SMEM_HOST_COUNT) {
- dev_err(smem->dev,
- "Invalid remote host %d\n",
- remote_host);
+ dev_err(smem->dev, "bad host %hu\n", remote_host);
return -EINVAL;
}
if (smem->partitions[remote_host]) {
- dev_err(smem->dev,
- "Already found a partition for host %d\n",
- remote_host);
- return -EINVAL;
- }
-
- header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
- host0 = le16_to_cpu(header->host0);
- host1 = le16_to_cpu(header->host1);
-
- if (memcmp(header->magic, SMEM_PART_MAGIC,
- sizeof(header->magic))) {
- dev_err(smem->dev,
- "Partition %d has invalid magic\n", i);
+ dev_err(smem->dev, "duplicate host %hu\n", remote_host);
return -EINVAL;
}
- if (host0 != local_host && host1 != local_host) {
- dev_err(smem->dev,
- "Partition %d hosts are invalid\n", i);
+ header = qcom_smem_partition_header(smem, entry, host0, host1);
+ if (!header)
return -EINVAL;
- }
-
- if (host0 != remote_host && host1 != remote_host) {
- dev_err(smem->dev,
- "Partition %d hosts are invalid\n", i);
- return -EINVAL;
- }
-
- if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
- dev_err(smem->dev,
- "Partition %d has invalid size\n", i);
- return -EINVAL;
- }
-
- if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) {
- dev_err(smem->dev,
- "Partition %d has invalid free pointer\n", i);
- return -EINVAL;
- }
smem->partitions[remote_host] = header;
smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline);
@@ -887,6 +876,7 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
{
struct device_node *np;
struct resource r;
+ resource_size_t size;
int ret;
np = of_parse_phandle(dev->of_node, name, 0);
@@ -899,12 +889,13 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
of_node_put(np);
if (ret)
return ret;
+ size = resource_size(&r);
- smem->regions[i].aux_base = (u32)r.start;
- smem->regions[i].size = resource_size(&r);
- smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, resource_size(&r));
+ smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size);
if (!smem->regions[i].virt_base)
return -ENOMEM;
+ smem->regions[i].aux_base = (u32)r.start;
+ smem->regions[i].size = size;
return 0;
}
@@ -962,6 +953,7 @@ static int qcom_smem_probe(struct platform_device *pdev)
return -EINVAL;
}
+ BUILD_BUG_ON(SMEM_HOST_APPS >= SMEM_HOST_COUNT);
ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
if (ret < 0 && ret != -ENOENT)
return ret;
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index f9d7a85b2822..53807e839664 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -219,6 +219,9 @@ static int __init qcom_cpuidle_init(struct device_node *cpu_node, int cpu)
cpumask_t mask;
bool use_scm_power_down = false;
+ if (!qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
for (i = 0; ; i++) {
state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
if (!state_node)
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
index df3ccb30bc2d..373400dd816d 100644
--- a/drivers/soc/qcom/wcnss_ctrl.c
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -281,7 +281,7 @@ struct rpmsg_endpoint *qcom_wcnss_open_channel(void *wcnss, const char *name, rp
struct rpmsg_channel_info chinfo;
struct wcnss_ctrl *_wcnss = wcnss;
- strncpy(chinfo.name, name, sizeof(chinfo.name));
+ strscpy(chinfo.name, name, sizeof(chinfo.name));
chinfo.src = RPMSG_ADDR_ANY;
chinfo.dst = RPMSG_ADDR_ANY;
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 1d824cbd462d..407f02c80e8b 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -1,14 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
config SOC_RENESAS
bool "Renesas SoC driver support" if COMPILE_TEST && !ARCH_RENESAS
default y if ARCH_RENESAS
select SOC_BUS
select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
- ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
- ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77990 || \
- ARCH_R8A77995
- select SYSC_R8A7743 if ARCH_R8A7743
+ ARCH_R8A774A1 || ARCH_R8A774C0 || ARCH_R8A7795 || \
+ ARCH_R8A7796 || ARCH_R8A77965 || ARCH_R8A77970 || \
+ ARCH_R8A77980 || ARCH_R8A77990 || ARCH_R8A77995
+ select SYSC_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
select SYSC_R8A7745 if ARCH_R8A7745
select SYSC_R8A77470 if ARCH_R8A77470
+ select SYSC_R8A774A1 if ARCH_R8A774A1
+ select SYSC_R8A774C0 if ARCH_R8A774C0
select SYSC_R8A7779 if ARCH_R8A7779
select SYSC_R8A7790 if ARCH_R8A7790
select SYSC_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
@@ -37,6 +40,14 @@ config SYSC_R8A77470
bool "RZ/G1C System Controller support" if COMPILE_TEST
select SYSC_RCAR
+config SYSC_R8A774A1
+ bool "RZ/G2M System Controller support" if COMPILE_TEST
+ select SYSC_RCAR
+
+config SYSC_R8A774C0
+ bool "RZ/G2E System Controller support" if COMPILE_TEST
+ select SYSC_RCAR
+
config SYSC_R8A7779
bool "R-Car H1 System Controller support" if COMPILE_TEST
select SYSC_RCAR
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index c37b0803c1b6..3bdd7dbc38a9 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -6,6 +6,8 @@ obj-$(CONFIG_SOC_RENESAS) += renesas-soc.o
obj-$(CONFIG_SYSC_R8A7743) += r8a7743-sysc.o
obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o
obj-$(CONFIG_SYSC_R8A77470) += r8a77470-sysc.o
+obj-$(CONFIG_SYSC_R8A774A1) += r8a774a1-sysc.o
+obj-$(CONFIG_SYSC_R8A774C0) += r8a774c0-sysc.o
obj-$(CONFIG_SYSC_R8A7779) += r8a7779-sysc.o
obj-$(CONFIG_SYSC_R8A7790) += r8a7790-sysc.o
obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o
diff --git a/drivers/soc/renesas/r8a7743-sysc.c b/drivers/soc/renesas/r8a7743-sysc.c
index 9583a327d90c..edf6436e879f 100644
--- a/drivers/soc/renesas/r8a7743-sysc.c
+++ b/drivers/soc/renesas/r8a7743-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas RZ/G1M System Controller
*
* Copyright (C) 2016 Cogent Embedded 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; of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7745-sysc.c b/drivers/soc/renesas/r8a7745-sysc.c
index d17887c08aa1..65dc6b09cc85 100644
--- a/drivers/soc/renesas/r8a7745-sysc.c
+++ b/drivers/soc/renesas/r8a7745-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas RZ/G1E System Controller
*
* Copyright (C) 2016 Cogent Embedded 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; of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a774a1-sysc.c b/drivers/soc/renesas/r8a774a1-sysc.c
new file mode 100644
index 000000000000..9db51ff6f5ed
--- /dev/null
+++ b/drivers/soc/renesas/r8a774a1-sysc.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2M System Controller
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on Renesas R-Car M3-W System Controller
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a774a1-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a774a1_areas[] __initconst = {
+ { "always-on", 0, 0, R8A774A1_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca57-scu", 0x1c0, 0, R8A774A1_PD_CA57_SCU, R8A774A1_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca57-cpu0", 0x80, 0, R8A774A1_PD_CA57_CPU0, R8A774A1_PD_CA57_SCU,
+ PD_CPU_NOCR },
+ { "ca57-cpu1", 0x80, 1, R8A774A1_PD_CA57_CPU1, R8A774A1_PD_CA57_SCU,
+ PD_CPU_NOCR },
+ { "ca53-scu", 0x140, 0, R8A774A1_PD_CA53_SCU, R8A774A1_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca53-cpu0", 0x200, 0, R8A774A1_PD_CA53_CPU0, R8A774A1_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "ca53-cpu1", 0x200, 1, R8A774A1_PD_CA53_CPU1, R8A774A1_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "ca53-cpu2", 0x200, 2, R8A774A1_PD_CA53_CPU2, R8A774A1_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "ca53-cpu3", 0x200, 3, R8A774A1_PD_CA53_CPU3, R8A774A1_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "a3vc", 0x380, 0, R8A774A1_PD_A3VC, R8A774A1_PD_ALWAYS_ON },
+ { "a2vc0", 0x3c0, 0, R8A774A1_PD_A2VC0, R8A774A1_PD_A3VC },
+ { "a2vc1", 0x3c0, 1, R8A774A1_PD_A2VC1, R8A774A1_PD_A3VC },
+ { "3dg-a", 0x100, 0, R8A774A1_PD_3DG_A, R8A774A1_PD_ALWAYS_ON },
+ { "3dg-b", 0x100, 1, R8A774A1_PD_3DG_B, R8A774A1_PD_3DG_A },
+};
+
+const struct rcar_sysc_info r8a774a1_sysc_info __initconst = {
+ .areas = r8a774a1_areas,
+ .num_areas = ARRAY_SIZE(r8a774a1_areas),
+};
diff --git a/drivers/soc/renesas/r8a774c0-sysc.c b/drivers/soc/renesas/r8a774c0-sysc.c
new file mode 100644
index 000000000000..e1ac4c0f6640
--- /dev/null
+++ b/drivers/soc/renesas/r8a774c0-sysc.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2E System Controller
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on Renesas R-Car E3 System Controller
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/sys_soc.h>
+
+#include <dt-bindings/power/r8a774c0-sysc.h>
+
+#include "rcar-sysc.h"
+
+static struct rcar_sysc_area r8a774c0_areas[] __initdata = {
+ { "always-on", 0, 0, R8A774C0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca53-scu", 0x140, 0, R8A774C0_PD_CA53_SCU, R8A774C0_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca53-cpu0", 0x200, 0, R8A774C0_PD_CA53_CPU0, R8A774C0_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "ca53-cpu1", 0x200, 1, R8A774C0_PD_CA53_CPU1, R8A774C0_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "a3vc", 0x380, 0, R8A774C0_PD_A3VC, R8A774C0_PD_ALWAYS_ON },
+ { "a2vc1", 0x3c0, 1, R8A774C0_PD_A2VC1, R8A774C0_PD_A3VC },
+ { "3dg-a", 0x100, 0, R8A774C0_PD_3DG_A, R8A774C0_PD_ALWAYS_ON },
+ { "3dg-b", 0x100, 1, R8A774C0_PD_3DG_B, R8A774C0_PD_3DG_A },
+};
+
+static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas,
+ unsigned int num_areas, u8 id,
+ int new_parent)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_areas; i++)
+ if (areas[i].isr_bit == id) {
+ areas[i].parent = new_parent;
+ return;
+ }
+}
+
+/* Fixups for RZ/G2E ES1.0 revision */
+static const struct soc_device_attribute r8a774c0[] __initconst = {
+ { .soc_id = "r8a774c0", .revision = "ES1.0" },
+ { /* sentinel */ }
+};
+
+static int __init r8a774c0_sysc_init(void)
+{
+ if (soc_device_match(r8a774c0)) {
+ rcar_sysc_fix_parent(r8a774c0_areas,
+ ARRAY_SIZE(r8a774c0_areas),
+ R8A774C0_PD_3DG_A, R8A774C0_PD_3DG_B);
+ rcar_sysc_fix_parent(r8a774c0_areas,
+ ARRAY_SIZE(r8a774c0_areas),
+ R8A774C0_PD_3DG_B, R8A774C0_PD_ALWAYS_ON);
+ }
+
+ return 0;
+}
+
+const struct rcar_sysc_info r8a774c0_sysc_info __initconst = {
+ .init = r8a774c0_sysc_init,
+ .areas = r8a774c0_areas,
+ .num_areas = ARRAY_SIZE(r8a774c0_areas),
+};
diff --git a/drivers/soc/renesas/r8a7779-sysc.c b/drivers/soc/renesas/r8a7779-sysc.c
index 9e8e6b7faa04..517aa40fa6e6 100644
--- a/drivers/soc/renesas/r8a7779-sysc.c
+++ b/drivers/soc/renesas/r8a7779-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car H1 System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7790-sysc.c b/drivers/soc/renesas/r8a7790-sysc.c
index 7a567ad0ff73..9b5a6bb62152 100644
--- a/drivers/soc/renesas/r8a7790-sysc.c
+++ b/drivers/soc/renesas/r8a7790-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car H2 System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7791-sysc.c b/drivers/soc/renesas/r8a7791-sysc.c
index 03b9f41a34e6..acf545cdebfb 100644
--- a/drivers/soc/renesas/r8a7791-sysc.c
+++ b/drivers/soc/renesas/r8a7791-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car M2-W/N System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7792-sysc.c b/drivers/soc/renesas/r8a7792-sysc.c
index ca7467d7b7ec..05b78525cc43 100644
--- a/drivers/soc/renesas/r8a7792-sysc.c
+++ b/drivers/soc/renesas/r8a7792-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car V2H (R8A7792) System Controller
*
* Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7794-sysc.c b/drivers/soc/renesas/r8a7794-sysc.c
index c4da2941e06c..0d42637fa662 100644
--- a/drivers/soc/renesas/r8a7794-sysc.c
+++ b/drivers/soc/renesas/r8a7794-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car E2 System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7795-sysc.c b/drivers/soc/renesas/r8a7795-sysc.c
index 7412666187b3..cda27a67de98 100644
--- a/drivers/soc/renesas/r8a7795-sysc.c
+++ b/drivers/soc/renesas/r8a7795-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car H3 System Controller
*
* Copyright (C) 2016-2017 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a7796-sysc.c b/drivers/soc/renesas/r8a7796-sysc.c
index f700c842b9e1..1b06f868b6e8 100644
--- a/drivers/soc/renesas/r8a7796-sysc.c
+++ b/drivers/soc/renesas/r8a7796-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car M3-W System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a77970-sysc.c b/drivers/soc/renesas/r8a77970-sysc.c
index caf894f193ed..35b30d6a8958 100644
--- a/drivers/soc/renesas/r8a77970-sysc.c
+++ b/drivers/soc/renesas/r8a77970-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car V3M System Controller
*
* Copyright (C) 2017 Cogent Embedded 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.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c
index 1b2ef415bbe1..6243aaaf60fb 100644
--- a/drivers/soc/renesas/r8a77995-sysc.c
+++ b/drivers/soc/renesas/r8a77995-sysc.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car D3 System Controller
*
* Copyright (C) 2017 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#include <linux/bug.h>
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
index d9c1034e70e9..d183c381e8db 100644
--- a/drivers/soc/renesas/rcar-rst.c
+++ b/drivers/soc/renesas/rcar-rst.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* R-Car Gen1 RESET/WDT, R-Car Gen2, Gen3, and RZ/G RST Driver
*
* Copyright (C) 2016 Glider bvba
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/err.h>
@@ -41,10 +38,14 @@ static const struct rst_config rcar_rst_gen3 __initconst = {
};
static const struct of_device_id rcar_rst_matches[] __initconst = {
- /* RZ/G is handled like R-Car Gen2 */
+ /* RZ/G1 is handled like R-Car Gen2 */
{ .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a7744-rst", .data = &rcar_rst_gen2 },
{ .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 },
{ .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 },
+ /* RZ/G2 is handled like R-Car Gen3 */
+ { .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 },
+ { .compatible = "renesas,r8a774c0-rst", .data = &rcar_rst_gen3 },
/* R-Car Gen1 */
{ .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 },
{ .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 },
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 029188e8be6e..af53363eda03 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* R-Car SYSC Power management support
*
* Copyright (C) 2014 Magnus Damm
* Copyright (C) 2015-2017 Glider bvba
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/clk/renesas.h>
@@ -268,6 +265,8 @@ finalize:
static const struct of_device_id rcar_sysc_matches[] __initconst = {
#ifdef CONFIG_SYSC_R8A7743
{ .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
+ /* RZ/G1N is identical to RZ/G2M w.r.t. power domains. */
+ { .compatible = "renesas,r8a7744-sysc", .data = &r8a7743_sysc_info },
#endif
#ifdef CONFIG_SYSC_R8A7745
{ .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
@@ -275,6 +274,12 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
#ifdef CONFIG_SYSC_R8A77470
{ .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info },
#endif
+#ifdef CONFIG_SYSC_R8A774A1
+ { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info },
+#endif
+#ifdef CONFIG_SYSC_R8A774C0
+ { .compatible = "renesas,r8a774c0-sysc", .data = &r8a774c0_sysc_info },
+#endif
#ifdef CONFIG_SYSC_R8A7779
{ .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
#endif
diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
index a22e7cf25e30..485520a5b295 100644
--- a/drivers/soc/renesas/rcar-sysc.h
+++ b/drivers/soc/renesas/rcar-sysc.h
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
* Renesas R-Car System Controller
*
* Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
*/
#ifndef __SOC_RENESAS_RCAR_SYSC_H__
#define __SOC_RENESAS_RCAR_SYSC_H__
@@ -52,6 +49,8 @@ struct rcar_sysc_info {
extern const struct rcar_sysc_info r8a7743_sysc_info;
extern const struct rcar_sysc_info r8a7745_sysc_info;
extern const struct rcar_sysc_info r8a77470_sysc_info;
+extern const struct rcar_sysc_info r8a774a1_sysc_info;
+extern const struct rcar_sysc_info r8a774c0_sysc_info;
extern const struct rcar_sysc_info r8a7779_sysc_info;
extern const struct rcar_sysc_info r8a7790_sysc_info;
extern const struct rcar_sysc_info r8a7791_sysc_info;
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index d44d0e687ab8..4af96e668a2f 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Renesas SoC Identification
*
* Copyright (C) 2014-2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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 the
- * GNU General Public License for more details.
*/
#include <linux/io.h>
@@ -46,15 +38,24 @@ static const struct renesas_family fam_rmobile __initconst __maybe_unused = {
.reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
};
-static const struct renesas_family fam_rza __initconst __maybe_unused = {
- .name = "RZ/A",
+static const struct renesas_family fam_rza1 __initconst __maybe_unused = {
+ .name = "RZ/A1",
+};
+
+static const struct renesas_family fam_rza2 __initconst __maybe_unused = {
+ .name = "RZ/A2",
};
-static const struct renesas_family fam_rzg __initconst __maybe_unused = {
- .name = "RZ/G",
+static const struct renesas_family fam_rzg1 __initconst __maybe_unused = {
+ .name = "RZ/G1",
.reg = 0xff000044, /* PRR (Product Register) */
};
+static const struct renesas_family fam_rzg2 __initconst __maybe_unused = {
+ .name = "RZ/G2",
+ .reg = 0xfff00044, /* PRR (Product Register) */
+};
+
static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
.name = "SH-Mobile",
.reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
@@ -67,7 +68,12 @@ struct renesas_soc {
};
static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = {
- .family = &fam_rza,
+ .family = &fam_rza1,
+};
+
+static const struct renesas_soc soc_rz_a2m __initconst __maybe_unused = {
+ .family = &fam_rza2,
+ .id = 0x3b,
};
static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = {
@@ -81,30 +87,40 @@ static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = {
};
static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = {
- .family = &fam_rzg,
+ .family = &fam_rzg1,
.id = 0x45,
};
static const struct renesas_soc soc_rz_g1m __initconst __maybe_unused = {
- .family = &fam_rzg,
+ .family = &fam_rzg1,
.id = 0x47,
};
static const struct renesas_soc soc_rz_g1n __initconst __maybe_unused = {
- .family = &fam_rzg,
+ .family = &fam_rzg1,
.id = 0x4b,
};
static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = {
- .family = &fam_rzg,
+ .family = &fam_rzg1,
.id = 0x4c,
};
static const struct renesas_soc soc_rz_g1c __initconst __maybe_unused = {
- .family = &fam_rzg,
+ .family = &fam_rzg1,
.id = 0x53,
};
+static const struct renesas_soc soc_rz_g2m __initconst __maybe_unused = {
+ .family = &fam_rzg2,
+ .id = 0x52,
+};
+
+static const struct renesas_soc soc_rz_g2e __initconst __maybe_unused = {
+ .family = &fam_rzg2,
+ .id = 0x57,
+};
+
static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
.family = &fam_rcar_gen1,
};
@@ -184,6 +200,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
#ifdef CONFIG_ARCH_R7S72100
{ .compatible = "renesas,r7s72100", .data = &soc_rz_a1h },
#endif
+#ifdef CONFIG_ARCH_R7S9210
+ { .compatible = "renesas,r7s9210", .data = &soc_rz_a2m },
+#endif
#ifdef CONFIG_ARCH_R8A73A4
{ .compatible = "renesas,r8a73a4", .data = &soc_rmobile_ape6 },
#endif
@@ -205,6 +224,12 @@ static const struct of_device_id renesas_socs[] __initconst = {
#ifdef CONFIG_ARCH_R8A77470
{ .compatible = "renesas,r8a77470", .data = &soc_rz_g1c },
#endif
+#ifdef CONFIG_ARCH_R8A774A1
+ { .compatible = "renesas,r8a774a1", .data = &soc_rz_g2m },
+#endif
+#ifdef CONFIG_ARCH_R8A774C0
+ { .compatible = "renesas,r8a774c0", .data = &soc_rz_g2e },
+#endif
#ifdef CONFIG_ARCH_R8A7778
{ .compatible = "renesas,r8a7778", .data = &soc_rcar_m1a },
#endif
@@ -262,7 +287,7 @@ static int __init renesas_soc_init(void)
void __iomem *chipid = NULL;
struct soc_device *soc_dev;
struct device_node *np;
- unsigned int product;
+ unsigned int product, eshi = 0, eslo;
match = of_match_node(renesas_socs, of_root);
if (!match)
@@ -271,6 +296,31 @@ static int __init renesas_soc_init(void)
soc = match->data;
family = soc->family;
+ np = of_find_compatible_node(NULL, NULL, "renesas,bsid");
+ if (np) {
+ chipid = of_iomap(np, 0);
+ of_node_put(np);
+
+ if (chipid) {
+ product = readl(chipid);
+ iounmap(chipid);
+
+ if (soc->id && ((product >> 16) & 0xff) != soc->id) {
+ pr_warn("SoC mismatch (product = 0x%x)\n",
+ product);
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * TODO: Upper 4 bits of BSID are for chip version, but the
+ * format is not known at this time so we don't know how to
+ * specify eshi and eslo
+ */
+
+ goto done;
+ }
+
/* Try PRR first, then hardcoded fallback */
np = of_find_compatible_node(NULL, NULL, "renesas,prr");
if (np) {
@@ -289,8 +339,11 @@ static int __init renesas_soc_init(void)
pr_warn("SoC mismatch (product = 0x%x)\n", product);
return -ENODEV;
}
+ eshi = ((product >> 4) & 0x0f) + 1;
+ eslo = product & 0xf;
}
+done:
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr)
return -ENOMEM;
@@ -302,10 +355,9 @@ static int __init renesas_soc_init(void)
soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1,
GFP_KERNEL);
- if (chipid)
- soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
- ((product >> 4) & 0x0f) + 1,
- product & 0xf);
+ if (eshi)
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi,
+ eslo);
pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family,
soc_dev_attr->soc_id, soc_dev_attr->revision ?: "");
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index acbe63e925d5..1fa840e3d930 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -33,6 +33,9 @@
#include <linux/of_address.h>
#include <linux/of_clk.h>
#include <linux/of_platform.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/reboot.h>
@@ -45,6 +48,8 @@
#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
+
#define PMC_CNTRL 0x0
#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
#define PMC_CNTRL_CPU_PWRREQ_OE BIT(16) /* CPU pwr req enable */
@@ -65,6 +70,8 @@
#define PWRGATE_STATUS 0x38
+#define PMC_IMPL_E_33V_PWR 0x40
+
#define PMC_PWR_DET 0x48
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
@@ -135,6 +142,7 @@ struct tegra_io_pad_soc {
enum tegra_io_pad id;
unsigned int dpd;
unsigned int voltage;
+ const char *name;
};
struct tegra_pmc_regs {
@@ -154,10 +162,14 @@ struct tegra_pmc_soc {
bool has_tsense_reset;
bool has_gpu_clamps;
bool needs_mbist_war;
+ bool has_impl_33v_pwr;
const struct tegra_io_pad_soc *io_pads;
unsigned int num_io_pads;
+ const struct pinctrl_pin_desc *pin_descs;
+ unsigned int num_pin_descs;
+
const struct tegra_pmc_regs *regs;
void (*init)(struct tegra_pmc *pmc);
void (*setup_irq_polarity)(struct tegra_pmc *pmc,
@@ -216,6 +228,8 @@ struct tegra_pmc {
DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX);
struct mutex powergates_lock;
+
+ struct pinctrl_dev *pctl_dev;
};
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
@@ -919,11 +933,12 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
return NULL;
}
-static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
- unsigned long *status, u32 *mask)
+static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id,
+ unsigned long *request,
+ unsigned long *status,
+ u32 *mask)
{
const struct tegra_io_pad_soc *pad;
- unsigned long rate, value;
pad = tegra_io_pad_find(pmc, id);
if (!pad) {
@@ -944,6 +959,19 @@ static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
*request = pmc->soc->regs->dpd2_req;
}
+ return 0;
+}
+
+static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
+ unsigned long *status, u32 *mask)
+{
+ unsigned long rate, value;
+ int err;
+
+ err = tegra_io_pad_get_dpd_register_bit(id, request, status, mask);
+ if (err)
+ return err;
+
if (pmc->clk) {
rate = clk_get_rate(pmc->clk);
if (!rate) {
@@ -1058,8 +1086,22 @@ unlock:
}
EXPORT_SYMBOL(tegra_io_pad_power_disable);
-int tegra_io_pad_set_voltage(enum tegra_io_pad id,
- enum tegra_io_pad_voltage voltage)
+static int tegra_io_pad_is_powered(enum tegra_io_pad id)
+{
+ unsigned long request, status;
+ u32 mask, value;
+ int err;
+
+ err = tegra_io_pad_get_dpd_register_bit(id, &request, &status, &mask);
+ if (err)
+ return err;
+
+ value = tegra_pmc_readl(status);
+
+ return !(value & mask);
+}
+
+static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage)
{
const struct tegra_io_pad_soc *pad;
u32 value;
@@ -1073,20 +1115,31 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id,
mutex_lock(&pmc->powergates_lock);
- /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
- value = tegra_pmc_readl(PMC_PWR_DET);
- value |= BIT(pad->voltage);
- tegra_pmc_writel(value, PMC_PWR_DET);
+ if (pmc->soc->has_impl_33v_pwr) {
+ value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR);
- /* update I/O voltage */
- value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+ if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+ value &= ~BIT(pad->voltage);
+ else
+ value |= BIT(pad->voltage);
- if (voltage == TEGRA_IO_PAD_1800000UV)
- value &= ~BIT(pad->voltage);
- else
+ tegra_pmc_writel(value, PMC_IMPL_E_33V_PWR);
+ } else {
+ /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
+ value = tegra_pmc_readl(PMC_PWR_DET);
value |= BIT(pad->voltage);
+ tegra_pmc_writel(value, PMC_PWR_DET);
- tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
+ /* update I/O voltage */
+ value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+
+ if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+ value &= ~BIT(pad->voltage);
+ else
+ value |= BIT(pad->voltage);
+
+ tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
+ }
mutex_unlock(&pmc->powergates_lock);
@@ -1094,9 +1147,8 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id,
return 0;
}
-EXPORT_SYMBOL(tegra_io_pad_set_voltage);
-int tegra_io_pad_get_voltage(enum tegra_io_pad id)
+static int tegra_io_pad_get_voltage(enum tegra_io_pad id)
{
const struct tegra_io_pad_soc *pad;
u32 value;
@@ -1108,14 +1160,16 @@ int tegra_io_pad_get_voltage(enum tegra_io_pad id)
if (pad->voltage == UINT_MAX)
return -ENOTSUPP;
- value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+ if (pmc->soc->has_impl_33v_pwr)
+ value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR);
+ else
+ value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
if ((value & BIT(pad->voltage)) == 0)
- return TEGRA_IO_PAD_1800000UV;
+ return TEGRA_IO_PAD_VOLTAGE_1V8;
- return TEGRA_IO_PAD_3300000UV;
+ return TEGRA_IO_PAD_VOLTAGE_3V3;
}
-EXPORT_SYMBOL(tegra_io_pad_get_voltage);
/**
* tegra_io_rail_power_on() - enable power to I/O rail
@@ -1288,7 +1342,7 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
if (!pmc->soc->has_tsense_reset)
return;
- np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
+ np = of_get_child_by_name(pmc->dev->of_node, "i2c-thermtrip");
if (!np) {
dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
return;
@@ -1353,6 +1407,142 @@ out:
of_node_put(np);
}
+static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev)
+{
+ return pmc->soc->num_io_pads;
+}
+
+static const char *tegra_io_pad_pinctrl_get_group_name(
+ struct pinctrl_dev *pctl, unsigned int group)
+{
+ return pmc->soc->io_pads[group].name;
+}
+
+static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev,
+ unsigned int group,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ *pins = &pmc->soc->io_pads[group].id;
+ *num_pins = 1;
+ return 0;
+}
+
+static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = {
+ .get_groups_count = tegra_io_pad_pinctrl_get_groups_count,
+ .get_group_name = tegra_io_pad_pinctrl_get_group_name,
+ .get_group_pins = tegra_io_pad_pinctrl_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev,
+ unsigned int pin, unsigned long *config)
+{
+ const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ int ret;
+ u32 arg;
+
+ if (!pad)
+ return -EINVAL;
+
+ switch (param) {
+ case PIN_CONFIG_POWER_SOURCE:
+ ret = tegra_io_pad_get_voltage(pad->id);
+ if (ret < 0)
+ return ret;
+ arg = ret;
+ break;
+ case PIN_CONFIG_LOW_POWER_MODE:
+ ret = tegra_io_pad_is_powered(pad->id);
+ if (ret < 0)
+ return ret;
+ arg = !ret;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin);
+ enum pin_config_param param;
+ unsigned int i;
+ int err;
+ u32 arg;
+
+ if (!pad)
+ return -EINVAL;
+
+ for (i = 0; i < num_configs; ++i) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_LOW_POWER_MODE:
+ if (arg)
+ err = tegra_io_pad_power_disable(pad->id);
+ else
+ err = tegra_io_pad_power_enable(pad->id);
+ if (err)
+ return err;
+ break;
+ case PIN_CONFIG_POWER_SOURCE:
+ if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 &&
+ arg != TEGRA_IO_PAD_VOLTAGE_3V3)
+ return -EINVAL;
+ err = tegra_io_pad_set_voltage(pad->id, arg);
+ if (err)
+ return err;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops tegra_io_pad_pinconf_ops = {
+ .pin_config_get = tegra_io_pad_pinconf_get,
+ .pin_config_set = tegra_io_pad_pinconf_set,
+ .is_generic = true,
+};
+
+static struct pinctrl_desc tegra_pmc_pctl_desc = {
+ .pctlops = &tegra_io_pad_pinctrl_ops,
+ .confops = &tegra_io_pad_pinconf_ops,
+};
+
+static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
+{
+ int err = 0;
+
+ if (!pmc->soc->num_pin_descs)
+ return 0;
+
+ tegra_pmc_pctl_desc.name = dev_name(pmc->dev);
+ tegra_pmc_pctl_desc.pins = pmc->soc->pin_descs;
+ tegra_pmc_pctl_desc.npins = pmc->soc->num_pin_descs;
+
+ pmc->pctl_dev = devm_pinctrl_register(pmc->dev, &tegra_pmc_pctl_desc,
+ pmc);
+ if (IS_ERR(pmc->pctl_dev)) {
+ err = PTR_ERR(pmc->pctl_dev);
+ dev_err(pmc->dev, "unable to register pinctrl, %d\n", err);
+ }
+
+ return err;
+}
+
static int tegra_pmc_probe(struct platform_device *pdev)
{
void __iomem *base;
@@ -1430,18 +1620,27 @@ static int tegra_pmc_probe(struct platform_device *pdev)
err = register_restart_handler(&tegra_pmc_restart_handler);
if (err) {
- debugfs_remove(pmc->debugfs);
dev_err(&pdev->dev, "unable to register restart handler, %d\n",
err);
- return err;
+ goto cleanup_debugfs;
}
+ err = tegra_pmc_pinctrl_init(pmc);
+ if (err)
+ goto cleanup_restart_handler;
+
mutex_lock(&pmc->powergates_lock);
iounmap(pmc->base);
pmc->base = base;
mutex_unlock(&pmc->powergates_lock);
return 0;
+
+cleanup_restart_handler:
+ unregister_restart_handler(&tegra_pmc_restart_handler);
+cleanup_debugfs:
+ debugfs_remove(pmc->debugfs);
+ return err;
}
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
@@ -1531,6 +1730,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.has_gpu_clamps = false,
.num_io_pads = 0,
.io_pads = NULL,
+ .num_pin_descs = 0,
+ .pin_descs = NULL,
.regs = &tegra20_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1567,8 +1768,11 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.cpu_powergates = tegra30_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = false,
+ .has_impl_33v_pwr = false,
.num_io_pads = 0,
.io_pads = NULL,
+ .num_pin_descs = 0,
+ .pin_descs = NULL,
.regs = &tegra20_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1609,8 +1813,11 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.cpu_powergates = tegra114_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = false,
+ .has_impl_33v_pwr = false,
.num_io_pads = 0,
.io_pads = NULL,
+ .num_pin_descs = 0,
+ .pin_descs = NULL,
.regs = &tegra20_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1649,37 +1856,59 @@ static const u8 tegra124_cpu_powergates[] = {
TEGRA_POWERGATE_CPU3,
};
+#define TEGRA_IO_PAD(_id, _dpd, _voltage, _name) \
+ ((struct tegra_io_pad_soc) { \
+ .id = (_id), \
+ .dpd = (_dpd), \
+ .voltage = (_voltage), \
+ .name = (_name), \
+ })
+
+#define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name) \
+ ((struct pinctrl_pin_desc) { \
+ .number = (_id), \
+ .name = (_name) \
+ })
+
+#define TEGRA124_IO_PAD_TABLE(_pad) \
+ /* .id .dpd .voltage .name */ \
+ _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
+ _pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \
+ _pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \
+ _pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \
+ _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
+ _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \
+ _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \
+ _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
+ _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
+ _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
+ _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
+ _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
+ _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
+ _pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \
+ _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
+ _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
+ _pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \
+ _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
+ _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
+ _pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \
+ _pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \
+ _pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \
+ _pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \
+ _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
+ _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
+ _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
+ _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
+ _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias")
+
static const struct tegra_io_pad_soc tegra124_io_pads[] = {
- { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_BB, .dpd = 15, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_COMP, .dpd = 22, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HV, .dpd = 38, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_NAND, .dpd = 13, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 35, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SYS_DDC, .dpd = 58, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+ TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
+ TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
};
static const struct tegra_pmc_soc tegra124_pmc_soc = {
@@ -1689,8 +1918,11 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.cpu_powergates = tegra124_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
+ .has_impl_33v_pwr = false,
.num_io_pads = ARRAY_SIZE(tegra124_io_pads),
.io_pads = tegra124_io_pads,
+ .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs),
+ .pin_descs = tegra124_pin_descs,
.regs = &tegra20_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1730,45 +1962,53 @@ static const u8 tegra210_cpu_powergates[] = {
TEGRA_POWERGATE_CPU3,
};
+#define TEGRA210_IO_PAD_TABLE(_pad) \
+ /* .id .dpd .voltage .name */ \
+ _pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \
+ _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \
+ _pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \
+ _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
+ _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
+ _pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \
+ _pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \
+ _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \
+ _pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \
+ _pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \
+ _pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \
+ _pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \
+ _pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \
+ _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
+ _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
+ _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
+ _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
+ _pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \
+ _pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \
+ _pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \
+ _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
+ _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
+ _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
+ _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
+ _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
+ _pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \
+ _pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \
+ _pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \
+ _pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \
+ _pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \
+ _pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \
+ _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
+ _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
+ _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
+ _pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \
+ _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias")
+
static const struct tegra_io_pad_soc tegra210_io_pads[] = {
- { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = 5 },
- { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 18 },
- { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = 10 },
- { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIC, .dpd = 42, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSID, .dpd = 43, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIF, .dpd = 45, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = 19 },
- { .id = TEGRA_IO_PAD_DEBUG_NONAO, .dpd = 26, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DMIC, .dpd = 50, .voltage = 20 },
- { .id = TEGRA_IO_PAD_DP, .dpd = 51, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_EMMC, .dpd = 35, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_EMMC2, .dpd = 37, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_GPIO, .dpd = 27, .voltage = 21 },
- { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = UINT_MAX, .voltage = 11 },
- { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = 12 },
- { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = 13 },
- { .id = TEGRA_IO_PAD_SPI, .dpd = 46, .voltage = 22 },
- { .id = TEGRA_IO_PAD_SPI_HV, .dpd = 47, .voltage = 23 },
- { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = 2 },
- { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB3, .dpd = 18, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+ TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
+ TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
};
static const struct tegra_pmc_soc tegra210_pmc_soc = {
@@ -1778,52 +2018,64 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.cpu_powergates = tegra210_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
+ .has_impl_33v_pwr = false,
.needs_mbist_war = true,
.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
.io_pads = tegra210_io_pads,
+ .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
+ .pin_descs = tegra210_pin_descs,
.regs = &tegra20_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
};
+#define TEGRA186_IO_PAD_TABLE(_pad) \
+ /* .id .dpd .voltage .name */ \
+ _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
+ _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
+ _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
+ _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
+ _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
+ _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
+ _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
+ _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
+ _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \
+ _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
+ _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
+ _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
+ _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
+ _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
+ _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
+ _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
+ _pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \
+ _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
+ _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
+ _pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \
+ _pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \
+ _pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \
+ _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
+ _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
+ _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
+ _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
+ _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
+ _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
+ _pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \
+ _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
+ _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
+ _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
+ _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
+ _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
+ _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
+
static const struct tegra_io_pad_soc tegra186_io_pads[] = {
- { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC2_HV, .dpd = 34, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CAM, .dpd = 38, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIB, .dpd = 40, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSIC, .dpd = 41, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DSID, .dpd = 42, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_DMIC_HV, .dpd = 52, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX },
- { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
+ TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra186_pin_descs[] = {
+ TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
};
static const struct tegra_pmc_regs tegra186_pmc_regs = {
@@ -1876,8 +2128,11 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.cpu_powergates = NULL,
.has_tsense_reset = false,
.has_gpu_clamps = false,
+ .has_impl_33v_pwr = true,
.num_io_pads = ARRAY_SIZE(tegra186_io_pads),
.io_pads = tegra186_io_pads,
+ .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
+ .pin_descs = tegra186_pin_descs,
.regs = &tegra186_pmc_regs,
.init = NULL,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
index bbd4e5bc8707..e05ab16d9a9e 100644
--- a/drivers/soc/ti/knav_dma.c
+++ b/drivers/soc/ti/knav_dma.c
@@ -438,7 +438,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
chan_num = of_channel_match_helper(dev->of_node, name, &instance);
if (chan_num < 0) {
- dev_err(kdev->dev, "No DMA instace with name %s\n", name);
+ dev_err(kdev->dev, "No DMA instance with name %s\n", name);
return (void *)-EINVAL;
}
@@ -461,7 +461,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
}
}
if (!found) {
- dev_err(kdev->dev, "No DMA instace with name %s\n", instance);
+ dev_err(kdev->dev, "No DMA instance with name %s\n", instance);
return (void *)-EINVAL;
}
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
index 3efc47e82973..7c128132799e 100644
--- a/drivers/soc/ti/knav_qmss.h
+++ b/drivers/soc/ti/knav_qmss.h
@@ -240,14 +240,14 @@ struct knav_pool {
};
/**
- * struct knav_queue_inst: qmss queue instace properties
+ * struct knav_queue_inst: qmss queue instance properties
* @descs: descriptor pointer
* @desc_head, desc_tail, desc_count: descriptor counters
* @acc: accumulator channel pointer
* @kdev: qmss device pointer
* @range: range info
* @qmgr: queue manager info
- * @id: queue instace id
+ * @id: queue instance id
* @irq_num: irq line number
* @notify_needed: notifier needed based on queue type
* @num_notifiers: total notifiers
@@ -274,7 +274,7 @@ struct knav_queue_inst {
/**
* struct knav_queue: qmss queue properties
* @reg_push, reg_pop, reg_peek: push, pop queue registers
- * @inst: qmss queue instace properties
+ * @inst: qmss queue instance properties
* @notifier_fn: notifier function
* @notifier_fn_arg: notifier function argument
* @notifier_enabled: notier enabled for a give queue