blob: f46b2f8038f0ef2016c16f2b785a4849e2436c20 [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);
133
David Daib640f672016-08-09 14:19:33 -0700134/* AXI Port configuration APIs */
135int msm_bus_axi_porthalt(int master_port);
136int msm_bus_axi_portunhalt(int master_port);
137
138#else
139static inline int __init msm_bus_fabric_init_driver(void) { return 0; }
140static struct msm_bus_client_handle dummy_cl;
141
142static inline uint32_t
143msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
144{
145 return 1;
146}
147
148static inline int
149msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
150{
151 return 0;
152}
153
154static inline int
155msm_bus_scale_client_update_context(uint32_t cl, bool active_only,
156 unsigned int ctx_idx)
157{
158 return 0;
159}
160
161static inline void
162msm_bus_scale_unregister_client(uint32_t cl)
163{
164}
165
166static inline int msm_bus_axi_porthalt(int master_port)
167{
168 return 0;
169}
170
171static inline int msm_bus_axi_portunhalt(int master_port)
172{
173 return 0;
174}
175
176static inline struct msm_bus_client_handle*
177msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name,
178 bool active_only)
179{
180 return &dummy_cl;
181}
182
183static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl)
184{
185}
186
187static inline int
188msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
189{
190 return 0;
191}
192
193static inline int
194msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
David Dai14e67ec2017-08-23 12:22:47 -0700195 u64 act_ib, u64 dual_ib, u64 dual_ab)
David Daib640f672016-08-09 14:19:33 -0700196
197{
198 return 0;
199}
200
David Dai9d66f3f2016-11-23 15:33:06 -0800201static inline int msm_bus_scale_query_tcs_cmd(struct msm_bus_tcs_usecase
202 *tcs_usecase, uint32_t cl,
203 unsigned int index)
204{
205 return 0;
206}
207
208static inline int msm_bus_scale_query_tcs_cmd_all(struct msm_bus_tcs_handle
209 *tcs_handle, uint32_t cl)
210{
211 return 0;
212}
213
Odelu Kukatla559858c2017-11-13 22:12:09 +0530214#endif
215
216#if defined(CONFIG_QCOM_BUS_SCALING) && defined(CONFIG_QCOM_BUS_CONFIG_RPMH)
217int msm_bus_noc_throttle_wa(bool enable);
218int msm_bus_noc_priority_wa(bool enable);
219#else
David Daiaf2e3792017-09-07 13:26:04 -0700220static inline int msm_bus_noc_throttle_wa(bool enable)
221{
222 return 0;
223}
224
225static inline int msm_bus_noc_priority_wa(bool enable)
226{
227 return 0;
228}
229
David Daib640f672016-08-09 14:19:33 -0700230#endif
231
232#if defined(CONFIG_OF) && defined(CONFIG_QCOM_BUS_SCALING)
233struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
234 struct platform_device *pdev, struct device_node *of_node);
235struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
236void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
237#else
238static inline struct msm_bus_scale_pdata
239*msm_bus_cl_get_pdata(struct platform_device *pdev)
240{
241 return NULL;
242}
243
244static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
245 struct platform_device *pdev, struct device_node *of_node)
246{
247 return NULL;
248}
249
250static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
251{
252}
253#endif
254
255#ifdef CONFIG_DEBUG_BUS_VOTER
256int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
257 bool active_only);
258int msm_bus_floor_vote(const char *name, u64 floor_hz);
259#else
260static inline int msm_bus_floor_vote(const char *name, u64 floor_hz)
261{
262 return -EINVAL;
263}
264
265static inline int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
266 bool active_only)
267{
268 return -EINVAL;
269}
270#endif /*defined(CONFIG_DEBUG_BUS_VOTER) && defined(CONFIG_BUS_TOPOLOGY_ADHOC)*/
271#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/