Reset controller updates for v5.15

Add support for the SC7280 PDC Global and RZ/G2L USB/PHY reset
 controllers, convert UniPhier glue device tree bindings to json-schema
 and remove a leftover mention of ZTE zx2967 from Kconfig.
 -----BEGIN PGP SIGNATURE-----
 
 iI0EABYIADUWIQRRO6F6WdpH1R0vGibVhaclGDdiwAUCYSOy1BcccC56YWJlbEBw
 ZW5ndXRyb25peC5kZQAKCRDVhaclGDdiwKxPAQDYffSCcsiXIcZqwO8mpBspzw+R
 rWTqcUeszNXJtPY0rwD/VFs7ESt2RijkKPJeP6VV7VvJkmzaRhFDtLB3MdyG1Qk=
 =60wV
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmEnXuMACgkQmmx57+YA
 GNmunBAAv8XVaPA47KvXrsZ8Day6GI9j0EyQAYRvm7MkxD35lDBaooniPT/6bGNs
 cfz6oolZPAzBtomErZUnqCADYGNKCta+Egsp836GCiX85M1sooic9gmidJW0oywQ
 98d+BNjNJDF42RmBdLGqsE4UA/lB/1CgiRKtxkeTDgORQ+UKwwC2CZRwIhyr2ku9
 /YsokNOLETSRf7UxERfZVQDoCpCY8rHn9Yk5Ldjf1a3wSNpEFcxY08TtK8wAxw1x
 ZdnIVMbDX9P3Yowh5LayguXUwXX3ZSiJJKeIaqf4FGn+7e0ISyGX2LSRmsLEP1N/
 gi0D3tS/C6GPiIIup92VAVgN60WwxPl7whwpon98ii7krY3LMr9BibqyL9QEkZF7
 W64flH+HUqm6zzZC26d73Ub413Y5ndSBzcq8Q8nrcsj/lPfUv1xzQMKm0WVUymxU
 7hIognQQCcVIdUk3Ht33wJ3MQOs4kgrQ/VdVqvNRlqE3JpWvd9X4L1D3eUXq9TWV
 2nAQoDQC5LmdW8V1HiV4RKmWqQxdGBlIFXscwH8W4TmRLJXGHQbGi9M2sjch3ycr
 RY0INAN3WpjhI/2saJxkGBeP1HmyQnmxNkfYZLbcFAvStXkgCBI5PIaO0flhevFK
 K10jMPajFaojRZpkQTc9WOasyv8IGez0TrVIgA1WlJZE6BL+KoE=
 =/KnZ
 -----END PGP SIGNATURE-----

Merge tag 'reset-for-v5.15' of git://git.pengutronix.de/pza/linux into arm/drivers

Reset controller updates for v5.15

Add support for the SC7280 PDC Global and RZ/G2L USB/PHY reset
controllers, convert UniPhier glue device tree bindings to json-schema
and remove a leftover mention of ZTE zx2967 from Kconfig.

* tag 'reset-for-v5.15' of git://git.pengutronix.de/pza/linux:
  reset: simple: remove ZTE details in Kconfig help
  reset: renesas: Add RZ/G2L usbphy control driver
  dt-bindings: reset: Document RZ/G2L USBPHY Control bindings
  dt-bindings: reset: Convert UniPhier glue reset to json-schema
  reset: qcom: Add PDC Global reset signals for WPSS
  dt-bindings: reset: pdc: Add PDC Global bindings
  dt-bindings: reset: aoss: Add AOSS reset controller binding

Link: https://lore.kernel.org/r/d42a75fc17ce718ef1b3fa4c5d3f5c7fb0bd2bc2.camel@pengutronix.de
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2021-08-26 11:29:06 +02:00
commit 06779631d1
10 changed files with 398 additions and 73 deletions

View File

