2018-06-20 16:26:58 +03:00
/* 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>
2020-07-25 00:17:11 +03:00
# include <linux/wait.h>
2018-06-20 16:26:58 +03:00
# 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)
2018-06-20 16:27:02 +03:00
# define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE)
2018-06-20 16:26:58 +03:00
struct rsc_drv ;
/**
* struct tcs_group : group of Trigger Command Sets ( TCS ) to send state requests
* to the controller
*
2020-04-13 20:04:11 +03:00
* @ 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 .
* @ req : Requests that are sent from the TCS ; only used for ACTIVE_ONLY
* transfers ( could be on a wake / sleep TCS if we are borrowing for
* an ACTIVE_ONLY transfer ) .
* Start : grab drv - > lock , set req , set tcs_in_use , drop drv - > lock ,
* trigger
* End : get irq , access req ,
* grab drv - > lock , clear tcs_in_use , drop drv - > lock
* @ slots : Indicates which of @ cmd_addr are occupied ; only used for
* SLEEP / WAKE TCSs . Things are tightly packed in the
* case that ( ncpt < MAX_CMDS_PER_TCS ) . That is if ncpt = 2 and
* MAX_CMDS_PER_TCS = 16 then bit [ 2 ] = the first bit in 2 nd TCS .
2018-06-20 16:26:58 +03:00
*/
struct tcs_group {
struct rsc_drv * drv ;
int type ;
u32 mask ;
u32 offset ;
int num_tcs ;
int ncpt ;
const struct tcs_request * req [ MAX_TCS_PER_TYPE ] ;
2018-06-20 16:27:02 +03:00
DECLARE_BITMAP ( slots , MAX_TCS_SLOTS ) ;
2018-06-20 16:26:58 +03:00
} ;
2018-06-20 16:27:01 +03:00
/**
* struct rpmh_request : the message to be sent to rpmh - rsc
*
* @ msg : the request
* @ cmd : the payload that will be part of the @ msg
* @ completion : triggered when request is done
* @ dev : the device making the request
2018-06-20 16:27:05 +03:00
* @ needs_free : check to free dynamically allocated request object
2018-06-20 16:27:01 +03:00
*/
struct rpmh_request {
struct tcs_request msg ;
struct tcs_cmd cmd [ MAX_RPMH_PAYLOAD ] ;
struct completion * completion ;
const struct device * dev ;
2018-06-20 16:27:05 +03:00
bool needs_free ;
2018-06-20 16:27:01 +03:00
} ;
/**
* struct rpmh_ctrlr : our representation of the controller
*
2018-06-20 16:27:04 +03:00
* @ cache : the list of cached requests
* @ cache_lock : synchronize access to the cache data
* @ dirty : was the cache updated since flush
2018-06-20 16:27:06 +03:00
* @ batch_cache : Cache sleep and wake requests sent as batch
2018-06-20 16:27:01 +03:00
*/
struct rpmh_ctrlr {
2018-06-20 16:27:04 +03:00
struct list_head cache ;
spinlock_t cache_lock ;
bool dirty ;
2018-06-20 16:27:06 +03:00
struct list_head batch_cache ;
2018-06-20 16:27:01 +03:00
} ;
2022-11-16 14:22:45 +03:00
struct rsc_ver {
u32 major ;
u32 minor ;
} ;
2018-06-20 16:26:58 +03:00
/**
* struct rsc_drv : the Direct Resource Voter ( DRV ) of the
* Resource State Coordinator controller ( RSC )
*
2020-04-13 20:04:11 +03:00
* @ name : Controller identifier .
2022-10-18 18:28:36 +03:00
* @ base : Start address of the DRV registers in this controller .
2020-04-13 20:04:11 +03:00
* @ 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 .
* @ rsc_pm : CPU PM notifier for controller .
* Used when solver mode is not present .
2020-05-04 20:50:19 +03:00
* @ cpus_in_pm : Number of CPUs not in idle power collapse .
2022-10-18 18:28:33 +03:00
* Used when solver mode and " power-domains " is not present .
* @ genpd_nb : PM Domain notifier for cluster genpd notifications .
2020-04-13 20:04:11 +03:00
* @ tcs : TCS groups .
* @ tcs_in_use : S / W state of the TCS ; only set for ACTIVE_ONLY
* transfers , but might show a sleep / wake TCS in use if
* it was borrowed for an active_only transfer . You
2020-05-04 20:50:18 +03:00
* must hold the lock in this struct ( AKA drv - > lock ) in
* order to update this .
2020-05-04 20:50:19 +03:00
* @ lock : Synchronize state of the controller . If RPMH ' s cache
* lock will also be held , the order is : drv - > lock then
* cache_lock .
2020-07-25 00:17:11 +03:00
* @ tcs_wait : Wait queue used to wait for @ tcs_in_use to free up a
* slot
2020-04-12 17:50:02 +03:00
* @ client : Handle to the DRV ' s client .
2022-10-18 18:28:37 +03:00
* @ dev : RSC device .
2018-06-20 16:26:58 +03:00
*/
struct rsc_drv {
const char * name ;
2022-10-18 18:28:36 +03:00
void __iomem * base ;
2018-06-20 16:26:58 +03:00
void __iomem * tcs_base ;
int id ;
int num_tcs ;
2020-04-12 17:50:02 +03:00
struct notifier_block rsc_pm ;
2022-10-18 18:28:33 +03:00
struct notifier_block genpd_nb ;
2020-05-04 20:50:19 +03:00
atomic_t cpus_in_pm ;
2018-06-20 16:26:58 +03:00
struct tcs_group tcs [ TCS_TYPE_NR ] ;
DECLARE_BITMAP ( tcs_in_use , MAX_TCS_NR ) ;
spinlock_t lock ;
2020-07-25 00:17:11 +03:00
wait_queue_head_t tcs_wait ;
2018-06-20 16:27:01 +03:00
struct rpmh_ctrlr client ;
2022-10-18 18:28:37 +03:00
struct device * dev ;
2022-11-16 14:22:45 +03:00
struct rsc_ver ver ;
u32 * regs ;
2018-06-20 16:26:58 +03:00
} ;
int rpmh_rsc_send_data ( struct rsc_drv * drv , const struct tcs_request * msg ) ;
2018-06-20 16:27:02 +03:00
int rpmh_rsc_write_ctrl_data ( struct rsc_drv * drv ,
const struct tcs_request * msg ) ;
2020-04-13 20:04:14 +03:00
void rpmh_rsc_invalidate ( struct rsc_drv * drv ) ;
2022-10-18 18:28:37 +03:00
void rpmh_rsc_write_next_wakeup ( struct rsc_drv * drv ) ;
2018-06-20 16:26:58 +03:00
2022-11-16 14:22:46 +03:00
void rpmh_tx_done ( const struct tcs_request * msg ) ;
2020-02-03 16:35:35 +03:00
int rpmh_flush ( struct rpmh_ctrlr * ctrlr ) ;
2018-06-20 16:27:01 +03:00
2018-06-20 16:26:58 +03:00
# endif /* __RPM_INTERNAL_H__ */