162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __RPM_INTERNAL_H__ 862306a36Sopenharmony_ci#define __RPM_INTERNAL_H__ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/bitmap.h> 1162306a36Sopenharmony_ci#include <linux/wait.h> 1262306a36Sopenharmony_ci#include <soc/qcom/tcs.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define TCS_TYPE_NR 4 1562306a36Sopenharmony_ci#define MAX_CMDS_PER_TCS 16 1662306a36Sopenharmony_ci#define MAX_TCS_PER_TYPE 3 1762306a36Sopenharmony_ci#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR) 1862306a36Sopenharmony_ci#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE) 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct rsc_drv; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/** 2362306a36Sopenharmony_ci * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests 2462306a36Sopenharmony_ci * to the controller 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * @drv: The controller. 2762306a36Sopenharmony_ci * @type: Type of the TCS in this group - active, sleep, wake. 2862306a36Sopenharmony_ci * @mask: Mask of the TCSes relative to all the TCSes in the RSC. 2962306a36Sopenharmony_ci * @offset: Start of the TCS group relative to the TCSes in the RSC. 3062306a36Sopenharmony_ci * @num_tcs: Number of TCSes in this type. 3162306a36Sopenharmony_ci * @ncpt: Number of commands in each TCS. 3262306a36Sopenharmony_ci * @req: Requests that are sent from the TCS; only used for ACTIVE_ONLY 3362306a36Sopenharmony_ci * transfers (could be on a wake/sleep TCS if we are borrowing for 3462306a36Sopenharmony_ci * an ACTIVE_ONLY transfer). 3562306a36Sopenharmony_ci * Start: grab drv->lock, set req, set tcs_in_use, drop drv->lock, 3662306a36Sopenharmony_ci * trigger 3762306a36Sopenharmony_ci * End: get irq, access req, 3862306a36Sopenharmony_ci * grab drv->lock, clear tcs_in_use, drop drv->lock 3962306a36Sopenharmony_ci * @slots: Indicates which of @cmd_addr are occupied; only used for 4062306a36Sopenharmony_ci * SLEEP / WAKE TCSs. Things are tightly packed in the 4162306a36Sopenharmony_ci * case that (ncpt < MAX_CMDS_PER_TCS). That is if ncpt = 2 and 4262306a36Sopenharmony_ci * MAX_CMDS_PER_TCS = 16 then bit[2] = the first bit in 2nd TCS. 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_cistruct tcs_group { 4562306a36Sopenharmony_ci struct rsc_drv *drv; 4662306a36Sopenharmony_ci int type; 4762306a36Sopenharmony_ci u32 mask; 4862306a36Sopenharmony_ci u32 offset; 4962306a36Sopenharmony_ci int num_tcs; 5062306a36Sopenharmony_ci int ncpt; 5162306a36Sopenharmony_ci const struct tcs_request *req[MAX_TCS_PER_TYPE]; 5262306a36Sopenharmony_ci DECLARE_BITMAP(slots, MAX_TCS_SLOTS); 5362306a36Sopenharmony_ci}; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/** 5662306a36Sopenharmony_ci * struct rpmh_request: the message to be sent to rpmh-rsc 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * @msg: the request 5962306a36Sopenharmony_ci * @cmd: the payload that will be part of the @msg 6062306a36Sopenharmony_ci * @completion: triggered when request is done 6162306a36Sopenharmony_ci * @dev: the device making the request 6262306a36Sopenharmony_ci * @needs_free: check to free dynamically allocated request object 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_cistruct rpmh_request { 6562306a36Sopenharmony_ci struct tcs_request msg; 6662306a36Sopenharmony_ci struct tcs_cmd cmd[MAX_RPMH_PAYLOAD]; 6762306a36Sopenharmony_ci struct completion *completion; 6862306a36Sopenharmony_ci const struct device *dev; 6962306a36Sopenharmony_ci bool needs_free; 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/** 7362306a36Sopenharmony_ci * struct rpmh_ctrlr: our representation of the controller 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * @cache: the list of cached requests 7662306a36Sopenharmony_ci * @cache_lock: synchronize access to the cache data 7762306a36Sopenharmony_ci * @dirty: was the cache updated since flush 7862306a36Sopenharmony_ci * @batch_cache: Cache sleep and wake requests sent as batch 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_cistruct rpmh_ctrlr { 8162306a36Sopenharmony_ci struct list_head cache; 8262306a36Sopenharmony_ci spinlock_t cache_lock; 8362306a36Sopenharmony_ci bool dirty; 8462306a36Sopenharmony_ci struct list_head batch_cache; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistruct rsc_ver { 8862306a36Sopenharmony_ci u32 major; 8962306a36Sopenharmony_ci u32 minor; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/** 9362306a36Sopenharmony_ci * struct rsc_drv: the Direct Resource Voter (DRV) of the 9462306a36Sopenharmony_ci * Resource State Coordinator controller (RSC) 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * @name: Controller identifier. 9762306a36Sopenharmony_ci * @base: Start address of the DRV registers in this controller. 9862306a36Sopenharmony_ci * @tcs_base: Start address of the TCS registers in this controller. 9962306a36Sopenharmony_ci * @id: Instance id in the controller (Direct Resource Voter). 10062306a36Sopenharmony_ci * @num_tcs: Number of TCSes in this DRV. 10162306a36Sopenharmony_ci * @rsc_pm: CPU PM notifier for controller. 10262306a36Sopenharmony_ci * Used when solver mode is not present. 10362306a36Sopenharmony_ci * @cpus_in_pm: Number of CPUs not in idle power collapse. 10462306a36Sopenharmony_ci * Used when solver mode and "power-domains" is not present. 10562306a36Sopenharmony_ci * @genpd_nb: PM Domain notifier for cluster genpd notifications. 10662306a36Sopenharmony_ci * @tcs: TCS groups. 10762306a36Sopenharmony_ci * @tcs_in_use: S/W state of the TCS; only set for ACTIVE_ONLY 10862306a36Sopenharmony_ci * transfers, but might show a sleep/wake TCS in use if 10962306a36Sopenharmony_ci * it was borrowed for an active_only transfer. You 11062306a36Sopenharmony_ci * must hold the lock in this struct (AKA drv->lock) in 11162306a36Sopenharmony_ci * order to update this. 11262306a36Sopenharmony_ci * @lock: Synchronize state of the controller. If RPMH's cache 11362306a36Sopenharmony_ci * lock will also be held, the order is: drv->lock then 11462306a36Sopenharmony_ci * cache_lock. 11562306a36Sopenharmony_ci * @tcs_wait: Wait queue used to wait for @tcs_in_use to free up a 11662306a36Sopenharmony_ci * slot 11762306a36Sopenharmony_ci * @client: Handle to the DRV's client. 11862306a36Sopenharmony_ci * @dev: RSC device. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_cistruct rsc_drv { 12162306a36Sopenharmony_ci const char *name; 12262306a36Sopenharmony_ci void __iomem *base; 12362306a36Sopenharmony_ci void __iomem *tcs_base; 12462306a36Sopenharmony_ci int id; 12562306a36Sopenharmony_ci int num_tcs; 12662306a36Sopenharmony_ci struct notifier_block rsc_pm; 12762306a36Sopenharmony_ci struct notifier_block genpd_nb; 12862306a36Sopenharmony_ci atomic_t cpus_in_pm; 12962306a36Sopenharmony_ci struct tcs_group tcs[TCS_TYPE_NR]; 13062306a36Sopenharmony_ci DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR); 13162306a36Sopenharmony_ci spinlock_t lock; 13262306a36Sopenharmony_ci wait_queue_head_t tcs_wait; 13362306a36Sopenharmony_ci struct rpmh_ctrlr client; 13462306a36Sopenharmony_ci struct device *dev; 13562306a36Sopenharmony_ci struct rsc_ver ver; 13662306a36Sopenharmony_ci u32 *regs; 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ciint rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg); 14062306a36Sopenharmony_ciint rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, 14162306a36Sopenharmony_ci const struct tcs_request *msg); 14262306a36Sopenharmony_civoid rpmh_rsc_invalidate(struct rsc_drv *drv); 14362306a36Sopenharmony_civoid rpmh_rsc_write_next_wakeup(struct rsc_drv *drv); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_civoid rpmh_tx_done(const struct tcs_request *msg); 14662306a36Sopenharmony_ciint rpmh_flush(struct rpmh_ctrlr *ctrlr); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci#endif /* __RPM_INTERNAL_H__ */ 149