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
about zynqmp resets.
@ -10,7 +10,8 @@ Please also refer to reset.txt in this directory for common reset
controller binding usage.
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
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
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>
For list of all valid reset indices for Versal see
<dt-bindings/reset/xlnx-versal-resets.h>
Example:

View File

@ -65,9 +65,10 @@ config RESET_HSDK
This enables the reset controller driver for HSDK board.
config RESET_IMX7
bool "i.MX7/8 Reset Driver" if COMPILE_TEST
tristate "i.MX7/8 Reset Driver"
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
help
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
* @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?
* @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
* only used for shared resets, which means that the value
* will be either 0 or 1.

View File

@ -8,7 +8,7 @@
*/
#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.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_L2RESET] = { SRC_A53RCR0, BIT(21) },
[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_OTG2_PHY_RESET] = { SRC_USBOPHY2_RCR, BIT(0) },
[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_RESET_N: /* fallthrough */
case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N: /* fallthrough */
case IMX8MQ_RESET_M4_ENABLE:
value = assert ? 0 : bit;
break;
}
@ -386,6 +390,7 @@ static const struct of_device_id imx7_reset_dt_ids[] = {
{ .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx7_reset_dt_ids);
static struct platform_driver imx7_reset_driver = {
.probe = imx7_reset_probe,
@ -394,4 +399,8 @@ static struct platform_driver imx7_reset_driver = {
.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/reset-controller.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_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 reset_controller_dev rcdev;
const struct zynqmp_reset_soc_data *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,
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);
}
static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev,
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);
}
static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
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)
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,
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);
}
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 = {
.reset = zynqmp_reset_reset,
.assert = zynqmp_reset_assert,
@ -71,18 +102,25 @@ static int zynqmp_reset_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
priv->data = of_device_get_match_data(&pdev->dev);
if (!priv->data)
return -EINVAL;
platform_set_drvdata(pdev, priv);
priv->rcdev.ops = &zynqmp_reset_ops;
priv->rcdev.owner = THIS_MODULE;
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);
}
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 */ },
};

View File

@ -17,7 +17,7 @@
#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.
* @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
* may be located in different system configuration registers.
* struct syscfg_reset_controller - A reset controller which groups together
* a set of related reset bits, which may be located in different system
* configuration registers.
*
* @rst: base reset controller structure.
* @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_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_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

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