Reset controller updates for v5.10

This tag allows to build reset-imx7 as a module, and adds support to
 reset the Cortex-M4 processor on i.MX8MQ to it, adds support for the
 Versal platform to the reset-zynqmp driver, and fixes some kerneldoc
 comments in the core and in sti/reset-syscfg.
 -----BEGIN PGP SIGNATURE-----
 
 iI0EABYIADUWIQRRO6F6WdpH1R0vGibVhaclGDdiwAUCX2tCQxcccC56YWJlbEBw
 ZW5ndXRyb25peC5kZQAKCRDVhaclGDdiwNnQAQDnOhM1615HbwZ0YZM+jHC8U8+e
 DfzXfsANHTffGJ4kZQEA1Z9uELtzsgQrrrtq3PaVVbYXGUcv2enMAO1AUD/0jwQ=
 =zNMu
 -----END PGP SIGNATURE-----

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

Reset controller updates for v5.10

This tag allows to build reset-imx7 as a module, and adds support to
reset the Cortex-M4 processor on i.MX8MQ to it, adds support for the
Versal platform to the reset-zynqmp driver, and fixes some kerneldoc
comments in the core and in sti/reset-syscfg.

* tag 'reset-for-v5.10' of git://git.pengutronix.de/pza/linux:
  reset: sti: reset-syscfg: fix struct description warnings
  reset: imx7: add the cm4 reset for i.MX8MQ
  dt-bindings: reset: imx8mq: add m4 reset
  reset: Fix and extend kerneldoc
  reset: reset-zynqmp: Added support for Versal platform
  dt-bindings: reset: Updated binding for Versal reset driver
  reset: imx7: Support module build

Link: https://lore.kernel.org/r/2b77c90d2b970eb8fa09000b9ecb564bffa76374.camel@pengutronix.de
Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2020-10-03 13:02:07 -07:00
commit c8952516e8
8 changed files with 180 additions and 19 deletions

View File

@ -1,7 +1,7 @@
-------------------------------------------------------------------------- --------------------------------------------------------------------------
= Zynq UltraScale+ MPSoC reset driver binding = = Zynq UltraScale+ MPSoC and Versal reset driver binding =
-------------------------------------------------------------------------- --------------------------------------------------------------------------
The Zynq UltraScale+ MPSoC has several different resets. The Zynq UltraScale+ MPSoC and Versal has several different resets.
See Chapter 36 of the Zynq UltraScale+ MPSoC TRM (UG) for more information See Chapter 36 of the Zynq UltraScale+ MPSoC TRM (UG) for more information
about zynqmp resets. about zynqmp resets.
@ -10,7 +10,8 @@ Please also refer to reset.txt in this directory for common reset
controller binding usage. controller binding usage.
Required Properties: Required Properties:
- compatible: "xlnx,zynqmp-reset" - compatible: "xlnx,zynqmp-reset" for Zynq UltraScale+ MPSoC platform
"xlnx,versal-reset" for Versal platform
- #reset-cells: Specifies the number of cells needed to encode reset - #reset-cells: Specifies the number of cells needed to encode reset
line, should be 1 line, should be 1
@ -37,8 +38,10 @@ Device nodes that need access to reset lines should
specify them as a reset phandle in their corresponding node as specify them as a reset phandle in their corresponding node as
specified in reset.txt. specified in reset.txt.
For list of all valid reset indicies see For list of all valid reset indices for Zynq UltraScale+ MPSoC see
<dt-bindings/reset/xlnx-zynqmp-resets.h> <dt-bindings/reset/xlnx-zynqmp-resets.h>
For list of all valid reset indices for Versal see
<dt-bindings/reset/xlnx-versal-resets.h>
Example: Example:

View File

@ -65,9 +65,10 @@ config RESET_HSDK
This enables the reset controller driver for HSDK board. This enables the reset controller driver for HSDK board.
config RESET_IMX7 config RESET_IMX7
bool "i.MX7/8 Reset Driver" if COMPILE_TEST tristate "i.MX7/8 Reset Driver"
depends on HAS_IOMEM depends on HAS_IOMEM
default SOC_IMX7D || (ARM64 && ARCH_MXC) depends on SOC_IMX7D || (ARM64 && ARCH_MXC) || COMPILE_TEST
default y if SOC_IMX7D
select MFD_SYSCON select MFD_SYSCON
help help
This enables the reset controller driver for i.MX7 SoCs. This enables the reset controller driver for i.MX7 SoCs.

