blob: aa8fa01250e731cb6a72c1653742b346a51284c0 [file] [log] [blame]
Dhaval Patel020f7e122016-11-15 14:39:18 -08001/* Copyright (c) 2016-2017, 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
14#define pr_fmt(fmt) "[sde_rsc_hw:%s:%d]: " fmt, __func__, __LINE__
15
16#include <linux/kernel.h>
17#include <linux/debugfs.h>
18#include <linux/delay.h>
19
Dhaval Patel49ef6d72017-03-26 09:35:53 -070020#include "sde_rsc_priv.h"
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -070021#include "sde_dbg.h"
Dhaval Patel020f7e122016-11-15 14:39:18 -080022
23/* display rsc offset */
24#define SDE_RSCC_PDC_SEQ_START_ADDR_REG_OFFSET_DRV0 0x020
25#define SDE_RSCC_PDC_MATCH_VALUE_LO_REG_OFFSET_DRV0 0x024
26#define SDE_RSCC_PDC_MATCH_VALUE_HI_REG_OFFSET_DRV0 0x028
27#define SDE_RSCC_PDC_SLAVE_ID_DRV0 0x02c
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -070028#define SDE_RSCC_SEQ_PROGRAM_COUNTER 0x408
Dhaval Patel020f7e122016-11-15 14:39:18 -080029#define SDE_RSCC_SEQ_CFG_BR_ADDR_0_DRV0 0x410
30#define SDE_RSCC_SEQ_CFG_BR_ADDR_1_DRV0 0x414
31#define SDE_RSCC_SEQ_MEM_0_DRV0 0x600
32#define SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0 0xc14
33#define SDE_RSCC_ERROR_IRQ_STATUS_DRV0 0x0d0
34#define SDE_RSCC_SEQ_BUSY_DRV0 0x404
35#define SDE_RSCC_SOLVER_STATUS0_DRV0 0xc24
36#define SDE_RSCC_SOLVER_STATUS1_DRV0 0xc28
37#define SDE_RSCC_SOLVER_STATUS2_DRV0 0xc2c
38#define SDE_RSCC_AMC_TCS_MODE_IRQ_STATUS_DRV0 0x1c00
39
40#define SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0 0xc04
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -070041#define SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0 0xc08
Dhaval Patel020f7e122016-11-15 14:39:18 -080042#define SDE_RSCC_MAX_IDLE_DURATION_DRV0 0xc0c
43#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0 0x1000
44#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0 0x1004
45#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_2_DRV0 0x1008
46#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_3_DRV0 0x100c
47
48#define SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0 0xc20
49#define SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT0_PRI0_DRV0 0x1080
50#define SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT1_PRI0_DRV0 0x1100
51#define SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT1_PRI3_DRV0 0x110c
52#define SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT2_PRI0_DRV0 0x1180
53#define SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT2_PRI3_DRV0 0x118c
54
55#define SDE_RSC_SOLVER_OVERRIDE_MODE_DRV0 0xc18
56#define SDE_RSC_SOLVER_OVERRIDE_CTRL_DRV0 0xc14
57#define SDE_RSC_TIMERS_CONSIDERED_DRV0 0xc00
58#define SDE_RSC_SOLVER_OVERRIDE_IDLE_TIME_DRV0 0xc1c
59
60#define SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE0 0xc30
61#define SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE0 0xc34
62#define SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE0 0xc38
63#define SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE0 0xc40
64
65#define SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE1 0xc4c
66#define SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE1 0xc50
67#define SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE1 0xc54
68#define SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE1 0xc5c
69
70#define SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE2 0xc68
71#define SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE2 0xc6c
72#define SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE2 0xc70
73#define SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE2 0xc78
74
75#define SDE_RSCC_TCS_DRV0_CONTROL 0x1c14
76
77#define SDE_RSCC_WRAPPER_CTRL 0x000
78#define SDE_RSCC_WRAPPER_OVERRIDE_CTRL 0x004
79#define SDE_RSCC_WRAPPER_STATIC_WAKEUP_0 0x008
80#define SDE_RSCC_WRAPPER_RSCC_MODE_THRESHOLD 0x00c
81#define SDE_RSCC_WRAPPER_DEBUG_BUS 0x010
82#define SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP0 0x018
83#define SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP1 0x01c
84#define SDE_RSCC_SPARE_PWR_EVENT 0x020
85#define SDE_RSCC_PWR_CTRL 0x024
86
87/* qtimer offset */
88#define SDE_RSCC_QTMR_AC_HW_FRAME_SEL_1 0x1FE0
89#define SDE_RSCC_QTMR_AC_HW_FRAME_SEL_2 0x1FF0
90#define SDE_RSCC_QTMR_AC_CNTACR0_FG0 0x1040
91#define SDE_RSCC_QTMR_AC_CNTACR1_FG0 0x1044
92#define SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO 0x2020
93#define SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI 0x2024
94#define SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO 0x3020
95#define SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI 0x3024
96#define SDE_RSCC_F0_QTMR_V1_CNTP_CTL 0x202C
97#define SDE_RSCC_F1_QTMR_V1_CNTP_CTL 0x302C
98
Dhaval Patel020f7e122016-11-15 14:39:18 -080099#define MAX_CHECK_LOOPS 500
Dhaval Patel824e9682017-05-01 23:31:22 -0700100#define POWER_CTRL_BIT_12 12
Dhaval Patel020f7e122016-11-15 14:39:18 -0800101
Dhaval Patel031b4152017-03-16 13:03:18 -0700102static void rsc_event_trigger(struct sde_rsc_priv *rsc, uint32_t event_type)
103{
104 struct sde_rsc_event *event;
105
106 list_for_each_entry(event, &rsc->event_list, list)
107 if (event->event_type & event_type)
108 event->cb_func(event_type, event->usr);
109}
110
Dhaval Patel020f7e122016-11-15 14:39:18 -0800111static int rsc_hw_qtimer_init(struct sde_rsc_priv *rsc)
112{
113 pr_debug("rsc hardware qtimer init\n");
114
115 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_QTMR_AC_HW_FRAME_SEL_1,
116 0xffffffff, rsc->debug_mode);
117 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_QTMR_AC_HW_FRAME_SEL_2,
118 0xffffffff, rsc->debug_mode);
119
120 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_QTMR_AC_CNTACR0_FG0,
121 0x1, rsc->debug_mode);
122 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_QTMR_AC_CNTACR1_FG0,
123 0x1, rsc->debug_mode);
124
125 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
126 0xffffffff, rsc->debug_mode);
127 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
128 0xffffffff, rsc->debug_mode);
129 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
130 0xffffffff, rsc->debug_mode);
131 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
132 0xffffffff, rsc->debug_mode);
133
134 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CTL,
135 0x1, rsc->debug_mode);
136 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CTL,
137 0x1, rsc->debug_mode);
138
139 return 0;
140}
141
142static int rsc_hw_pdc_init(struct sde_rsc_priv *rsc)
143{
144 pr_debug("rsc hardware pdc init\n");
145
146 dss_reg_w(&rsc->drv_io, SDE_RSCC_PDC_SEQ_START_ADDR_REG_OFFSET_DRV0,
147 0x4520, rsc->debug_mode);
148 dss_reg_w(&rsc->drv_io, SDE_RSCC_PDC_MATCH_VALUE_LO_REG_OFFSET_DRV0,
149 0x4510, rsc->debug_mode);
150 dss_reg_w(&rsc->drv_io, SDE_RSCC_PDC_MATCH_VALUE_HI_REG_OFFSET_DRV0,
151 0x4514, rsc->debug_mode);
152 dss_reg_w(&rsc->drv_io, SDE_RSCC_PDC_SLAVE_ID_DRV0,
153 0x1, rsc->debug_mode);
154
155 return 0;
156}
157
158static int rsc_hw_wrapper_init(struct sde_rsc_priv *rsc)
159{
160 pr_debug("rsc hardware wrapper init\n");
161
162 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_STATIC_WAKEUP_0,
163 rsc->timer_config.static_wakeup_time_ns, rsc->debug_mode);
164
165 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_RSCC_MODE_THRESHOLD,
166 rsc->timer_config.rsc_mode_threshold_time_ns, rsc->debug_mode);
167
168 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
169 BIT(8), rsc->debug_mode);
170 return 0;
171}
172
173static int rsc_hw_seq_memory_init(struct sde_rsc_priv *rsc)
174{
175 pr_debug("rsc sequencer memory init\n");
176
177 /* Mode - 0 sequence */
178 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x0,
179 0xe0a88bab, rsc->debug_mode);
180 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x4,
181 0x8babec39, rsc->debug_mode);
182 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x8,
183 0x8bab2088, rsc->debug_mode);
184
185 /* Mode - 1 sequence */
186 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0xc,
187 0x39e038a8, rsc->debug_mode);
188 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x10,
189 0x888babec, rsc->debug_mode);
190 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x14,
Dhaval Patelf8718a12017-03-14 13:30:52 -0700191 0xa806a020, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800192
193 /* Mode - 2 sequence */
194 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x18,
Dhaval Patelf8718a12017-03-14 13:30:52 -0700195 0xa138ebaa, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800196 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x1c,
Dhaval Patel824e9682017-05-01 23:31:22 -0700197 0xaca581e1, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800198 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x20,
Dhaval Patel824e9682017-05-01 23:31:22 -0700199 0xe2a2ede0, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800200 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x24,
Dhaval Patel824e9682017-05-01 23:31:22 -0700201 0xea8a3982, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800202 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x28,
Dhaval Patel824e9682017-05-01 23:31:22 -0700203 0xa920888c, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800204
205 /* tcs sleep sequence */
206 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x2c,
Dhaval Patel824e9682017-05-01 23:31:22 -0700207 0x89e6a6e9, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800208 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x30,
Dhaval Patel824e9682017-05-01 23:31:22 -0700209 0xa7e9a920, rsc->debug_mode);
Dhaval Patelf8718a12017-03-14 13:30:52 -0700210 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x34,
Dhaval Patelc063d1f2017-06-08 13:19:26 -0700211 0x002089e7, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800212
213 /* branch address */
214 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_0_DRV0,
Dhaval Patel824e9682017-05-01 23:31:22 -0700215 0x2b, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800216 dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_1_DRV0,
Dhaval Patel824e9682017-05-01 23:31:22 -0700217 0x31, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800218
219 return 0;
220}
221
222static int rsc_hw_solver_init(struct sde_rsc_priv *rsc)
223{
224 const u32 mode_0_start_addr = 0x0;
225 const u32 mode_1_start_addr = 0xa;
226 const u32 mode_2_start_addr = 0x15;
227
228 pr_debug("rsc solver init\n");
229
230 dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0,
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -0700231 0xFFFFFFFF, rsc->debug_mode);
232 dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0,
233 0xFFFFFFFF, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800234 dss_reg_w(&rsc->drv_io, SDE_RSCC_MAX_IDLE_DURATION_DRV0,
235 0xEFFFFFFF, rsc->debug_mode);
236
237 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0,
238 0x0, rsc->debug_mode);
239 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0,
240 rsc->timer_config.rsc_time_slot_0_ns, rsc->debug_mode);
241 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_2_DRV0,
242 rsc->timer_config.rsc_time_slot_1_ns, rsc->debug_mode);
243 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_3_DRV0,
244 rsc->timer_config.rsc_time_slot_2_ns, rsc->debug_mode);
245
246 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0,
247 0x7, rsc->debug_mode);
248
249 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT0_PRI0_DRV0,
250 0x0, rsc->debug_mode);
251 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT1_PRI0_DRV0,
252 0x1, rsc->debug_mode);
253 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT1_PRI3_DRV0,
254 0x1, rsc->debug_mode);
255 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT2_PRI0_DRV0,
256 0x2, rsc->debug_mode);
257 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PRI_TABLE_SLOT2_PRI3_DRV0,
258 0x2, rsc->debug_mode);
259
260 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_OVERRIDE_MODE_DRV0,
261 0x0, rsc->debug_mode);
262 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_OVERRIDE_CTRL_DRV0,
263 mode_0_start_addr, rsc->debug_mode);
264 dss_reg_w(&rsc->drv_io, SDE_RSC_TIMERS_CONSIDERED_DRV0,
265 0x1, rsc->debug_mode);
266 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_OVERRIDE_IDLE_TIME_DRV0,
267 0x01000010, rsc->debug_mode);
268
269 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE0,
270 mode_0_start_addr, rsc->debug_mode);
271 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE0,
Dhaval Patel824e9682017-05-01 23:31:22 -0700272 0x80000000, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800273 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE0,
274 rsc->timer_config.rsc_backoff_time_ns, rsc->debug_mode);
275 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE0,
276 rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
277
278 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE1,
279 mode_1_start_addr, rsc->debug_mode);
280 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE1,
Dhaval Patel824e9682017-05-01 23:31:22 -0700281 0x80000000, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800282 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE1,
283 rsc->timer_config.rsc_backoff_time_ns, rsc->debug_mode);
284 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE1,
285 rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
286
287 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM0_DRV0_MODE2,
288 mode_2_start_addr, rsc->debug_mode);
289 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM1_DRV0_MODE2,
Dhaval Patel824e9682017-05-01 23:31:22 -0700290 0x80000000, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800291 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM2_DRV0_MODE2,
Dhaval Patel824e9682017-05-01 23:31:22 -0700292 0x0, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800293 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_MODE_PARM3_DRV0_MODE2,
294 rsc->timer_config.pdc_backoff_time_ns, rsc->debug_mode);
295
296 return 0;
297}
298
Dhaval Patelf2c1df92017-06-28 18:32:39 -0700299static int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc,
300 enum sde_rsc_state state)
Dhaval Patel020f7e122016-11-15 14:39:18 -0800301{
302 int rc = -EBUSY;
303 int count, reg;
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -0700304 unsigned long power_status;
Dhaval Patel020f7e122016-11-15 14:39:18 -0800305
Dhaval Patel031b4152017-03-16 13:03:18 -0700306 rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_RESTORE);
307
Dhaval Patelfbb11f02017-04-06 13:43:28 -0700308 /**
309 * force busy and idle during clk & video mode state because it
310 * is trying to entry in mode-2 without turning on the vysnc.
311 */
312 if ((state == SDE_RSC_VID_STATE) || (state == SDE_RSC_CLK_STATE)) {
313 reg = dss_reg_r(&rsc->wrapper_io,
314 SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -0700315 reg &= ~(BIT(8) | BIT(0));
Dhaval Patelfbb11f02017-04-06 13:43:28 -0700316 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
317 reg, rsc->debug_mode);
318 }
319
Dhaval Patel020f7e122016-11-15 14:39:18 -0800320 // needs review with HPG sequence
321 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
322 0x0, rsc->debug_mode);
323 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
324 0x0, rsc->debug_mode);
325
326 reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
327 rsc->debug_mode);
328 reg &= ~BIT(3);
329 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
330 reg, rsc->debug_mode);
331
332 reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
333 rsc->debug_mode);
334 reg |= BIT(13);
335 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
336 reg, rsc->debug_mode);
337
338 /* make sure that mode-2 exit before wait*/
339 wmb();
340
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -0700341 /* this wait is required to make sure that gdsc is powered on */
Dhaval Patel020f7e122016-11-15 14:39:18 -0800342 for (count = MAX_CHECK_LOOPS; count > 0; count--) {
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -0700343 power_status = dss_reg_r(&rsc->wrapper_io,
344 SDE_RSCC_PWR_CTRL, rsc->debug_mode);
345 if (!test_bit(POWER_CTRL_BIT_12, &power_status)) {
346 reg = dss_reg_r(&rsc->drv_io,
347 SDE_RSCC_SEQ_PROGRAM_COUNTER, rsc->debug_mode);
Dhaval Patela5f75952017-07-25 11:17:41 -0700348 SDE_EVT32_VERBOSE(count, reg, power_status);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800349 rc = 0;
350 break;
351 }
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -0700352 usleep_range(10, 100);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800353 }
354
355 reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
356 rsc->debug_mode);
357 reg &= ~BIT(13);
358 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
359 reg, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800360 if (rc)
361 pr_err("vdd reg is not enabled yet\n");
362
Dhaval Patel031b4152017-03-16 13:03:18 -0700363 rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE);
364
Dhaval Patel020f7e122016-11-15 14:39:18 -0800365 return rc;
366}
367
Dhaval Patelf2c1df92017-06-28 18:32:39 -0700368static int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc)
369{
370 int rc;
371 int count, wrapper_status;
372 unsigned long reg;
373
374 if (rsc->power_collapse_block)
375 return -EINVAL;
376
377 rc = regulator_set_mode(rsc->fs, REGULATOR_MODE_FAST);
378 if (rc) {
379 pr_err("vdd reg fast mode set failed rc:%d\n", rc);
380 return rc;
381 }
382
383 rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC);
384
385 /* update qtimers to high during clk & video mode state */
386 if ((rsc->current_state == SDE_RSC_VID_STATE) ||
387 (rsc->current_state == SDE_RSC_CLK_STATE)) {
388 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
389 0xffffffff, rsc->debug_mode);
390 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
391 0xffffffff, rsc->debug_mode);
392 }
393
394 wrapper_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
395 rsc->debug_mode);
396 wrapper_status |= BIT(3);
397 wrapper_status |= BIT(0);
398 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
399 wrapper_status, rsc->debug_mode);
400
401 /**
402 * force busy and idle during clk & video mode state because it
403 * is trying to entry in mode-2 without turning on the vysnc.
404 */
405 if ((rsc->current_state == SDE_RSC_VID_STATE) ||
406 (rsc->current_state == SDE_RSC_CLK_STATE)) {
407 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
408 BIT(0) | BIT(1), rsc->debug_mode);
409 wmb(); /* force busy gurantee */
410 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
411 BIT(0) | BIT(9), rsc->debug_mode);
412 }
413
414 /* make sure that mode-2 is triggered before wait*/
415 wmb();
416
417 rc = -EBUSY;
418 /* this wait is required to turn off the rscc clocks */
419 for (count = MAX_CHECK_LOOPS; count > 0; count--) {
420 reg = dss_reg_r(&rsc->wrapper_io,
421 SDE_RSCC_PWR_CTRL, rsc->debug_mode);
422 if (test_bit(POWER_CTRL_BIT_12, &reg)) {
423 rc = 0;
424 break;
425 }
Dhaval Patelc8bdc2e2017-07-14 08:52:02 -0700426 usleep_range(10, 100);
Dhaval Patelf2c1df92017-06-28 18:32:39 -0700427 }
428
429 if (rc) {
430 pr_err("mdss gdsc power down failed rc:%d\n", rc);
431 goto end;
432 }
433
434 if ((rsc->current_state == SDE_RSC_VID_STATE) ||
435 (rsc->current_state == SDE_RSC_CLK_STATE)) {
436 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
437 BIT(0) | BIT(8), rsc->debug_mode);
438 wmb(); /* force busy on vsync */
439 }
440
441 rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_PC);
442
443 return 0;
444
445end:
446 sde_rsc_mode2_exit(rsc, rsc->current_state);
447
448 return rc;
449}
450
Dhaval Patel020f7e122016-11-15 14:39:18 -0800451static int sde_rsc_state_update(struct sde_rsc_priv *rsc,
452 enum sde_rsc_state state)
453{
454 int rc = 0;
455 int reg;
456
457 if (rsc->power_collapse) {
Dhaval Patelfbb11f02017-04-06 13:43:28 -0700458 rc = sde_rsc_mode2_exit(rsc, state);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800459 if (rc)
460 pr_err("power collapse: mode2 exit failed\n");
461 else
462 rsc->power_collapse = false;
463 }
464
465 switch (state) {
466 case SDE_RSC_CMD_STATE:
467 pr_debug("command mode handling\n");
468
469 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
470 0x1, rsc->debug_mode);
471 dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0,
472 0x0, rsc->debug_mode);
473 reg = dss_reg_r(&rsc->wrapper_io,
474 SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
475 reg |= (BIT(0) | BIT(8));
476 reg &= ~(BIT(1) | BIT(2) | BIT(3) | BIT(6) | BIT(7));
477 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
478 reg, rsc->debug_mode);
479 /* make sure that solver is enabled */
480 wmb();
Dhaval Patel031b4152017-03-16 13:03:18 -0700481
482 rsc_event_trigger(rsc, SDE_RSC_EVENT_SOLVER_ENABLED);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800483 break;
484
485 case SDE_RSC_VID_STATE:
486 pr_debug("video mode handling\n");
487
488 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
489 0x1, rsc->debug_mode);
490 reg = dss_reg_r(&rsc->wrapper_io,
491 SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
492 reg |= BIT(8);
493 reg &= ~(BIT(1) | BIT(0));
494 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
495 reg, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800496 /* make sure that solver mode is override */
497 wmb();
Dhaval Patel031b4152017-03-16 13:03:18 -0700498
499 rsc_event_trigger(rsc, SDE_RSC_EVENT_SOLVER_DISABLED);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800500 break;
501
Dhaval Patelfbb11f02017-04-06 13:43:28 -0700502 case SDE_RSC_CLK_STATE:
503 pr_debug("clk state handling\n");
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -0700504
505 reg = dss_reg_r(&rsc->wrapper_io,
506 SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
507 reg &= ~(BIT(8) | BIT(0));
508 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
509 reg, rsc->debug_mode);
Dhaval Pateld2dd1ad2017-03-29 16:13:17 -0700510 /* make sure that solver mode is disabled */
511 wmb();
Dhaval Patelfbb11f02017-04-06 13:43:28 -0700512 break;
513
Dhaval Patel020f7e122016-11-15 14:39:18 -0800514 case SDE_RSC_IDLE_STATE:
515 rc = sde_rsc_mode2_entry(rsc);
516 if (rc)
517 pr_err("power collapse - mode 2 entry failed\n");
518 else
519 rsc->power_collapse = true;
520 break;
521
522 default:
523 pr_err("state:%d handling is not supported\n", state);
524 break;
525 }
526
527 return rc;
528}
529
530int rsc_hw_init(struct sde_rsc_priv *rsc)
531{
532 int rc = 0;
533
534 rc = rsc_hw_qtimer_init(rsc);
535 if (rc) {
536 pr_err("rsc hw qtimer init failed\n");
537 goto end;
538 }
539
540 rc = rsc_hw_wrapper_init(rsc);
541 if (rc) {
542 pr_err("rsc hw wrapper init failed\n");
543 goto end;
544 }
545
546 rc = rsc_hw_seq_memory_init(rsc);
547 if (rc) {
548 pr_err("rsc sequencer memory init failed\n");
549 goto end;
550 }
551
552 rc = rsc_hw_solver_init(rsc);
553 if (rc) {
554 pr_err("rsc solver init failed\n");
555 goto end;
556 }
557
558 rc = rsc_hw_pdc_init(rsc);
559 if (rc) {
560 pr_err("rsc hw pdc init failed\n");
561 goto end;
562 }
563
564 /* make sure that hw is initialized */
565 wmb();
566
567 pr_info("sde rsc init successfully done\n");
568end:
569 return rc;
570}
571
572int rsc_hw_mode_ctrl(struct sde_rsc_priv *rsc, enum rsc_mode_req request,
Dhaval Patel3d56f892017-05-05 12:21:08 -0700573 char *buffer, int buffer_size, u32 mode)
Dhaval Patel020f7e122016-11-15 14:39:18 -0800574{
575 u32 blen = 0;
576 u32 slot_time;
577
578 switch (request) {
579 case MODE_READ:
580 if (!buffer || !buffer_size)
581 return blen;
582
583 blen = snprintf(buffer, buffer_size - blen,
584 "mode_status:0x%x\n",
585 dss_reg_r(&rsc->drv_io, SDE_RSCC_SOLVER_STATUS2_DRV0,
586 rsc->debug_mode));
587 break;
588
Dhaval Patel3d56f892017-05-05 12:21:08 -0700589 case MODE_UPDATE:
590 slot_time = mode & BIT(0) ? 0x0 :
591 rsc->timer_config.rsc_time_slot_2_ns;
592 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0,
593 slot_time, rsc->debug_mode);
594
595 slot_time = mode & BIT(1) ?
596 rsc->timer_config.rsc_time_slot_0_ns :
Dhaval Patel020f7e122016-11-15 14:39:18 -0800597 rsc->timer_config.rsc_time_slot_2_ns;
598 dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0,
599 slot_time, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800600
Dhaval Patel3d56f892017-05-05 12:21:08 -0700601 rsc->power_collapse_block = !(mode & BIT(2));
Dhaval Patel020f7e122016-11-15 14:39:18 -0800602 break;
603
604 default:
605 break;
606 }
607
608 return blen;
609}
610
611int sde_rsc_debug_show(struct seq_file *s, struct sde_rsc_priv *rsc)
612{
613 seq_printf(s, "override ctrl:0x%x\n",
614 dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
615 rsc->debug_mode));
616 seq_printf(s, "power ctrl:0x%x\n",
617 dss_reg_r(&rsc->wrapper_io, SDE_RSCC_PWR_CTRL,
618 rsc->debug_mode));
619 seq_printf(s, "vsycn timestamp0:0x%x\n",
620 dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP0,
621 rsc->debug_mode));
622 seq_printf(s, "vsycn timestamp1:0x%x\n",
623 dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP1,
624 rsc->debug_mode));
625
626 seq_printf(s, "error irq status:0x%x\n",
627 dss_reg_r(&rsc->drv_io, SDE_RSCC_ERROR_IRQ_STATUS_DRV0,
628 rsc->debug_mode));
629
630 seq_printf(s, "seq busy status:0x%x\n",
631 dss_reg_r(&rsc->drv_io, SDE_RSCC_SEQ_BUSY_DRV0,
632 rsc->debug_mode));
633
634 seq_printf(s, "solver override ctrl status:0x%x\n",
635 dss_reg_r(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0,
636 rsc->debug_mode));
637 seq_printf(s, "solver override status:0x%x\n",
638 dss_reg_r(&rsc->drv_io, SDE_RSCC_SOLVER_STATUS0_DRV0,
639 rsc->debug_mode));
640 seq_printf(s, "solver timeslot status:0x%x\n",
641 dss_reg_r(&rsc->drv_io, SDE_RSCC_SOLVER_STATUS1_DRV0,
642 rsc->debug_mode));
643 seq_printf(s, "solver mode status:0x%x\n",
644 dss_reg_r(&rsc->drv_io, SDE_RSCC_SOLVER_STATUS2_DRV0,
645 rsc->debug_mode));
646
647 seq_printf(s, "amc status:0x%x\n",
648 dss_reg_r(&rsc->drv_io, SDE_RSCC_AMC_TCS_MODE_IRQ_STATUS_DRV0,
649 rsc->debug_mode));
650
651 return 0;
652}
653
654int rsc_hw_vsync(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
655 char *buffer, int buffer_size, u32 mode)
656{
657 u32 blen = 0, reg;
658
659 switch (request) {
660 case VSYNC_READ:
661 if (!buffer || !buffer_size)
662 return blen;
663
664 blen = snprintf(buffer, buffer_size - blen, "vsync0:0x%x\n",
Dhaval Patel3d56f892017-05-05 12:21:08 -0700665 dss_reg_r(&rsc->wrapper_io,
Dhaval Patel020f7e122016-11-15 14:39:18 -0800666 SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP0,
667 rsc->debug_mode));
668 if (blen >= buffer_size)
669 return blen;
670
671 blen += snprintf(buffer + blen, buffer_size - blen,
672 "vsync1:0x%x\n",
Dhaval Patel3d56f892017-05-05 12:21:08 -0700673 dss_reg_r(&rsc->wrapper_io,
Dhaval Patel020f7e122016-11-15 14:39:18 -0800674 SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP1,
675 rsc->debug_mode));
676 break;
677
678 case VSYNC_ENABLE:
Ingrid Gallardofe757d22017-06-29 19:37:53 -0700679 reg = BIT(8) | ((mode & 0x7) << 10);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800680 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_DEBUG_BUS,
Dhaval Patel3d56f892017-05-05 12:21:08 -0700681 reg, rsc->debug_mode);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800682 break;
683
684 case VSYNC_DISABLE:
685 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_DEBUG_BUS,
686 0x0, rsc->debug_mode);
687 break;
688 }
689
690 return blen;
691}
692
693bool rsc_hw_is_amc_mode(struct sde_rsc_priv *rsc)
694{
695 return dss_reg_r(&rsc->drv_io, SDE_RSCC_TCS_DRV0_CONTROL,
696 rsc->debug_mode) & BIT(16);
697}
698
699int rsc_hw_tcs_wait(struct sde_rsc_priv *rsc)
700{
701 int rc = -EBUSY;
702 int count, seq_status;
703
704 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
705 0x0, rsc->debug_mode);
706 seq_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
707 rsc->debug_mode) & BIT(1);
708 /* if seq busy - set TCS use OK to high and wait for 200us */
709 if (seq_status) {
710 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
711 0x1, rsc->debug_mode);
712 usleep_range(100, 200);
713 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
714 0x0, rsc->debug_mode);
715 }
716
717 /* check for sequence running status before exiting */
718 for (count = MAX_CHECK_LOOPS; count > 0; count--) {
719 seq_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
720 rsc->debug_mode) & BIT(1);
721 if (!seq_status) {
722 rc = 0;
723 break;
724 }
725 usleep_range(1, 2);
726 }
727
728 return rc;
729}
730
731int rsc_hw_tcs_use_ok(struct sde_rsc_priv *rsc)
732{
733 dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
734 0x1, rsc->debug_mode);
735 return 0;
736}
737
738int sde_rsc_hw_register(struct sde_rsc_priv *rsc)
739{
740 pr_debug("rsc hardware register\n");
741
742 rsc->hw_ops.init = rsc_hw_init;
743
744 rsc->hw_ops.tcs_wait = rsc_hw_tcs_wait;
745 rsc->hw_ops.tcs_use_ok = rsc_hw_tcs_use_ok;
746 rsc->hw_ops.is_amc_mode = rsc_hw_is_amc_mode;
747
Dhaval Patel020f7e122016-11-15 14:39:18 -0800748 rsc->hw_ops.hw_vsync = rsc_hw_vsync;
749 rsc->hw_ops.state_update = sde_rsc_state_update;
750 rsc->hw_ops.debug_show = sde_rsc_debug_show;
751 rsc->hw_ops.mode_ctrl = rsc_hw_mode_ctrl;
752
753 return 0;
754}