aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Royer <nroyer@baylibre.com>2020-09-27 17:38:23 +0200
committernicola-mazzucato-arm <42373140+nicola-mazzucato-arm@users.noreply.github.com>2020-10-15 17:45:38 +0100
commit482732a38c153d98d4fd2360fefcae99e745e2f1 (patch)
tree2e67ecaa39435bfb7dd5571d30dc25d905b1c14a
parent4c1cf6658adeeddcd85c4917380b6a96d2b749b1 (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.h52
-rw-r--r--product/rcar/module/rcar_mfismh/src/Makefile11
-rw-r--r--product/rcar/module/rcar_mfismh/src/mod_rcar_mfismh.c257
-rw-r--r--product/rcar/module/rcar_mfismh/src/rcar_mfismh.h40
-rw-r--r--product/rcar/scp_ramfw/config_rcar_mfismh.c41
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),
+};