nuttx/arch/risc-v/src/k230/k230_ipi.h
Yanfeng Liu 4456b2db29 risc-v/k230: add IPI support to speed up RPTUN/RPMSG
This patch adds inter-processor interrupt support using K230 mailbox
device to improve the RPMsg efficiency. The polling logic has been
dropped.

Major changes:

- in arch/risc-v/include/k230:
  - irq.h          add IRQ for IPI devices
- in arch/risc-v/src/k230:
  - Kconfig        add IPI related config, increase polling delay
  - Make.defs      add k230_ipi.c to CHIP_SRCS
  - k230_hart.c    fix typo, add notes of zero MISA reading w/ NUTTSBI
  - k230_irq.c     use K230_PLIC_IRQS as ext IRQ limit to support IPI
  - k230_rptun.c   use IPI instead of polling
- in boards/risc-v/k230/canmv230/configs
  - master         enable IPI support
  - remote         enable IPI, TMPFS, RPMSGFS etc

New additions:

- in arch/risc-v/src/k230:
  - k230_ipi.h     add K230 IPI related defintions
  - k230_ipi.c     add K230 IPI driver

Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
2024-02-21 04:37:03 -08:00

156 lines
6.0 KiB
C

/****************************************************************************
* arch/risc-v/src/k230/k230_ipi.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_K230_K230_IPI_H
#define __ARCH_RISCV_SRC_K230_K230_IPI_H
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* K230 has 4 IPI devices, each has 10 registers with 32 bit width. */
#define K230_IPI_DEVN_MAX 3
#define K230_IPI_LINE_MAX 15
#define K230_IPI_BASE(n) (0x91104000ul + n * 0x28)
/* The IPI registers are organized in two directions (M2R or R2M), there are
* 5 registers for each direction, with 16 IPI lines for each node. Though
* K230 names the two directions as CPU2DSP or DSP2CPU, we use M2R or R2M.
*
* The Status register has 2-bit counter for each IPI line.
* The Set/Clear registers accepts values from 0..15 for 16 IPI lines.
* Setting a line increases its counter by 1, clearing the line decreases it
* by 1. The Error register further uses the high/low 16 bits to flag the
* over/under-run situations of counters.
*
* The Enable register's bit 16..31 are for line enable, bit 0 is for device
* interrupt enable, bit 1 for resetting line counters to zero.
*
* Also note the directions M2R/R2M are tied to the CPU cores: little core is
* M and big core is R. So we can also select the direction based on current
* core, but due to that we can't read correct MISA register value with NSBI
* booting environment, that method is not used and the role is passed in.
*/
#define K230_IPI_M2R_INTEN(n) (K230_IPI_BASE(n) + 0)
#define K230_IPI_M2R_INTSET(n) (K230_IPI_BASE(n) + 4)
#define K230_IPI_M2R_INTCLR(n) (K230_IPI_BASE(n) + 8)
#define K230_IPI_M2R_INTSTS(n) (K230_IPI_BASE(n) + 12)
#define K230_IPI_M2R_INTERR(n) (K230_IPI_BASE(n) + 16)
#define K230_IPI_R2M_INTEN(n) (K230_IPI_BASE(n) + 20)
#define K230_IPI_R2M_INTSET(n) (K230_IPI_BASE(n) + 24)
#define K230_IPI_R2M_INTCLR(n) (K230_IPI_BASE(n) + 28)
#define K230_IPI_R2M_INTSTS(n) (K230_IPI_BASE(n) + 32)
#define K230_IPI_R2M_INTERR(n) (K230_IPI_BASE(n) + 36)
#define IPI_ROLE_MASTER 1 /* master role, for little core */
#define IPI_ROLE_REMOTE 2 /* remote role, for big core */
/* Tools for handling uint16_t device and line id combo */
#define IPI_DEVN(x) ((x & 0xFF00) >> 8)
#define IPI_LINE(x) (x & 0xFF)
#define IPI_COMB(d,l) ((d << 8) | (l & 0xFF))
/****************************************************************************
* Public types
****************************************************************************/
/****************************************************************************
* Name: ipi_callback_t
* Description:
* Callback for a particular IPI line. Should be brief as maybe running in
* ISR context.
* Params;
* comb: combined IPI dev and line ids, see IPI_COMB above
* args: the args used in subscription
****************************************************************************/
typedef void (*ipi_callback_t)(uint16_t comb, void *args);
/****************************************************************************
* Public functions
****************************************************************************/
/****************************************************************************
* Name: k230_ipi_init
* Description:
* Initialzie IPI device with receiving and sending line masks.
* Params:
* devn: IPI device number in 0..K230_IPI_DEVN_MAX
* mask: allowed lines mask for notifying peers or receiving notifications
* role: IPI role of this node (IPI_ROLE_MASTER or IPI_ROLE_REMOTE)
* ipcb: callback for incoming IPI notifications
* args: last parameter for the callback.
* Returns:
* 0 on success, or negative value on errors
****************************************************************************/
int k230_ipi_init(uintptr_t devn, uint16_t mask, uint16_t role,
ipi_callback_t ipcb, void *args);
/****************************************************************************
* Name: k230_ipi_notify
* Description:
* Notify peers via IPI.
* Params:
* devn: device id in 0..K230_IPI_DEVN_MAX
* line: line id in 0..K230_IPI_LINE_MAX
****************************************************************************/
void k230_ipi_notify(uint8_t devn, uint8_t line);
/****************************************************************************
* Name: k230_ipi_finish
* Description:
* Deinitializes IPI device
* Params:
* devn: IPI device number initialized previously.
* mask: line masks iniitialied previously.
****************************************************************************/
void k230_ipi_finish(uint8_t devn, uint16_t mask);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_K230_K230_IPI_H */