diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 9cc1b3c23f9..fdb514625fd 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 35081140493..5e856643de3 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 ed2ebb83702..ca769647bae 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 dcdc4bbc733..31bc7039d6a 100644 --- a/arch/risc-v/src/mpfs/mpfs_corepwm.c +++ b/arch/risc-v/src/mpfs/mpfs_corepwm.c @@ -44,7 +44,11 @@ #include +#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 82645717238..d261b0a4f0d 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 8201bcd4f17..f51e16c0a07 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 00000000000..8fd747b682f --- /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 + +#include + +#include +#include + +#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 00000000000..6437de22c8e --- /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 + +#include + +/**************************************************************************** + * 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 */