This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 25e7b48c7e mpfs/mpfs_rcc: Add stub driver for FPGA clock and reset
controller
25e7b48c7e is described below
commit 25e7b48c7eb6ee9fec27e8f13d06749c4c2c0b8c
Author: Ville Juven <[email protected]>
AuthorDate: Thu Mar 20 13:42:45 2025 +0200
mpfs/mpfs_rcc: Add stub driver for FPGA clock and reset controller
This patch adds a driver framework to control individual FPGA reset and
clock gates.
For FPGA devices, only the fabric (FIC0/FIC1/FIC3) clock and reset can be
controlled, which affects the whole fabric / domain. This is problematic
for obvious reasons.
For MSS peripherals, clocks and reset are controlled individually for each
peripheral via MSS memory mapped registers (MPFS_SYSREG). To get the same
capability for FPGA peripherals, the same controller needs to be
fabricated on the FPGA.
However, the FPGA clock/reset controller is entirely user dependent, so a
generic implementation is not possible. However, a generic driver is
needed in order to build the current FPGA peripheral drivers. A stub
implementation of the driver is provided in order to achieve this.
Signed-off-by: Ville Juven <[email protected]>
---
arch/risc-v/src/mpfs/Kconfig | 6 ++
arch/risc-v/src/mpfs/Make.defs | 3 +
arch/risc-v/src/mpfs/hardware/mpfs_sysreg.h | 5 ++
arch/risc-v/src/mpfs/mpfs_corepwm.c | 26 +++++-
arch/risc-v/src/mpfs/mpfs_corespi.c | 6 ++
arch/risc-v/src/mpfs/mpfs_i2c.c | 6 ++
arch/risc-v/src/mpfs/mpfs_rcc.c | 99 +++++++++++++++++++++++
arch/risc-v/src/mpfs/mpfs_rcc.h | 121 ++++++++++++++++++++++++++++
8 files changed, 271 insertions(+), 1 deletion(-)
diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig
index 9cc1b3c23f..fdb514625f 100644
--- a/arch/risc-v/src/mpfs/Kconfig
+++ b/arch/risc-v/src/mpfs/Kconfig
@@ -828,6 +828,12 @@ config MPFS_MPUCFG
---help---
Enable driver to set MPUCFG entries.
+config MPFS_RCC
+ bool "Enable Reset and Clock Controller (RCC) driver"
+ default y
+ ---help---
+ Enable driver for reset / clock controller.
+
config MPFS_HAVE_CORERMII
bool "CoreRMII FPGA IP block configured"
default n
diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs
index 3508114049..5e856643de 100644
--- a/arch/risc-v/src/mpfs/Make.defs
+++ b/arch/risc-v/src/mpfs/Make.defs
@@ -122,3 +122,6 @@ ifeq ($(CONFIG_MPFS_MPUCFG),y)
CHIP_CSRCS += mpfs_mpu.c
endif
+ifeq ($(CONFIG_MPFS_RCC),y)
+CHIP_CSRCS += mpfs_rcc.c
+endif
diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_sysreg.h
b/arch/risc-v/src/mpfs/hardware/mpfs_sysreg.h
index ed2ebb8370..ca769647ba 100644
--- a/arch/risc-v/src/mpfs/hardware/mpfs_sysreg.h
+++ b/arch/risc-v/src/mpfs/hardware/mpfs_sysreg.h
@@ -137,6 +137,11 @@
#define MPFS_SYSREG_SPARE_PERIM_RW_OFFSET 0x02DC /* Spare signal
back to G5C */
#define MPFS_SYSREG_SPARE_FIC_OFFSET 0x02E0 /* Unused FIC
resets */
+#define MPFS_SYSREG_SOFT_RESET_CR (MPFS_SYSREG_BASE + \
+ MPFS_SYSREG_SOFT_RESET_CR_OFFSET)
+#define MPFS_SYSREG_SUBBLK_CLOCK_CR (MPFS_SYSREG_BASE + \
+ MPFS_SYSREG_SUBBLK_CLOCK_CR_OFFSET)
+
/* Register bit field definitions *******************************************/
/* CLOCK_CONFIG_CR:
diff --git a/arch/risc-v/src/mpfs/mpfs_corepwm.c
b/arch/risc-v/src/mpfs/mpfs_corepwm.c
index dcdc4bbc73..31bc7039d6 100644
--- a/arch/risc-v/src/mpfs/mpfs_corepwm.c
+++ b/arch/risc-v/src/mpfs/mpfs_corepwm.c
@@ -44,7 +44,11 @@
#include <arch/board/board.h>
+#include "mpfs_rcc.h"
+
+#include "hardware/mpfs_memorymap.h"
#include "hardware/mpfs_corepwm.h"
+#include "hardware/mpfs_sysreg.h"
#include "riscv_internal.h"
/****************************************************************************
@@ -752,6 +756,25 @@ static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd,
return -ENOTTY;
}
+static int pwm_init(struct mpfs_pwmtimer_s *priv)
+{
+ /* Toggle peripheral reset */
+
+ mpfs_set_reset(MPFS_RCC_I2C, priv->pwmid, 1);
+ mpfs_set_reset(MPFS_RCC_I2C, priv->pwmid, 0);
+
+ /* Release FIC reset and enable clocks */
+
+ modifyreg32(MPFS_SYSREG_SOFT_RESET_CR,
+ SYSREG_SOFT_RESET_CR_FIC3 | SYSREG_SOFT_RESET_CR_FPGA,
+ 0);
+
+ modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, 0,
+ SYSREG_SUBBLK_CLOCK_CR_FIC3);
+
+ return OK;
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -795,6 +818,7 @@ struct pwm_lowerhalf_s *mpfs_corepwm_init(int pwmid)
return NULL;
}
+ pwm_init(lower);
+
return (struct pwm_lowerhalf_s *)lower;
}
-
diff --git a/arch/risc-v/src/mpfs/mpfs_corespi.c
b/arch/risc-v/src/mpfs/mpfs_corespi.c
index 8264571723..d261b0a4f0 100644
--- a/arch/risc-v/src/mpfs/mpfs_corespi.c
+++ b/arch/risc-v/src/mpfs/mpfs_corespi.c
@@ -44,6 +44,7 @@
#include "mpfs_gpio.h"
#include "mpfs_corespi.h"
+#include "mpfs_rcc.h"
#include "hardware/mpfs_corespi.h"
#include "hardware/mpfs_sysreg.h"
#include "riscv_internal.h"
@@ -1513,6 +1514,11 @@ static void mpfs_spi_init(struct spi_dev_s *dev)
up_disable_irq(priv->plic_irq);
+ /* Toggle peripheral reset */
+
+ mpfs_set_reset(MPFS_RCC_SPI, priv->id, 1);
+ mpfs_set_reset(MPFS_RCC_SPI, priv->id, 0);
+
/* Release FIC reset and enable clocks */
modifyreg32(MPFS_SYSREG_SOFT_RESET_CR,
diff --git a/arch/risc-v/src/mpfs/mpfs_i2c.c b/arch/risc-v/src/mpfs/mpfs_i2c.c
index 8201bcd4f1..f51e16c0a0 100644
--- a/arch/risc-v/src/mpfs/mpfs_i2c.c
+++ b/arch/risc-v/src/mpfs/mpfs_i2c.c
@@ -48,6 +48,7 @@
#include "mpfs_gpio.h"
#include "mpfs_i2c.h"
+#include "mpfs_rcc.h"
#include "riscv_internal.h"
#include "hardware/mpfs_i2c.h"
@@ -369,6 +370,11 @@ static int mpfs_i2c_init(struct mpfs_i2c_priv_s *priv)
if (priv->fpga)
{
+ /* Toggle peripheral reset */
+
+ mpfs_set_reset(MPFS_RCC_I2C, priv->id, 1);
+ mpfs_set_reset(MPFS_RCC_I2C, priv->id, 0);
+
/* FIC3 is used by many, don't reset it here, or many
* FPGA based modules will stop working right here. Just
* bring out of reset instead.
diff --git a/arch/risc-v/src/mpfs/mpfs_rcc.c b/arch/risc-v/src/mpfs/mpfs_rcc.c
new file mode 100644
index 0000000000..8fd747b682
--- /dev/null
+++ b/arch/risc-v/src/mpfs/mpfs_rcc.c
@@ -0,0 +1,99 @@
+/****************************************************************************
+ * arch/risc-v/src/mpfs/mpfs_rcc.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/spinlock.h>
+
+#include <errno.h>
+#include <sys/types.h>
+
+#include "mpfs_rcc.h"
+#include "mpfs_memorymap.h"
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mpfs_set_reset
+ *
+ * Description:
+ * Enable / disable peripheral reset.
+ *
+ * Input Parameters:
+ * rcc_id - Device id.
+ * instance - Optional instance number for device.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+int mpfs_set_reset(int rcc_id, int instance, bool state)
+{
+ return -ENODEV;
+}
+
+/****************************************************************************
+ * Name: mpfs_set_clock
+ *
+ * Description:
+ * Enable / disable peripheral clock.
+ *
+ * Input Parameters:
+ * rcc_id - Device id.
+ * instance - Optional instance number for device.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+int mpfs_set_clock(int rcc_id, int instance, bool state)
+{
+ return -ENODEV;
+}
diff --git a/arch/risc-v/src/mpfs/mpfs_rcc.h b/arch/risc-v/src/mpfs/mpfs_rcc.h
new file mode 100644
index 0000000000..6437de22c8
--- /dev/null
+++ b/arch/risc-v/src/mpfs/mpfs_rcc.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+ * arch/risc-v/src/mpfs/mpfs_rcc.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef ARCH_RISC_V_SRC_MPFS_MPFS_RCC_H
+#define ARCH_RISC_V_SRC_MPFS_MPFS_RCC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+enum mpfs_rcc_id_e
+{
+ MPFS_RCC_CAN,
+ MPFS_RCC_I2C,
+ MPFS_RCC_PWM,
+ MPFS_RCC_SPI,
+ MPFS_RCC_UART,
+ MPFS_RCC_LAST,
+};
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mpfs_set_reset
+ *
+ * Description:
+ * Enable / disable peripheral reset.
+ *
+ * Input Parameters:
+ * rcc_id - Device id.
+ * instance - Optional instance number for device.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_MPFS_RCC
+int mpfs_set_reset(int rcc_id, int instance, bool state);
+#else
+# define mpfs_set_reset(rcc_id, instance, state) (0)
+#endif
+
+/****************************************************************************
+ * Name: mpfs_set_clock
+ *
+ * Description:
+ * Enable / disable peripheral clock.
+ *
+ * Input Parameters:
+ * rcc_id - Device id.
+ * instance - Optional instance number for device.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_MPFS_RCC
+int mpfs_set_clock(int rcc_id, int instance, bool state);
+#else
+# define mpfs_set_clock(rcc_id, instance, state) (0)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#undef EXTERN
+
+#endif /* __ASSEMBLY__ */
+#endif /* ARCH_RISC_V_SRC_MPFS_MPFS_RCC_H */