@ -21,6 +21,11 @@ properties:
- const: "qcom,sc7180-aoss-cc"
- const: "qcom,sdm845-aoss-cc"
- description: on SC7280 SoCs the following compatibles must be specified
items:
- const: "qcom,sc7280-aoss-cc"
- const: "qcom,sdm845-aoss-cc"
- description: on SDM845 SoCs the following compatibles must be specified
items:
- const: "qcom,sdm845-aoss-cc"

View File

@ -21,6 +21,10 @@ properties:
- const: "qcom,sc7180-pdc-global"
- const: "qcom,sdm845-pdc-global"
- description: on SC7280 SoCs the following compatibles must be specified
items:
- const: "qcom,sc7280-pdc-global"
- description: on SDM845 SoCs the following compatibles must be specified
items:
- const: "qcom,sdm845-pdc-global"

View File

@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/reset/renesas,rzg2l-usbphy-ctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/G2L USBPHY Control
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
description:
The RZ/G2L USBPHY Control mainly controls reset and power down of the
USB/PHY.
properties:
compatible:
items:
- enum:
- renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
- const: renesas,rzg2l-usbphy-ctrl
reg:
maxItems: 1
clocks:
maxItems: 1
resets:
maxItems: 1
power-domains:
maxItems: 1
'#reset-cells':
const: 1
description: |
The phandle's argument in the reset specifier is the PHY reset associated
with the USB port.
0 = Port 1 Phy reset
1 = Port 2 Phy reset
required:
- compatible
- reg
- clocks
- resets
- power-domains
- '#reset-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/r9a07g044-cpg.h>
phyrst: usbphy-ctrl@11c40000 {
compatible = "renesas,r9a07g044-usbphy-ctrl",
"renesas,rzg2l-usbphy-ctrl";
reg = <0x11c40000 0x10000>;
clocks = <&cpg CPG_MOD R9A07G044_USB_PCLK>;
resets = <&cpg R9A07G044_USB_PRESETN>;
power-domains = <&cpg>;
#reset-cells = <1>;
};

View File

@ -0,0 +1,88 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/reset/socionext,uniphier-glue-reset.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Socionext UniPhier peripheral core reset in glue layer
description: |
Some peripheral core reset belongs to its own glue layer. Before using
this core reset, it is necessary to control the clocks and resets to
enable this layer. These clocks and resets should be described in each
property.
maintainers:
- Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
properties:
compatible:
enum:
- socionext,uniphier-pro4-usb3-reset
- socionext,uniphier-pro5-usb3-reset
- socionext,uniphier-pxs2-usb3-reset
- socionext,uniphier-ld20-usb3-reset
- socionext,uniphier-pxs3-usb3-reset
- socionext,uniphier-pro4-ahci-reset
- socionext,uniphier-pxs2-ahci-reset
- socionext,uniphier-pxs3-ahci-reset
reg:
maxItems: 1
"#reset-cells":
const: 1
clocks:
minItems: 1
maxItems: 2
clock-names:
oneOf:
- items: # for Pro4, Pro5
- const: gio
- const: link
- items: # for others
- const: link
resets:
minItems: 1
maxItems: 2
reset-names:
oneOf:
- items: # for Pro4, Pro5
- const: gio
- const: link
- items: # for others
- const: link
additionalProperties: false
required:
- compatible
- reg
- "#reset-cells"
- clocks
- clock-names
- resets
- reset-names
examples:
- |
usb-glue@65b00000 {
compatible = "simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b00000 0x400>;
usb_rst: reset@0 {
compatible = "socionext,uniphier-ld20-usb3-reset";
reg = <0x0 0x4>;
#reset-cells = <1>;
clock-names = "link";
clocks = <&sys_clk 14>;
reset-names = "link";
resets = <&sys_rst 14>;
};
};

View File

