mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
ARM: SoC driver updates for v4.14
This branch contains platform-related driver updates for ARM and ARM64.
Among them:
- Reset driver updates:
+ New API for dealing with arrays of resets
+ Make unimplemented {de,}assert return success on shared resets
+ MSDKv1 driver
+ Removal of obsolete Gemini reset driver
+ Misc updates for sunxi and Uniphier
- SoC drivers:
+ Platform SoC driver registration on Tegra
+ Shuffle of Qualcomm drivers into a submenu
+ Allwinner A64 support for SRAM
+ Renesas R-Car R3 support
+ Power domains for Rockchip RK3366
- Misc updates and smaller fixes for TEE and memory driver subsystems
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJZtdt7AAoJEIwa5zzehBx3EboP/jR2T9lrMavXR1zL48L14yJb
S+fiJlrX1Kr42UF4PQvsfs+uTqOLmycrPVFkMb6IwoUPzQ9UCOSoiMzYm2b7ZPvt
uIesHhdM3/xun6wKfieN8GmNA1yDVynTxo0TTYDw5ha7I6s2GHgw0GSFzy3wm0Qg
KzerAO3gzf3L5XsKR0cai3IXNjHO9ubpFG1ReR09da28nPElP8ggWg0KnqdO76Ch
BGpFj78EC875ZNqwHgnspUqgGDJnBjig3m/uA4FWA0G9Jl38tCyKTZfUR7cEraoV
kyCgBlR/UrI8eXVTyEy5k5iTsQ3A1VhX4rGjyH+5NZHTs1yWr4+RDND/qeGl9tSo
VASuOtH6Rc3vdUDpHPBNAFNQH8fwwDoKf96dvN1tiffsx6LSKb//NyOfkXzKOtR6
CP5raYfX4YktLtHq0XVTZ/6r3XmLcTHzElR/dCFpQOFcTOYii0pWtfcWouahbZ1w
dhoBX/dbNq37MfzrxtHN2VTIEHpn2GU7u+ZGkp2ArokD58BAft/M3Xee1cDnF75g
ZDwe5eNFT8aBZKaY7zwG8cdxiw9kACAivDRwW+zgpfUr39c+d0+QmVfnfJh4EGXK
Ri6yr2EfBWK6jw3cwkdSyyt7iSzIkB+RiuuD1MjpYhWzAvoDpzqkXYukFGbpXnuy
vUFHNuP1ocUsRtCs8mm1
=yBzS
-----END PGP SIGNATURE-----
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
"This branch contains platform-related driver updates for ARM and ARM64.
Among them:
- Reset driver updates:
+ New API for dealing with arrays of resets
+ Make unimplemented {de,}assert return success on shared resets
+ MSDKv1 driver
+ Removal of obsolete Gemini reset driver
+ Misc updates for sunxi and Uniphier
- SoC drivers:
+ Platform SoC driver registration on Tegra
+ Shuffle of Qualcomm drivers into a submenu
+ Allwinner A64 support for SRAM
+ Renesas R-Car R3 support
+ Power domains for Rockchip RK3366
- Misc updates and smaller fixes for TEE and memory driver
subsystems"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
firmware: arm_scpi: fix endianness of dev_id in struct dev_pstate_set
soc/tegra: fuse: Add missing semi-colon
soc/tegra: Restrict SoC device registration to Tegra
drivers: soc: sunxi: add support for A64 and its SRAM C
drivers: soc: sunxi: add support for remapping func value to reg value
drivers: soc: sunxi: fix error processing on base address when claiming
dt-bindings: add binding for Allwinner A64 SRAM controller and SRAM C
bus: sunxi-rsb: Enable by default for ARM64
soc/tegra: Register SoC device
firmware: tegra: set drvdata earlier
memory: Convert to using %pOF instead of full_name
soc: Convert to using %pOF instead of full_name
bus: Convert to using %pOF instead of full_name
firmware: Convert to using %pOF instead of full_name
soc: mediatek: add SCPSYS power domain driver for MediaTek MT7622 SoC
soc: mediatek: add header files required for MT7622 SCPSYS dt-binding
soc: mediatek: reduce code duplication of scpsys_probe across all SoCs
dt-bindings: soc: update the binding document for SCPSYS on MediaTek MT7622 SoC
reset: uniphier: add analog amplifiers reset control
reset: uniphier: add video input subsystem reset control
...
This commit is contained in:
commit
ae46654bcf
74 changed files with 1347 additions and 462 deletions
|
|
@ -1,6 +1,7 @@
|
|||
menu "SOC (System On Chip) specific Drivers"
|
||||
|
||||
source "drivers/soc/actions/Kconfig"
|
||||
source "drivers/soc/amlogic/Kconfig"
|
||||
source "drivers/soc/atmel/Kconfig"
|
||||
source "drivers/soc/bcm/Kconfig"
|
||||
source "drivers/soc/fsl/Kconfig"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_DOVE) += dove/
|
|||
obj-y += fsl/
|
||||
obj-$(CONFIG_ARCH_MXC) += imx/
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_MESON) += amlogic/
|
||||
obj-$(CONFIG_ARCH_QCOM) += qcom/
|
||||
obj-y += renesas/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
|
|
|
|||
12
drivers/soc/amlogic/Kconfig
Normal file
12
drivers/soc/amlogic/Kconfig
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
menu "Amlogic SoC drivers"
|
||||
|
||||
config MESON_GX_SOCINFO
|
||||
bool "Amlogic Meson GX SoC Information driver"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
default ARCH_MESON
|
||||
select SOC_BUS
|
||||
help
|
||||
Say yes to support decoding of Amlogic Meson GX SoC family
|
||||
information about the type, package and version.
|
||||
|
||||
endmenu
|
||||
1
drivers/soc/amlogic/Makefile
Normal file
1
drivers/soc/amlogic/Makefile
Normal file
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
|
||||
177
drivers/soc/amlogic/meson-gx-socinfo.c
Normal file
177
drivers/soc/amlogic/meson-gx-socinfo.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2017 BayLibre, SAS
|
||||
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
#define AO_SEC_SD_CFG8 0xe0
|
||||
#define AO_SEC_SOCINFO_OFFSET AO_SEC_SD_CFG8
|
||||
|
||||
#define SOCINFO_MAJOR GENMASK(31, 24)
|
||||
#define SOCINFO_MINOR GENMASK(23, 16)
|
||||
#define SOCINFO_PACK GENMASK(15, 8)
|
||||
#define SOCINFO_MISC GENMASK(7, 0)
|
||||
|
||||
static const struct meson_gx_soc_id {
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
} soc_ids[] = {
|
||||
{ "GXBB", 0x1f },
|
||||
{ "GXTVBB", 0x20 },
|
||||
{ "GXL", 0x21 },
|
||||
{ "GXM", 0x22 },
|
||||
{ "TXL", 0x23 },
|
||||
};
|
||||
|
||||
static const struct meson_gx_package_id {
|
||||
const char *name;
|
||||
unsigned int major_id;
|
||||
unsigned int pack_id;
|
||||
} soc_packages[] = {
|
||||
{ "S905", 0x1f, 0 },
|
||||
{ "S905M", 0x1f, 0x20 },
|
||||
{ "S905D", 0x21, 0 },
|
||||
{ "S905X", 0x21, 0x80 },
|
||||
{ "S905L", 0x21, 0xc0 },
|
||||
{ "S905M2", 0x21, 0xe0 },
|
||||
{ "S912", 0x22, 0 },
|
||||
};
|
||||
|
||||
static inline unsigned int socinfo_to_major(u32 socinfo)
|
||||
{
|
||||
return FIELD_GET(SOCINFO_MAJOR, socinfo);
|
||||
}
|
||||
|
||||
static inline unsigned int socinfo_to_minor(u32 socinfo)
|
||||
{
|
||||
return FIELD_GET(SOCINFO_MINOR, socinfo);
|
||||
}
|
||||
|
||||
static inline unsigned int socinfo_to_pack(u32 socinfo)
|
||||
{
|
||||
return FIELD_GET(SOCINFO_PACK, socinfo);
|
||||
}
|
||||
|
||||
static inline unsigned int socinfo_to_misc(u32 socinfo)
|
||||
{
|
||||
return FIELD_GET(SOCINFO_MISC, socinfo);
|
||||
}
|
||||
|
||||
static const char *socinfo_to_package_id(u32 socinfo)
|
||||
{
|
||||
unsigned int pack = socinfo_to_pack(socinfo) & 0xf0;
|
||||
unsigned int major = socinfo_to_major(socinfo);
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
|
||||
if (soc_packages[i].major_id == major &&
|
||||
soc_packages[i].pack_id == pack)
|
||||
return soc_packages[i].name;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static const char *socinfo_to_soc_id(u32 socinfo)
|
||||
{
|
||||
unsigned int id = socinfo_to_major(socinfo);
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
|
||||
if (soc_ids[i].id == id)
|
||||
return soc_ids[i].name;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
int __init meson_gx_socinfo_init(void)
|
||||
{
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
struct soc_device *soc_dev;
|
||||
struct device_node *np;
|
||||
struct regmap *regmap;
|
||||
unsigned int socinfo;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
/* look up for chipid node */
|
||||
np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gx-ao-secure");
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
/* check if interface is enabled */
|
||||
if (!of_device_is_available(np))
|
||||
return -ENODEV;
|
||||
|
||||
/* check if chip-id is available */
|
||||
if (!of_property_read_bool(np, "amlogic,has-chip-id"))
|
||||
return -ENODEV;
|
||||
|
||||
/* node should be a syscon */
|
||||
regmap = syscon_node_to_regmap(np);
|
||||
of_node_put(np);
|
||||
if (IS_ERR(regmap)) {
|
||||
pr_err("%s: failed to get regmap\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!socinfo) {
|
||||
pr_err("%s: invalid chipid value\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return -ENODEV;
|
||||
|
||||
soc_dev_attr->family = "Amlogic Meson";
|
||||
|
||||
np = of_find_node_by_path("/");
|
||||
of_property_read_string(np, "model", &soc_dev_attr->machine);
|
||||
of_node_put(np);
|
||||
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x",
|
||||
socinfo_to_major(socinfo),
|
||||
socinfo_to_minor(socinfo),
|
||||
socinfo_to_pack(socinfo),
|
||||
socinfo_to_misc(socinfo));
|
||||
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)",
|
||||
socinfo_to_soc_id(socinfo),
|
||||
socinfo_to_package_id(socinfo));
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR(soc_dev)) {
|
||||
kfree(soc_dev_attr->revision);
|
||||
kfree_const(soc_dev_attr->soc_id);
|
||||
kfree(soc_dev_attr);
|
||||
return PTR_ERR(soc_dev);
|
||||
}
|
||||
dev = soc_device_to_device(soc_dev);
|
||||
|
||||
dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n",
|
||||
soc_dev_attr->soc_id,
|
||||
socinfo_to_major(socinfo),
|
||||
socinfo_to_minor(socinfo),
|
||||
socinfo_to_pack(socinfo),
|
||||
socinfo_to_misc(socinfo));
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(meson_gx_socinfo_init);
|
||||
|
|
@ -177,8 +177,8 @@ static int fsl_bman_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
|
||||
node);
|
||||
return -ENXIO;
|
||||
}
|
||||
bm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
|
||||
|
|
@ -205,14 +205,14 @@ static int fsl_bman_probe(struct platform_device *pdev)
|
|||
|
||||
err_irq = platform_get_irq(pdev, 0);
|
||||
if (err_irq <= 0) {
|
||||
dev_info(dev, "Can't get %s IRQ\n", node->full_name);
|
||||
dev_info(dev, "Can't get %pOF IRQ\n", node);
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = devm_request_irq(dev, err_irq, bman_isr, IRQF_SHARED, "bman-err",
|
||||
dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
|
||||
ret, node->full_name);
|
||||
dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
|
||||
ret, node);
|
||||
return ret;
|
||||
}
|
||||
/* Disable Buffer Pool State Change */
|
||||
|
|
|
|||
|
|
@ -103,16 +103,14 @@ static int bman_portal_probe(struct platform_device *pdev)
|
|||
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
DPAA_PORTAL_CE);
|
||||
if (!addr_phys[0]) {
|
||||
dev_err(dev, "Can't get %s property 'reg::CE'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
DPAA_PORTAL_CI);
|
||||
if (!addr_phys[1]) {
|
||||
dev_err(dev, "Can't get %s property 'reg::CI'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +118,7 @@ static int bman_portal_probe(struct platform_device *pdev)
|
|||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0) {
|
||||
dev_err(dev, "Can't get %s IRQ'\n", node->full_name);
|
||||
dev_err(dev, "Can't get %pOF IRQ'\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
pcfg->irq = irq;
|
||||
|
|
|
|||
|
|
@ -695,8 +695,8 @@ static int fsl_qman_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
|
||||
node);
|
||||
return -ENXIO;
|
||||
}
|
||||
qm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
|
||||
|
|
@ -740,15 +740,15 @@ static int fsl_qman_probe(struct platform_device *pdev)
|
|||
|
||||
err_irq = platform_get_irq(pdev, 0);
|
||||
if (err_irq <= 0) {
|
||||
dev_info(dev, "Can't get %s property 'interrupts'\n",
|
||||
node->full_name);
|
||||
dev_info(dev, "Can't get %pOF property 'interrupts'\n",
|
||||
node);
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = devm_request_irq(dev, err_irq, qman_isr, IRQF_SHARED, "qman-err",
|
||||
dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
|
||||
ret, node->full_name);
|
||||
dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
|
||||
ret, node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,30 +237,27 @@ static int qman_portal_probe(struct platform_device *pdev)
|
|||
addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
DPAA_PORTAL_CE);
|
||||
if (!addr_phys[0]) {
|
||||
dev_err(dev, "Can't get %s property 'reg::CE'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
DPAA_PORTAL_CI);
|
||||
if (!addr_phys[1]) {
|
||||
dev_err(dev, "Can't get %s property 'reg::CI'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
err = of_property_read_u32(node, "cell-index", &val);
|
||||
if (err) {
|
||||
dev_err(dev, "Can't get %s property 'cell-index'\n",
|
||||
node->full_name);
|
||||
dev_err(dev, "Can't get %pOF property 'cell-index'\n", node);
|
||||
return err;
|
||||
}
|
||||
pcfg->channel = val;
|
||||
pcfg->cpu = -1;
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0) {
|
||||
dev_err(dev, "Can't get %s IRQ\n", node->full_name);
|
||||
dev_err(dev, "Can't get %pOF IRQ\n", node);
|
||||
return -ENXIO;
|
||||
}
|
||||
pcfg->irq = irq;
|
||||
|
|
|
|||
|
|
@ -304,8 +304,8 @@ static int __init qe_add_gpiochips(void)
|
|||
goto err;
|
||||
continue;
|
||||
err:
|
||||
pr_err("%s: registration failed with status %d\n",
|
||||
np->full_name, ret);
|
||||
pr_err("%pOF: registration failed with status %d\n",
|
||||
np, ret);
|
||||
kfree(qe_gc);
|
||||
/* try others anyway */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1067,7 +1067,7 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
|
|||
.init_soc_specific = pwrap_mt2701_init_soc_specific,
|
||||
};
|
||||
|
||||
static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
static const struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.regs = mt8135_regs,
|
||||
.type = PWRAP_MT8135,
|
||||
.arb_en_all = 0x1ff,
|
||||
|
|
@ -1079,7 +1079,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
|||
.init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
|
||||
static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
static const struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.regs = mt8173_regs,
|
||||
.type = PWRAP_MT8173,
|
||||
.arb_en_all = 0x3f,
|
||||
|
|
@ -1091,7 +1091,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
|||
.init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
|
||||
static struct of_device_id of_pwrap_match_tbl[] = {
|
||||
static const struct of_device_id of_pwrap_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt2701-pwrap",
|
||||
.data = &pwrap_mt2701,
|
||||
|
|
@ -1233,8 +1233,8 @@ static int pwrap_probe(struct platform_device *pdev)
|
|||
|
||||
ret = of_platform_populate(np, NULL, NULL, wrp->dev);
|
||||
if (ret) {
|
||||
dev_dbg(wrp->dev, "failed to create child devices at %s\n",
|
||||
np->full_name);
|
||||
dev_dbg(wrp->dev, "failed to create child devices at %pOF\n",
|
||||
np);
|
||||
goto err_out2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <dt-bindings/power/mt2701-power.h>
|
||||
#include <dt-bindings/power/mt6797-power.h>
|
||||
#include <dt-bindings/power/mt7622-power.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
#define SPM_VDE_PWR_CON 0x0210
|
||||
|
|
@ -39,6 +40,11 @@
|
|||
#define SPM_MFG_2D_PWR_CON 0x02c0
|
||||
#define SPM_MFG_ASYNC_PWR_CON 0x02c4
|
||||
#define SPM_USB_PWR_CON 0x02cc
|
||||
#define SPM_ETHSYS_PWR_CON 0x02e0 /* MT7622 */
|
||||
#define SPM_HIF0_PWR_CON 0x02e4 /* MT7622 */
|
||||
#define SPM_HIF1_PWR_CON 0x02e8 /* MT7622 */
|
||||
#define SPM_WB_PWR_CON 0x02ec /* MT7622 */
|
||||
|
||||
|
||||
#define SPM_PWR_STATUS 0x060c
|
||||
#define SPM_PWR_STATUS_2ND 0x0610
|
||||
|
|
@ -64,6 +70,10 @@
|
|||
#define PWR_STATUS_MFG_ASYNC BIT(23)
|
||||
#define PWR_STATUS_AUDIO BIT(24)
|
||||
#define PWR_STATUS_USB BIT(25)
|
||||
#define PWR_STATUS_ETHSYS BIT(24) /* MT7622 */
|
||||
#define PWR_STATUS_HIF0 BIT(25) /* MT7622 */
|
||||
#define PWR_STATUS_HIF1 BIT(26) /* MT7622 */
|
||||
#define PWR_STATUS_WB BIT(27) /* MT7622 */
|
||||
|
||||
enum clk_id {
|
||||
CLK_NONE,
|
||||
|
|
@ -73,6 +83,7 @@ enum clk_id {
|
|||
CLK_VENC_LT,
|
||||
CLK_ETHIF,
|
||||
CLK_VDEC,
|
||||
CLK_HIFSEL,
|
||||
CLK_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -84,6 +95,7 @@ static const char * const clk_names[] = {
|
|||
"venc_lt",
|
||||
"ethif",
|
||||
"vdec",
|
||||
"hif_sel",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -124,6 +136,19 @@ struct scp {
|
|||
struct scp_ctrl_reg ctrl_reg;
|
||||
};
|
||||
|
||||
struct scp_subdomain {
|
||||
int origin;
|
||||
int subdomain;
|
||||
};
|
||||
|
||||
struct scp_soc_data {
|
||||
const struct scp_domain_data *domains;
|
||||
int num_domains;
|
||||
const struct scp_subdomain *subdomains;
|
||||
int num_subdomains;
|
||||
const struct scp_ctrl_reg regs;
|
||||
};
|
||||
|
||||
static int scpsys_domain_is_on(struct scp_domain *scpd)
|
||||
{
|
||||
struct scp *scp = scpd->scp;
|
||||
|
|
@ -357,7 +382,7 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
|
|||
|
||||
static struct scp *init_scp(struct platform_device *pdev,
|
||||
const struct scp_domain_data *scp_domain_data, int num,
|
||||
struct scp_ctrl_reg *scp_ctrl_reg)
|
||||
const struct scp_ctrl_reg *scp_ctrl_reg)
|
||||
{
|
||||
struct genpd_onecell_data *pd_data;
|
||||
struct resource *res;
|
||||
|
|
@ -565,26 +590,6 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define NUM_DOMAINS_MT2701 ARRAY_SIZE(scp_domain_data_mt2701)
|
||||
|
||||
static int __init scpsys_probe_mt2701(struct platform_device *pdev)
|
||||
{
|
||||
struct scp *scp;
|
||||
struct scp_ctrl_reg scp_reg;
|
||||
|
||||
scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
|
||||
scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
|
||||
|
||||
scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
|
||||
&scp_reg);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
|
||||
mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MT6797 power domain support
|
||||
*/
|
||||
|
|
@ -649,51 +654,62 @@ static const struct scp_domain_data scp_domain_data_mt6797[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define NUM_DOMAINS_MT6797 ARRAY_SIZE(scp_domain_data_mt6797)
|
||||
#define SPM_PWR_STATUS_MT6797 0x0180
|
||||
#define SPM_PWR_STATUS_2ND_MT6797 0x0184
|
||||
|
||||
static int __init scpsys_probe_mt6797(struct platform_device *pdev)
|
||||
{
|
||||
struct scp *scp;
|
||||
struct genpd_onecell_data *pd_data;
|
||||
int ret;
|
||||
struct scp_ctrl_reg scp_reg;
|
||||
static const struct scp_subdomain scp_subdomain_mt6797[] = {
|
||||
{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
|
||||
{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
|
||||
{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
|
||||
{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
|
||||
};
|
||||
|
||||
scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
|
||||
scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;
|
||||
/*
|
||||
* MT7622 power domain support
|
||||
*/
|
||||
|
||||
scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797,
|
||||
&scp_reg);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
|
||||
mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797);
|
||||
|
||||
pd_data = &scp->pd_data;
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
|
||||
pd_data->domains[MT6797_POWER_DOMAIN_VDEC]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
|
||||
pd_data->domains[MT6797_POWER_DOMAIN_ISP]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
|
||||
pd_data->domains[MT6797_POWER_DOMAIN_VENC]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
|
||||
pd_data->domains[MT6797_POWER_DOMAIN_MJC]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const struct scp_domain_data scp_domain_data_mt7622[] = {
|
||||
[MT7622_POWER_DOMAIN_ETHSYS] = {
|
||||
.name = "ethsys",
|
||||
.sta_mask = PWR_STATUS_ETHSYS,
|
||||
.ctl_offs = SPM_ETHSYS_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = {CLK_NONE},
|
||||
.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
|
||||
.active_wakeup = true,
|
||||
},
|
||||
[MT7622_POWER_DOMAIN_HIF0] = {
|
||||
.name = "hif0",
|
||||
.sta_mask = PWR_STATUS_HIF0,
|
||||
.ctl_offs = SPM_HIF0_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = {CLK_HIFSEL},
|
||||
.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
|
||||
.active_wakeup = true,
|
||||
},
|
||||
[MT7622_POWER_DOMAIN_HIF1] = {
|
||||
.name = "hif1",
|
||||
.sta_mask = PWR_STATUS_HIF1,
|
||||
.ctl_offs = SPM_HIF1_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = {CLK_HIFSEL},
|
||||
.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
|
||||
.active_wakeup = true,
|
||||
},
|
||||
[MT7622_POWER_DOMAIN_WB] = {
|
||||
.name = "wb",
|
||||
.sta_mask = PWR_STATUS_WB,
|
||||
.ctl_offs = SPM_WB_PWR_CON,
|
||||
.sram_pdn_bits = 0,
|
||||
.sram_pdn_ack_bits = 0,
|
||||
.clk_id = {CLK_NONE},
|
||||
.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
|
||||
.active_wakeup = true,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* MT8173 power domain support
|
||||
|
|
@ -789,39 +805,50 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173)
|
||||
static const struct scp_subdomain scp_subdomain_mt8173[] = {
|
||||
{MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
|
||||
{MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
|
||||
};
|
||||
|
||||
static int __init scpsys_probe_mt8173(struct platform_device *pdev)
|
||||
{
|
||||
struct scp *scp;
|
||||
struct genpd_onecell_data *pd_data;
|
||||
int ret;
|
||||
struct scp_ctrl_reg scp_reg;
|
||||
static const struct scp_soc_data mt2701_data = {
|
||||
.domains = scp_domain_data_mt2701,
|
||||
.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
|
||||
.regs = {
|
||||
.pwr_sta_offs = SPM_PWR_STATUS,
|
||||
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
|
||||
}
|
||||
};
|
||||
|
||||
scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
|
||||
scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
|
||||
static const struct scp_soc_data mt6797_data = {
|
||||
.domains = scp_domain_data_mt6797,
|
||||
.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
|
||||
.subdomains = scp_subdomain_mt6797,
|
||||
.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
|
||||
.regs = {
|
||||
.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
|
||||
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
|
||||
}
|
||||
};
|
||||
|
||||
scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
|
||||
&scp_reg);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
static const struct scp_soc_data mt7622_data = {
|
||||
.domains = scp_domain_data_mt7622,
|
||||
.num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
|
||||
.regs = {
|
||||
.pwr_sta_offs = SPM_PWR_STATUS,
|
||||
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
|
||||
}
|
||||
};
|
||||
|
||||
mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
|
||||
|
||||
pd_data = &scp->pd_data;
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
|
||||
pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
|
||||
pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const struct scp_soc_data mt8173_data = {
|
||||
.domains = scp_domain_data_mt8173,
|
||||
.num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
|
||||
.subdomains = scp_subdomain_mt8173,
|
||||
.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
|
||||
.regs = {
|
||||
.pwr_sta_offs = SPM_PWR_STATUS,
|
||||
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* scpsys driver init
|
||||
|
|
@ -830,13 +857,16 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
|
|||
static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt2701-scpsys",
|
||||
.data = scpsys_probe_mt2701,
|
||||
.data = &mt2701_data,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6797-scpsys",
|
||||
.data = scpsys_probe_mt6797,
|
||||
.data = &mt6797_data,
|
||||
}, {
|
||||
.compatible = "mediatek,mt7622-scpsys",
|
||||
.data = &mt7622_data,
|
||||
}, {
|
||||
.compatible = "mediatek,mt8173-scpsys",
|
||||
.data = scpsys_probe_mt8173,
|
||||
.data = &mt8173_data,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
|
|
@ -844,16 +874,33 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
|
|||
|
||||
static int scpsys_probe(struct platform_device *pdev)
|
||||
{
|
||||
int (*probe)(struct platform_device *);
|
||||
const struct of_device_id *of_id;
|
||||
const struct of_device_id *match;
|
||||
const struct scp_subdomain *sd;
|
||||
const struct scp_soc_data *soc;
|
||||
struct scp *scp;
|
||||
struct genpd_onecell_data *pd_data;
|
||||
int i, ret;
|
||||
|
||||
of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
|
||||
if (!of_id || !of_id->data)
|
||||
return -EINVAL;
|
||||
match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
|
||||
soc = (const struct scp_soc_data *)match->data;
|
||||
|
||||
probe = of_id->data;
|
||||
scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
|
||||
return probe(pdev);
|
||||
mtk_register_power_domains(pdev, scp, soc->num_domains);
|
||||
|
||||
pd_data = &scp->pd_data;
|
||||
|
||||
for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
|
||||
ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
|
||||
pd_data->domains[sd->subdomain]);
|
||||
if (ret && IS_ENABLED(CONFIG_PM))
|
||||
dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver scpsys_drv = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#
|
||||
# QCOM Soc drivers
|
||||
#
|
||||
menu "Qualcomm SoC drivers"
|
||||
|
||||
config QCOM_GLINK_SSR
|
||||
tristate "Qualcomm Glink SSR driver"
|
||||
depends on RPMSG
|
||||
|
|
@ -83,3 +85,5 @@ config QCOM_WCNSS_CTRL
|
|||
help
|
||||
Client driver for the WCNSS_CTRL SMD channel, used to download nv
|
||||
firmware to a newly booted WCNSS chip.
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -178,14 +178,13 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||
|
||||
if (phdr->p_filesz) {
|
||||
sprintf(fw_name + fw_name_len - 3, "b%02d", i);
|
||||
ret = request_firmware(&seg_fw, fw_name, dev);
|
||||
ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
|
||||
ptr, phdr->p_filesz);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to load %s\n", fw_name);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(ptr, seg_fw->data, seg_fw->size);
|
||||
|
||||
release_firmware(seg_fw);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -496,7 +496,8 @@ static int qcom_smsm_probe(struct platform_device *pdev)
|
|||
if (!smsm->hosts)
|
||||
return -ENOMEM;
|
||||
|
||||
local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,smem-state-cells");
|
||||
local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node),
|
||||
"#qcom,smem-state-cells");
|
||||
if (!local_node) {
|
||||
dev_err(&pdev->dev, "no state entry\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ static const struct of_device_id wcnss_ctrl_of_match[] = {
|
|||
{ .compatible = "qcom,wcnss", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wcnss_ctrl_of_match);
|
||||
|
||||
static struct rpmsg_driver wcnss_ctrl_driver = {
|
||||
.probe = wcnss_ctrl_probe,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ config SOC_RENESAS
|
|||
default y if ARCH_RENESAS
|
||||
select SOC_BUS
|
||||
select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
|
||||
ARCH_R8A7795 || ARCH_R8A7796
|
||||
ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77995
|
||||
select SYSC_R8A7743 if ARCH_R8A7743
|
||||
select SYSC_R8A7745 if ARCH_R8A7745
|
||||
select SYSC_R8A7779 if ARCH_R8A7779
|
||||
|
|
@ -13,6 +13,7 @@ config SOC_RENESAS
|
|||
select SYSC_R8A7794 if ARCH_R8A7794
|
||||
select SYSC_R8A7795 if ARCH_R8A7795
|
||||
select SYSC_R8A7796 if ARCH_R8A7796
|
||||
select SYSC_R8A77995 if ARCH_R8A77995
|
||||
|
||||
if SOC_RENESAS
|
||||
|
||||
|
|
@ -53,6 +54,10 @@ config SYSC_R8A7796
|
|||
bool "R-Car M3-W System Controller support" if COMPILE_TEST
|
||||
select SYSC_RCAR
|
||||
|
||||
config SYSC_R8A77995
|
||||
bool "R-Car D3 System Controller support" if COMPILE_TEST
|
||||
select SYSC_RCAR
|
||||
|
||||
# Family
|
||||
config RST_RCAR
|
||||
bool "R-Car Reset Controller support" if COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o
|
|||
obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o
|
||||
obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o
|
||||
obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o
|
||||
obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o
|
||||
|
||||
# Family
|
||||
obj-$(CONFIG_RST_RCAR) += rcar-rst.o
|
||||
|
|
|
|||
31
drivers/soc/renesas/r8a77995-sysc.c
Normal file
31
drivers/soc/renesas/r8a77995-sysc.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include <dt-bindings/power/r8a77995-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static struct rcar_sysc_area r8a77995_areas[] __initdata = {
|
||||
{ "always-on", 0, 0, R8A77995_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "ca53-scu", 0x140, 0, R8A77995_PD_CA53_SCU, R8A77995_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca53-cpu0", 0x200, 0, R8A77995_PD_CA53_CPU0, R8A77995_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
};
|
||||
|
||||
|
||||
const struct rcar_sysc_info r8a77995_sysc_info __initconst = {
|
||||
.areas = r8a77995_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a77995_areas),
|
||||
};
|
||||
|
|
@ -41,6 +41,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
|
|||
/* R-Car Gen3 is handled like R-Car Gen2 */
|
||||
{ .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
|
||||
{ .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
|
||||
{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ static int __init rcar_rst_init(void)
|
|||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
pr_warn("%s: Cannot map regs\n", np->full_name);
|
||||
pr_warn("%pOF: Cannot map regs\n", np);
|
||||
error = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
|
@ -70,7 +71,7 @@ static int __init rcar_rst_init(void)
|
|||
cfg = match->data;
|
||||
saved_mode = ioread32(base + cfg->modemr);
|
||||
|
||||
pr_debug("%s: MODE = 0x%08x\n", np->full_name, saved_mode);
|
||||
pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode);
|
||||
|
||||
out_put:
|
||||
of_node_put(np);
|
||||
|
|
|
|||
|
|
@ -283,6 +283,9 @@ static const struct of_device_id rcar_sysc_matches[] = {
|
|||
#endif
|
||||
#ifdef CONFIG_SYSC_R8A7796
|
||||
{ .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_SYSC_R8A77995
|
||||
{ .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
|
||||
#endif
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
|
@ -323,7 +326,7 @@ static int __init rcar_sysc_pd_init(void)
|
|||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
pr_warn("%s: Cannot map regs\n", np->full_name);
|
||||
pr_warn("%pOF: Cannot map regs\n", np);
|
||||
error = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
|
@ -348,13 +351,13 @@ static int __init rcar_sysc_pd_init(void)
|
|||
*/
|
||||
syscimr = ioread32(base + SYSCIMR);
|
||||
syscimr |= syscier;
|
||||
pr_debug("%s: syscimr = 0x%08x\n", np->full_name, syscimr);
|
||||
pr_debug("%pOF: syscimr = 0x%08x\n", np, syscimr);
|
||||
iowrite32(syscimr, base + SYSCIMR);
|
||||
|
||||
/*
|
||||
* SYSC needs all interrupt sources enabled to control power.
|
||||
*/
|
||||
pr_debug("%s: syscier = 0x%08x\n", np->full_name, syscier);
|
||||
pr_debug("%pOF: syscier = 0x%08x\n", np, syscier);
|
||||
iowrite32(syscier, base + SYSCIER);
|
||||
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ extern const struct rcar_sysc_info r8a7792_sysc_info;
|
|||
extern const struct rcar_sysc_info r8a7794_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7795_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7796_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a77995_sysc_info;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -144,6 +144,11 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
|
|||
.id = 0x52,
|
||||
};
|
||||
|
||||
static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
|
||||
.family = &fam_rcar_gen3,
|
||||
.id = 0x58,
|
||||
};
|
||||
|
||||
static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
|
||||
.family = &fam_shmobile,
|
||||
.id = 0x37,
|
||||
|
|
@ -199,6 +204,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
|
|||
#ifdef CONFIG_ARCH_R8A7796
|
||||
{ .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A77995
|
||||
{ .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_SH73A0
|
||||
{ .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -54,6 +54,17 @@ static const struct rockchip_grf_info rk3288_grf __initconst = {
|
|||
.num_values = ARRAY_SIZE(rk3288_defaults),
|
||||
};
|
||||
|
||||
#define RK3328_GRF_SOC_CON4 0x410
|
||||
|
||||
static const struct rockchip_grf_value rk3328_defaults[] __initconst = {
|
||||
{ "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) },
|
||||
};
|
||||
|
||||
static const struct rockchip_grf_info rk3328_grf __initconst = {
|
||||
.values = rk3328_defaults,
|
||||
.num_values = ARRAY_SIZE(rk3328_defaults),
|
||||
};
|
||||
|
||||
#define RK3368_GRF_SOC_CON15 0x43c
|
||||
|
||||
static const struct rockchip_grf_value rk3368_defaults[] __initconst = {
|
||||
|
|
@ -83,6 +94,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
|
|||
}, {
|
||||
.compatible = "rockchip,rk3288-grf",
|
||||
.data = (void *)&rk3288_grf,
|
||||
}, {
|
||||
.compatible = "rockchip,rk3328-grf",
|
||||
.data = (void *)&rk3328_grf,
|
||||
}, {
|
||||
.compatible = "rockchip,rk3368-grf",
|
||||
.data = (void *)&rk3368_grf,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/mfd/syscon.h>
|
||||
#include <dt-bindings/power/rk3288-power.h>
|
||||
#include <dt-bindings/power/rk3328-power.h>
|
||||
#include <dt-bindings/power/rk3366-power.h>
|
||||
#include <dt-bindings/power/rk3368-power.h>
|
||||
#include <dt-bindings/power/rk3399-power.h>
|
||||
|
||||
|
|
@ -730,6 +731,16 @@ static const struct rockchip_domain_info rk3328_pm_domains[] = {
|
|||
[RK3328_PD_VPU] = DOMAIN_RK3328(-1, 9, 9, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3366_pm_domains[] = {
|
||||
[RK3366_PD_PERI] = DOMAIN_RK3368(10, 10, 6, true),
|
||||
[RK3366_PD_VIO] = DOMAIN_RK3368(14, 14, 8, false),
|
||||
[RK3366_PD_VIDEO] = DOMAIN_RK3368(13, 13, 7, false),
|
||||
[RK3366_PD_RKVDEC] = DOMAIN_RK3368(11, 11, 7, false),
|
||||
[RK3366_PD_WIFIBT] = DOMAIN_RK3368(8, 8, 9, false),
|
||||
[RK3366_PD_VPU] = DOMAIN_RK3368(12, 12, 7, false),
|
||||
[RK3366_PD_GPU] = DOMAIN_RK3368(15, 15, 2, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3368_pm_domains[] = {
|
||||
[RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6, true),
|
||||
[RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8, false),
|
||||
|
|
@ -794,6 +805,23 @@ static const struct rockchip_pmu_info rk3328_pmu = {
|
|||
.domain_info = rk3328_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3366_pmu = {
|
||||
.pwr_offset = 0x0c,
|
||||
.status_offset = 0x10,
|
||||
.req_offset = 0x3c,
|
||||
.idle_offset = 0x40,
|
||||
.ack_offset = 0x40,
|
||||
|
||||
.core_pwrcnt_offset = 0x48,
|
||||
.gpu_pwrcnt_offset = 0x50,
|
||||
|
||||
.core_power_transition_time = 24,
|
||||
.gpu_power_transition_time = 24,
|
||||
|
||||
.num_domains = ARRAY_SIZE(rk3366_pm_domains),
|
||||
.domain_info = rk3366_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3368_pmu = {
|
||||
.pwr_offset = 0x0c,
|
||||
.status_offset = 0x10,
|
||||
|
|
@ -833,6 +861,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
|
|||
.compatible = "rockchip,rk3328-power-controller",
|
||||
.data = (void *)&rk3328_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3366-power-controller",
|
||||
.data = (void *)&rk3366_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3368-power-controller",
|
||||
.data = (void *)&rk3368_pmu,
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
|
|||
const char *name;
|
||||
|
||||
if (of_property_read_string(node, "label", &name) < 0)
|
||||
name = strrchr(node->full_name, '/') + 1;
|
||||
name = kbasename(node->full_name);
|
||||
return kstrdup_const(name, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
|
@ -237,11 +237,11 @@ no_clk:
|
|||
continue;
|
||||
|
||||
if (of_genpd_add_subdomain(&parent, &child))
|
||||
pr_warn("%s failed to add subdomain: %s\n",
|
||||
parent.np->full_name, child.np->full_name);
|
||||
pr_warn("%pOF failed to add subdomain: %pOF\n",
|
||||
parent.np, child.np);
|
||||
else
|
||||
pr_info("%s has as child subdomain: %s.\n",
|
||||
parent.np->full_name, child.np->full_name);
|
||||
pr_info("%pOF has as child subdomain: %pOF.\n",
|
||||
parent.np, child.np);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
struct sunxi_sram_func {
|
||||
char *func;
|
||||
u8 val;
|
||||
u32 reg_val;
|
||||
};
|
||||
|
||||
struct sunxi_sram_data {
|
||||
|
|
@ -39,10 +40,11 @@ struct sunxi_sram_desc {
|
|||
bool claimed;
|
||||
};
|
||||
|
||||
#define SUNXI_SRAM_MAP(_val, _func) \
|
||||
#define SUNXI_SRAM_MAP(_reg_val, _val, _func) \
|
||||
{ \
|
||||
.func = _func, \
|
||||
.val = _val, \
|
||||
.reg_val = _reg_val, \
|
||||
}
|
||||
|
||||
#define SUNXI_SRAM_DATA(_name, _reg, _off, _width, ...) \
|
||||
|
|
@ -57,14 +59,20 @@ struct sunxi_sram_desc {
|
|||
|
||||
static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = {
|
||||
.data = SUNXI_SRAM_DATA("A3-A4", 0x4, 0x4, 2,
|
||||
SUNXI_SRAM_MAP(0, "cpu"),
|
||||
SUNXI_SRAM_MAP(1, "emac")),
|
||||
SUNXI_SRAM_MAP(0, 0, "cpu"),
|
||||
SUNXI_SRAM_MAP(1, 1, "emac")),
|
||||
};
|
||||
|
||||
static struct sunxi_sram_desc sun4i_a10_sram_d = {
|
||||
.data = SUNXI_SRAM_DATA("D", 0x4, 0x0, 1,
|
||||
SUNXI_SRAM_MAP(0, "cpu"),
|
||||
SUNXI_SRAM_MAP(1, "usb-otg")),
|
||||
SUNXI_SRAM_MAP(0, 0, "cpu"),
|
||||
SUNXI_SRAM_MAP(1, 1, "usb-otg")),
|
||||
};
|
||||
|
||||
static struct sunxi_sram_desc sun50i_a64_sram_c = {
|
||||
.data = SUNXI_SRAM_DATA("C", 0x4, 24, 1,
|
||||
SUNXI_SRAM_MAP(0, 1, "cpu"),
|
||||
SUNXI_SRAM_MAP(1, 0, "de2")),
|
||||
};
|
||||
|
||||
static const struct of_device_id sunxi_sram_dt_ids[] = {
|
||||
|
|
@ -76,6 +84,10 @@ static const struct of_device_id sunxi_sram_dt_ids[] = {
|
|||
.compatible = "allwinner,sun4i-a10-sram-d",
|
||||
.data = &sun4i_a10_sram_d.data,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-a64-sram-c",
|
||||
.data = &sun50i_a64_sram_c.data,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -121,7 +133,8 @@ static int sunxi_sram_show(struct seq_file *s, void *data)
|
|||
|
||||
for (func = sram_data->func; func->func; func++) {
|
||||
seq_printf(s, "\t\t%s%c\n", func->func,
|
||||
func->val == val ? '*' : ' ');
|
||||
func->reg_val == val ?
|
||||
'*' : ' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,10 +162,13 @@ static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data
|
|||
}
|
||||
|
||||
static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node,
|
||||
unsigned int *value)
|
||||
unsigned int *reg_value)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct sunxi_sram_data *data;
|
||||
struct sunxi_sram_func *func;
|
||||
struct of_phandle_args args;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0,
|
||||
|
|
@ -165,8 +181,7 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (value)
|
||||
*value = args.args[0];
|
||||
val = args.args[0];
|
||||
|
||||
match = of_match_node(sunxi_sram_dt_ids, args.np);
|
||||
if (!match) {
|
||||
|
|
@ -174,6 +189,26 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod
|
|||
goto err;
|
||||
}
|
||||
|
||||
data = match->data;
|
||||
if (!data) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
};
|
||||
|
||||
for (func = data->func; func->func; func++) {
|
||||
if (val == func->val) {
|
||||
if (reg_value)
|
||||
*reg_value = func->reg_val;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!func->func) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
of_node_put(args.np);
|
||||
return match->data;
|
||||
|
||||
|
|
@ -190,6 +225,9 @@ int sunxi_sram_claim(struct device *dev)
|
|||
u32 val, mask;
|
||||
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
if (!base)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (!dev || !dev->of_node)
|
||||
|
|
@ -267,6 +305,7 @@ static int sunxi_sram_probe(struct platform_device *pdev)
|
|||
|
||||
static const struct of_device_id sunxi_sram_dt_match[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-sram-controller" },
|
||||
{ .compatible = "allwinner,sun50i-a64-sram-controller" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
|
||||
|
|
|
|||
|
|
@ -107,6 +107,11 @@ config ARCH_TEGRA_186_SOC
|
|||
endif
|
||||
endif
|
||||
|
||||
config SOC_TEGRA_FUSE
|
||||
def_bool y
|
||||
depends on ARCH_TEGRA
|
||||
select SOC_BUS
|
||||
|
||||
config SOC_TEGRA_FLOWCTRL
|
||||
bool
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include <soc/tegra/common.h>
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
|
@ -210,6 +212,31 @@ static void tegra_enable_fuse_clk(void __iomem *base)
|
|||
writel(reg, base + 0x14);
|
||||
}
|
||||
|
||||
struct device * __init tegra_soc_device_register(void)
|
||||
{
|
||||
struct soc_device_attribute *attr;
|
||||
struct soc_device *dev;
|
||||
|
||||
attr = kzalloc(sizeof(*attr), GFP_KERNEL);
|
||||
if (!attr)
|
||||
return NULL;
|
||||
|
||||
attr->family = kasprintf(GFP_KERNEL, "Tegra");
|
||||
attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
|
||||
attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
|
||||
|
||||
dev = soc_device_register(attr);
|
||||
if (IS_ERR(dev)) {
|
||||
kfree(attr->soc_id);
|
||||
kfree(attr->revision);
|
||||
kfree(attr->family);
|
||||
kfree(attr);
|
||||
return ERR_CAST(dev);
|
||||
}
|
||||
|
||||
return soc_device_to_device(dev);
|
||||
}
|
||||
|
||||
static int __init tegra_init_fuse(void)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
|
|
@ -311,6 +338,31 @@ static int __init tegra_init_fuse(void)
|
|||
pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
|
||||
tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_initcall(tegra_init_fuse);
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
static int __init tegra_init_soc(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device *soc;
|
||||
|
||||
/* make sure we're running on Tegra */
|
||||
np = of_find_matching_node(NULL, tegra_fuse_match);
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
soc = tegra_soc_device_register();
|
||||
if (IS_ERR(soc)) {
|
||||
pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc));
|
||||
return PTR_ERR(soc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(tegra_init_soc);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -918,10 +918,8 @@ static void tegra_powergate_init(struct tegra_pmc *pmc,
|
|||
if (!np)
|
||||
return;
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
for_each_child_of_node(np, child)
|
||||
tegra_powergate_add(pmc, child);
|
||||
of_node_put(child);
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue