9
9
#include <linux/delay.h>
10
10
#include <linux/dma-mapping.h>
11
11
#include <linux/err.h>
12
+ #include <linux/firmware.h>
12
13
#include <linux/iopoll.h>
13
14
#include <linux/kernel.h>
14
15
#include <linux/module.h>
16
+ #include <linux/nvmem-consumer.h>
15
17
#include <linux/of.h>
16
18
#include <linux/platform_device.h>
17
19
#include <linux/pm_runtime.h>
20
+ #include <linux/sys_soc.h>
18
21
#include <ufs/ufshcd.h>
19
22
20
23
#include "ufshcd-pltfrm.h"
21
24
25
+ #define EFUSE_CALIB_SIZE 8
26
+
22
27
struct ufs_renesas_priv {
28
+ const struct firmware * fw ;
29
+ void (* pre_init )(struct ufs_hba * hba );
23
30
bool initialized ; /* The hardware needs initialization once */
31
+ u8 calib [EFUSE_CALIB_SIZE ];
24
32
};
25
33
34
+ #define UFS_RENESAS_FIRMWARE_NAME "r8a779f0_ufs.bin"
35
+ MODULE_FIRMWARE (UFS_RENESAS_FIRMWARE_NAME );
36
+
26
37
static void ufs_renesas_dbg_register_dump (struct ufs_hba * hba )
27
38
{
28
39
ufshcd_dump_regs (hba , 0xc0 , 0x40 , "regs: 0xc0 + " );
@@ -116,6 +127,22 @@ static void ufs_renesas_set_phy(struct ufs_hba *hba, u32 addr16, u32 data16)
116
127
ufs_renesas_write_phy (hba , addr16 , data16 );
117
128
}
118
129
130
+ static void ufs_renesas_reset_indirect_write (struct ufs_hba * hba , int gpio ,
131
+ u32 addr , u32 data )
132
+ {
133
+ ufs_renesas_write (hba , 0xf0 , gpio );
134
+ ufs_renesas_write_800_80c_poll (hba , addr , data );
135
+ }
136
+
137
+ static void ufs_renesas_reset_indirect_update (struct ufs_hba * hba )
138
+ {
139
+ ufs_renesas_write_d0_d4 (hba , 0x0000082c , 0x0f000000 );
140
+ ufs_renesas_write_d0_d4 (hba , 0x00000828 , 0x0f000000 );
141
+ ufs_renesas_write (hba , 0xd0 , 0x0000082c );
142
+ ufs_renesas_poll (hba , 0xd4 , BIT (27 ) | BIT (26 ) | BIT (24 ), BIT (27 ) | BIT (26 ) | BIT (24 ));
143
+ ufs_renesas_write (hba , 0xf0 , 0 );
144
+ }
145
+
119
146
static void ufs_renesas_indirect_write (struct ufs_hba * hba , u32 gpio , u32 addr ,
120
147
u32 data_800 )
121
148
{
@@ -135,15 +162,19 @@ static void ufs_renesas_indirect_poll(struct ufs_hba *hba, u32 gpio, u32 addr,
135
162
ufs_renesas_write (hba , 0xf0 , 0 );
136
163
}
137
164
138
- static void ufs_renesas_init_step1_to_3 (struct ufs_hba * hba )
165
+ static void ufs_renesas_init_step1_to_3 (struct ufs_hba * hba , bool init108 )
139
166
{
140
167
ufs_renesas_write (hba , 0xc0 , 0x49425308 );
141
168
ufs_renesas_write_d0_d4 (hba , 0x00000104 , 0x00000002 );
169
+ if (init108 )
170
+ ufs_renesas_write_d0_d4 (hba , 0x00000108 , 0x00000002 );
142
171
udelay (1 );
143
172
ufs_renesas_write_d0_d4 (hba , 0x00000828 , 0x00000200 );
144
173
udelay (1 );
145
174
ufs_renesas_write_d0_d4 (hba , 0x00000828 , 0x00000000 );
146
175
ufs_renesas_write_d0_d4 (hba , 0x00000104 , 0x00000001 );
176
+ if (init108 )
177
+ ufs_renesas_write_d0_d4 (hba , 0x00000108 , 0x00000001 );
147
178
ufs_renesas_write_d0_d4 (hba , 0x00000940 , 0x00000001 );
148
179
udelay (1 );
149
180
ufs_renesas_write_d0_d4 (hba , 0x00000940 , 0x00000000 );
@@ -207,12 +238,12 @@ static void ufs_renesas_init_compensation_and_slicers(struct ufs_hba *hba)
207
238
ufs_renesas_write_phy_10ad_10af (hba , 0x0080 , 0x001a );
208
239
}
209
240
210
- static void ufs_renesas_pre_init (struct ufs_hba * hba )
241
+ static void ufs_renesas_r8a779f0_es10_pre_init (struct ufs_hba * hba )
211
242
{
212
243
u32 timer_val ;
213
244
214
245
/* This setting is for SERIES B */
215
- ufs_renesas_init_step1_to_3 (hba );
246
+ ufs_renesas_init_step1_to_3 (hba , false );
216
247
217
248
ufs_renesas_init_step4_to_6 (hba );
218
249
@@ -283,6 +314,105 @@ static void ufs_renesas_pre_init(struct ufs_hba *hba)
283
314
ufs_renesas_init_enable_timer (hba , timer_val );
284
315
}
285
316
317
+ static void ufs_renesas_r8a779f0_init_step3_add (struct ufs_hba * hba , bool assert )
318
+ {
319
+ u32 val_2x = 0 , val_3x = 0 , val_4x = 0 ;
320
+
321
+ if (assert ) {
322
+ val_2x = 0x0001 ;
323
+ val_3x = 0x0003 ;
324
+ val_4x = 0x0001 ;
325
+ }
326
+
327
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x20 , val_2x );
328
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x4a , val_4x );
329
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x35 , val_3x );
330
+ ufs_renesas_reset_indirect_update (hba );
331
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x21 , val_2x );
332
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x4b , val_4x );
333
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x36 , val_3x );
334
+ ufs_renesas_reset_indirect_update (hba );
335
+ }
336
+
337
+ static void ufs_renesas_r8a779f0_pre_init (struct ufs_hba * hba )
338
+ {
339
+ struct ufs_renesas_priv * priv = ufshcd_get_variant (hba );
340
+ u32 timer_val ;
341
+ u32 data ;
342
+ int i ;
343
+
344
+ /* This setting is for SERIES B */
345
+ ufs_renesas_init_step1_to_3 (hba , true);
346
+
347
+ ufs_renesas_r8a779f0_init_step3_add (hba , true);
348
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x5f , 0x0063 );
349
+ ufs_renesas_reset_indirect_update (hba );
350
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x60 , 0x0003 );
351
+ ufs_renesas_reset_indirect_update (hba );
352
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x5b , 0x00a6 );
353
+ ufs_renesas_reset_indirect_update (hba );
354
+ ufs_renesas_reset_indirect_write (hba , 7 , 0x5c , 0x0003 );
355
+ ufs_renesas_reset_indirect_update (hba );
356
+ ufs_renesas_r8a779f0_init_step3_add (hba , false);
357
+
358
+ ufs_renesas_init_step4_to_6 (hba );
359
+
360
+ timer_val = ufs_renesas_init_disable_timer (hba );
361
+
362
+ ufs_renesas_indirect_write (hba , 1 , 0x01 , 0x001f );
363
+ ufs_renesas_indirect_write (hba , 7 , 0x5d , 0x0014 );
364
+ ufs_renesas_indirect_write (hba , 7 , 0x5e , 0x0014 );
365
+ ufs_renesas_indirect_write (hba , 7 , 0x0d , 0x0007 );
366
+ ufs_renesas_indirect_write (hba , 7 , 0x0e , 0x0007 );
367
+
368
+ ufs_renesas_indirect_poll (hba , 7 , 0x3c , 0 , BIT (7 ));
369
+ ufs_renesas_indirect_poll (hba , 7 , 0x4c , 0 , BIT (4 ));
370
+
371
+ ufs_renesas_indirect_write (hba , 1 , 0x32 , 0x0080 );
372
+ ufs_renesas_indirect_write (hba , 1 , 0x1f , 0x0001 );
373
+ ufs_renesas_indirect_write (hba , 1 , 0x2c , 0x0001 );
374
+ ufs_renesas_indirect_write (hba , 1 , 0x32 , 0x0087 );
375
+
376
+ ufs_renesas_indirect_write (hba , 1 , 0x4d , priv -> calib [2 ]);
377
+ ufs_renesas_indirect_write (hba , 1 , 0x4e , priv -> calib [3 ]);
378
+ ufs_renesas_indirect_write (hba , 1 , 0x0d , 0x0006 );
379
+ ufs_renesas_indirect_write (hba , 1 , 0x0e , 0x0007 );
380
+ ufs_renesas_write_phy (hba , 0x0028 , priv -> calib [3 ]);
381
+ ufs_renesas_write_phy (hba , 0x4014 , priv -> calib [3 ]);
382
+
383
+ ufs_renesas_set_phy (hba , 0x401c , BIT (2 ));
384
+
385
+ ufs_renesas_write_phy (hba , 0x4000 , priv -> calib [6 ]);
386
+ ufs_renesas_write_phy (hba , 0x4001 , priv -> calib [7 ]);
387
+
388
+ ufs_renesas_indirect_write (hba , 1 , 0x14 , 0x0001 );
389
+
390
+ ufs_renesas_init_compensation_and_slicers (hba );
391
+
392
+ ufs_renesas_indirect_write (hba , 7 , 0x79 , 0x0000 );
393
+ ufs_renesas_indirect_write (hba , 7 , 0x24 , 0x000c );
394
+ ufs_renesas_indirect_write (hba , 7 , 0x25 , 0x000c );
395
+ ufs_renesas_indirect_write (hba , 7 , 0x62 , 0x00c0 );
396
+ ufs_renesas_indirect_write (hba , 7 , 0x63 , 0x0001 );
397
+
398
+ for (i = 0 ; i < priv -> fw -> size / 2 ; i ++ ) {
399
+ data = (priv -> fw -> data [i * 2 + 1 ] << 8 ) | priv -> fw -> data [i * 2 ];
400
+ ufs_renesas_write_phy (hba , 0xc000 + i , data );
401
+ }
402
+
403
+ ufs_renesas_indirect_write (hba , 7 , 0x0d , 0x0002 );
404
+ ufs_renesas_indirect_write (hba , 7 , 0x0e , 0x0007 );
405
+
406
+ ufs_renesas_indirect_write (hba , 7 , 0x5d , 0x0014 );
407
+ ufs_renesas_indirect_write (hba , 7 , 0x5e , 0x0017 );
408
+ ufs_renesas_indirect_write (hba , 7 , 0x5d , 0x0004 );
409
+ ufs_renesas_indirect_write (hba , 7 , 0x5e , 0x0017 );
410
+ ufs_renesas_indirect_poll (hba , 7 , 0x55 , 0 , BIT (6 ));
411
+ ufs_renesas_indirect_poll (hba , 7 , 0x41 , 0 , BIT (7 ));
412
+
413
+ ufs_renesas_init_enable_timer (hba , timer_val );
414
+ }
415
+
286
416
static int ufs_renesas_hce_enable_notify (struct ufs_hba * hba ,
287
417
enum ufs_notify_change_status status )
288
418
{
@@ -292,7 +422,7 @@ static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba,
292
422
return 0 ;
293
423
294
424
if (status == PRE_CHANGE )
295
- ufs_renesas_pre_init (hba );
425
+ priv -> pre_init (hba );
296
426
297
427
priv -> initialized = true;
298
428
@@ -310,20 +440,78 @@ static int ufs_renesas_setup_clocks(struct ufs_hba *hba, bool on,
310
440
return 0 ;
311
441
}
312
442
443
+ static const struct soc_device_attribute ufs_fallback [] = {
444
+ { .soc_id = "r8a779f0" , .revision = "ES1.[01]" },
445
+ { /* Sentinel */ }
446
+ };
447
+
313
448
static int ufs_renesas_init (struct ufs_hba * hba )
314
449
{
450
+ const struct soc_device_attribute * attr ;
451
+ struct nvmem_cell * cell = NULL ;
452
+ struct device * dev = hba -> dev ;
315
453
struct ufs_renesas_priv * priv ;
454
+ u8 * data = NULL ;
455
+ size_t len ;
456
+ int ret ;
316
457
317
- priv = devm_kzalloc (hba -> dev , sizeof (* priv ), GFP_KERNEL );
458
+ priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
318
459
if (!priv )
319
460
return - ENOMEM ;
320
461
ufshcd_set_variant (hba , priv );
321
462
322
463
hba -> quirks |= UFSHCD_QUIRK_HIBERN_FASTAUTO ;
323
464
465
+ attr = soc_device_match (ufs_fallback );
466
+ if (attr )
467
+ goto fallback ;
468
+
469
+ ret = request_firmware (& priv -> fw , UFS_RENESAS_FIRMWARE_NAME , dev );
470
+ if (ret ) {
471
+ dev_warn (dev , "Failed to load firmware\n" );
472
+ goto fallback ;
473
+ }
474
+
475
+ cell = nvmem_cell_get (dev , "calibration" );
476
+ if (IS_ERR (cell )) {
477
+ dev_warn (dev , "No calibration data specified\n" );
478
+ goto fallback ;
479
+ }
480
+
481
+ data = nvmem_cell_read (cell , & len );
482
+ if (IS_ERR (data )) {
483
+ dev_warn (dev , "Failed to read calibration data: %pe\n" , data );
484
+ goto fallback ;
485
+ }
486
+
487
+ if (len != EFUSE_CALIB_SIZE ) {
488
+ dev_warn (dev , "Invalid calibration data size %zu\n" , len );
489
+ goto fallback ;
490
+ }
491
+
492
+ memcpy (priv -> calib , data , EFUSE_CALIB_SIZE );
493
+ priv -> pre_init = ufs_renesas_r8a779f0_pre_init ;
494
+ goto out ;
495
+
496
+ fallback :
497
+ dev_info (dev , "Using ES1.0 init code\n" );
498
+ priv -> pre_init = ufs_renesas_r8a779f0_es10_pre_init ;
499
+
500
+ out :
501
+ kfree (data );
502
+ if (!IS_ERR_OR_NULL (cell ))
503
+ nvmem_cell_put (cell );
504
+
324
505
return 0 ;
325
506
}
326
507
508
+ static void ufs_renesas_exit (struct ufs_hba * hba )
509
+ {
510
+ struct ufs_renesas_priv * priv = ufshcd_get_variant (hba );
511
+
512
+ release_firmware (priv -> fw );
513
+ }
514
+
327
515
static int ufs_renesas_set_dma_mask (struct ufs_hba * hba )
328
516
{
329
517
return dma_set_mask_and_coherent (hba -> dev , DMA_BIT_MASK (32 ));
@@ -332,6 +520,7 @@ static int ufs_renesas_set_dma_mask(struct ufs_hba *hba)
332
520
static const struct ufs_hba_variant_ops ufs_renesas_vops = {
333
521
.name = "renesas" ,
334
522
.init = ufs_renesas_init ,
523
+ .exit = ufs_renesas_exit ,
335
524
.set_dma_mask = ufs_renesas_set_dma_mask ,
336
525
.setup_clocks = ufs_renesas_setup_clocks ,
337
526
.hce_enable_notify = ufs_renesas_hce_enable_notify ,
0 commit comments