arch/risc-v/src/mpfs: Add CorePWM driver

Add a driver for CorePWM block, which can be instantiated on PolarFire SOC FPGA

This supports 2 CorePWM blocks on the FPGA. One CorePWM block provides 8 PWM output signals
This commit is contained in:
Antti Vähälummukka
2021-06-23 10:53:23 +03:00
committed by Alan Carvalho de Assis
parent bed0f50182
commit 6eb73ced51
10 changed files with 1161 additions and 0 deletions
+1
View File
@@ -66,6 +66,7 @@ config ARCH_CHIP_MPFS
select ARCH_RV64GC select ARCH_RV64GC
select ARCH_HAVE_MPU select ARCH_HAVE_MPU
select ARCH_HAVE_RESET select ARCH_HAVE_RESET
select ARCH_HAVE_PWM_MULTICHAN
---help--- ---help---
MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions). MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions).
+64
View File
@@ -103,6 +103,70 @@ config MPFS_I2C1
select ARCH_HAVE_I2CRESET select ARCH_HAVE_I2CRESET
default n default n
comment "CorePWM Options"
config MPFS_HAVE_COREPWM
bool "CorePWM FPGA IP block configured"
default n
config MPFS_COREPWM0
bool "CorePWM0 FPGA IP block configured"
default n
select PWM_MULTICHAN
depends on MPFS_HAVE_COREPWM
config MPFS_COREPWM0_BASE
hex "Base address for the instance"
default 0x44000000
depends on MPFS_COREPWM0
config MPFS_COREPWM0_PWMCLK
int "Clock frequency of the CorePWM0 block (Hz)"
default 25000000
range 1000000 100000000
depends on MPFS_COREPWM0
config MPFS_COREPWM0_REGWIDTH
int "Width of the PWM register (8, 16 or 32 bits)"
default 32
range 8 32
depends on MPFS_COREPWM0
config MPFS_COREPWM0_NCHANNELS
int "Number of Output Channels for CorePWM0"
default 8
range 1 16
depends on MPFS_COREPWM0
config MPFS_COREPWM1
bool "CorePWM1 FPGA IP block configured"
default n
select PWM_MULTICHAN
depends on MPFS_HAVE_COREPWM
config MPFS_COREPWM1_BASE
hex "Base address for the instance"
default 0x45000000
depends on MPFS_COREPWM1
config MPFS_COREPWM1_PWMCLK
int "Clock frequency of the CorePWM1 block (Hz)"
default 25000000
range 1000000 100000000
depends on MPFS_COREPWM1
config MPFS_COREPWM1_REGWIDTH
int "Width of the PWM register (8, 16 or 32 bits)"
default 32
range 8 32
depends on MPFS_COREPWM1
config MPFS_COREPWM1_NCHANNELS
int "Number of Output Channels for CorePWM1"
default 2
range 1 16
depends on MPFS_COREPWM1
endmenu endmenu
config MPFS_DMA config MPFS_DMA
+4
View File
@@ -73,3 +73,7 @@ endif
ifeq ($(CONFIG_I2C),y) ifeq ($(CONFIG_I2C),y)
CHIP_CSRCS += mpfs_i2c.c CHIP_CSRCS += mpfs_i2c.c
endif endif
ifeq (${CONFIG_MPFS_HAVE_COREPWM},y)
CHIP_CSRCS += mpfs_corepwm.c
endif
@@ -0,0 +1,98 @@
/****************************************************************************
* arch/risc-v/src/mpfs/hardware/mpfs_corepwm.h
*
* 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_RISCV_SRC_MPFS_HARDWARE_MPFS_COREPWM_H
#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_COREPWM_H
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* CorePWM features *********************************************************/
#define MPFS_MAX_PWM_CHANNELS 16
/* Register Base Address ****************************************************/
#define MPFS_COREPWM0_BASE (CONFIG_MPFS_COREPWM0_BASE)
#define MPFS_COREPWM1_BASE (CONFIG_MPFS_COREPWM1_BASE)
/* Register offsets *********************************************************/
#define MPFS_COREPWM_PRESCALE_OFFSET (0x00)
#define MPFS_COREPWM_PERIOD_OFFSET (0x04)
#define MPFS_COREPWM_PWM_ENABLE_0_7_OFFSET (0x08)
#define MPFS_COREPWM_PWM_ENABLE_8_15_OFFSET (0x0C)
#define MPFS_COREPWM_PWM1_POS_EDGE_OFFSET (0x10)
#define MPFS_COREPWM_PWM1_NEG_EDGE_OFFSET (0x14)
#define MPFS_COREPWM_PWM2_POS_EDGE_OFFSET (0x18)
#define MPFS_COREPWM_PWM2_NEG_EDGE_OFFSET (0x1C)
#define MPFS_COREPWM_PWM3_POS_EDGE_OFFSET (0x20)
#define MPFS_COREPWM_PWM3_NEG_EDGE_OFFSET (0x24)
#define MPFS_COREPWM_PWM4_POS_EDGE_OFFSET (0x28)
#define MPFS_COREPWM_PWM4_NEG_EDGE_OFFSET (0x2C)
#define MPFS_COREPWM_PWM5_POS_EDGE_OFFSET (0x30)
#define MPFS_COREPWM_PWM5_NEG_EDGE_OFFSET (0x34)
#define MPFS_COREPWM_PWM6_POS_EDGE_OFFSET (0x38)
#define MPFS_COREPWM_PWM6_NEG_EDGE_OFFSET (0x3C)
#define MPFS_COREPWM_PWM7_POS_EDGE_OFFSET (0x40)
#define MPFS_COREPWM_PWM7_NEG_EDGE_OFFSET (0x44)
#define MPFS_COREPWM_PWM8_POS_EDGE_OFFSET (0x48)
#define MPFS_COREPWM_PWM8_NEG_EDGE_OFFSET (0x4C)
#define MPFS_COREPWM_PWM9_POS_EDGE_OFFSET (0x50)
#define MPFS_COREPWM_PWM9_NEG_EDGE_OFFSET (0x54)
#define MPFS_COREPWM_PWM10_POS_EDGE_OFFSET (0x58)
#define MPFS_COREPWM_PWM10_NEG_EDGE_OFFSET (0x5C)
#define MPFS_COREPWM_PWM11_POS_EDGE_OFFSET (0x60)
#define MPFS_COREPWM_PWM11_NEG_EDGE_OFFSET (0x64)
#define MPFS_COREPWM_PWM12_POS_EDGE_OFFSET (0x68)
#define MPFS_COREPWM_PWM12_NEG_EDGE_OFFSET (0x6C)
#define MPFS_COREPWM_PWM13_POS_EDGE_OFFSET (0x70)
#define MPFS_COREPWM_PWM13_NEG_EDGE_OFFSET (0x74)
#define MPFS_COREPWM_PWM14_POS_EDGE_OFFSET (0x78)
#define MPFS_COREPWM_PWM14_NEG_EDGE_OFFSET (0x7C)
#define MPFS_COREPWM_PWM15_POS_EDGE_OFFSET (0x80)
#define MPFS_COREPWM_PWM15_NEG_EDGE_OFFSET (0x84)
#define MPFS_COREPWM_PWM16_POS_EDGE_OFFSET (0x88)
#define MPFS_COREPWM_PWM16_NEG_EDGE_OFFSET (0x8C)
#define MPFS_COREPWM_STRETCH_OFFSET (0x90)
#define MPFS_COREPWM_TACHPRESCALE_OFFSET (0x94)
#define MPFS_COREPWM_TACHSTATUS_OFFSET (0x98)
#define MPFS_COREPWM_TACHIRQMASK_OFFSET (0x9C)
#define MPFS_COREPWM_TACHMODE_OFFSET (0xA0)
#define MPFS_COREPWM_TACHPULSEDUR_0_OFFSET (0xA4)
#define MPFS_COREPWM_TACHPULSEDUR_1_OFFSET (0xA8)
#define MPFS_COREPWM_TACHPULSEDUR_2_OFFSET (0xAC)
#define MPFS_COREPWM_TACHPULSEDUR_3_OFFSET (0xB0)
#define MPFS_COREPWM_TACHPULSEDUR_4_OFFSET (0xB4)
#define MPFS_COREPWM_TACHPULSEDUR_5_OFFSET (0xB8)
#define MPFS_COREPWM_TACHPULSEDUR_6_OFFSET (0xBC)
#define MPFS_COREPWM_TACHPULSEDUR_7_OFFSET (0xC0)
#define MPFS_COREPWM_TACHPULSEDUR_8_OFFSET (0xC4)
#define MPFS_COREPWM_TACHPULSEDUR_9_OFFSET (0xC8)
#define MPFS_COREPWM_TACHPULSEDUR_10_OFFSET (0xCC)
#define MPFS_COREPWM_TACHPULSEDUR_11_OFFSET (0xD0)
#define MPFS_COREPWM_TACHPULSEDUR_12_OFFSET (0xD4)
#define MPFS_COREPWM_TACHPULSEDUR_13_OFFSET (0xD8)
#define MPFS_COREPWM_TACHPULSEDUR_14_OFFSET (0xDC)
#define MPFS_COREPWM_TACHPULSEDUR_15_OFFSET (0xE0)
#define MPFS_COREPWM_SYNC_UPDATE_OFFSET (0xE4)
#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_COREPWM_H */
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_corepwm.h
*
* 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_RISCV_SRCMPFS_MPFS_MPFS_COREPWM_H
#define __ARCH_RISCV_SRCMPFS_MPFS_MPFS_COREPWM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Check if PWM support for any channel is enabled. */
#ifdef CONFIG_MPFS_HAVE_COREPWM
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/board/board.h>
#include "mpfs_hal/mss_hal.h"
#include "hardware/mpfs_corepwm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: mpfs_corepwm_init
*
* Description:
* Initialize a CorePWM block.
*
* Input Parameters:
* pwmid - A number identifying the pwm block. The number of valid
* IDs varies depending on the configuration of the FPGA.
*
* Returned Value:
* On success, a pointer to the MPFS CorePWM lower half PWM driver is
* returned. NULL is returned on any failure.
*
****************************************************************************/
FAR struct pwm_lowerhalf_s *mpfs_corepwm_init(int pwmid);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_MPFS_HAVE_COREPWM */
#endif /* __ARCH_RISCV_SRCMPFS_MPFS_MPFS_COREPWM_H */
+4
View File
@@ -42,4 +42,8 @@ ifeq ($(CONFIG_SPI),y)
CSRCS += mpfs_board_spi.c CSRCS += mpfs_board_spi.c
endif endif
ifeq ($(CONFIG_MPFS_HAVE_COREPWM),y)
CSRCS += mpfs_pwm.c
endif
include $(TOPDIR)/boards/Board.mk include $(TOPDIR)/boards/Board.mk
@@ -34,6 +34,7 @@
#include <nuttx/drivers/ramdisk.h> #include <nuttx/drivers/ramdisk.h>
#include "mpfsicicle.h" #include "mpfsicicle.h"
#include "mpfs_corepwm.h"
#include "mpfs.h" #include "mpfs.h"
/**************************************************************************** /****************************************************************************
@@ -80,5 +81,16 @@ int mpfs_bringup(void)
} }
#endif #endif
#ifdef CONFIG_MPFS_HAVE_COREPWM
/* Configure PWM peripheral interfaces */
ret = mpfs_pwm_setup();
if (ret < 0)
{
syslog(LOG_ERR, "Failed to initialize CorePWM driver: %d\n", ret);
}
#endif
return ret; return ret;
} }
+90
View File
@@ -0,0 +1,90 @@
/****************************************************************************
* boards/risc-v/mpfs/icicle/src/mpfs_pwm.c
*
* 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 <errno.h>
#include <stddef.h>
#include <debug.h>
#include <string.h>
#include <limits.h>
#include <nuttx/timers/pwm.h>
#include <arch/board/board.h>
#include "mpfs_corepwm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mpfs_pwm_setup
*
* Description:
*
* Initialize PWM and register PWM devices
*
****************************************************************************/
int mpfs_pwm_setup(void)
{
struct pwm_lowerhalf_s *lower_half = NULL; /* lower-half handle */
/* The underlying CorePWM driver "knows" there are up to 16 channels
* available for each timer device, so we don't have to do anything
* special here.
*/
#ifdef CONFIG_MPFS_COREPWM0
lower_half = mpfs_corepwm_init(0);
/* If we can't get the lower-half handle, skip and keep going. */
if (lower_half)
{
/* Translate the peripheral number to a device name. */
pwm_register("/dev/corepwm0", lower_half);
}
#endif
#ifdef CONFIG_MPFS_COREPWM1
lower_half = mpfs_corepwm_init(1);
/* If we can't get the lower-half handle, skip and keep going. */
if (lower_half)
{
/* Translate the peripheral number to a device name. */
pwm_register("/dev/corepwm1", lower_half);
}
#endif
return 0;
}
@@ -44,5 +44,6 @@
int mpfs_bringup(void); int mpfs_bringup(void);
int mpfs_board_spi_init(void); int mpfs_board_spi_init(void);
int mpfs_board_i2c_init(void); int mpfs_board_i2c_init(void);
int mpfs_pwm_setup(void);
#endif /* __BOARDS_RISCV_ICICLE_MPFS_SRC_MPFSICICLE_H */ #endif /* __BOARDS_RISCV_ICICLE_MPFS_SRC_MPFSICICLE_H */