mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
Renesas driver updates for v7.2
- Add Multifunctional Interface (MFIS) mailbox and product register
support for R-Car X5H,
- Miscellaneous fixes and improvements.
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQQ9qaHoIs/1I4cXmEiKwlD9ZEnxcAUCagwTtgAKCRCKwlD9ZEnx
cLDkAQDhxksjowi3Ax4f8PUBawEnJoy8lameVXx/y6SihMh//AD+P4uMbbcCVs7j
thXfW9l69oi/g+xc1M/fNFKrLFp8Bwk=
=q0zd
-----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmoNipoACgkQmmx57+YA
GNkuhg/9GWPhQQ66flfK8nP8pscy2CAsGFT5K8UeFE9rCAUIEKxm9aEDPkLTzlJW
Yi6cYYA7b/hHMKXXBfJR59Bthh1eLOyz7XMQu08COHrqL1fNfj6+ug6RG49R10g8
9ru9E+NxoyC9P+yQgzehsGLBeW4awFQWbwyq2RBaycwni853cPzfKQeC2rK0Pwuv
nutLUpP0YnNG/vveACK5t7OnG90Yi9aGcfphq5Nl/VSrZ5ju7xLtkEZVRVbP6Cbt
9dcQ4klmnQ0u5VUsYx/F7OiGfMh6LUm4oJna4SCYiWqdkujobsQ/9/IzCWPp00P5
6k9T+l5QLGviCQxuSwAtVMheVB6bbr8gvqteHIPRhYKGVGQBsY/LQjeTwmpiUJYu
4/uV6eGtblAbARIqxViqLrPjwlX8qWkqJ8p4MJedAreHcOt8pMjXCnMlVxbl/rOV
LaXpIC2o+8ppyVhHCvh/tHRevQSuoefZ4gHHy8ETbA3Tq/jLrvemzIyBGNfRc7Ye
CwjiOFPtYtFD1WEAWGyNisvZuNUS4ayxxP+rhS1C5KvywJNf7xmGkFm1PEqyfLw9
OgBfimYrzj6VMWFj+j1OlO5B524wh83h/n9YFG1md6w4UzHgYQb4Fq1os2e1XvXS
e2mXpqiz6TVYYicpKmLxxPlrjdIoguzZ4sir72UMYCW8n8yHddo=
=cz+6
-----END PGP SIGNATURE-----
Merge tag 'renesas-drivers-for-v7.2-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/drivers
Renesas driver updates for v7.2
- Add Multifunctional Interface (MFIS) mailbox and product register
support for R-Car X5H,
- Miscellaneous fixes and improvements.
* tag 'renesas-drivers-for-v7.2-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel:
soc: renesas: Convert to of_machine_get_match()
soc: renesas: Add R-Car X5H PRR support
soc: renesas: Add Renesas R-Car MFIS driver
dt-bindings: soc: renesas: Document MFIS IP core
soc: renesas: r9a09g057-sys: Move common code to a helper
soc: renesas: r9a09g056-sys: Move common code to a helper
soc: renesas: r9a09g047-sys: Move common code to a helper
soc: renesas: r9a08g046-sysc: Move common code to a helper
soc: renesas: r9a08g045-sysc: Move common code to a helper
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
b1700f8d6c
|
|
@ -0,0 +1,187 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/renesas/renesas,r8a78000-mfis.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas MFIS (Multifunctional Interface) controller
|
||||
|
||||
maintainers:
|
||||
- Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
|
||||
description:
|
||||
The Renesas Multifunctional Interface (MFIS) provides various functionality
|
||||
like mailboxes, hardware spinlocks, product identification, error injection,
|
||||
error detection and such. Parts of it can be used for communication between
|
||||
different CPU cores. Those cores can be in various domains like AP, RT, or
|
||||
SCP. Often multiple domain-specific MFIS instances exist in one SoC.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- renesas,r8a78000-mfis # R-Car X5H (AP<->AP, with PRR)
|
||||
- renesas,r8a78000-mfis-scp # R-Car X5H (AP<->SCP, without PRR)
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: common
|
||||
- const: mboxes
|
||||
|
||||
interrupts:
|
||||
minItems: 32
|
||||
maxItems: 128
|
||||
description:
|
||||
The interrupts raised by the remote doorbells.
|
||||
|
||||
interrupt-names:
|
||||
minItems: 32
|
||||
maxItems: 128
|
||||
description:
|
||||
An interrupt name is constructed with the prefix 'ch'. Then, the
|
||||
channel number as specified in the documentation of the SoC. Finally,
|
||||
the letter 'i' if the interrupt is raised by the IICR register. Or 'e'
|
||||
if it is raised by the EICR register.
|
||||
|
||||
"#hwlock-cells":
|
||||
const: 1
|
||||
|
||||
"#mbox-cells":
|
||||
const: 2
|
||||
description:
|
||||
The first cell is the channel number as specified in the documentation
|
||||
of the SoC. The second cell may specify flags as described in the file
|
||||
<dt-bindings/soc/renesas,r8a78000-mfis.h>.
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r8a78000-mfis
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 128
|
||||
interrupt-names:
|
||||
minItems: 128
|
||||
items:
|
||||
pattern: "^ch[0-9]+[ie]$"
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r8a78000-mfis-scp
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 32
|
||||
interrupt-names:
|
||||
maxItems: 32
|
||||
items:
|
||||
pattern: "^ch[0-9]+i$"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- "#hwlock-cells"
|
||||
- "#mbox-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
system-controller@189e0000 {
|
||||
compatible = "renesas,r8a78000-mfis";
|
||||
reg = <0x189e0000 0x1000>, <0x18800000 0x40000>;
|
||||
reg-names = "common", "mboxes";
|
||||
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "ch0i", "ch0e", "ch1i", "ch1e", "ch2i", "ch2e", "ch3i", "ch3e",
|
||||
"ch4i", "ch4e", "ch5i", "ch5e", "ch6i", "ch6e", "ch7i", "ch7e",
|
||||
"ch8i", "ch8e", "ch9i", "ch9e", "ch10i", "ch10e", "ch11i", "ch11e",
|
||||
"ch12i", "ch12e", "ch13i", "ch13e", "ch14i", "ch14e", "ch15i", "ch15e",
|
||||
"ch16i", "ch16e", "ch17i", "ch17e", "ch18i", "ch18e", "ch19i", "ch19e",
|
||||
"ch20i", "ch20e", "ch21i", "ch21e", "ch22i", "ch22e", "ch23i", "ch23e",
|
||||
"ch24i", "ch24e", "ch25i", "ch25e", "ch26i", "ch26e", "ch27i", "ch27e",
|
||||
"ch28i", "ch28e", "ch29i", "ch29e", "ch30i", "ch30e", "ch31i", "ch31e",
|
||||
"ch32i", "ch32e", "ch33i", "ch33e", "ch34i", "ch34e", "ch35i", "ch35e",
|
||||
"ch36i", "ch36e", "ch37i", "ch37e", "ch38i", "ch38e", "ch39i", "ch39e",
|
||||
"ch40i", "ch40e", "ch41i", "ch41e", "ch42i", "ch42e", "ch43i", "ch43e",
|
||||
"ch44i", "ch44e", "ch45i", "ch45e", "ch46i", "ch46e", "ch47i", "ch47e",
|
||||
"ch48i", "ch48e", "ch49i", "ch49e", "ch50i", "ch50e", "ch51i", "ch51e",
|
||||
"ch52i", "ch52e", "ch53i", "ch53e", "ch54i", "ch54e", "ch55i", "ch55e",
|
||||
"ch56i", "ch56e", "ch57i", "ch57e", "ch58i", "ch58e", "ch59i", "ch59e",
|
||||
"ch60i", "ch60e", "ch61i", "ch61e", "ch62i", "ch62e", "ch63i", "ch63e";
|
||||
#hwlock-cells = <1>;
|
||||
#mbox-cells = <2>;
|
||||
};
|
||||
|
|
@ -465,6 +465,15 @@ config ARCH_R9A07G043
|
|||
|
||||
endif # RISCV
|
||||
|
||||
config RCAR_MFIS
|
||||
tristate "Renesas R-Car MFIS driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
depends on MAILBOX
|
||||
help
|
||||
Select this option to enable the Renesas R-Car MFIS core driver for
|
||||
the MFIS device found on SoCs like R-Car. On families like Gen5, this
|
||||
is needed to communicate with the SCP.
|
||||
|
||||
config PWC_RZV2M
|
||||
bool "Renesas RZ/V2M PWC support" if COMPILE_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ obj-$(CONFIG_SYS_R9A09G057) += r9a09g057-sys.o
|
|||
|
||||
# Family
|
||||
obj-$(CONFIG_PWC_RZV2M) += pwc-rzv2m.o
|
||||
obj-$(CONFIG_RCAR_MFIS) += rcar-mfis.o
|
||||
obj-$(CONFIG_RST_RCAR) += rcar-rst.o
|
||||
obj-$(CONFIG_RZN1_IRQMUX) += rzn1_irqmux.o
|
||||
obj-$(CONFIG_SYSC_RZ) += rz-sysc.o
|
||||
|
|
|
|||
|
|
@ -37,18 +37,14 @@ static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initc
|
|||
.specific_id_mask = GENMASK(27, 0),
|
||||
};
|
||||
|
||||
static bool rzg3s_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzg3s_regmap_readable_writeable_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_XSPI_MAP_STAADD_CS0:
|
||||
case SYS_XSPI_MAP_ENDADD_CS0:
|
||||
case SYS_XSPI_MAP_STAADD_CS1:
|
||||
case SYS_XSPI_MAP_ENDADD_CS1:
|
||||
case SYS_GETH0_CFG:
|
||||
case SYS_GETH1_CFG:
|
||||
case SYS_PCIE_CFG:
|
||||
case SYS_PCIE_MON:
|
||||
case SYS_PCIE_ERR_MON:
|
||||
case SYS_PCIE_PHY:
|
||||
case SYS_I2C0_CFG:
|
||||
case SYS_I2C1_CFG:
|
||||
|
|
@ -63,26 +59,25 @@ static bool rzg3s_regmap_readable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rzg3s_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (rzg3s_regmap_readable_writeable_reg(reg))
|
||||
return true;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_GETH0_CFG:
|
||||
case SYS_GETH1_CFG:
|
||||
case SYS_PCIE_MON:
|
||||
case SYS_PCIE_ERR_MON:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rzg3s_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_XSPI_MAP_STAADD_CS0:
|
||||
case SYS_XSPI_MAP_ENDADD_CS0:
|
||||
case SYS_XSPI_MAP_STAADD_CS1:
|
||||
case SYS_XSPI_MAP_ENDADD_CS1:
|
||||
case SYS_PCIE_CFG:
|
||||
case SYS_PCIE_PHY:
|
||||
case SYS_I2C0_CFG:
|
||||
case SYS_I2C1_CFG:
|
||||
case SYS_I2C2_CFG:
|
||||
case SYS_I2C3_CFG:
|
||||
case SYS_I3C_CFG:
|
||||
case SYS_USB_PWRRDY:
|
||||
case SYS_PCIE_RST_RSM_B:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return rzg3s_regmap_readable_writeable_reg(reg);
|
||||
}
|
||||
|
||||
const struct rz_sysc_init_data rzg3s_sysc_init_data __initconst = {
|
||||
|
|
|
|||
|
|
@ -28,17 +28,14 @@
|
|||
#define SYS_PWRRDY_N 0xd70
|
||||
#define SYS_IPCONT_SEL_CLONECH 0xe2c
|
||||
|
||||
static bool rzg3l_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzg3l_regmap_readable_writeable_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_XSPI_MAP_STAADD_CS0:
|
||||
case SYS_XSPI_MAP_ENDADD_CS0:
|
||||
case SYS_XSPI_MAP_STAADD_CS1:
|
||||
case SYS_XSPI_MAP_ENDADD_CS1:
|
||||
case SYS_GETH0_CFG:
|
||||
case SYS_GETH1_CFG:
|
||||
case SYS_PCIE_CFG:
|
||||
case SYS_PCIE_MON:
|
||||
case SYS_PCIE_PHY:
|
||||
case SYS_I2C0_CFG:
|
||||
case SYS_I2C1_CFG:
|
||||
|
|
@ -53,28 +50,26 @@ static bool rzg3l_regmap_readable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rzg3l_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzg3l_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (rzg3l_regmap_readable_writeable_reg(reg))
|
||||
return true;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_XSPI_MAP_STAADD_CS0:
|
||||
case SYS_XSPI_MAP_ENDADD_CS0:
|
||||
case SYS_XSPI_MAP_STAADD_CS1:
|
||||
case SYS_XSPI_MAP_ENDADD_CS1:
|
||||
case SYS_PCIE_CFG:
|
||||
case SYS_PCIE_PHY:
|
||||
case SYS_I2C0_CFG:
|
||||
case SYS_I2C1_CFG:
|
||||
case SYS_I2C2_CFG:
|
||||
case SYS_I2C3_CFG:
|
||||
case SYS_I3C_CFG:
|
||||
case SYS_PWRRDY_N:
|
||||
case SYS_IPCONT_SEL_CLONECH:
|
||||
case SYS_GETH0_CFG:
|
||||
case SYS_GETH1_CFG:
|
||||
case SYS_PCIE_MON:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rzg3l_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return rzg3l_regmap_readable_writeable_reg(reg);
|
||||
}
|
||||
|
||||
static const struct rz_sysc_soc_id_init_data rzg3l_sysc_soc_id_init_data __initconst = {
|
||||
.family = "RZ/G3L",
|
||||
.id = 0x87d9447,
|
||||
|
|
|
|||
|
|
@ -83,11 +83,9 @@ static const struct rz_sysc_soc_id_init_data rzg3e_sys_soc_id_init_data __initco
|
|||
.print_id = rzg3e_sys_print_id,
|
||||
};
|
||||
|
||||
static bool rzg3e_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzg3e_regmap_readable_writeable_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
case SYS_SPI_STAADDCS0:
|
||||
case SYS_SPI_ENDADDCS0:
|
||||
case SYS_SPI_STAADDCS1:
|
||||
|
|
@ -112,31 +110,23 @@ static bool rzg3e_regmap_readable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rzg3e_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (rzg3e_regmap_readable_writeable_reg(reg))
|
||||
return true;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rzg3e_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_SPI_STAADDCS0:
|
||||
case SYS_SPI_ENDADDCS0:
|
||||
case SYS_SPI_STAADDCS1:
|
||||
case SYS_SPI_ENDADDCS1:
|
||||
case SYS_VSP_CLK:
|
||||
case SYS_GBETH0_CFG:
|
||||
case SYS_GBETH1_CFG:
|
||||
case SYS_PCIE_INTX_CH0:
|
||||
case SYS_PCIE_MSI1_CH0:
|
||||
case SYS_PCIE_MSI2_CH0:
|
||||
case SYS_PCIE_MSI3_CH0:
|
||||
case SYS_PCIE_MSI4_CH0:
|
||||
case SYS_PCIE_MSI5_CH0:
|
||||
case SYS_PCIE_PME_CH0:
|
||||
case SYS_PCIE_ACK_CH0:
|
||||
case SYS_PCIE_MISC_CH0:
|
||||
case SYS_PCIE_MODE_CH0:
|
||||
case SYS_ADC_CFG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return rzg3e_regmap_readable_writeable_reg(reg);
|
||||
}
|
||||
|
||||
const struct rz_sysc_init_data rzg3e_sys_init_data __initconst = {
|
||||
|
|
|
|||
|
|
@ -88,13 +88,9 @@ static const struct rz_sysc_soc_id_init_data rzv2n_sys_soc_id_init_data __initco
|
|||
.print_id = rzv2n_sys_print_id,
|
||||
};
|
||||
|
||||
static bool rzv2n_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzv2n_regmap_readable_writeable_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU0TRMVAL0:
|
||||
case SYS_LSI_OTPTSU0TRMVAL1:
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
case SYS_GBETH0_CFG:
|
||||
case SYS_GBETH1_CFG:
|
||||
case SYS_PCIE_INTX_CH0:
|
||||
|
|
@ -114,26 +110,25 @@ static bool rzv2n_regmap_readable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rzv2n_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (rzv2n_regmap_readable_writeable_reg(reg))
|
||||
return true;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU0TRMVAL0:
|
||||
case SYS_LSI_OTPTSU0TRMVAL1:
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rzv2n_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_GBETH0_CFG:
|
||||
case SYS_GBETH1_CFG:
|
||||
case SYS_PCIE_INTX_CH0:
|
||||
case SYS_PCIE_MSI1_CH0:
|
||||
case SYS_PCIE_MSI2_CH0:
|
||||
case SYS_PCIE_MSI3_CH0:
|
||||
case SYS_PCIE_MSI4_CH0:
|
||||
case SYS_PCIE_MSI5_CH0:
|
||||
case SYS_PCIE_PME_CH0:
|
||||
case SYS_PCIE_ACK_CH0:
|
||||
case SYS_PCIE_MISC_CH0:
|
||||
case SYS_PCIE_MODE_CH0:
|
||||
case SYS_ADC_CFG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return rzv2n_regmap_readable_writeable_reg(reg);
|
||||
}
|
||||
|
||||
const struct rz_sysc_init_data rzv2n_sys_init_data __initconst = {
|
||||
|
|
|
|||
|
|
@ -91,13 +91,9 @@ static const struct rz_sysc_soc_id_init_data rzv2h_sys_soc_id_init_data __initco
|
|||
.print_id = rzv2h_sys_print_id,
|
||||
};
|
||||
|
||||
static bool rzv2h_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool rzv2h_regmap_readable_writeable_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU0TRMVAL0:
|
||||
case SYS_LSI_OTPTSU0TRMVAL1:
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
case SYS_GBETH0_CFG:
|
||||
case SYS_GBETH1_CFG:
|
||||
case SYS_PCIE_INTX_CH0:
|
||||
|
|
@ -128,37 +124,25 @@ static bool rzv2h_regmap_readable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rzv2h_regmap_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (rzv2h_regmap_readable_writeable_reg(reg))
|
||||
return true;
|
||||
|
||||
switch (reg) {
|
||||
case SYS_LSI_OTPTSU0TRMVAL0:
|
||||
case SYS_LSI_OTPTSU0TRMVAL1:
|
||||
case SYS_LSI_OTPTSU1TRMVAL0:
|
||||
case SYS_LSI_OTPTSU1TRMVAL1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rzv2h_regmap_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SYS_GBETH0_CFG:
|
||||
case SYS_GBETH1_CFG:
|
||||
case SYS_PCIE_INTX_CH0:
|
||||
case SYS_PCIE_MSI1_CH0:
|
||||
case SYS_PCIE_MSI2_CH0:
|
||||
case SYS_PCIE_MSI3_CH0:
|
||||
case SYS_PCIE_MSI4_CH0:
|
||||
case SYS_PCIE_MSI5_CH0:
|
||||
case SYS_PCIE_PME_CH0:
|
||||
case SYS_PCIE_ACK_CH0:
|
||||
case SYS_PCIE_MISC_CH0:
|
||||
case SYS_PCIE_MODE_CH0:
|
||||
case SYS_PCIE_INTX_CH1:
|
||||
case SYS_PCIE_MSI1_CH1:
|
||||
case SYS_PCIE_MSI2_CH1:
|
||||
case SYS_PCIE_MSI3_CH1:
|
||||
case SYS_PCIE_MSI4_CH1:
|
||||
case SYS_PCIE_MSI5_CH1:
|
||||
case SYS_PCIE_PME_CH1:
|
||||
case SYS_PCIE_ACK_CH1:
|
||||
case SYS_PCIE_MISC_CH1:
|
||||
case SYS_PCIE_MODE_CH1:
|
||||
case SYS_PCIE_MODE:
|
||||
case SYS_ADC_CFG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return rzv2h_regmap_readable_writeable_reg(reg);
|
||||
}
|
||||
|
||||
const struct rz_sysc_init_data rzv2h_sys_init_data __initconst = {
|
||||
|
|
|
|||
344
drivers/soc/renesas/rcar-mfis.c
Normal file
344
drivers/soc/renesas/rcar-mfis.c
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Renesas R-Car MFIS (Multifunctional Interface) driver
|
||||
*
|
||||
* Copyright (C) Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
* Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
*/
|
||||
#include <dt-bindings/soc/renesas,r8a78000-mfis.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define MFISWPCNTR 0x0900
|
||||
#define MFISWACNTR 0x0904
|
||||
|
||||
#define MFIS_X5H_IICR(i) ((i) * 0x1000 + 0x00)
|
||||
#define MFIS_X5H_EICR(i) ((i) * 0x1000 + 0x04)
|
||||
|
||||
#define MFIS_UNPROTECT_KEY 0xACCE0000
|
||||
|
||||
struct mfis_priv;
|
||||
|
||||
struct mfis_reg {
|
||||
void __iomem *base;
|
||||
resource_size_t start;
|
||||
struct mfis_priv *priv;
|
||||
};
|
||||
|
||||
struct mfis_info {
|
||||
u32 unprotect_mask;
|
||||
unsigned int mb_num_channels;
|
||||
unsigned int mb_reg_comes_from_dt:1;
|
||||
unsigned int mb_tx_uses_eicr:1;
|
||||
unsigned int mb_channels_are_unidir:1;
|
||||
};
|
||||
|
||||
struct mfis_chan_priv {
|
||||
u32 reg;
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct mfis_priv {
|
||||
spinlock_t unprotect_lock; /* guards access to the unprotection reg */
|
||||
struct device *dev;
|
||||
struct mfis_reg common_reg;
|
||||
struct mfis_reg mbox_reg;
|
||||
const struct mfis_info *info;
|
||||
|
||||
/* mailbox private data */
|
||||
struct mbox_controller mbox;
|
||||
struct mfis_chan_priv *chan_privs;
|
||||
};
|
||||
|
||||
static u32 mfis_read(struct mfis_reg *mreg, unsigned int reg)
|
||||
{
|
||||
return ioread32(mreg->base + reg);
|
||||
}
|
||||
|
||||
static void mfis_write(struct mfis_reg *mreg, u32 reg, u32 val)
|
||||
{
|
||||
struct mfis_priv *priv = mreg->priv;
|
||||
u32 unprotect_mask = priv->info->unprotect_mask;
|
||||
unsigned long flags;
|
||||
u32 unprotect_code;
|
||||
|
||||
/*
|
||||
* [Gen4] key: 0xACCE0000, mask: 0x0000FFFF
|
||||
* [Gen5] key: 0xACC00000, mask: 0x000FFFFF
|
||||
*/
|
||||
unprotect_code = (MFIS_UNPROTECT_KEY & ~unprotect_mask) |
|
||||
((mreg->start + reg) & unprotect_mask);
|
||||
|
||||
spin_lock_irqsave(&priv->unprotect_lock, flags);
|
||||
iowrite32(unprotect_code, priv->common_reg.base + MFISWACNTR);
|
||||
iowrite32(val, mreg->base + reg);
|
||||
spin_unlock_irqrestore(&priv->unprotect_lock, flags);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* Mailbox *
|
||||
********************************************************/
|
||||
|
||||
#define mfis_mb_mbox_to_priv(_m) container_of((_m), struct mfis_priv, mbox)
|
||||
|
||||
static irqreturn_t mfis_mb_iicr_interrupt(int irq, void *data)
|
||||
{
|
||||
struct mbox_chan *chan = data;
|
||||
struct mfis_priv *priv = mfis_mb_mbox_to_priv(chan->mbox);
|
||||
struct mfis_chan_priv *chan_priv = chan->con_priv;
|
||||
|
||||
mbox_chan_received_data(chan, NULL);
|
||||
/* Stop remote(!) doorbell */
|
||||
mfis_write(&priv->mbox_reg, chan_priv->reg, 0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mfis_mb_startup(struct mbox_chan *chan)
|
||||
{
|
||||
struct mfis_chan_priv *chan_priv = chan->con_priv;
|
||||
|
||||
if (!chan_priv->irq)
|
||||
return 0;
|
||||
|
||||
return request_irq(chan_priv->irq, mfis_mb_iicr_interrupt, 0,
|
||||
dev_name(chan->mbox->dev), chan);
|
||||
}
|
||||
|
||||
static void mfis_mb_shutdown(struct mbox_chan *chan)
|
||||
{
|
||||
struct mfis_chan_priv *chan_priv = chan->con_priv;
|
||||
|
||||
if (chan_priv->irq)
|
||||
free_irq(chan_priv->irq, chan);
|
||||
}
|
||||
|
||||
static int mfis_mb_iicr_send_data(struct mbox_chan *chan, void *data)
|
||||
{
|
||||
struct mfis_priv *priv = mfis_mb_mbox_to_priv(chan->mbox);
|
||||
struct mfis_chan_priv *chan_priv = chan->con_priv;
|
||||
|
||||
/* Our doorbell still active? */
|
||||
if (mfis_read(&priv->mbox_reg, chan_priv->reg) & BIT(0))
|
||||
return -EBUSY;
|
||||
|
||||
/* Start our doorbell */
|
||||
mfis_write(&priv->mbox_reg, chan_priv->reg, BIT(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool mfis_mb_iicr_last_tx_done(struct mbox_chan *chan)
|
||||
{
|
||||
struct mfis_priv *priv = mfis_mb_mbox_to_priv(chan->mbox);
|
||||
struct mfis_chan_priv *chan_priv = chan->con_priv;
|
||||
|
||||
/* Our doorbell still active? */
|
||||
return !(mfis_read(&priv->mbox_reg, chan_priv->reg) & BIT(0));
|
||||
}
|
||||
|
||||
/* For MFIS variants using the IICR/EICR register pair */
|
||||
static const struct mbox_chan_ops mfis_iicr_ops = {
|
||||
.startup = mfis_mb_startup,
|
||||
.shutdown = mfis_mb_shutdown,
|
||||
.send_data = mfis_mb_iicr_send_data,
|
||||
.last_tx_done = mfis_mb_iicr_last_tx_done,
|
||||
};
|
||||
|
||||
static struct mbox_chan *mfis_mb_of_xlate(struct mbox_controller *mbox,
|
||||
const struct of_phandle_args *sp)
|
||||
{
|
||||
struct mfis_priv *priv = mfis_mb_mbox_to_priv(mbox);
|
||||
struct mfis_chan_priv *chan_priv;
|
||||
bool tx_uses_eicr, is_only_rx;
|
||||
u32 chan_num, chan_flags;
|
||||
struct mbox_chan *chan;
|
||||
|
||||
if (sp->args_count != 2)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
chan_num = sp->args[0];
|
||||
chan_flags = sp->args[1];
|
||||
|
||||
if (chan_num >= priv->info->mb_num_channels)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Channel layout is described in mfis_mb_probe() */
|
||||
if (priv->info->mb_channels_are_unidir) {
|
||||
is_only_rx = chan_flags & MFIS_CHANNEL_RX;
|
||||
chan = mbox->chans + 2 * chan_num + is_only_rx;
|
||||
} else {
|
||||
is_only_rx = false;
|
||||
chan = mbox->chans + chan_num;
|
||||
}
|
||||
|
||||
if (priv->info->mb_reg_comes_from_dt) {
|
||||
tx_uses_eicr = chan_flags & MFIS_CHANNEL_EICR;
|
||||
if (tx_uses_eicr)
|
||||
chan += mbox->num_chans / 2;
|
||||
} else {
|
||||
tx_uses_eicr = priv->info->mb_tx_uses_eicr;
|
||||
}
|
||||
|
||||
chan_priv = chan->con_priv;
|
||||
chan_priv->reg = (tx_uses_eicr ^ is_only_rx) ? MFIS_X5H_EICR(chan_num) :
|
||||
MFIS_X5H_IICR(chan_num);
|
||||
|
||||
if (!priv->info->mb_channels_are_unidir || is_only_rx) {
|
||||
char irqname[8];
|
||||
char suffix = tx_uses_eicr ? 'i' : 'e';
|
||||
|
||||
/* "ch0i" or "ch0e" */
|
||||
scnprintf(irqname, sizeof(irqname), "ch%u%c", chan_num, suffix);
|
||||
|
||||
chan_priv->irq = of_irq_get_byname(mbox->dev->of_node, irqname);
|
||||
if (chan_priv->irq < 0)
|
||||
return ERR_PTR(chan_priv->irq);
|
||||
if (chan_priv->irq == 0)
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
static int mfis_mb_probe(struct mfis_priv *priv)
|
||||
{
|
||||
unsigned int num_chan = priv->info->mb_num_channels;
|
||||
struct device *dev = priv->dev;
|
||||
struct mbox_controller *mbox;
|
||||
struct mbox_chan *chan;
|
||||
|
||||
if (priv->info->mb_channels_are_unidir) {
|
||||
/* Channel layout: Ch0-TX, Ch0-RX, Ch1-TX... */
|
||||
num_chan *= 2;
|
||||
}
|
||||
|
||||
if (priv->info->mb_reg_comes_from_dt) {
|
||||
/* Channel layout: <n> IICR channels, <n> EICR channels */
|
||||
num_chan *= 2;
|
||||
}
|
||||
|
||||
chan = devm_kcalloc(dev, num_chan, sizeof(*chan), GFP_KERNEL);
|
||||
if (!chan)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->chan_privs = devm_kcalloc(dev, num_chan, sizeof(*priv->chan_privs),
|
||||
GFP_KERNEL);
|
||||
if (!priv->chan_privs)
|
||||
return -ENOMEM;
|
||||
|
||||
mbox = &priv->mbox;
|
||||
|
||||
for (unsigned int i = 0; i < num_chan; i++)
|
||||
chan[i].con_priv = &priv->chan_privs[i];
|
||||
|
||||
mbox->chans = chan;
|
||||
mbox->num_chans = num_chan;
|
||||
mbox->txdone_poll = true;
|
||||
mbox->ops = &mfis_iicr_ops;
|
||||
mbox->dev = dev;
|
||||
mbox->of_xlate = mfis_mb_of_xlate;
|
||||
|
||||
return devm_mbox_controller_register(dev, mbox);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* Common *
|
||||
********************************************************/
|
||||
static int mfis_reg_probe(struct platform_device *pdev, struct mfis_priv *priv,
|
||||
struct mfis_reg *mreg, const char *name, bool required)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
|
||||
|
||||
/* If there is no mailbox resource, registers are in the common space */
|
||||
if (!res && !required) {
|
||||
*mreg = priv->common_reg;
|
||||
} else {
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
mreg->base = base;
|
||||
mreg->start = res->start;
|
||||
mreg->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mfis_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mfis_priv *priv;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
priv->info = of_device_get_match_data(dev);
|
||||
if (!priv->info)
|
||||
return -ENOENT;
|
||||
|
||||
spin_lock_init(&priv->unprotect_lock);
|
||||
|
||||
ret = mfis_reg_probe(pdev, priv, &priv->common_reg, "common", true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mfis_reg_probe(pdev, priv, &priv->mbox_reg, "mboxes", false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mfis_mb_probe(priv);
|
||||
}
|
||||
|
||||
static const struct mfis_info mfis_info_r8a78000 = {
|
||||
.unprotect_mask = 0x000fffff,
|
||||
.mb_num_channels = 64,
|
||||
.mb_reg_comes_from_dt = true,
|
||||
.mb_channels_are_unidir = true,
|
||||
};
|
||||
|
||||
static const struct mfis_info mfis_info_r8a78000_scp = {
|
||||
.unprotect_mask = 0x000fffff,
|
||||
.mb_num_channels = 32,
|
||||
.mb_tx_uses_eicr = true,
|
||||
.mb_channels_are_unidir = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id mfis_mfd_of_match[] = {
|
||||
{ .compatible = "renesas,r8a78000-mfis", .data = &mfis_info_r8a78000, },
|
||||
{ .compatible = "renesas,r8a78000-mfis-scp", .data = &mfis_info_r8a78000_scp, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mfis_mfd_of_match);
|
||||
|
||||
static struct platform_driver mfis_driver = {
|
||||
.driver = {
|
||||
.name = "rcar-mfis",
|
||||
.of_match_table = mfis_mfd_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = mfis_probe,
|
||||
};
|
||||
module_platform_driver(mfis_driver);
|
||||
|
||||
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
|
||||
MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Renesas R-Car MFIS driver");
|
||||
|
|
@ -442,8 +442,14 @@ static const struct renesas_id id_prr __initconst = {
|
|||
.mask = 0xff00,
|
||||
};
|
||||
|
||||
static const struct renesas_id id_mfis __initconst = {
|
||||
.offset = 0x44,
|
||||
.mask = 0xff00,
|
||||
};
|
||||
|
||||
static const struct of_device_id renesas_ids[] __initconst = {
|
||||
{ .compatible = "renesas,bsid", .data = &id_bsid },
|
||||
{ .compatible = "renesas,r8a78000-mfis", .data = &id_mfis },
|
||||
{ .compatible = "renesas,r9a07g043-sysc", .data = &id_rzg2l },
|
||||
{ .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },
|
||||
{ .compatible = "renesas,r9a07g054-sysc", .data = &id_rzg2l },
|
||||
|
|
@ -468,7 +474,7 @@ static int __init renesas_soc_init(void)
|
|||
const char *soc_id;
|
||||
int ret;
|
||||
|
||||
match = of_match_node(renesas_socs, of_root);
|
||||
match = of_machine_get_match(renesas_socs);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -501,7 +507,7 @@ static int __init renesas_soc_init(void)
|
|||
product = readl(chipid + id->offset);
|
||||
iounmap(chipid);
|
||||
|
||||
if (id == &id_prr) {
|
||||
if (id == &id_prr || id == &id_mfis) {
|
||||
/* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */
|
||||
if ((product & 0x7fff) == 0x5210)
|
||||
product ^= 0x11;
|
||||
|
|
|
|||
28
include/dt-bindings/soc/renesas,r8a78000-mfis.h
Normal file
28
include/dt-bindings/soc/renesas,r8a78000-mfis.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
#ifndef _DT_BINDINGS_SOC_RENESAS_R8A78000_MFIS_H
|
||||
#define _DT_BINDINGS_SOC_RENESAS_R8A78000_MFIS_H
|
||||
|
||||
/*
|
||||
* Constants for the second mbox-cell of the Renesas MFIS IP core. To be treated
|
||||
* as bit flags which can be ORed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MFIS HW design before r8a78001 requires a channel to be marked as either
|
||||
* TX or RX.
|
||||
*/
|
||||
#define MFIS_CHANNEL_TX (0 << 0)
|
||||
#define MFIS_CHANNEL_RX (1 << 0)
|
||||
|
||||
/*
|
||||
* MFIS variants before r8a78001 work with pairs of IICR and EICR registers.
|
||||
* Usually, it is specified in the datasheets which of the two a specific core
|
||||
* should use. Then, it does not need extra description in DT. For plain MFIS
|
||||
* of r8a78000, this is selectable, though. According to the system design and
|
||||
* the firmware in use, these channels need to be marked. This is not needed
|
||||
* with other versions of the MFIS, not even with MFIS-SCP of r8a78000.
|
||||
*/
|
||||
#define MFIS_CHANNEL_IICR (0 << 1)
|
||||
#define MFIS_CHANNEL_EICR (1 << 1)
|
||||
|
||||
#endif /* _DT_BINDINGS_SOC_RENESAS_R8A78000_MFIS_H */
|
||||
Loading…
Reference in New Issue
Block a user