@ -1,61 +0,0 @@
UniPhier glue reset controller
Peripheral core reset in glue layer
-----------------------------------
Some peripheral core reset belongs to its own glue layer. Before using
this core reset, it is necessary to control the clocks and resets to enable
this layer. These clocks and resets should be described in each property.
Required properties:
- compatible: Should be
"socionext,uniphier-pro4-usb3-reset" - for Pro4 SoC USB3
"socionext,uniphier-pro5-usb3-reset" - for Pro5 SoC USB3
"socionext,uniphier-pxs2-usb3-reset" - for PXs2 SoC USB3
"socionext,uniphier-ld20-usb3-reset" - for LD20 SoC USB3
"socionext,uniphier-pxs3-usb3-reset" - for PXs3 SoC USB3
"socionext,uniphier-pro4-ahci-reset" - for Pro4 SoC AHCI
"socionext,uniphier-pxs2-ahci-reset" - for PXs2 SoC AHCI
"socionext,uniphier-pxs3-ahci-reset" - for PXs3 SoC AHCI
- #reset-cells: Should be 1.
- reg: Specifies offset and length of the register set for the device.
- clocks: A list of phandles to the clock gate for the glue layer.
According to the clock-names, appropriate clocks are required.
- clock-names: Should contain
"gio", "link" - for Pro4 and Pro5 SoCs
"link" - for others
- resets: A list of phandles to the reset control for the glue layer.
According to the reset-names, appropriate resets are required.
- reset-names: Should contain
"gio", "link" - for Pro4 and Pro5 SoCs
"link" - for others
Example:
usb-glue@65b00000 {
compatible = "socionext,uniphier-ld20-dwc3-glue",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b00000 0x400>;
usb_rst: reset@0 {
compatible = "socionext,uniphier-ld20-usb3-reset";
reg = <0x0 0x4>;
#reset-cells = <1>;
clock-names = "link";
clocks = <&sys_clk 14>;
reset-names = "link";
resets = <&sys_rst 14>;
};
regulator {
...
};
phy {
...
};
...
};

View File

@ -181,6 +181,13 @@ config RESET_RASPBERRYPI
interfacing with RPi4's co-processor and model these firmware
initialization routines as reset lines.
config RESET_RZG2L_USBPHY_CTRL
tristate "Renesas RZ/G2L USBPHY control driver"
depends on ARCH_R9A07G044 || COMPILE_TEST
help
Support for USBPHY Control found on RZ/G2L family. It mainly
controls reset and power down of the USB/PHY.
config RESET_SCMI
tristate "Reset driver controlled via ARM SCMI interface"
depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
@ -207,7 +214,6 @@ config RESET_SIMPLE
- Realtek SoCs
- RCC reset controller in STM32 MCUs
- Allwinner SoCs
- ZTE's zx2967 family
- SiFive FU740 SoCs
config RESET_SOCFPGA

View File

@ -25,6 +25,7 @@ obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o

View File

