blob: a584e0ad1ae111b8c7c6c90dfb7cbf5885baa4b2 [file] [log] [blame]
David Daibee66232017-03-31 19:05:39 -07001/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
David Daib640f672016-08-09 14:19:33 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#ifndef _ARCH_ARM_MACH_MSM_BUS_H
14#define _ARCH_ARM_MACH_MSM_BUS_H
15
16#include <linux/types.h>
17#include <linux/input.h>
18#include <linux/platform_device.h>
David Dai9d66f3f2016-11-23 15:33:06 -080019#include <soc/qcom/tcs.h>
David Daib640f672016-08-09 14:19:33 -070020
21/*
22 * Macros for clients to convert their data to ib and ab
23 * Ws : Time window over which to transfer the data in SECONDS
24 * Bs : Size of the data block in bytes
25 * Per : Recurrence period
26 * Tb : Throughput bandwidth to prevent stalling
27 * R : Ratio of actual bandwidth used to Tb
28 * Ib : Instantaneous bandwidth
29 * Ab : Arbitrated bandwidth
30 *
31 * IB_RECURRBLOCK and AB_RECURRBLOCK:
32 * These are used if the requirement is to transfer a
33 * recurring block of data over a known time window.
34 *
35 * IB_THROUGHPUTBW and AB_THROUGHPUTBW:
36 * These are used for CPU style masters. Here the requirement
37 * is to have minimum throughput bandwidth available to avoid
38 * stalling.
39 */
40#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws)))
41#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per)))
42#define IB_THROUGHPUTBW(Tb) (Tb)
43#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R))
David Dai9d66f3f2016-11-23 15:33:06 -080044#define MSM_BUS_MAX_TCS_CMDS 16
David Daib640f672016-08-09 14:19:33 -070045
46struct msm_bus_vectors {
47 int src; /* Master */
48 int dst; /* Slave */
49 uint64_t ab; /* Arbitrated bandwidth */
50 uint64_t ib; /* Instantaneous bandwidth */
51};
52
53struct msm_bus_paths {
54 int num_paths;
55 struct msm_bus_vectors *vectors;
56};
57
David Daibee66232017-03-31 19:05:39 -070058struct msm_bus_lat_vectors {
59 uint64_t fal_ns; /* First Access Latency */
60 uint64_t idle_t_ns; /* Idle Time */
61};
62
David Daib640f672016-08-09 14:19:33 -070063struct msm_bus_scale_pdata {
64 struct msm_bus_paths *usecase;
David Daibee66232017-03-31 19:05:39 -070065 struct msm_bus_lat_vectors *usecase_lat;
David Daib640f672016-08-09 14:19:33 -070066 int num_usecases;
67 const char *name;
68 /*
69 * If the active_only flag is set to 1, the BW request is applied
70 * only when at least one CPU is active (powered on). If the flag
71 * is set to 0, then the BW request is always applied irrespective
72 * of the CPU state.
73 */
74 unsigned int active_only;
David Daibee66232017-03-31 19:05:39 -070075 /*
76 * If the ALC(Active Latency Client) flag is set to 1,
77 * use lat_usecases for latency voting.
78 */
79 unsigned int alc;
David Daib640f672016-08-09 14:19:33 -070080};
81
82struct msm_bus_client_handle {
83 char *name;
84 int mas;
85 int slv;
86 int first_hop;
87 struct device *mas_dev;
88 u64 cur_act_ib;
89 u64 cur_act_ab;
David Dai14e67ec2017-08-23 12:22:47 -070090 u64 cur_dual_ib;
91 u64 cur_dual_ab;
David Daib640f672016-08-09 14:19:33 -070092 bool active_only;
93};
94
David Dai9d66f3f2016-11-23 15:33:06 -080095struct msm_bus_tcs_usecase {
96 int num_cmds;
97 struct tcs_cmd cmds[MSM_BUS_MAX_TCS_CMDS];
98};
99
100struct msm_bus_tcs_handle {
101 int num_usecases;
102 struct msm_bus_tcs_usecase *usecases;
103};
104
David Daib640f672016-08-09 14:19:33 -0700105/* Scaling APIs */
106
107/*
108 * This function returns a handle to the client. This should be used to
109 * call msm_bus_scale_client_update_request.
110 * The function returns 0 if bus driver is unable to register a client
111 */
112
113#if (defined(CONFIG_QCOM_BUS_SCALING) ||\
114 defined(CONFIG_QCOM_BUS_TOPOLOGY_ADHOC))
115int __init msm_bus_fabric_init_driver(void);
116uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata);
117int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index);
118void msm_bus_scale_unregister_client(uint32_t cl);
119int msm_bus_scale_client_update_context(uint32_t cl, bool active_only,
120 unsigned int ctx_idx);
121
122struct msm_bus_client_handle*
123msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name,
124 bool active_only);
125void msm_bus_scale_unregister(struct msm_bus_client_handle *cl);
126int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib);
127int msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl,
David Dai14e67ec2017-08-23 12:22:47 -0700128 u64 act_ab, u64 act_ib, u64 dual_ib, u64 dual_ab);
David Dai9d66f3f2016-11-23 15:33:06 -0800129int msm_bus_scale_query_tcs_cmd(struct msm_bus_tcs_usecase *tcs_usecase,
130 uint32_t cl, unsigned int index);
131int msm_bus_scale_query_tcs_cmd_all(struct msm_bus_tcs_handle *tcs_handle,
132 uint32_t cl);
David Daiaf2e3792017-09-07 13:26:04 -0700133int msm_bus_noc_throttle_wa(bool enable);
134int msm_bus_noc_priority_wa(bool enable);
David Dai9d66f3f2016-11-23 15:33:06 -0800135
David Daib640f672016-08-09 14:19:33 -0700136/* AXI Port configuration APIs */
137int msm_bus_axi_porthalt(int master_port);
138int msm_bus_axi_portunhalt(int master_port);
139
140#else
141static inline int __init msm_bus_fabric_init_driver(void) { return 0; }
142static struct msm_bus_client_handle dummy_cl;
143
144static inline uint32_t
145msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
146{
147 return 1;
148}
149
150static inline int
151msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
152{
153 return 0;
154}
155
156static inline int
157msm_bus_scale_client_update_context(uint32_t cl, bool active_only,
158 unsigned int ctx_idx)
159{
160 return 0;
161}
162
163static inline void
164msm_bus_scale_unregister_client(uint32_t cl)
165{
166}
167
168static inline int msm_bus_axi_porthalt(int master_port)
169{
170 return 0;
171}
172
173static inline int msm_bus_axi_portunhalt(int master_port)
174{
175 return 0;
176}
177
178static inline struct msm_bus_client_handle*
179msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name,
180 bool active_only)
181{
182 return &dummy_cl;
183}
184
185static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl)
186{
187}
188
189static inline int
190msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
191{
192 return 0;
193}
194
195static inline int
196msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
David Dai14e67ec2017-08-23 12:22:47 -0700197 u64 act_ib, u64 dual_ib, u64 dual_ab)
David Daib640f672016-08-09 14:19:33 -0700198
199{
200 return 0;
201}
202
David Dai9d66f3f2016-11-23 15:33:06 -0800203static inline int msm_bus_scale_query_tcs_cmd(struct msm_bus_tcs_usecase
204 *tcs_usecase, uint32_t cl,
205 unsigned int index)
206{
207 return 0;
208}
209
210static inline int msm_bus_scale_query_tcs_cmd_all(struct msm_bus_tcs_handle
211 *tcs_handle, uint32_t cl)
212{
213 return 0;
214}
215
David Daiaf2e3792017-09-07 13:26:04 -0700216static inline int msm_bus_noc_throttle_wa(bool enable)
217{
218 return 0;
219}
220
221static inline int msm_bus_noc_priority_wa(bool enable)
222{
223 return 0;
224}
225
David Daib640f672016-08-09 14:19:33 -0700226#endif
227
228#if defined(CONFIG_OF) && defined(CONFIG_QCOM_BUS_SCALING)
229struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
230 struct platform_device *pdev, struct device_node *of_node);
231struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
232void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
233#else
234static inline struct msm_bus_scale_pdata
235*msm_bus_cl_get_pdata(struct platform_device *pdev)
236{
237 return NULL;
238}
239
240static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
241 struct platform_device *pdev, struct device_node *of_node)
242{
243 return NULL;
244}
245
246static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
247{
248}
249#endif
250
251#ifdef CONFIG_DEBUG_BUS_VOTER
252int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
253 bool active_only);
254int msm_bus_floor_vote(const char *name, u64 floor_hz);
255#else
256static inline int msm_bus_floor_vote(const char *name, u64 floor_hz)
257{
258 return -EINVAL;
259}
260
261static inline int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
262 bool active_only)
263{
264 return -EINVAL;
265}
266#endif /*defined(CONFIG_DEBUG_BUS_VOTER) && defined(CONFIG_BUS_TOPOLOGY_ADHOC)*/
267#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/