blob: 6ebdaa21ba09e5ff4216cbc12717673516c11a58 [file] [log] [blame]
David Daib640f672016-08-09 14:19:33 -07001/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
2 *
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>
19
20/*
21 * Macros for clients to convert their data to ib and ab
22 * Ws : Time window over which to transfer the data in SECONDS
23 * Bs : Size of the data block in bytes
24 * Per : Recurrence period
25 * Tb : Throughput bandwidth to prevent stalling
26 * R : Ratio of actual bandwidth used to Tb
27 * Ib : Instantaneous bandwidth
28 * Ab : Arbitrated bandwidth
29 *
30 * IB_RECURRBLOCK and AB_RECURRBLOCK:
31 * These are used if the requirement is to transfer a
32 * recurring block of data over a known time window.
33 *
34 * IB_THROUGHPUTBW and AB_THROUGHPUTBW:
35 * These are used for CPU style masters. Here the requirement
36 * is to have minimum throughput bandwidth available to avoid
37 * stalling.
38 */
39#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws)))
40#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per)))
41#define IB_THROUGHPUTBW(Tb) (Tb)
42#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R))
43
44struct msm_bus_vectors {
45 int src; /* Master */
46 int dst; /* Slave */
47 uint64_t ab; /* Arbitrated bandwidth */
48 uint64_t ib; /* Instantaneous bandwidth */
49};
50
51struct msm_bus_paths {
52 int num_paths;
53 struct msm_bus_vectors *vectors;
54};
55
56struct msm_bus_scale_pdata {
57 struct msm_bus_paths *usecase;
58 int num_usecases;
59 const char *name;
60 /*
61 * If the active_only flag is set to 1, the BW request is applied
62 * only when at least one CPU is active (powered on). If the flag
63 * is set to 0, then the BW request is always applied irrespective
64 * of the CPU state.
65 */
66 unsigned int active_only;
67};
68
69struct msm_bus_client_handle {
70 char *name;
71 int mas;
72 int slv;
73 int first_hop;
74 struct device *mas_dev;
75 u64 cur_act_ib;
76 u64 cur_act_ab;
77 u64 cur_slp_ib;
78 u64 cur_slp_ab;
79 bool active_only;
80};
81
82/* Scaling APIs */
83
84/*
85 * This function returns a handle to the client. This should be used to
86 * call msm_bus_scale_client_update_request.
87 * The function returns 0 if bus driver is unable to register a client
88 */
89
90#if (defined(CONFIG_QCOM_BUS_SCALING) ||\
91 defined(CONFIG_QCOM_BUS_TOPOLOGY_ADHOC))
92int __init msm_bus_fabric_init_driver(void);
93uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata);
94int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index);
95void msm_bus_scale_unregister_client(uint32_t cl);
96int msm_bus_scale_client_update_context(uint32_t cl, bool active_only,
97 unsigned int ctx_idx);
98
99struct msm_bus_client_handle*
100msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name,
101 bool active_only);
102void msm_bus_scale_unregister(struct msm_bus_client_handle *cl);
103int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib);
104int msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl,
105 u64 act_ab, u64 act_ib, u64 slp_ib, u64 slp_ab);
106/* AXI Port configuration APIs */
107int msm_bus_axi_porthalt(int master_port);
108int msm_bus_axi_portunhalt(int master_port);
109
110#else
111static inline int __init msm_bus_fabric_init_driver(void) { return 0; }
112static struct msm_bus_client_handle dummy_cl;
113
114static inline uint32_t
115msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
116{
117 return 1;
118}
119
120static inline int
121msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
122{
123 return 0;
124}
125
126static inline int
127msm_bus_scale_client_update_context(uint32_t cl, bool active_only,
128 unsigned int ctx_idx)
129{
130 return 0;
131}
132
133static inline void
134msm_bus_scale_unregister_client(uint32_t cl)
135{
136}
137
138static inline int msm_bus_axi_porthalt(int master_port)
139{
140 return 0;
141}
142
143static inline int msm_bus_axi_portunhalt(int master_port)
144{
145 return 0;
146}
147
148static inline struct msm_bus_client_handle*
149msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name,
150 bool active_only)
151{
152 return &dummy_cl;
153}
154
155static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl)
156{
157}
158
159static inline int
160msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
161{
162 return 0;
163}
164
165static inline int
166msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
167 u64 act_ib, u64 slp_ib, u64 slp_ab)
168
169{
170 return 0;
171}
172
173#endif
174
175#if defined(CONFIG_OF) && defined(CONFIG_QCOM_BUS_SCALING)
176struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
177 struct platform_device *pdev, struct device_node *of_node);
178struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
179void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
180#else
181static inline struct msm_bus_scale_pdata
182*msm_bus_cl_get_pdata(struct platform_device *pdev)
183{
184 return NULL;
185}
186
187static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
188 struct platform_device *pdev, struct device_node *of_node)
189{
190 return NULL;
191}
192
193static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
194{
195}
196#endif
197
198#ifdef CONFIG_DEBUG_BUS_VOTER
199int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
200 bool active_only);
201int msm_bus_floor_vote(const char *name, u64 floor_hz);
202#else
203static inline int msm_bus_floor_vote(const char *name, u64 floor_hz)
204{
205 return -EINVAL;
206}
207
208static inline int msm_bus_floor_vote_context(const char *name, u64 floor_hz,
209 bool active_only)
210{
211 return -EINVAL;
212}
213#endif /*defined(CONFIG_DEBUG_BUS_VOTER) && defined(CONFIG_BUS_TOPOLOGY_ADHOC)*/
214#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/