Commit 658628e7 authored by Lina Iyer's avatar Lina Iyer Committed by Andy Gross

drivers: qcom: rpmh-rsc: add RPMH controller for QCOM SoCs

Add controller driver for QCOM SoCs that have hardware based shared
resource management. The hardware IP known as RSC (Resource State
Coordinator) houses multiple Direct Resource Voter (DRV) for different
execution levels. A DRV is a unique voter on the state of a shared
resource. A Trigger Control Set (TCS) is a bunch of slots that can house
multiple resource state requests, that when triggered will issue those
requests through an internal bus to the Resource Power Manager Hardened
(RPMH) blocks. These hardware blocks are capable of adjusting clocks,
voltages, etc. The resource state request from a DRV are aggregated
along with state requests from other processors in the SoC and the
aggregate value is applied on the resource.

Some important aspects of the RPMH communication -
- Requests are <addr, value> with some header information
- Multiple requests (upto 16) may be sent through a TCS, at a time
- Requests in a TCS are sent in sequence
- Requests may be fire-n-forget or completion (response expected)
- Multiple TCS from the same DRV may be triggered simultaneously
- Cannot send a request if another request for the same addr is in
  progress from the same DRV
- When all the requests from a TCS are complete, an IRQ is raised
- The IRQ handler needs to clear the TCS before it is available for
  reuse
- TCS configuration is specific to a DRV
- Platform drivers may use DRV from different RSCs to make requests

Resource state requests made when CPUs are active are called 'active'
state requests. Requests made when all the CPUs are powered down (idle
state) are called 'sleep' state requests. They are matched by a
corresponding 'wake' state requests which puts the resources back in to
previously requested active state before resuming any CPU. TCSes are
dedicated for each type of requests. Active mode TCSes (AMC) are used to
send requests immediately to the resource, while control TCS are used to
provide specific information to the controller. Sleep and Wake TCS send
sleep and wake requests, after and before the system halt respectively.
Signed-off-by: default avatarLina Iyer <ilina@codeaurora.org>
Signed-off-by: default avatarRaju P.L.S.S.S.N <rplsssn@codeaurora.org>
Signed-off-by: default avatarAndy Gross <andy.gross@linaro.org>
parent a3134fb0
...@@ -91,6 +91,16 @@ config QCOM_RMTFS_MEM ...@@ -91,6 +91,16 @@ config QCOM_RMTFS_MEM
Say y here if you intend to boot the modem remoteproc. Say y here if you intend to boot the modem remoteproc.
config QCOM_RPMH
bool "Qualcomm RPM-Hardened (RPMH) Communication"
depends on ARCH_QCOM && ARM64 && OF || COMPILE_TEST
help
Support for communication with the hardened-RPM blocks in
Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an
internal bus to transmit state requests for shared resources. A set
of hardware components aggregate requests for these resources and
help apply the aggregated state on the resource.
config QCOM_SMEM config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)" tristate "Qualcomm Shared Memory Manager (SMEM)"
depends on ARCH_QCOM depends on ARCH_QCOM
......
...@@ -8,6 +8,7 @@ obj-$(CONFIG_QCOM_PM) += spm.o ...@@ -8,6 +8,7 @@ obj-$(CONFIG_QCOM_PM) += spm.o
obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
qmi_helpers-y += qmi_encdec.o qmi_interface.o qmi_helpers-y += qmi_encdec.o qmi_interface.o
obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o
obj-$(CONFIG_QCOM_RPMH) += rpmh-rsc.o
obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) += smem.o obj-$(CONFIG_QCOM_SMEM) += smem.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __RPM_INTERNAL_H__
#define __RPM_INTERNAL_H__
#include <linux/bitmap.h>
#include <soc/qcom/tcs.h>
#define TCS_TYPE_NR 4
#define MAX_CMDS_PER_TCS 16
#define MAX_TCS_PER_TYPE 3
#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR)
struct rsc_drv;
/**
* struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
* to the controller
*
* @drv: the controller
* @type: type of the TCS in this group - active, sleep, wake
* @mask: mask of the TCSes relative to all the TCSes in the RSC
* @offset: start of the TCS group relative to the TCSes in the RSC
* @num_tcs: number of TCSes in this type
* @ncpt: number of commands in each TCS
* @lock: lock for synchronizing this TCS writes
* @req: requests that are sent from the TCS
*/
struct tcs_group {
struct rsc_drv *drv;
int type;
u32 mask;
u32 offset;
int num_tcs;
int ncpt;
spinlock_t lock;
const struct tcs_request *req[MAX_TCS_PER_TYPE];
};
/**
* struct rsc_drv: the Direct Resource Voter (DRV) of the
* Resource State Coordinator controller (RSC)
*
* @name: controller identifier
* @tcs_base: start address of the TCS registers in this controller
* @id: instance id in the controller (Direct Resource Voter)
* @num_tcs: number of TCSes in this DRV
* @tcs: TCS groups
* @tcs_in_use: s/w state of the TCS
* @lock: synchronize state of the controller
*/
struct rsc_drv {
const char *name;
void __iomem *tcs_base;
int id;
int num_tcs;
struct tcs_group tcs[TCS_TYPE_NR];
DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
spinlock_t lock;
};
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
#endif /* __RPM_INTERNAL_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __DT_QCOM_RPMH_RSC_H__
#define __DT_QCOM_RPMH_RSC_H__
#define SLEEP_TCS 0
#define WAKE_TCS 1
#define ACTIVE_TCS 2
#define CONTROL_TCS 3
#endif /* __DT_QCOM_RPMH_RSC_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __SOC_QCOM_TCS_H__
#define __SOC_QCOM_TCS_H__
#define MAX_RPMH_PAYLOAD 16
/**
* rpmh_state: state for the request
*
* RPMH_SLEEP_STATE: State of the resource when the processor subsystem
* is powered down. There is no client using the
* resource actively.
* RPMH_WAKE_ONLY_STATE: Resume resource state to the value previously
* requested before the processor was powered down.
* RPMH_ACTIVE_ONLY_STATE: Active or AMC mode requests. Resource state
* is aggregated immediately.
*/
enum rpmh_state {
RPMH_SLEEP_STATE,
RPMH_WAKE_ONLY_STATE,
RPMH_ACTIVE_ONLY_STATE,
};
/**
* struct tcs_cmd: an individual request to RPMH.
*
* @addr: the address of the resource slv_id:18:16 | offset:0:15
* @data: the resource state request
* @wait: wait for this request to be complete before sending the next
*/
struct tcs_cmd {
u32 addr;
u32 data;
u32 wait;
};
/**
* struct tcs_request: A set of tcs_cmds sent together in a TCS
*
* @state: state for the request.
* @wait_for_compl: wait until we get a response from the h/w accelerator
* @num_cmds: the number of @cmds in this request
* @cmds: an array of tcs_cmds
*/
struct tcs_request {
enum rpmh_state state;
u32 wait_for_compl;
u32 num_cmds;
struct tcs_cmd *cmds;
};
#endif /* __SOC_QCOM_TCS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment