1 #ifndef __ONCHIPROM_KIRIN_UFS_H__
2 #define __ONCHIPROM_KIRIN_UFS_H__
3
4 /*#define UFS_FPGA*/
5
6 #define COMBO_PHY_V120
7
8 #define DELAY_US (1000)
9
10 #ifndef UFS_FPGA
11 #define REG_BASE_UFS_ADDRESS 0x10010000
12 #else
13 #define REG_BASE_UFS_ADDRESS 0x113a0000
14 #endif
15
16 #ifdef UFS_FPGA
17 #define REG_BASE_FPGA2_APB_IF_ADDRESS 0x113f7000
18 #define UFS_CTRL1 0x0000
19 #define UFS_CTRL2 0x0004
20 #define UFS_CTRL3 0x0008
21 /*UFS_CTRL1*/
22 #define RX_SYMBOLCLK_SEL (0x1 << 25)
23 #define RX_SYMBOLCLK1_SEL (0x1 << 24)
24 /*UFS_CTRL2*/
25 #define TX_SYMBOLCLK_SEL (0x1 << 8)
26 #define UFS_CLK_EN (0x1 << 1)
27 #define UFS_SRST_REQ (0x1 << 0)
28 /*UFS_CTRL3*/
29 #define UFS_RST (0x1 << 31)
30 #define I2C_SCL (0x1 << 21)
31 #define I2C_SDA (0x1 << 20)
32 #define IF_AMUX_SEL (0x1 << 17)
33 #define UFS_SEL (0x1 << 16)
34 #endif
35
36 #define UFS_SYS_PSW_POWER_CTRL (REG_BASE_UFS_SYS + 0x04)
37 #define UFS_SYS_PHY_ISO_EN (REG_BASE_UFS_SYS + 0x08)
38 #define UFS_SYS_HC_LP_CTRL (REG_BASE_UFS_SYS + 0x0C)
39 #define UFS_SYS_PHY_CLK_CTRL (REG_BASE_UFS_SYS + 0x10)
40 #define UFS_SYS_PSW_CLK_CTRL (REG_BASE_UFS_SYS + 0x14)
41 #define UFS_SYS_CLOCK_GATE_BYPASS (REG_BASE_UFS_SYS + 0x18)
42 #define UFS_SYS_RESET_CTRL_EN (REG_BASE_UFS_SYS + 0x1C)
43 #define UFS_SYS_UFS_SYSCTRL (REG_BASE_UFS_SYS + 0x5C)
44 #define UFS_SYS_UFS_DEVICE_RESET_CTRL (REG_BASE_UFS_SYS + 0x60)
45
46 #define BIT_UFS_PSW_ISO_CTRL (1 << 16)
47 #define BIT_UFS_PSW_MTCMOS_EN (1 << 0)
48 #define BIT_UFS_REFCLK_ISO_EN (1 << 16)
49 #define BIT_UFS_PHY_ISO_CTRL (1 << 0)
50 #define BIT_SYSCTRL_LP_ISOL_EN (1 << 16)
51 #define BIT_SYSCTRL_PWR_READY (1 << 8)
52 #define BIT_SYSCTRL_REF_CLOCK_EN (1 << 24)
53 #define MASK_SYSCTRL_REF_CLOCK_SEL (0x3 << 8)
54 #define MASK_SYSCTRL_CFG_CLOCK_FREQ (0xFF)
55 #define UFS_FREQ_CFG_CLK (0x14)
56 #define BIT_SYSCTRL_PSW_CLK_EN (1 << 4)
57 #define MASK_UFS_CLK_GATE_BYPASS (0x3F)
58 #define BIT_SYSCTRL_LP_RESET_N (1 << 0)
59 #define BIT_UFS_REFCLK_SRC_SEl (1 << 0)
60 #define MASK_UFS_SYSCRTL_BYPASS (0x3F << 16)
61 #define MASK_UFS_DEVICE_RESET (0x1 << 16)
62 #define BIT_UFS_DEVICE_RESET (0x1)
63
64 /* UFSHCD Registers Offsets */
65 #define UFS_CAP_OFF 0x00
66 #define UFS_VER_OFF 0x08
67 #define UFS_AHIT_OFF 0x18
68 #define UFS_IS_OFF 0x20
69 #define UFS_IE_OFF 0x24
70 #define UFS_HCS_OFF 0x30
71 #define UFS_HCE_OFF 0x34
72 #define UFS_UECPA_OFF 0x38
73 #define UFS_UECDL_OFF 0x3C
74 #define UFS_UECN_OFF 0x40
75 #define UFS_UECT_OFF 0x44
76 #define UFS_UECDME_OFF 0x48
77 #define UFS_UTRLBA_OFF 0x50
78 #define UFS_UTRLBAU_OFF 0x54
79 #define UFS_UTRLDBR_OFF 0x58
80 #define UFS_UTRLCLR_OFF 0x5C
81 #define UFS_UTRLRSR_OFF 0x60
82 #define UFS_UTMRLBA_OFF 0x70
83 #define UFS_UTMRLBAU_OFF 0x74
84 #define UFS_UTMRLDBR_OFF 0x78
85 #define UFS_UTMRLRSR_OFF 0x80
86 #define UFS_UICCMD_OFF 0x90
87 #define UFS_UICCMDARG1_OFF 0x94
88 #define UFS_UICCMDARG2_OFF 0x98
89 #define UFS_UICCMDARG3_OFF 0x9C
90 #define UFS_LBMCFG_OFF 0xF0
91 #define UFS_HCLKDIV_OFF 0xFC
92
93 #define UFS_HCE_RESET_BIT (1 << 0)
94 #define UFS_HCS_UCRDY_BIT (1 << 3)
95 #define UFS_HCS_DP_BIT (1 << 0)
96 #define UFS_IS_UE_BIT (1 << 2)
97 #define UFS_IS_ULSS_BIT (1 << 8)
98 #define UFS_IS_UCCS_BIT (1 << 10)
99 #define UFS_UICCMDARG2_RET_MASK (0xFF)
100 #define UFS_AHIT_AH8ITV_MASK (0x2FF)
101 #define UFS_UTP_RUN_BIT (1 << 0)
102
103 #define UFS_HCLKDIV_NORMAL_VALUE 0x12C
104 #ifdef UFS_FPGA
105 #define UFS_HCLKDIV_FPGA_VALUE (0x28)
106 #else
107 #define UFS_HCLKDIV_SLOW_VALUE (0x14)
108 #endif
109
110 #define UIC_LINK_STARTUP_CMD 0x16
111 #define NOP_TRANS_TYPE 0x20
112
113 #define UFS_BOOT_LUN 0xB0
114
115 //#define DEBUG_UFS
116 #ifdef DEBUG_UFS
117 #define debug_printf(fmt,args...) printf (fmt ,##args)
118 #else
119 #define debug_printf(fmt,args...)
120 #endif
121
122 #define UFS_HC_INIT_TIMEOUT_MS 1000
123 #define UFS_HC_ENABLE_TIMEOUT_MS 1
124 #define UFS_LINK_STARTUP_TIMEOUT_MS 200
125 #define UFS_HC_WAIT_UCRDY_TIMEOUT_MS 1
126 #define UFS_HC_WAIT_ULSS_TIMEOUT_MS 50
127 #define UFS_SEND_UIC_CMD_TIMEOUT_MS 10
128 #define UFS_READ_UIC_CMD_TIMEOUT_MS 10
129 #define UFS_SEND_NOP_OUT_TIMEOUT_MS 10
130
131 /* Byte swap u16*/
swap_16(uint16_t val)132 static inline uint16_t swap_16(uint16_t val)
133 {
134 return (uint16_t)((val << 8) | (val >> 8));
135 }
136
137 /* Byte swap unsigned int */
swap_32(uint32_t val)138 static inline uint32_t swap_32(uint32_t val)
139 {
140
141 val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF);
142 return (val << 16) | (val >> 16);
143 }
144
to_bigendian32(uint32_t val)145 static inline uint32_t to_bigendian32(uint32_t val)
146 {
147 #ifdef HOST_BIG_ENDIAN
148 return val;
149 #else
150 return swap_32(val);
151 #endif
152 }
153
to_littleendian32(uint32_t val)154 static inline uint32_t to_littleendian32(uint32_t val)
155 {
156 #ifdef HOST_BIG_ENDIAN
157 return swap_32(val);
158 #else
159 return val;
160 #endif
161 }
162
to_bigendian16(uint16_t val)163 static inline uint16_t to_bigendian16(uint16_t val)
164 {
165 #ifdef HOST_BIG_ENDIAN
166 return val;
167 #else
168 return swap_16(val);
169 #endif
170 }
171
to_littleendian16(uint16_t val)172 static inline uint16_t to_littleendian16(uint16_t val)
173 {
174 #ifdef HOST_BIG_ENDIAN
175 return swap_16(val);
176 #else
177 return val;
178 #endif
179 }
dwc_ufs_read_reg(uint32_t reg_offset)180 static inline uint32_t dwc_ufs_read_reg(uint32_t reg_offset)
181 {
182 uint32_t value;
183
184 value = (*((volatile uint32_t *)(long)(REG_BASE_UFS_ADDRESS + reg_offset)));
185 return value;
186 }
187
dwc_ufs_write_reg(uint32_t reg_offset,uint32_t value)188 static inline void dwc_ufs_write_reg(uint32_t reg_offset, uint32_t value)
189 {
190 (*((volatile uint32_t *)(long)(REG_BASE_UFS_ADDRESS + reg_offset))) = value;
191 }
192
193 enum uic_dme_type {
194 /*Configuration */
195 DME_GET = 0x01,
196 DME_SET = 0x02,
197 DME_PEER_GET = 0x03,
198 DME_PEER_SET = 0x04,
199 /*Control */
200 DME_POWERON = 0x10,
201 DME_POWEROFF = 0x11,
202 DME_ENABLE = 0x12,
203
204 DME_Reserve_1 = 0x13,
205 DME_RESET = 0x14,
206 DME_ENDPOINTRESET = 0x15,
207 DME_LINKSTARTUP = 0x16,
208 DME_HIBERNATE_ENTER = 0x17,
209 DME_HIBERNATE_EXIT = 0x18,
210 DME_Reserve_2 = 0x19,
211 DME_TEST_MODE = 0x1A,
212 };
213
214 enum {
215 UFS_SUCCESS = 0x00,
216 UFS_LINK_STARTUP_FAIL = -0x02,
217 UFS_UTRD_DOORBELL_TIMEOUT = -0x03,
218 UFS_NOP_RESP_FAIL = -0x04,
219 UFS_INVALID_NOP_IN = -0x05,
220
221 /* response upiu status error */
222 RESP_STAT_CONDITION_MET = -0x14,
223 RESP_STAT_BUSY = -0x15,
224 RESP_STAT_RESERVATION_CONFLICT = -0x16,
225 RESP_STAT_TASK_SET_FULL = -0x17,
226 RESP_STAT_ACA_ACTIVE = -0x18,
227 RESP_STAT_TASK_ABORTED = -0x19,
228 RESP_STAT_UNKNOW = -0x1F,
229
230 #define RET_SENSE_KEY_OFF (0x20)
231 /* sense key */
232 NO_SENSE = -0x20,
233 RECOVERED_ERROR = -0x21,
234 NOT_READY = -0x22,
235 MEDIUM_ERROR = -0x23,
236 HARDWARE_ERROR = -0x24,
237 ILLEGAL_REQUEST = -0x25,
238 UNIT_ATTENTION = -0x26,
239 DATA_PROTECT = -0x27,
240 BLANK_CHECK = -0x28,
241 VENDOR_SPECIFIC = -0x29,
242 ABORTED_COMMAND = -0x2B,
243 VOLUME_OVERFLOW = -0x2D,
244 MISCOMPARE = -0x2E,
245
246 #define RET_UIC_CONFIG_ERROR_OFF (0xA0)
247 /* UIC Config Result Error */
248 UFS_UIC_TIMEOUT = -0xA0,
249 INVALID_MIB_ATTRIBUTE = -0xA1,
250 INVALID_MIB_ATTRIBUTE_VALUE = -0xA2,
251 READ_ONLY_MIB_ATTRIBUTE = -0xA3,
252 WRITE_ONLY_MIB_ATTRIBUTE = -0xA4,
253 BAD_INDEX = -0xA5,
254 LOCKED_MIB_ATTRIBUTE = -0xA6,
255 BAD_TEST_FEATURE_INDEX = -0xA7,
256 PEER_COMMUNICATION_FAILURE = -0xA8,
257 BUSY = -0xA9,
258 DME_FAILURE = -0xAA,
259
260 #define RET_UTRD_OCS_ERROR_OFF (0xB0)
261 /* utrd ocs error */
262 INVALID_COMMAND_TABLE_ATTRIBUTES = -0xB1,
263 INVALID_PRDT_ATTRIBUTES = -0xB2,
264 MISMATCH_DATA_BUFFER_SIZE = -0xB3,
265 MISMATCH_RESPONSE_UPIU_SIZE = -0xB4,
266 COMMUNICATION_FAILURE = -0xB5,
267 ABORTED = -0xB6,
268 FATAL_ERROR = -0xB7,
269 INVALID_OCS_VALUE = -0xBF,
270
271 UFS_SOFTWARE_ERROR = -0xFF
272 };
273
274 #define UFS_STATIC_WORK_SPACE_ADDRESS ufsboot_static_space_address
275 /* DDR address */
276 #define UFS_START_WORK_SPACE_START 0x50000000
277 #define UFS_STATIC_WORK_SPACE_SIZE 0x2000
278
279 #define UFS_CMD_UPIU_BASE (UFS_STATIC_WORK_SPACE_ADDRESS + 0x0)
280 #define UFS_RESP_UPIU_BASE (UFS_STATIC_WORK_SPACE_ADDRESS + 0x200)
281 #define UFS_PRDT_BASE (UFS_STATIC_WORK_SPACE_ADDRESS + 0x400)
282 #define UFS_TR_UTP_BASE (UFS_STATIC_WORK_SPACE_ADDRESS + 0x800)
283 #define UFS_TMR_UTP_BASE (UFS_STATIC_WORK_SPACE_ADDRESS + 0xC00)
284 #define STATIC_UFS_TAG_ADDR (UFS_STATIC_WORK_SPACE_ADDRESS + 0x1000)
285
286 #define MAX_TR_TASK 32
287 #define MAX_PRDT_ENTRIES 64
288 #define PRDT_BUFFER_SIZE 0x40000
289 #define LOGICAL_BLK_SIZE 4096
290 //#define LPRAM_ADDR_FROM_LPM3_TO_CPU(x) ((x) - REG_BASE_LP_RAM + REG_BASE_LP_RAM_ACORE)
291 #define LPRAM_ADDR_FROM_LPM3_TO_CPU(x) ((x))
292
293 #define BYTES_ALIGN_1024(x) ((x + 1024 -1)& ~(1024 - 1))
294 #define BYTES_ALIGN_4096(x) ((x + 4096 -1)& ~(4096 - 1))
295
296 #pragma pack(push)
297 #pragma pack(1)
298
299 #define write_error_code(c)
300
ufs_memset(void * mem,uint8_t val,uint32_t size)301 static inline void ufs_memset(void* mem, uint8_t val, uint32_t size)
302 {
303 uint8_t *pf8 = (uint8_t*)mem;
304 uint32_t i;
305
306 for (i = 0; i < size; i++) {
307 pf8[i] = val;
308 pf8++;
309 }
310 }
311
delay(unsigned int cnt)312 static inline void delay(unsigned int cnt)
313 {
314 while (cnt--) {
315 __asm__ __volatile__("nop");
316 }
317 }
318
ufs_waitus(uint32_t us)319 static inline void ufs_waitus(uint32_t us)
320 {
321 while (us--) {
322 delay(DELAY_US);
323 }
324 }
325
ufs_waitms(uint32_t ms)326 static inline void ufs_waitms(uint32_t ms)
327 {
328 while (ms--) {
329 delay(1000 * DELAY_US);
330 }
331 }
332
333 static uint32_t ufs_cur_time_ms = 0;
current_time(void)334 static inline uint32_t current_time(void)
335 {
336 ufs_cur_time_ms = 0;
337 return ufs_cur_time_ms;
338 }
339
time_passed_ms(uint32_t last)340 static inline uint32_t time_passed_ms(uint32_t last)
341 {
342 delay(1000 * DELAY_US);
343 ufs_cur_time_ms++;
344 return ufs_cur_time_ms;
345 }
346
347 /*
348 * Command UPIU Structure
349 */
350 struct dwc_ufs_cmd_upiu {
351 uint8_t trans_type;
352 uint8_t flags;
353 uint8_t lun;
354 uint8_t task_tag;
355 uint8_t cmd_set_type; /* Only LS nibble is valid. Others Reserved */
356 uint8_t reserved_1_0;
357 uint8_t reserved_1_1;
358 uint8_t reserved_1_2;
359 uint8_t tot_ehs_len;
360 uint8_t reserved_2;
361 uint16_t data_seg_len;
362 uint32_t exp_data_xfer_len;
363 uint8_t cdb[16]; /* UFS/SCSI command descriptor block */
364 };
365
366 /*
367 * Transfer Response UPIU Structure
368 */
369 struct dwc_ufs_xfer_resp_upiu {
370 uint8_t trans_type;
371 uint8_t flags;
372 uint8_t lun;
373 uint8_t task_tag;
374 uint8_t cmd_set_type; /* Only LS nibble is valid. Others Reserved */
375 uint8_t reserved_1;
376 uint8_t response;
377 uint8_t status; /* This is SCSI status */
378 uint8_t tot_ehs_len;
379 uint8_t device_info;
380 uint16_t data_seg_len;
381 uint32_t residual_xfer_count;
382 uint32_t reserved_2;
383 uint32_t reserved_3;
384 uint32_t reserved_4;
385 uint32_t reserved_5;
386 uint16_t sense_data_len;
387 uint8_t sense_data[18];
388 };
389
390 /*
391 * NOP OUT UPIU Structure
392 */
393 struct dwc_ufs_nop_req_upiu {
394 uint8_t trans_type;
395 uint8_t flags;
396 uint8_t reserved_1;
397 uint8_t task_tag;
398 uint32_t reserved_2;
399 uint8_t tot_ehs_len;
400 uint8_t reserved_3;
401 uint16_t data_seg_len;
402 uint8_t reserved_4[20];
403 };
404
405 /*
406 * NOP IN UPIU Structure
407 */
408 struct dwc_ufs_nop_resp_upiu {
409 uint8_t trans_type;
410 uint8_t flags;
411 uint8_t reserved_1;
412 uint8_t task_tag;
413 uint8_t reserved_2_0;
414 uint8_t reserved_2_1;
415 uint8_t response;
416 uint8_t reserved_3;
417 uint8_t tot_ehs_len;
418 uint8_t device_info;
419 uint16_t data_seg_len;
420 uint8_t reserved_4[20];
421 };
422
423 struct dwc_ufs_prd {
424 uint32_t base_addr;
425 uint32_t upper_addr;
426 uint32_t reserved1;
427 uint32_t size;
428 };
429
430 struct dwc_ufs_utrd {
431 uint8_t reserved_1_0 : 8;
432 uint8_t reserved_1_1 : 8;
433 uint8_t reserved_1_2 : 8;
434 uint8_t ct_and_flags : 8;
435 uint32_t reserved_2 : 32;
436 uint8_t ocs : 8;
437 uint8_t reserved_3_0 : 8;
438 uint8_t reserved_3_1 : 8;
439 uint8_t reserved_3_2 : 8;
440 uint32_t reserved_4 : 32;
441
442 uint32_t ucdba : 32; /* Only bits 31:7 are valid; 128B Aligned addr */
443 uint32_t ucdbau : 32;
444 uint16_t resp_upiu_length : 16;
445 uint16_t resp_upiu_offset : 16;
446
447 uint16_t prdt_length : 16;
448 uint16_t prdt_offset : 16;
449 };
450
451 #pragma pack(pop)
452
453 /* UTP Transfer Request Data Direction (DD) */
454 enum {
455 UTP_NO_DATA_TRANSFER = 0x00,
456 UTP_HOST_TO_DEVICE = 0x02,
457 UTP_DEVICE_TO_HOST = 0x04
458 };
459
460 /* UPIU Read/Write flags */
461 enum {
462 UPIU_CMD_FLAGS_NONE = 0x00,
463 UPIU_CMD_FLAGS_WRITE = 0x20,
464 UPIU_CMD_FLAGS_READ = 0x40
465 };
466
467 enum {
468 UTP_SCSI_COMMAND = 0x00,
469 };
470
471 enum {
472 UTP_UFS_STORAGE_COMMAND = (1 << 4)
473 };
474
475 enum dma_data_direction {
476 DMA_FROM_DEVICE = 2,
477 DMA_NONE = 3
478 };
479
480 #endif
481
482