@ -11,18 +11,26 @@
#include <dt-bindings/reset/qcom,sdm845-pdc.h>
#define RPMH_PDC_SYNC_RESET 0x100
#define RPMH_SDM845_PDC_SYNC_RESET 0x100
#define RPMH_SC7280_PDC_SYNC_RESET 0x1000
struct qcom_pdc_reset_map {
u8 bit;
};
struct qcom_pdc_reset_desc {
const struct qcom_pdc_reset_map *resets;
size_t num_resets;
unsigned int offset;
};
struct qcom_pdc_reset_data {
struct reset_controller_dev rcdev;
struct regmap *regmap;
const struct qcom_pdc_reset_desc *desc;
};
static const struct regmap_config sdm845_pdc_regmap_config = {
static const struct regmap_config pdc_regmap_config = {
.name = "pdc-reset",
.reg_bits = 32,
.reg_stride = 4,
@ -44,6 +52,33 @@ static const struct qcom_pdc_reset_map sdm845_pdc_resets[] = {
[PDC_MODEM_SYNC_RESET] = {9},
};
static const struct qcom_pdc_reset_desc sdm845_pdc_reset_desc = {
.resets = sdm845_pdc_resets,
.num_resets = ARRAY_SIZE(sdm845_pdc_resets),
.offset = RPMH_SDM845_PDC_SYNC_RESET,
};
static const struct qcom_pdc_reset_map sc7280_pdc_resets[] = {
[PDC_APPS_SYNC_RESET] = {0},
[PDC_SP_SYNC_RESET] = {1},
[PDC_AUDIO_SYNC_RESET] = {2},
[PDC_SENSORS_SYNC_RESET] = {3},
[PDC_AOP_SYNC_RESET] = {4},
[PDC_DEBUG_SYNC_RESET] = {5},
[PDC_GPU_SYNC_RESET] = {6},
[PDC_DISPLAY_SYNC_RESET] = {7},
[PDC_COMPUTE_SYNC_RESET] = {8},
[PDC_MODEM_SYNC_RESET] = {9},
[PDC_WLAN_RF_SYNC_RESET] = {10},
[PDC_WPSS_SYNC_RESET] = {11},
};
static const struct qcom_pdc_reset_desc sc7280_pdc_reset_desc = {
.resets = sc7280_pdc_resets,
.num_resets = ARRAY_SIZE(sc7280_pdc_resets),
.offset = RPMH_SC7280_PDC_SYNC_RESET,
};
static inline struct qcom_pdc_reset_data *to_qcom_pdc_reset_data(
struct reset_controller_dev *rcdev)
{
@ -54,19 +89,18 @@ static int qcom_pdc_control_assert(struct reset_controller_dev *rcdev,
unsigned long idx)
{
struct qcom_pdc_reset_data *data = to_qcom_pdc_reset_data(rcdev);
u32 mask = BIT(data->desc->resets[idx].bit);
return regmap_update_bits(data->regmap, RPMH_PDC_SYNC_RESET,
BIT(sdm845_pdc_resets[idx].bit),
BIT(sdm845_pdc_resets[idx].bit));
return regmap_update_bits(data->regmap, data->desc->offset, mask, mask);
}
static int qcom_pdc_control_deassert(struct reset_controller_dev *rcdev,
unsigned long idx)
{
struct qcom_pdc_reset_data *data = to_qcom_pdc_reset_data(rcdev);
u32 mask = BIT(data->desc->resets[idx].bit);
return regmap_update_bits(data->regmap, RPMH_PDC_SYNC_RESET,
BIT(sdm845_pdc_resets[idx].bit), 0);
return regmap_update_bits(data->regmap, data->desc->offset, mask, 0);
}
static const struct reset_control_ops qcom_pdc_reset_ops = {
@ -76,22 +110,27 @@ static const struct reset_control_ops qcom_pdc_reset_ops = {
static int qcom_pdc_reset_probe(struct platform_device *pdev)
{
const struct qcom_pdc_reset_desc *desc;
struct qcom_pdc_reset_data *data;
struct device *dev = &pdev->dev;
void __iomem *base;
struct resource *res;
desc = device_get_match_data(&pdev->dev);
if (!desc)
return -EINVAL;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->desc = desc;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
data->regmap = devm_regmap_init_mmio(dev, base,
&sdm845_pdc_regmap_config);
data->regmap = devm_regmap_init_mmio(dev, base, &pdc_regmap_config);
if (IS_ERR(data->regmap)) {
dev_err(dev, "Unable to initialize regmap\n");
return PTR_ERR(data->regmap);
@ -99,14 +138,15 @@ static int qcom_pdc_reset_probe(struct platform_device *pdev)
data->rcdev.owner = THIS_MODULE;
data->rcdev.ops = &qcom_pdc_reset_ops;
data->rcdev.nr_resets = ARRAY_SIZE(sdm845_pdc_resets);
data->rcdev.nr_resets = desc->num_resets;
data->rcdev.of_node = dev->of_node;
return devm_reset_controller_register(dev, &data->rcdev);
}
static const struct of_device_id qcom_pdc_reset_of_match[] = {
{ .compatible = "qcom,sdm845-pdc-global" },
{ .compatible = "qcom,sc7280-pdc-global", .data = &sc7280_pdc_reset_desc },
{ .compatible = "qcom,sdm845-pdc-global", .data = &sdm845_pdc_reset_desc },
{}
};
MODULE_DEVICE_TABLE(of, qcom_pdc_reset_of_match);

View File

@ -0,0 +1,175 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas RZ/G2L USBPHY control driver
*
* Copyright (C) 2021 Renesas Electronics Corporation
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
#define RESET 0x000
#define RESET_SEL_PLLRESET BIT(12)
#define RESET_PLLRESET BIT(8)
#define RESET_SEL_P2RESET BIT(5)
#define RESET_SEL_P1RESET BIT(4)
#define RESET_PHYRST_2 BIT(1)
#define RESET_PHYRST_1 BIT(0)
#define PHY_RESET_PORT2 (RESET_SEL_P2RESET | RESET_PHYRST_2)
#define PHY_RESET_PORT1 (RESET_SEL_P1RESET | RESET_PHYRST_1)
#define NUM_PORTS 2
struct rzg2l_usbphy_ctrl_priv {
struct reset_controller_dev rcdev;
struct reset_control *rstc;
void __iomem *base;
spinlock_t lock;
};
#define rcdev_to_priv(x) container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)
static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
u32 port_mask = PHY_RESET_PORT1 | PHY_RESET_PORT2;
void __iomem *base = priv->base;
unsigned long flags;
u32 val;
spin_lock_irqsave(&priv->lock, flags);
val = readl(base + RESET);
val |= id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;
if (port_mask == (val & port_mask))
val |= RESET_PLLRESET;
writel(val, base + RESET);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int rzg2l_usbphy_ctrl_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
void __iomem *base = priv->base;
unsigned long flags;
u32 val;
spin_lock_irqsave(&priv->lock, flags);
val = readl(base + RESET);
val |= RESET_SEL_PLLRESET;
val &= ~(RESET_PLLRESET | (id ? PHY_RESET_PORT2 : PHY_RESET_PORT1));
writel(val, base + RESET);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
u32 port_mask;
port_mask = id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;
return !!(readl(priv->base + RESET) & port_mask);
}
static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table);
static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = {
.assert = rzg2l_usbphy_ctrl_assert,
.deassert = rzg2l_usbphy_ctrl_deassert,
.status = rzg2l_usbphy_ctrl_status,
};
static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rzg2l_usbphy_ctrl_priv *priv;
unsigned long flags;
int error;
u32 val;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(priv->rstc))
return dev_err_probe(dev, PTR_ERR(priv->rstc),
"failed to get reset\n");
reset_control_deassert(priv->rstc);
priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops;
priv->rcdev.of_reset_n_cells = 1;
priv->rcdev.nr_resets = NUM_PORTS;
priv->rcdev.of_node = dev->of_node;
priv->rcdev.dev = dev;
error = devm_reset_controller_register(dev, &priv->rcdev);
if (error)
return error;
spin_lock_init(&priv->lock);
dev_set_drvdata(dev, priv);
pm_runtime_enable(&pdev->dev);
pm_runtime_resume_and_get(&pdev->dev);
/* put pll and phy into reset state */
spin_lock_irqsave(&priv->lock, flags);
val = readl(priv->base + RESET);
val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1;
writel(val, priv->base + RESET);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
{
struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
reset_control_assert(priv->rstc);
return 0;
}
static struct platform_driver rzg2l_usbphy_ctrl_driver = {
.driver = {
.name = "rzg2l_usbphy_ctrl",
.of_match_table = rzg2l_usbphy_ctrl_match_table,
},
.probe = rzg2l_usbphy_ctrl_probe,
.remove = rzg2l_usbphy_ctrl_remove,
};
module_platform_driver(rzg2l_usbphy_ctrl_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas RZ/G2L USBPHY Control");
MODULE_AUTHOR("biju.das.jz@bp.renesas.com>");

View File

@ -16,5 +16,7 @@
#define PDC_DISPLAY_SYNC_RESET 7
#define PDC_COMPUTE_SYNC_RESET 8
#define PDC_MODEM_SYNC_RESET 9
#define PDC_WLAN_RF_SYNC_RESET 10
#define PDC_WPSS_SYNC_RESET 11
#endif