View File

@ -32,7 +32,8 @@ static LIST_HEAD(reset_lookup_list);
* @refcnt: Number of gets of this reset_control * @refcnt: Number of gets of this reset_control
* @acquired: Only one reset_control may be acquired for a given rcdev and id. * @acquired: Only one reset_control may be acquired for a given rcdev and id.
* @shared: Is this a shared (1), or an exclusive (0) reset_control? * @shared: Is this a shared (1), or an exclusive (0) reset_control?
* @deassert_cnt: Number of times this reset line has been deasserted * @array: Is this an array of reset controls (1)?
* @deassert_count: Number of times this reset line has been deasserted
* @triggered_count: Number of times this reset line has been reset. Currently * @triggered_count: Number of times this reset line has been reset. Currently
* only used for shared resets, which means that the value * only used for shared resets, which means that the value
* will be either 0 or 1. * will be either 0 or 1.

View File

@ -8,7 +8,7 @@
*/ */
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset-controller.h> #include <linux/reset-controller.h>
@ -178,6 +178,9 @@ static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
[IMX8MQ_RESET_A53_SOC_DBG_RESET] = { SRC_A53RCR0, BIT(20) }, [IMX8MQ_RESET_A53_SOC_DBG_RESET] = { SRC_A53RCR0, BIT(20) },
[IMX8MQ_RESET_A53_L2RESET] = { SRC_A53RCR0, BIT(21) }, [IMX8MQ_RESET_A53_L2RESET] = { SRC_A53RCR0, BIT(21) },
[IMX8MQ_RESET_SW_NON_SCLR_M4C_RST] = { SRC_M4RCR, BIT(0) }, [IMX8MQ_RESET_SW_NON_SCLR_M4C_RST] = { SRC_M4RCR, BIT(0) },
[IMX8MQ_RESET_SW_M4C_RST] = { SRC_M4RCR, BIT(1) },
[IMX8MQ_RESET_SW_M4P_RST] = { SRC_M4RCR, BIT(2) },
[IMX8MQ_RESET_M4_ENABLE] = { SRC_M4RCR, BIT(3) },
[IMX8MQ_RESET_OTG1_PHY_RESET] = { SRC_USBOPHY1_RCR, BIT(0) }, [IMX8MQ_RESET_OTG1_PHY_RESET] = { SRC_USBOPHY1_RCR, BIT(0) },
[IMX8MQ_RESET_OTG2_PHY_RESET] = { SRC_USBOPHY2_RCR, BIT(0) }, [IMX8MQ_RESET_OTG2_PHY_RESET] = { SRC_USBOPHY2_RCR, BIT(0) },
[IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N] = { SRC_MIPIPHY_RCR, BIT(1) }, [IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N] = { SRC_MIPIPHY_RCR, BIT(1) },
@ -238,6 +241,7 @@ static int imx8mq_reset_set(struct reset_controller_dev *rcdev,
case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N: /* fallthrough */ case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N: /* fallthrough */
case IMX8MQ_RESET_MIPI_DSI_RESET_N: /* fallthrough */ case IMX8MQ_RESET_MIPI_DSI_RESET_N: /* fallthrough */
case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N: /* fallthrough */ case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N: /* fallthrough */
case IMX8MQ_RESET_M4_ENABLE:
value = assert ? 0 : bit; value = assert ? 0 : bit;
break; break;
} }
@ -386,6 +390,7 @@ static const struct of_device_id imx7_reset_dt_ids[] = {
{ .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp }, { .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp },
{ /* sentinel */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(of, imx7_reset_dt_ids);
static struct platform_driver imx7_reset_driver = { static struct platform_driver imx7_reset_driver = {
.probe = imx7_reset_probe, .probe = imx7_reset_probe,
@ -394,4 +399,8 @@ static struct platform_driver imx7_reset_driver = {
.of_match_table = imx7_reset_dt_ids, .of_match_table = imx7_reset_dt_ids,
}, },
}; };
builtin_platform_driver(imx7_reset_driver); module_platform_driver(imx7_reset_driver);
MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
MODULE_DESCRIPTION("NXP i.MX7 reset driver");
MODULE_LICENSE("GPL v2");

View File

@ -9,12 +9,20 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset-controller.h> #include <linux/reset-controller.h>
#include <linux/firmware/xlnx-zynqmp.h> #include <linux/firmware/xlnx-zynqmp.h>
#include <linux/of_device.h>
#define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START) #define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
#define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START #define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START
#define VERSAL_NR_RESETS 95
struct zynqmp_reset_soc_data {
u32 reset_id;
u32 num_resets;
};
struct zynqmp_reset_data { struct zynqmp_reset_data {
struct reset_controller_dev rcdev; struct reset_controller_dev rcdev;
const struct zynqmp_reset_soc_data *data;
}; };
static inline struct zynqmp_reset_data * static inline struct zynqmp_reset_data *
@ -26,23 +34,28 @@ to_zynqmp_reset_data(struct reset_controller_dev *rcdev)
static int zynqmp_reset_assert(struct reset_controller_dev *rcdev, static int zynqmp_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id) unsigned long id)
{ {
return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id, struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
return zynqmp_pm_reset_assert(priv->data->reset_id + id,
PM_RESET_ACTION_ASSERT); PM_RESET_ACTION_ASSERT);
} }
static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev, static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id) unsigned long id)
{ {
return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id, struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
return zynqmp_pm_reset_assert(priv->data->reset_id + id,
PM_RESET_ACTION_RELEASE); PM_RESET_ACTION_RELEASE);
} }
static int zynqmp_reset_status(struct reset_controller_dev *rcdev, static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
unsigned long id) unsigned long id)
{ {
struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
int val, err; int val, err;
err = zynqmp_pm_reset_get_status(ZYNQMP_RESET_ID + id, &val); err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
if (err) if (err)
return err; return err;
@ -52,10 +65,28 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
static int zynqmp_reset_reset(struct reset_controller_dev *rcdev, static int zynqmp_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id) unsigned long id)
{ {
return zynqmp_pm_reset_assert(ZYNQMP_RESET_ID + id, struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
return zynqmp_pm_reset_assert(priv->data->reset_id + id,
PM_RESET_ACTION_PULSE); PM_RESET_ACTION_PULSE);
} }
static int zynqmp_reset_of_xlate(struct reset_controller_dev *rcdev,
const struct of_phandle_args *reset_spec)
{
return reset_spec->args[0];
}
static const struct zynqmp_reset_soc_data zynqmp_reset_data = {
.reset_id = ZYNQMP_RESET_ID,
.num_resets = ZYNQMP_NR_RESETS,
};
static const struct zynqmp_reset_soc_data versal_reset_data = {
.reset_id = 0,
.num_resets = VERSAL_NR_RESETS,
};
static const struct reset_control_ops zynqmp_reset_ops = { static const struct reset_control_ops zynqmp_reset_ops = {
.reset = zynqmp_reset_reset, .reset = zynqmp_reset_reset,
.assert = zynqmp_reset_assert, .assert = zynqmp_reset_assert,
@ -71,18 +102,25 @@ static int zynqmp_reset_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->data = of_device_get_match_data(&pdev->dev);
if (!priv->data)
return -EINVAL;
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
priv->rcdev.ops = &zynqmp_reset_ops; priv->rcdev.ops = &zynqmp_reset_ops;
priv->rcdev.owner = THIS_MODULE; priv->rcdev.owner = THIS_MODULE;
priv->rcdev.of_node = pdev->dev.of_node; priv->rcdev.of_node = pdev->dev.of_node;
priv->rcdev.nr_resets = ZYNQMP_NR_RESETS; priv->rcdev.nr_resets = priv->data->num_resets;
priv->rcdev.of_reset_n_cells = 1;
priv->rcdev.of_xlate = zynqmp_reset_of_xlate;
return devm_reset_controller_register(&pdev->dev, &priv->rcdev); return devm_reset_controller_register(&pdev->dev, &priv->rcdev);
} }
static const struct of_device_id zynqmp_reset_dt_ids[] = { static const struct of_device_id zynqmp_reset_dt_ids[] = {
{ .compatible = "xlnx,zynqmp-reset", }, { .compatible = "xlnx,zynqmp-reset", .data = &zynqmp_reset_data, },
{ .compatible = "xlnx,versal-reset", .data = &versal_reset_data, },
{ /* sentinel */ }, { /* sentinel */ },
}; };

View File

@ -17,7 +17,7 @@
#include "reset-syscfg.h" #include "reset-syscfg.h"
/** /**
* Reset channel regmap configuration * struct syscfg_reset_channel - Reset channel regmap configuration
* *
* @reset: regmap field for the channel's reset bit. * @reset: regmap field for the channel's reset bit.
* @ack: regmap field for the channel's ack bit (optional). * @ack: regmap field for the channel's ack bit (optional).
@ -28,8 +28,9 @@ struct syscfg_reset_channel {
}; };
/** /**
* A reset controller which groups together a set of related reset bits, which * struct syscfg_reset_controller - A reset controller which groups together
* may be located in different system configuration registers. * a set of related reset bits, which may be located in different system
* configuration registers.
* *
* @rst: base reset controller structure. * @rst: base reset controller structure.
* @active_low: are the resets in this controller active low, i.e. clearing * @active_low: are the resets in this controller active low, i.e. clearing

View File

@ -58,7 +58,10 @@
#define IMX8MQ_RESET_DDRC2_PRST 47 /* i.MX8MM/i.MX8MN does NOT support */ #define IMX8MQ_RESET_DDRC2_PRST 47 /* i.MX8MM/i.MX8MN does NOT support */
#define IMX8MQ_RESET_DDRC2_CORE_RESET 48 /* i.MX8MM/i.MX8MN does NOT support */ #define IMX8MQ_RESET_DDRC2_CORE_RESET 48 /* i.MX8MM/i.MX8MN does NOT support */
#define IMX8MQ_RESET_DDRC2_PHY_RESET 49 /* i.MX8MM/i.MX8MN does NOT support */ #define IMX8MQ_RESET_DDRC2_PHY_RESET 49 /* i.MX8MM/i.MX8MN does NOT support */
#define IMX8MQ_RESET_SW_M4C_RST 50
#define IMX8MQ_RESET_SW_M4P_RST 51
#define IMX8MQ_RESET_M4_ENABLE 52
#define IMX8MQ_RESET_NUM 50 #define IMX8MQ_RESET_NUM 53
#endif #endif

View File

@ -0,0 +1,105 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 Xilinx, Inc.
*/
#ifndef _DT_BINDINGS_VERSAL_RESETS_H
#define _DT_BINDINGS_VERSAL_RESETS_H
#define VERSAL_RST_PMC_POR (0xc30c001U)
#define VERSAL_RST_PMC (0xc410002U)
#define VERSAL_RST_PS_POR (0xc30c003U)
#define VERSAL_RST_PL_POR (0xc30c004U)
#define VERSAL_RST_NOC_POR (0xc30c005U)
#define VERSAL_RST_FPD_POR (0xc30c006U)
#define VERSAL_RST_ACPU_0_POR (0xc30c007U)
#define VERSAL_RST_ACPU_1_POR (0xc30c008U)
#define VERSAL_RST_OCM2_POR (0xc30c009U)
#define VERSAL_RST_PS_SRST (0xc41000aU)
#define VERSAL_RST_PL_SRST (0xc41000bU)
#define VERSAL_RST_NOC (0xc41000cU)
#define VERSAL_RST_NPI (0xc41000dU)
#define VERSAL_RST_SYS_RST_1 (0xc41000eU)
#define VERSAL_RST_SYS_RST_2 (0xc41000fU)
#define VERSAL_RST_SYS_RST_3 (0xc410010U)
#define VERSAL_RST_FPD (0xc410011U)
#define VERSAL_RST_PL0 (0xc410012U)
#define VERSAL_RST_PL1 (0xc410013U)
#define VERSAL_RST_PL2 (0xc410014U)
#define VERSAL_RST_PL3 (0xc410015U)
#define VERSAL_RST_APU (0xc410016U)
#define VERSAL_RST_ACPU_0 (0xc410017U)
#define VERSAL_RST_ACPU_1 (0xc410018U)
#define VERSAL_RST_ACPU_L2 (0xc410019U)
#define VERSAL_RST_ACPU_GIC (0xc41001aU)
#define VERSAL_RST_RPU_ISLAND (0xc41001bU)
#define VERSAL_RST_RPU_AMBA (0xc41001cU)
#define VERSAL_RST_R5_0 (0xc41001dU)
#define VERSAL_RST_R5_1 (0xc41001eU)
#define VERSAL_RST_SYSMON_PMC_SEQ_RST (0xc41001fU)
#define VERSAL_RST_SYSMON_PMC_CFG_RST (0xc410020U)
#define VERSAL_RST_SYSMON_FPD_CFG_RST (0xc410021U)
#define VERSAL_RST_SYSMON_FPD_SEQ_RST (0xc410022U)
#define VERSAL_RST_SYSMON_LPD (0xc410023U)
#define VERSAL_RST_PDMA_RST1 (0xc410024U)
#define VERSAL_RST_PDMA_RST0 (0xc410025U)
#define VERSAL_RST_ADMA (0xc410026U)
#define VERSAL_RST_TIMESTAMP (0xc410027U)
#define VERSAL_RST_OCM (0xc410028U)
#define VERSAL_RST_OCM2_RST (0xc410029U)
#define VERSAL_RST_IPI (0xc41002aU)
#define VERSAL_RST_SBI (0xc41002bU)
#define VERSAL_RST_LPD (0xc41002cU)
#define VERSAL_RST_QSPI (0xc10402dU)
#define VERSAL_RST_OSPI (0xc10402eU)
#define VERSAL_RST_SDIO_0 (0xc10402fU)
#define VERSAL_RST_SDIO_1 (0xc104030U)
#define VERSAL_RST_I2C_PMC (0xc104031U)
#define VERSAL_RST_GPIO_PMC (0xc104032U)
#define VERSAL_RST_GEM_0 (0xc104033U)
#define VERSAL_RST_GEM_1 (0xc104034U)
#define VERSAL_RST_SPARE (0xc104035U)
#define VERSAL_RST_USB_0 (0xc104036U)
#define VERSAL_RST_UART_0 (0xc104037U)
#define VERSAL_RST_UART_1 (0xc104038U)
#define VERSAL_RST_SPI_0 (0xc104039U)
#define VERSAL_RST_SPI_1 (0xc10403aU)
#define VERSAL_RST_CAN_FD_0 (0xc10403bU)
#define VERSAL_RST_CAN_FD_1 (0xc10403cU)
#define VERSAL_RST_I2C_0 (0xc10403dU)
#define VERSAL_RST_I2C_1 (0xc10403eU)
#define VERSAL_RST_GPIO_LPD (0xc10403fU)
#define VERSAL_RST_TTC_0 (0xc104040U)
#define VERSAL_RST_TTC_1 (0xc104041U)
#define VERSAL_RST_TTC_2 (0xc104042U)
#define VERSAL_RST_TTC_3 (0xc104043U)
#define VERSAL_RST_SWDT_FPD (0xc104044U)
#define VERSAL_RST_SWDT_LPD (0xc104045U)
#define VERSAL_RST_USB (0xc104046U)
#define VERSAL_RST_DPC (0xc208047U)
#define VERSAL_RST_PMCDBG (0xc208048U)
#define VERSAL_RST_DBG_TRACE (0xc208049U)
#define VERSAL_RST_DBG_FPD (0xc20804aU)
#define VERSAL_RST_DBG_TSTMP (0xc20804bU)
#define VERSAL_RST_RPU0_DBG (0xc20804cU)
#define VERSAL_RST_RPU1_DBG (0xc20804dU)
#define VERSAL_RST_HSDP (0xc20804eU)
#define VERSAL_RST_DBG_LPD (0xc20804fU)
#define VERSAL_RST_CPM_POR (0xc30c050U)
#define VERSAL_RST_CPM (0xc410051U)
#define VERSAL_RST_CPMDBG (0xc208052U)
#define VERSAL_RST_PCIE_CFG (0xc410053U)
#define VERSAL_RST_PCIE_CORE0 (0xc410054U)
#define VERSAL_RST_PCIE_CORE1 (0xc410055U)
#define VERSAL_RST_PCIE_DMA (0xc410056U)
#define VERSAL_RST_CMN (0xc410057U)
#define VERSAL_RST_L2_0 (0xc410058U)
#define VERSAL_RST_L2_1 (0xc410059U)
#define VERSAL_RST_ADDR_REMAP (0xc41005aU)
#define VERSAL_RST_CPI0 (0xc41005bU)
#define VERSAL_RST_CPI1 (0xc41005cU)
#define VERSAL_RST_XRAM (0xc30c05dU)
#define VERSAL_RST_AIE_ARRAY (0xc10405eU)
#define VERSAL_RST_AIE_SHIM (0xc10405fU)
#endif