diff options
author | Nicolas Royer <nroyer@baylibre.com> | 2020-09-27 17:38:23 +0200 |
---|---|---|
committer | nicola-mazzucato-arm <42373140+nicola-mazzucato-arm@users.noreply.github.com> | 2020-10-15 17:45:38 +0100 |
commit | 482732a38c153d98d4fd2360fefcae99e745e2f1 (patch) | |
tree | 2e67ecaa39435bfb7dd5571d30dc25d905b1c14a | |
parent | 4c1cf6658adeeddcd85c4917380b6a96d2b749b1 (diff) |
rcar/module: add rcar mfismh module and config data
Change-Id: Id87daed4990c2af79f608f74438d6062915d74f1
Signed-off-by: Tsutomu Muroya <tsutomu.muroya.jy@bp.renesas.com>
Signed-off-by: Nicolas Royer <nroyer@baylibre.com>
-rw-r--r-- | product/rcar/module/rcar_mfismh/include/mod_rcar_mfismh.h | 52 | ||||
-rw-r--r-- | product/rcar/module/rcar_mfismh/src/Makefile | 11 | ||||
-rw-r--r-- | product/rcar/module/rcar_mfismh/src/mod_rcar_mfismh.c | 257 | ||||
-rw-r--r-- | product/rcar/module/rcar_mfismh/src/rcar_mfismh.h | 40 | ||||
-rw-r--r-- | product/rcar/scp_ramfw/config_rcar_mfismh.c | 41 |
5 files changed, 401 insertions, 0 deletions
diff --git a/product/rcar/module/rcar_mfismh/include/mod_rcar_mfismh.h b/product/rcar/module/rcar_mfismh/include/mod_rcar_mfismh.h new file mode 100644 index 00000000..fe6b6dff --- /dev/null +++ b/product/rcar/module/rcar_mfismh/include/mod_rcar_mfismh.h @@ -0,0 +1,52 @@ +/* + * Renesas SCP/MCP Software + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_RCAR_MFISMH_H +#define MOD_RCAR_MFISMH_H + +#include <fwk_macros.h> + +#include <stdint.h> + +/*! + * \addtogroup GroupRCARModule RCAR Product Modules + * @{ + */ + +/*! + * \defgroup GroupRCARMHU Message Handling Unit (MHU) Driver + * @{ + */ + +/*! + * \brief MFISMB device + * + * \details Abstract representation of a bidirectional + * MFISMB device that consists + * of a single receive interrupt line and a pair of register sets, one for + * each direction of communication. + */ +struct mod_rcar_mfismh_device_config { + /*! IRQ number of the receive interrupt line */ + unsigned int irq; + + /*! Base address of the registers of the incoming MFISMHU */ + uintptr_t in; + + /*! Base address of the registers of the outgoing MFISMHU */ + uintptr_t out; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_RCAR_MFISMH_H */ diff --git a/product/rcar/module/rcar_mfismh/src/Makefile b/product/rcar/module/rcar_mfismh/src/Makefile new file mode 100644 index 00000000..5d769b93 --- /dev/null +++ b/product/rcar/module/rcar_mfismh/src/Makefile @@ -0,0 +1,11 @@ +# +# Renesas SCP/MCP Software +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := RCAR MFISMH +BS_LIB_SOURCES := mod_rcar_mfismh.c + +include $(BS_DIR)/lib.mk diff --git a/product/rcar/module/rcar_mfismh/src/mod_rcar_mfismh.c b/product/rcar/module/rcar_mfismh/src/mod_rcar_mfismh.c new file mode 100644 index 00000000..1d7af9f3 --- /dev/null +++ b/product/rcar/module/rcar_mfismh/src/mod_rcar_mfismh.c @@ -0,0 +1,257 @@ +/* + * Renesas SCP/MCP Software + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "rcar_mfismh.h" + +#include <rcar_mmap.h> + +#include <mod_smt.h> + +#include <fwk_id.h> +#include <fwk_interrupt.h> +#include <fwk_mm.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <fwk_status.h> + +#include <stddef.h> + +/* + * Maximum number of slots per MFISMH device. The maximum number of slots is 31 + * and not 32 because bit [31] in the MFISMH STAT register is reserved in secure + * MFISMHs for indicating that a non-secure access attempt occurred. + * This reservation also applies to non-secure MFISMHs for consistency, + * though the bit is unused. + */ +#define MFISMH_SLOT_COUNT_MAX 31 + +struct mfismh_reg *mfis_regs; + +struct mfismh_smt_channel { + fwk_id_t id; + struct mod_smt_driver_input_api *api; +}; + +/* MFISMH device context */ +struct mfismh_device_ctx { + /* Pointer to the device configuration */ + const struct mod_rcar_mfismh_device_config *config; + + /* Number of slots (represented by sub-elements) */ + unsigned int slot_count; + + /* Mask of slots that are bound to an SMT channel */ + uint32_t bound_slots; + + /* Table of SMT channels bound to the device */ + struct mfismh_smt_channel *smt_channel_table; +}; + +/* MFISMH context */ +struct mfismh_ctx { + /* Table of device contexts */ + struct mfismh_device_ctx *device_ctx_table; + + /* Number of devices in the device context table*/ + unsigned int device_count; +}; + +static struct mfismh_ctx mfismh_ctx; + +static void mfismh_isr(void) +{ + int status; + unsigned int interrupt; + unsigned int device_idx; + struct mfismh_device_ctx *device_ctx; + unsigned int slot; + struct mfismh_reg *reg; + struct mfismh_smt_channel *smt_channel; + + status = fwk_interrupt_get_current(&interrupt); + if (status != FWK_SUCCESS) + return; + + if (!IS_MFIS_IRQ(interrupt)) + return; + + for (device_idx = 0; device_idx < mfismh_ctx.device_count; device_idx++) { + device_ctx = &mfismh_ctx.device_ctx_table[device_idx]; + if (device_ctx->config->irq == interrupt) + break; + } + + if (device_idx >= mfismh_ctx.device_count) + return; + + reg = (struct mfismh_reg *)&mfis_regs[MFIS_IRQ2NO(interrupt)]; + + /* Acknowledge the interrupt */ + reg->CCR.eir = 0; + + /* Loop over all the slots */ /* For prototyping, slot number is 0 only. */ + { + slot = 0; + + /* + * If the slot is bound to an SMT channel, signal the message to the + * SMT channel. + */ + if (device_ctx->bound_slots & (1 << slot)) { + smt_channel = &device_ctx->smt_channel_table[slot]; + smt_channel->api->signal_message(smt_channel->id); + } + } +} + +/* + * SMT module driver API + */ +static int raise_interrupt(fwk_id_t slot_id) +{ + /* This function is unsupported. */ + return FWK_SUCCESS; +} + +const struct mod_smt_driver_api mfismh_mod_smt_driver_api = { + .raise_interrupt = raise_interrupt, +}; + +/* + * Framework handlers + */ +static int mfismh_init( + fwk_id_t module_id, + unsigned int device_count, + const void *unused) +{ + if (device_count == 0) + return FWK_E_PARAM; + + mfismh_ctx.device_ctx_table = + fwk_mm_calloc(device_count, sizeof(mfismh_ctx.device_ctx_table[0])); + if (mfismh_ctx.device_ctx_table == NULL) + return FWK_E_NOMEM; + + mfismh_ctx.device_count = device_count; + + return FWK_SUCCESS; +} + +static int mfismh_device_init( + fwk_id_t device_id, + unsigned int slot_count, + const void *data) +{ + struct mod_rcar_mfismh_device_config *config = + (struct mod_rcar_mfismh_device_config *)data; + struct mfismh_device_ctx *device_ctx; + + device_ctx = + &mfismh_ctx.device_ctx_table[fwk_id_get_element_idx(device_id)]; + + device_ctx->smt_channel_table = + fwk_mm_calloc(slot_count, sizeof(device_ctx->smt_channel_table[0])); + if (device_ctx->smt_channel_table == NULL) + return FWK_E_NOMEM; + + device_ctx->config = config; + device_ctx->slot_count = slot_count; + + mfis_regs = (struct mfismh_reg *)MFISAREICR_BASE; + + return FWK_SUCCESS; +} + +static int mfismh_bind(fwk_id_t id, unsigned int round) +{ + int status; + struct mfismh_device_ctx *device_ctx; + unsigned int slot; + struct mfismh_smt_channel *smt_channel; + + if ((round == 1) && fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) { + device_ctx = &mfismh_ctx.device_ctx_table[fwk_id_get_element_idx(id)]; + + for (slot = 0; slot < MFISMH_SLOT_COUNT_MAX; slot++) { + if (!(device_ctx->bound_slots & (1 << slot))) + continue; + + smt_channel = &device_ctx->smt_channel_table[slot]; + + status = fwk_module_bind( + smt_channel->id, + FWK_ID_API(FWK_MODULE_IDX_SMT, MOD_SMT_API_IDX_DRIVER_INPUT), + &smt_channel->api); + if (status != FWK_SUCCESS) + return status; + } + } + + return FWK_SUCCESS; +} + +static int mfismh_process_bind_request( + fwk_id_t source_id, + fwk_id_t target_id, + fwk_id_t api_id, + const void **api) +{ + struct mfismh_device_ctx *device_ctx; + unsigned int slot; + + if (!fwk_id_is_type(target_id, FWK_ID_TYPE_SUB_ELEMENT)) + return FWK_E_ACCESS; + + device_ctx = + &mfismh_ctx.device_ctx_table[fwk_id_get_element_idx(target_id)]; + slot = fwk_id_get_sub_element_idx(target_id); + + if (device_ctx->bound_slots & (1 << slot)) + return FWK_E_ACCESS; + + device_ctx->smt_channel_table[slot].id = source_id; + device_ctx->bound_slots |= 1 << slot; + + *api = &mfismh_mod_smt_driver_api; + + return FWK_SUCCESS; +} + +static int mfismh_start(fwk_id_t id) +{ + int status; + struct mfismh_device_ctx *device_ctx; + + if (fwk_id_get_type(id) == FWK_ID_TYPE_MODULE) + return FWK_SUCCESS; + + device_ctx = &mfismh_ctx.device_ctx_table[fwk_id_get_element_idx(id)]; + + if (device_ctx->bound_slots != 0) { + status = fwk_interrupt_set_isr(device_ctx->config->irq, &mfismh_isr); + if (status != FWK_SUCCESS) + return status; + status = fwk_interrupt_enable(device_ctx->config->irq); + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +/* MFISMH module definition */ +const struct fwk_module module_rcar_mfismh = { + .name = "RCAR MFISMH", + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = 1, + .init = mfismh_init, + .element_init = mfismh_device_init, + .bind = mfismh_bind, + .start = mfismh_start, + .process_bind_request = mfismh_process_bind_request, +}; diff --git a/product/rcar/module/rcar_mfismh/src/rcar_mfismh.h b/product/rcar/module/rcar_mfismh/src/rcar_mfismh.h new file mode 100644 index 00000000..e01d2133 --- /dev/null +++ b/product/rcar/module/rcar_mfismh/src/rcar_mfismh.h @@ -0,0 +1,40 @@ +/* + * Renesas SCP/MCP Software + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RCAR_MFISMH_H +#define RCAR_MFISMH_H + +#include <mod_rcar_mfismh.h> + +#include <fwk_macros.h> + +#include <stdint.h> + +#define MFIS_IRQ_MIN (256U) +#define MFIS_IRQ_MAX (MFIS_IRQ_MIN + 8U) +#define MFIS_IRQ2NO(irn) (irn - MFIS_IRQ_MIN) +#define IS_MFIS_IRQ(irn) \ + (((irn < MFIS_IRQ_MIN) || (irn > MFIS_IRQ_MAX)) ? 0 : 1) + +/*! + * \brief SMCMB Register Definitions + */ +struct mfismh_reg { + /*! Communication Control Register(->R) */ + FWK_R uint32_t reserve; + /*! Communication Control Register(->CA) */ + FWK_W union { + struct { + uint32_t eir : 1; + uint32_t eic : 15; + uint32_t reserve : 16; + } CCR; + uint32_t CCR2CA; + }; +}; + +#endif /* RCAR_MFISMH_H */ diff --git a/product/rcar/scp_ramfw/config_rcar_mfismh.c b/product/rcar/scp_ramfw/config_rcar_mfismh.c new file mode 100644 index 00000000..0d9d7ce9 --- /dev/null +++ b/product/rcar/scp_ramfw/config_rcar_mfismh.c @@ -0,0 +1,41 @@ +/* + * Renesas SCP/MCP Software + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <rcar_irq.h> +#include <rcar_mfismh.h> +#include <rcar_mmap.h> + +#include <mod_rcar_mfismh.h> + +#include <fwk_element.h> +#include <fwk_id.h> +#include <fwk_module.h> + +static const struct fwk_element mfismh_element_table[] = { + [RCAR_MFISMH_DEVICE_IDX_S] = { .name = "MFISMH_S", + .sub_element_count = 1, + .data = + &((struct mod_rcar_mfismh_device_config){ + .irq = MFIS_AREICR2_IRQ, + }) }, + [RCAR_MFISMH_DEVICE_IDX_NS_L] = { .name = "MSIFMH_NS_L", + .sub_element_count = 1, + .data = &(( + struct mod_rcar_mfismh_device_config){ + .irq = MFIS_AREICR1_IRQ, + }) }, + [RCAR_MFISMH_DEVICE_IDX_COUNT] = {}, +}; + +static const struct fwk_element *mfismh_get_element_table(fwk_id_t module_id) +{ + return mfismh_element_table; +} + +struct fwk_module_config config_rcar_mfismh = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(mfismh_get_element_table), +}; |