mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 12:24:34 +08:00
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:
commit
06779631d1
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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>;
|
||||
};
|
@ -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>;
|
||||
};
|
||||
};
|
@ -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 {
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
175
drivers/reset/reset-rzg2l-usbphy-ctrl.c
Normal file
175
drivers/reset/reset-rzg2l-usbphy-ctrl.c
Normal 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>");
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user