aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Royer <nroyer@baylibre.com>2020-09-27 17:40:53 +0200
committernicola-mazzucato-arm <42373140+nicola-mazzucato-arm@users.noreply.github.com>2020-10-15 17:45:38 +0100
commit9407c9b53bc33339c6d28a68fc1d4a1fd9951f73 (patch)
tree3e2062bc1e04e0cd12a12bc60f80ef29a31aec93
parent67bf97ee7bf9c18c2fc89c98bbd92c32393c1434 (diff)
rcar/module: add rcar pmic module and config data
Change-Id: Id50d856cdc888badf5dd658496d6d69d2ed3c06f 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_pmic/include/mod_rcar_pmic.h260
-rw-r--r--product/rcar/module/rcar_pmic/src/Makefile14
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api.c194
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api_private.h16
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event.c96
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event_private.h29
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module.c124
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module_private.h31
-rw-r--r--product/rcar/module/rcar_pmic/src/mod_rcar_pmic_private.h17
-rw-r--r--product/rcar/scp_ramfw/config_rcar_pmic.c67
10 files changed, 848 insertions, 0 deletions
diff --git a/product/rcar/module/rcar_pmic/include/mod_rcar_pmic.h b/product/rcar/module/rcar_pmic/include/mod_rcar_pmic.h
new file mode 100644
index 00000000..2994bb78
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/include/mod_rcar_pmic.h
@@ -0,0 +1,260 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_RCAR_PMIC_H
+#define MOD_RCAR_PMIC_H
+
+#include <fwk_id.h>
+#include <fwk_module_idx.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/*!
+ * \ingroup GroupRCARModule
+ * \defgroup GroupRCARPmic PMIC
+ * \{
+ */
+
+/*!
+ * \defgroup GroupRCARPmicApis APIs
+ * \{
+ */
+
+/*!
+ * \brief Device API.
+ */
+struct mod_rcar_pmic_device_api {
+ /*!
+ * \brief Get the enabled state of a device.
+ *
+ * \param device_id Identifier of the device to get the state of.
+ * \param [out] enabled \c true if the device is enabled, or \c if it is
+ * disabled.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_HANDLER An error occurred in the device driver.
+ */
+ int (*get_enabled)(fwk_id_t device_id, bool *enabled);
+
+ /*!
+ * \brief Set the enabled state of a device.
+ *
+ * \param device_id Identifier of the device to set the state of.
+ * \param enable \c true to enable the device, or \c false to disable it.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_HANDLER An error occurred in the device driver.
+ */
+ int (*set_enabled)(fwk_id_t device_id, bool enable);
+
+ /*!
+ * \brief Set the enabled state of a device.
+ *
+ * \param device_id Identifier of the device to set the state of.
+ * \param enable \c true to enable the device, or \c false to disable it.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_NOMEM The event queue is full.
+ * \retval FWK_E_PANIC An error in the framework occurred.
+ */
+ int (*set_enabled_async)(fwk_id_t device_id, bool enable);
+
+ /*!
+ * \brief Get the voltage of a device.
+ *
+ * \param device_id Identifier of the device to get the voltage of.
+ * \param [out] voltage Voltage in mV.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_HANDLER An error occurred in the device driver.
+ */
+ int (*get_voltage)(fwk_id_t device_id, uint64_t *voltage);
+
+ /*!
+ * \brief Set the voltage of a device.
+ *
+ * \param device_id Identifier of the device to set the voltage of.
+ * \param voltage New voltage in mV.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_HANDLER An error occurred in the device driver.
+ */
+ int (*set_voltage)(fwk_id_t device_id, uint64_t voltage);
+
+ /*!
+ * \brief Set the voltage of a device.
+ *
+ * \param device_id Identifier of the device to set the voltage of.
+ * \param voltage New voltage in mV.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \retval FWK_E_PARAM One or more parameters were invalid.
+ * \retval FWK_E_STATE The element cannot accept the request.
+ * \retval FWK_E_NOMEM The event queue is full.
+ * \retval FWK_E_PANIC An error in the framework occurred.
+ */
+ int (*set_voltage_async)(fwk_id_t device_id, uint64_t voltage);
+};
+
+/*!
+ * \brief Driver API.
+ */
+struct mod_rcar_pmic_driver_api {
+ /*!
+ * \brief Set the enabled state of a device.
+ *
+ * \param id Identifier of the device to set the state of.
+ * \param enable \c true to enable the device, or \c false to disable it.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \return One of the other driver-defined error codes.
+ */
+ int (*set_enabled)(fwk_id_t id, bool enable);
+
+ /*!
+ * \brief Get the enabled state of a device.
+ *
+ * \param id Identifier of the device to get the state of.
+ * \param [out] enabled \c true if the device is enabled, or \c if it is
+ * disabled.
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \return One of the other driver-defined error codes.
+ */
+ int (*get_enabled)(fwk_id_t id, bool *enabled);
+
+ /*!
+ * \brief Set the voltage of a device.
+ *
+ * \param id Identifier of the device to set the voltage of.
+ * \param voltage New voltage in millivolts (mV).
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \return One of the other driver-defined error codes.
+ */
+ int (*set_voltage)(fwk_id_t id, uint64_t voltage);
+
+ /*!
+ * \brief Get the voltage of a device.
+ *
+ * \param id Identifier of the device to get the voltage of.
+ * \param [out] voltage Voltage in millivolts (mV).
+ *
+ * \retval FWK_SUCCESS The operation succeeded.
+ * \return One of the other driver-defined error codes.
+ */
+ int (*get_voltage)(fwk_id_t id, uint64_t *voltage);
+};
+
+/*!
+ * \}
+ */
+
+/*!
+ * \defgroup GroupRCARPmicConfig Configuration
+ * \{
+ */
+
+/*!
+ * \brief Device configuration.
+ */
+struct mod_rcar_pmic_device_config {
+ fwk_id_t driver_id; /*!< Driver identifier */
+ fwk_id_t driver_api_id; /*!< Driver API identifier */
+};
+
+/*!
+ * \}
+ */
+
+/*!
+ * \defgroup GroupRCARPmicEvents Events
+ * \{
+ */
+
+/*!
+ * \brief <tt>Set enabled</tt> event response parameters.
+ */
+struct mod_rcar_pmic_event_params_set_enabled_response {
+ int status; /*!< Status of the request */
+};
+
+/*!
+ * \brief <tt>Set voltage</tt> event response parameters.
+ */
+struct mod_rcar_pmic_event_params_set_voltage_response {
+ int status; /*!< Status of the request */
+};
+
+/*!
+ * \}
+ */
+
+/*!
+ * \defgroup GroupRCARPmicIds Identifiers
+ * \{
+ */
+
+/*!
+ * \brief API indices.
+ */
+enum mod_rcar_pmic_api_idx {
+ /*! API index for mod_rcar_pmic_api_id_device */
+ MOD_RCAR_PMIC_API_IDX_DEVICE,
+
+ /*! Number of defined APIs */
+ MOD_RCAR_PMIC_API_IDX_COUNT
+};
+
+/*! Device API identifier */
+static const fwk_id_t mod_rcar_pmic_api_id_device =
+ FWK_ID_API_INIT(FWK_MODULE_IDX_RCAR_PMIC, MOD_RCAR_PMIC_API_IDX_DEVICE);
+
+/*!
+ * \brief Event indices.
+ */
+enum mod_rcar_pmic_event_idx {
+ /*! Event index for mod_rcar_pmic_event_id_set_enabled */
+ MOD_RCAR_PMIC_EVENT_IDX_SET_ENABLED,
+
+ /*! Event index for mod_psu_event_id_set_voltage */
+ MOD_RCAR_PMIC_EVENT_IDX_SET_VOLTAGE,
+
+ /*! Number of defined events */
+ MOD_RCAR_PMIC_EVENT_IDX_COUNT
+};
+
+/*! <tt>Set enabled</tt> event identifier */
+static const fwk_id_t mod_rcar_pmic_event_id_set_enabled = FWK_ID_EVENT_INIT(
+ FWK_MODULE_IDX_RCAR_PMIC,
+ MOD_RCAR_PMIC_EVENT_IDX_SET_ENABLED);
+
+/*! <tt>Set voltage</tt> event identifier */
+static const fwk_id_t mod_psu_event_id_set_voltage = FWK_ID_EVENT_INIT(
+ FWK_MODULE_IDX_RCAR_PMIC,
+ MOD_RCAR_PMIC_EVENT_IDX_SET_VOLTAGE);
+
+/*!
+ * \}
+ */
+
+/*!
+ * \}
+ */
+
+#endif /* MOD_RCAR_PMIC_H */
diff --git a/product/rcar/module/rcar_pmic/src/Makefile b/product/rcar/module/rcar_pmic/src/Makefile
new file mode 100644
index 00000000..31569fe1
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/Makefile
@@ -0,0 +1,14 @@
+#
+# Renesas SCP/MCP Software
+# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := rcar_pmic
+BS_LIB_SOURCES := \
+ mod_rcar_pmic_device_api.c \
+ mod_rcar_pmic_event.c \
+ mod_rcar_pmic_module.c
+
+include $(BS_DIR)/lib.mk
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api.c b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api.c
new file mode 100644
index 00000000..efde5d53
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api.c
@@ -0,0 +1,194 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mod_rcar_pmic_private.h>
+
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <fwk_thread.h>
+
+static int api_get_enabled(fwk_id_t device_id, bool *enabled)
+{
+ int status;
+ const struct mod_rcar_pmic_device_ctx *ctx;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to a valid element */
+ if (!fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ ctx = __mod_rcar_pmic_get_valid_device_ctx(device_id);
+ if (ctx == NULL)
+ return FWK_E_PARAM;
+
+ /* Get the enabled state from the driver */
+ status = ctx->apis.driver->get_enabled(ctx->config->driver_id, enabled);
+ if (status != FWK_SUCCESS)
+ return FWK_E_HANDLER;
+
+ return FWK_SUCCESS;
+}
+
+static int api_set_enabled(fwk_id_t device_id, bool enable)
+{
+ int status;
+ const struct mod_rcar_pmic_device_ctx *ctx;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to a valid element */
+ if (!fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ ctx = __mod_rcar_pmic_get_valid_device_ctx(device_id);
+ if (ctx == NULL)
+ return FWK_E_PARAM;
+
+ /* Set the enabled state through the driver */
+ status = ctx->apis.driver->set_enabled(ctx->config->driver_id, enable);
+ if (status != FWK_SUCCESS)
+ return FWK_E_HANDLER;
+
+ return FWK_SUCCESS;
+}
+
+static int api_set_enabled_async(fwk_id_t device_id, bool enable)
+{
+ int status;
+ struct fwk_event event;
+ struct mod_rcar_pmic_event_params_set_enabled *params;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to an existing element */
+ if (fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ /* Build and submit the event */
+ event = (struct fwk_event){
+ .id = mod_rcar_pmic_event_id_set_enabled,
+ .target_id = device_id,
+ .response_requested = true,
+ };
+
+ params = (void *)&event.params;
+ *params = (struct mod_rcar_pmic_event_params_set_enabled){
+ .enable = enable,
+ };
+
+ /* Submit the event for processing */
+ status = fwk_thread_put_event(&event);
+ if (status == FWK_E_NOMEM)
+ return FWK_E_NOMEM;
+ else if (status != FWK_SUCCESS)
+ return FWK_E_PANIC;
+
+ return FWK_SUCCESS;
+}
+
+static int api_get_voltage(fwk_id_t device_id, uint64_t *voltage)
+{
+ int status;
+ const struct mod_rcar_pmic_device_ctx *ctx;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to a valid element */
+ if (!fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ ctx = __mod_rcar_pmic_get_valid_device_ctx(device_id);
+ if (ctx == NULL)
+ return FWK_E_PARAM;
+
+ /* Get the voltage from the driver */
+ status = ctx->apis.driver->get_voltage(ctx->config->driver_id, voltage);
+ if (status != FWK_SUCCESS)
+ return FWK_E_HANDLER;
+
+ return FWK_SUCCESS;
+}
+
+static int api_set_voltage(fwk_id_t device_id, uint64_t voltage)
+{
+ int status;
+ const struct mod_rcar_pmic_device_ctx *ctx;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to a valid element */
+ if (!fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ ctx = __mod_rcar_pmic_get_valid_device_ctx(device_id);
+ if (ctx == NULL)
+ return FWK_E_PARAM;
+
+ /* Set the voltage state through the driver */
+ status = ctx->apis.driver->set_voltage(ctx->config->driver_id, voltage);
+ if (status != FWK_SUCCESS)
+ return FWK_E_HANDLER;
+
+ return FWK_SUCCESS;
+}
+
+static int api_set_voltage_async(fwk_id_t device_id, uint64_t voltage)
+{
+ int status;
+ struct fwk_event event;
+ struct mod_rcar_pmic_event_params_set_voltage *params;
+
+ /* This API call cannot target another module */
+ if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the identifier refers to an existing element */
+ if (fwk_module_is_valid_element_id(device_id))
+ return FWK_E_PARAM;
+
+ /* Build and submit the event */
+ event = (struct fwk_event){
+ .id = mod_rcar_pmic_event_id_set_enabled,
+ .target_id = device_id,
+ .response_requested = true,
+ };
+
+ params = (void *)&event.params;
+ *params = (struct mod_rcar_pmic_event_params_set_voltage){
+ .voltage = voltage,
+ };
+
+ status = fwk_thread_put_event(&event);
+ if (status == FWK_E_NOMEM)
+ return FWK_E_NOMEM;
+ else if (status != FWK_SUCCESS)
+ return FWK_E_PANIC;
+
+ return FWK_SUCCESS;
+}
+
+/* Module API implementation */
+const struct mod_rcar_pmic_device_api __mod_rcar_pmic_device_api = {
+ .get_enabled = api_get_enabled,
+ .set_enabled = api_set_enabled,
+ .set_enabled_async = api_set_enabled_async,
+ .get_voltage = api_get_voltage,
+ .set_voltage = api_set_voltage,
+ .set_voltage_async = api_set_voltage_async,
+};
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api_private.h b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api_private.h
new file mode 100644
index 00000000..a5ed6411
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_device_api_private.h
@@ -0,0 +1,16 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_RCAR_PMIC_DEVICE_API_PRIVATE_H
+#define MOD_RCAR_PMIC_DEVICE_API_PRIVATE_H
+
+#include <mod_rcar_pmic.h>
+
+/* Module API implementation */
+extern const struct mod_rcar_pmic_device_api __mod_rcar_pmic_device_api;
+
+#endif /* MOD_RCAR_PMIC_DEVICE_API_PRIVATE_H */
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event.c b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event.c
new file mode 100644
index 00000000..7b65412b
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event.c
@@ -0,0 +1,96 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mod_rcar_pmic_private.h>
+
+#include <fwk_assert.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+
+int mod_rcar_pmic_event_set_enabled(
+ const struct fwk_event *event,
+ struct fwk_event *response)
+{
+ const struct mod_rcar_pmic_device_ctx *ctx;
+ const struct mod_rcar_pmic_event_params_set_enabled *params;
+ struct mod_rcar_pmic_event_params_set_enabled_response *response_params;
+
+ /* These conditions were checked when we submitted the event */
+ assert(fwk_id_get_module_idx(event->target_id) == FWK_MODULE_IDX_RCAR_PMIC);
+ assert(fwk_module_is_valid_element_id(event->target_id));
+
+ /* Explicitly cast to our parameter types */
+ params = (void *)&event->params;
+ response_params = (void *)&response->params;
+
+ ctx = __mod_rcar_pmic_get_device_ctx(event->target_id);
+
+ /* Set the enabled state through the driver */
+ response_params->status =
+ ctx->apis.driver->set_enabled(ctx->config->driver_id, params->enable);
+
+ return FWK_SUCCESS;
+}
+
+int mod_rcar_pmic_event_set_voltage(
+ const struct fwk_event *event,
+ struct fwk_event *response)
+{
+ const struct mod_rcar_pmic_device_ctx *ctx;
+ const struct mod_rcar_pmic_event_params_set_voltage *params;
+ struct mod_rcar_pmic_event_params_set_voltage_response *response_params;
+
+ /* These conditions were checked when we submitted the event */
+ assert(fwk_id_get_module_idx(event->target_id) == FWK_MODULE_IDX_RCAR_PMIC);
+ assert(fwk_module_is_valid_element_id(event->target_id));
+
+ /* Explicitly cast to our parameter types */
+ params = (void *)&event->params;
+ response_params = (void *)&response->params;
+
+ ctx = __mod_rcar_pmic_get_device_ctx(event->target_id);
+
+ /* Set the voltage through the driver */
+ response_params->status =
+ ctx->apis.driver->set_voltage(ctx->config->driver_id, params->voltage);
+
+ return FWK_SUCCESS;
+}
+
+int __mod_rcar_pmic_process_event(
+ const struct fwk_event *event,
+ struct fwk_event *response)
+{
+ typedef int (*handler_t)(
+ const struct fwk_event *event, struct fwk_event *response);
+
+ static const handler_t handlers[] = {
+ [MOD_RCAR_PMIC_EVENT_IDX_SET_ENABLED] = mod_rcar_pmic_event_set_enabled,
+ [MOD_RCAR_PMIC_EVENT_IDX_SET_VOLTAGE] = mod_rcar_pmic_event_set_voltage,
+ };
+
+ unsigned int event_idx;
+ handler_t handler;
+
+ /* We only handle the events defined by us */
+ if (fwk_id_get_module_idx(event->id) != FWK_MODULE_IDX_RCAR_PMIC)
+ return FWK_E_PARAM;
+
+ /* Ensure the event index is within bounds we can handle */
+ event_idx = fwk_id_get_event_idx(event->id);
+ if (event_idx >= FWK_ARRAY_SIZE(handlers))
+ return FWK_E_PARAM;
+
+ /* Ensure we have an implemented handler for this event */
+ handler = handlers[event_idx];
+ if (handler == NULL)
+ return FWK_E_PARAM;
+
+ /* Delegate event handling to the relevant handler */
+ return handler(event, response);
+}
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event_private.h b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event_private.h
new file mode 100644
index 00000000..a59631a8
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_event_private.h
@@ -0,0 +1,29 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_RCAR_PMIC_EVENT_PRIVATE_H
+#define MOD_RCAR_PMIC_EVENT_PRIVATE_H
+
+#include <fwk_event.h>
+#include <fwk_id.h>
+
+/* "Set enabled" event */
+struct mod_rcar_pmic_event_params_set_enabled {
+ bool enable;
+};
+
+/* "Set voltage" event */
+struct mod_rcar_pmic_event_params_set_voltage {
+ uint64_t voltage;
+};
+
+/* Event handler */
+int __mod_rcar_pmic_process_event(
+ const struct fwk_event *event,
+ struct fwk_event *response);
+
+#endif /* MOD_RCAR_PMIC_EVENT_PRIVATE_H */
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module.c b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module.c
new file mode 100644
index 00000000..cfe6e148
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module.c
@@ -0,0 +1,124 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mod_rcar_pmic_private.h>
+
+#include <fwk_assert.h>
+#include <fwk_macros.h>
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+
+/* Device context table */
+static struct mod_rcar_pmic_device_ctx (*device_ctx)[];
+
+static int rcar_pmic_init(
+ fwk_id_t module_id,
+ unsigned int element_count,
+ const void *data)
+{
+ device_ctx = fwk_mm_calloc(element_count, sizeof((*device_ctx)[0]));
+ if (device_ctx == NULL)
+ return FWK_E_NOMEM;
+
+ return FWK_SUCCESS;
+}
+
+static int rcar_pmic_element_init(
+ fwk_id_t device_id,
+ unsigned int sub_element_count,
+ const void *data)
+{
+ assert(sub_element_count == 0);
+
+ __mod_rcar_pmic_get_device_ctx(device_id)->config = data;
+
+ return FWK_SUCCESS;
+}
+
+static int rcar_pmic_bind_element(fwk_id_t device_id, unsigned int round)
+{
+ int status;
+ const struct mod_rcar_pmic_device_ctx *ctx;
+
+ /* Only handle the first round */
+ if (round > 0)
+ return FWK_SUCCESS;
+
+ ctx = __mod_rcar_pmic_get_device_ctx(device_id);
+
+ /* Bind to the driver */
+ status = fwk_module_bind(
+ ctx->config->driver_id, ctx->config->driver_api_id, &ctx->apis.driver);
+ if (status != FWK_SUCCESS) {
+ assert(false);
+
+ return FWK_E_PANIC;
+ }
+
+ assert(ctx->apis.driver->set_enabled != NULL);
+ assert(ctx->apis.driver->get_enabled != NULL);
+ assert(ctx->apis.driver->set_voltage != NULL);
+ assert(ctx->apis.driver->get_voltage != NULL);
+
+ return FWK_SUCCESS;
+}
+
+static int rcar_pmic_bind(fwk_id_t id, unsigned int round)
+{
+ /* We only need to handle element binding */
+ if (fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT))
+ return rcar_pmic_bind_element(id, round);
+
+ return FWK_SUCCESS;
+}
+
+static int rcar_pmic_process_bind_request(
+ fwk_id_t source_id,
+ fwk_id_t target_id,
+ fwk_id_t api_id,
+ const void **api)
+{
+ /* Only accept binds to the elements */
+ if (!fwk_id_is_type(target_id, FWK_ID_TYPE_ELEMENT))
+ return FWK_E_PARAM;
+
+ /* Only expose the device API */
+ if (!fwk_id_is_equal(api_id, mod_rcar_pmic_api_id_device))
+ return FWK_E_PARAM;
+
+ *api = &__mod_rcar_pmic_device_api;
+
+ return FWK_SUCCESS;
+}
+
+struct mod_rcar_pmic_device_ctx *__mod_rcar_pmic_get_device_ctx(
+ fwk_id_t device_id)
+{
+ unsigned int element_idx = fwk_id_get_element_idx(device_id);
+
+ return &(*device_ctx)[element_idx];
+}
+
+struct mod_rcar_pmic_device_ctx *__mod_rcar_pmic_get_valid_device_ctx(
+ fwk_id_t device_id)
+{
+ return __mod_rcar_pmic_get_device_ctx(device_id);
+}
+
+/* Module description */
+const struct fwk_module module_rcar_pmic = {
+ .name = "RCAR_PMIC",
+ .type = FWK_MODULE_TYPE_HAL,
+ .init = rcar_pmic_init,
+ .element_init = rcar_pmic_element_init,
+ .bind = rcar_pmic_bind,
+ .process_bind_request = rcar_pmic_process_bind_request,
+ .process_event = __mod_rcar_pmic_process_event,
+ .api_count = MOD_RCAR_PMIC_API_IDX_COUNT,
+ .event_count = MOD_RCAR_PMIC_EVENT_IDX_COUNT,
+};
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module_private.h b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module_private.h
new file mode 100644
index 00000000..eaedd0c9
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_module_private.h
@@ -0,0 +1,31 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_RCAR_PMIC_DEVICE_CTX_PRIVATE_H
+#define MOD_RCAR_PMIC_DEVICE_CTX_PRIVATE_H
+
+#include <mod_rcar_pmic.h>
+
+#include <fwk_id.h>
+
+/* Device context */
+struct mod_rcar_pmic_device_ctx {
+ /* Device configuration */
+ const struct mod_rcar_pmic_device_config *config;
+
+ struct {
+ /* Driver API */
+ const struct mod_rcar_pmic_driver_api *driver;
+ } apis;
+};
+
+struct mod_rcar_pmic_device_ctx *__mod_rcar_pmic_get_device_ctx(
+ fwk_id_t device_id);
+struct mod_rcar_pmic_device_ctx *__mod_rcar_pmic_get_valid_device_ctx(
+ fwk_id_t device_id);
+
+#endif /* MOD_RCAR_PMIC_DEVICE_CTX_PRIVATE_H */
diff --git a/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_private.h b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_private.h
new file mode 100644
index 00000000..21114392
--- /dev/null
+++ b/product/rcar/module/rcar_pmic/src/mod_rcar_pmic_private.h
@@ -0,0 +1,17 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_RCAR_PMIC_PRIVATE_H
+#define MOD_RCAR_PMIC_PRIVATE_H
+
+#include <mod_rcar_pmic_device_api_private.h>
+#include <mod_rcar_pmic_event_private.h>
+#include <mod_rcar_pmic_module_private.h>
+
+#include <fwk_id.h>
+
+#endif /* MOD_RCAR_PMIC_PRIVATE_H */
diff --git a/product/rcar/scp_ramfw/config_rcar_pmic.c b/product/rcar/scp_ramfw/config_rcar_pmic.c
new file mode 100644
index 00000000..ac52b755
--- /dev/null
+++ b/product/rcar/scp_ramfw/config_rcar_pmic.c
@@ -0,0 +1,67 @@
+/*
+ * Renesas SCP/MCP Software
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mod_rcar_mock_pmic.h>
+#include <mod_rcar_pmic.h>
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+
+static const struct fwk_element element_table[] = {
+ {
+ .name = "CPU_GROUP_LITTLE",
+ .data =
+ &(const struct mod_rcar_pmic_device_config){
+ .driver_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RCAR_MOCK_PMIC, 0),
+ .driver_api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_RCAR_MOCK_PMIC,
+ MOD_RCAR_MOCK_PMIC_API_IDX_PSU_DRIVER) },
+ },
+ {
+ .name = "CPU_GROUP_BIG",
+ .data =
+ &(const struct mod_rcar_pmic_device_config){
+ .driver_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RCAR_MOCK_PMIC, 1),
+ .driver_api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_RCAR_MOCK_PMIC,
+ MOD_RCAR_MOCK_PMIC_API_IDX_PSU_DRIVER) },
+ },
+ {
+ .name = "GPU",
+ .data =
+ &(const struct mod_rcar_pmic_device_config){
+ .driver_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RCAR_MOCK_PMIC, 2),
+ .driver_api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_RCAR_MOCK_PMIC,
+ MOD_RCAR_MOCK_PMIC_API_IDX_PSU_DRIVER) },
+ },
+ {
+ .name = "VPU",
+ .data =
+ &(const struct mod_rcar_pmic_device_config){
+ .driver_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RCAR_MOCK_PMIC, 3),
+ .driver_api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_RCAR_MOCK_PMIC,
+ MOD_RCAR_MOCK_PMIC_API_IDX_PSU_DRIVER) },
+ },
+ { 0 }
+};
+
+static const struct fwk_element *rcar_pmic_get_element_table(fwk_id_t module_id)
+{
+ return element_table;
+}
+
+struct fwk_module_config config_rcar_pmic = {
+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(rcar_pmic_get_element_table),
+ .data = NULL,
+};