1 /* arch/arm/mach-exynos/cal_bts.c
3 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
6 * EXYNOS - BTS CAL code.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include "cal_bts8895.h"
14 #include <linux/soc/samsung/exynos-soc.h>
18 seq_printf(buf, x, ##__VA_ARGS__); \
21 /* for BTS V3.0 Register */
23 #define TREX_CON 0x000
24 #define TREX_TIMEOUT 0x010
25 #define TREX_BLOCK_IDMASK 0x018
26 #define TREX_BLOCK_IDVALUE 0x01C
27 #define TREX_RCON 0x020
28 #define TREX_WCON 0x040
29 #define TREX_RBLOCK_UPPER 0x024
30 #define TREX_WBLOCK_UPPER 0x044
31 #define TREX_RBLOCK_UPPER_NORMAL 0x028
32 #define TREX_WBLOCK_UPPER_NORMAL 0x048
33 #define TREX_RBLOCK_UPPER_FULL 0x02C
34 #define TREX_WBLOCK_UPPER_FULL 0x04C
35 #define TREX_RBLOCK_UPPER_BUSY 0x030
36 #define TREX_WBLOCK_UPPER_BUSY 0x050
37 #define TREX_RBLOCK_UPPER_MAX 0x034
38 #define TREX_WBLOCK_UPPER_MAX 0x054
40 /* trex qos register */
42 #define SCI_CTRL 0x0000
43 #define VC_NUM0 0x0050
44 #define VC_NUM1 0x0054
45 #define VC_NUM2 0x0058
46 #define VC_NUM3 0x005C
47 #define TH_IMM_R_0 0x0100
48 #define TH_IMM_R_1 0x0104
49 #define TH_IMM_R_2 0x0108
50 #define TH_IMM_R_3 0x010C
51 #define TH_IMM_R_4 0x0110
52 #define TH_IMM_R_5 0x0114
53 #define TH_IMM_R_6 0x0118
54 #define TH_IMM_R_7 0x011C
55 #define TH_IMM_R_8 0x0120
56 #define TH_IMM_R_9 0x0124
57 #define TH_IMM_R_10 0x0128
58 #define TH_IMM_R_11 0x012C
59 #define TH_IMM_R_12 0x0130
60 #define TH_IMM_R_13 0x0134
61 #define TH_IMM_W_0 0x0180
62 #define TH_IMM_W_1 0x0184
63 #define TH_IMM_W_2 0x0188
64 #define TH_IMM_W_3 0x018C
65 #define TH_IMM_W_4 0x0190
66 #define TH_IMM_W_5 0x0194
67 #define TH_IMM_W_6 0x0198
68 #define TH_IMM_W_7 0x019C
69 #define TH_IMM_W_8 0x01A0
70 #define TH_IMM_W_9 0x01A4
71 #define TH_IMM_W_10 0x01A8
72 #define TH_IMM_W_11 0x01AC
73 #define TH_IMM_W_12 0x01B0
74 #define TH_IMM_W_13 0x01B4
75 #define TH_HIGH_R_0 0x0200
76 #define TH_HIGH_R_1 0x0204
77 #define TH_HIGH_R_2 0x0208
78 #define TH_HIGH_R_3 0x020C
79 #define TH_HIGH_R_4 0x0210
80 #define TH_HIGH_R_5 0x0214
81 #define TH_HIGH_R_6 0x0218
82 #define TH_HIGH_R_7 0x021C
83 #define TH_HIGH_R_8 0x0220
84 #define TH_HIGH_R_9 0x0224
85 #define TH_HIGH_R_10 0x0228
86 #define TH_HIGH_R_11 0x022C
87 #define TH_HIGH_R_12 0x0230
88 #define TH_HIGH_R_13 0x0234
89 #define TH_HIGH_W_0 0x0280
90 #define TH_HIGH_W_1 0x0284
91 #define TH_HIGH_W_2 0x0288
92 #define TH_HIGH_W_3 0x028C
93 #define TH_HIGH_W_4 0x0290
94 #define TH_HIGH_W_5 0x0294
95 #define TH_HIGH_W_6 0x0298
96 #define TH_HIGH_W_7 0x029C
97 #define TH_HIGH_W_8 0x02A0
98 #define TH_HIGH_W_9 0x02A4
99 #define TH_HIGH_W_10 0x02A8
100 #define TH_HIGH_W_11 0x02AC
101 #define TH_HIGH_W_12 0x02B0
102 #define TH_HIGH_W_13 0x02B4
104 #define QMAX_THRESHOLD_R 0x0050
105 #define QMAX_THRESHOLD_W 0x0054
107 #define SCI_CCMCMDTOKENS0 0x00fc
108 #define SCI_CCMCMDTOKENS1 0x0110
109 #define SCI_CCMTOKENRELEASECTL 0x0104
111 #define SCI_CRP0_CON 0x0204
112 #define SCI_CRP1_CON 0x022C
113 #define SCI_CRP2_CON 0x0254
115 #define SMC_SCHEDCTL_BUNDLE_CTRL4 0x0258
117 static unsigned int set_mo(unsigned int mo
)
119 if (mo
> BTS_MAX_MO
|| !mo
)
124 void bts_setqos(void __iomem
*base
, struct bts_status
*stat
)
126 unsigned int tmp_reg
= 0;
127 bool block_en
= false;
133 __raw_writel(0x4000, base
+ TREX_RCON
);
134 __raw_writel(0x4000, base
+ TREX_WCON
);
135 __raw_writel(0x0, base
+ TREX_CON
);
138 __raw_writel(set_mo(stat
->rmo
), base
+ TREX_RBLOCK_UPPER
);
139 __raw_writel(set_mo(stat
->wmo
), base
+ TREX_WBLOCK_UPPER
);
140 if (stat
->max_rmo
|| stat
->max_wmo
|| stat
->busy_rmo
|| stat
->busy_wmo
)
142 __raw_writel(set_mo(stat
->max_rmo
),
143 base
+ TREX_RBLOCK_UPPER_MAX
);
144 __raw_writel(set_mo(stat
->max_wmo
),
145 base
+ TREX_WBLOCK_UPPER_MAX
);
146 __raw_writel(set_mo(stat
->full_rmo
),
147 base
+ TREX_RBLOCK_UPPER_FULL
);
148 __raw_writel(set_mo(stat
->full_wmo
),
149 base
+ TREX_WBLOCK_UPPER_FULL
);
150 __raw_writel(set_mo(stat
->busy_rmo
),
151 base
+ TREX_RBLOCK_UPPER_BUSY
);
152 __raw_writel(set_mo(stat
->busy_wmo
),
153 base
+ TREX_WBLOCK_UPPER_BUSY
);
154 if (stat
->timeout_en
) {
155 if (stat
->timeout_r
> 0xff)
156 stat
->timeout_r
= 0xff;
157 if (stat
->timeout_w
> 0xff)
158 stat
->timeout_w
= 0xff;
159 __raw_writel(stat
->timeout_w
| (stat
->timeout_r
<< 16),
160 base
+ TREX_TIMEOUT
);
162 __raw_writel(0xff | (0xff << 16),
163 base
+ TREX_TIMEOUT
);
165 /* override QoS value */
166 tmp_reg
|= (1 & !stat
->bypass_en
) << 8;
167 tmp_reg
|= (stat
->priority
& 0xf) << 12;
168 /* enable Blocking logic */
169 tmp_reg
|= (1 & block_en
) << 0;
170 __raw_writel(tmp_reg
, base
+ TREX_RCON
);
171 __raw_writel(tmp_reg
, base
+ TREX_WCON
);
173 __raw_writel(((1 & stat
->timeout_en
) << 20) | 0x1, base
+ TREX_CON
);
176 void bts_showqos(void __iomem
*base
, struct seq_file
*buf
)
180 LOG("CON0x%08X qos(%d,%d)0x%Xr%Xw TO(%d)0x%04Xr%04Xw"
181 "MO(%d,%d)0x%04xr%04xwQbusy0x%04xr%04xwQfull0x%04xr%04xw"
182 "Qmax0x%04xr%04xw\n",
183 __raw_readl(base
+ TREX_CON
),
184 (__raw_readl(base
+ TREX_RCON
) >> 8) & 0x1,
185 (__raw_readl(base
+ TREX_WCON
) >> 8) & 0x1,
186 (__raw_readl(base
+ TREX_RCON
) >> 12) & 0xf,
187 (__raw_readl(base
+ TREX_WCON
) >> 12) & 0xf,
188 (__raw_readl(base
+ TREX_CON
) >> 20) & 0x1,
189 (__raw_readl(base
+ TREX_TIMEOUT
)) & 0xff,
190 (__raw_readl(base
+ TREX_TIMEOUT
) >> 16) & 0xff,
191 __raw_readl(base
+ TREX_RCON
) & 0x1,
192 __raw_readl(base
+ TREX_WCON
) & 0x1,
193 __raw_readl(base
+ TREX_RBLOCK_UPPER
),
194 __raw_readl(base
+ TREX_WBLOCK_UPPER
),
195 __raw_readl(base
+ TREX_RBLOCK_UPPER_BUSY
),
196 __raw_readl(base
+ TREX_WBLOCK_UPPER_BUSY
),
197 __raw_readl(base
+ TREX_RBLOCK_UPPER_FULL
),
198 __raw_readl(base
+ TREX_WBLOCK_UPPER_FULL
),
199 __raw_readl(base
+ TREX_RBLOCK_UPPER_MAX
),
200 __raw_readl(base
+ TREX_WBLOCK_UPPER_MAX
));
203 void bts_trex_init(void __iomem
*base
)
208 /* high [27:24] mid [19:16] threshold */
209 __raw_writel(0x0B050000, base
+ SCI_CTRL
);
210 /* disp [5:0] cam [11:6] ISPLP [11:10] SRDZ [13:12] */
211 __raw_writel(0x00000A95, base
+ VC_NUM0
);
212 __raw_writel(0x0A95C000, base
+ VC_NUM1
);
213 __raw_writel(0xC0000000, base
+ VC_NUM2
);
214 __raw_writel(0x00000300, base
+ VC_NUM3
);
216 __raw_writel(0x0c101010, base
+ TH_IMM_R_0
);
217 __raw_writel(0x10100c0c, base
+ TH_IMM_R_1
);
218 __raw_writel(0x0c101010, base
+ TH_IMM_R_6
);
219 __raw_writel(0x10100c0c, base
+ TH_IMM_R_7
);
220 __raw_writel(0x0006000c, base
+ TH_IMM_W_0
);
221 __raw_writel(0x10100606, base
+ TH_IMM_W_1
);
222 __raw_writel(0x0006000c, base
+ TH_IMM_W_6
);
223 __raw_writel(0x10100606, base
+ TH_IMM_W_7
);
224 __raw_writel(0x04101010, base
+ TH_HIGH_R_0
);
225 __raw_writel(0x10100404, base
+ TH_HIGH_R_1
);
226 __raw_writel(0x04101010, base
+ TH_HIGH_R_6
);
227 __raw_writel(0x10100404, base
+ TH_HIGH_R_7
);
228 __raw_writel(0x02101010, base
+ TH_HIGH_W_0
);
229 __raw_writel(0x10100202, base
+ TH_HIGH_W_1
);
230 __raw_writel(0x02101010, base
+ TH_HIGH_W_6
);
231 __raw_writel(0x10100202, base
+ TH_HIGH_W_7
);
234 void bts_set_qmax(void __iomem
*base
, unsigned int rmo
, unsigned int wmo
)
236 __raw_writel(set_mo(rmo
), base
+ QMAX_THRESHOLD_R
);
237 __raw_writel(set_mo(wmo
), base
+ QMAX_THRESHOLD_W
);
241 void bts_set_tq(void __iomem
*base
, unsigned int tq
)
243 unsigned int tmp_reg
= 0;
246 tmp_reg
= __raw_readl(base
+ SCI_CRP0_CON
);
247 tmp_reg
&= ~(0x7 << 20);
249 __raw_writel(tmp_reg
, base
+ SCI_CRP0_CON
);
250 tmp_reg
= __raw_readl(base
+ SCI_CRP1_CON
);
251 tmp_reg
&= ~(0x7 << 20);
253 __raw_writel(tmp_reg
, base
+ SCI_CRP1_CON
);
254 tmp_reg
= __raw_readl(base
+ SCI_CRP2_CON
);
255 tmp_reg
&= ~(0x7 << 20);
257 __raw_writel(tmp_reg
, base
+ SCI_CRP2_CON
);
260 void bts_set_qbusy(void __iomem
*base
, unsigned int qbusy
)
262 unsigned int tmp_reg
= 0;
265 tmp_reg
= __raw_readl(base
+ SMC_SCHEDCTL_BUNDLE_CTRL4
);
266 tmp_reg
&= ~(0x3f << 16);
267 tmp_reg
&= ~(0x3f << 24);
268 tmp_reg
|= qbusy
<< 16;
269 tmp_reg
|= qbusy
<< 24;
270 __raw_writel(tmp_reg
, base
+ SMC_SCHEDCTL_BUNDLE_CTRL4
);
273 void bts_set_qfull(void __iomem
*base
, unsigned int qfull_low
,
274 unsigned int qfull_high
)
276 unsigned int tmp_reg
= 0;
277 if (qfull_low
> 0x3f)
279 if (qfull_high
< qfull_low
)
280 qfull_high
= qfull_low
;
281 else if (qfull_high
> 0x3f)
283 tmp_reg
= __raw_readl(base
+ SCI_CCMTOKENRELEASECTL
);
284 tmp_reg
&= ~(0x3f << 6);
285 tmp_reg
&= ~(0x3f << 12);
286 tmp_reg
|= qfull_high
<< 6;
287 tmp_reg
|= qfull_low
<< 12;
288 __raw_writel(tmp_reg
, base
+ SCI_CCMTOKENRELEASECTL
);