35
35
#include "nvme.h"
36
36
37
37
#define APPLE_ANS_BOOT_TIMEOUT USEC_PER_SEC
38
- #define APPLE_ANS_MAX_QUEUE_DEPTH 64
39
38
40
39
#define APPLE_ANS_COPROC_CPU_CONTROL 0x44
41
40
#define APPLE_ANS_COPROC_CPU_CONTROL_RUN BIT(4)
75
74
#define APPLE_NVME_AQ_DEPTH 2
76
75
#define APPLE_NVME_AQ_MQ_TAG_DEPTH (APPLE_NVME_AQ_DEPTH - 1)
77
76
77
+ #define APPLE_NVME_IOSQES 7
78
+
78
79
/*
79
80
* These can be higher, but we need to ensure that any command doesn't
80
81
* require an sg allocation that needs more than a page of data.
@@ -142,6 +143,7 @@ struct apple_nvme_queue {
142
143
u32 __iomem * sq_db ;
143
144
u32 __iomem * cq_db ;
144
145
146
+ u16 sq_tail ;
145
147
u16 cq_head ;
146
148
u8 cq_phase ;
147
149
@@ -166,11 +168,17 @@ struct apple_nvme_iod {
166
168
struct scatterlist * sg ;
167
169
};
168
170
171
+ struct apple_nvme_hw {
172
+ bool has_lsq_nvmmu ;
173
+ u32 max_queue_depth ;
174
+ };
175
+
169
176
struct apple_nvme {
170
177
struct device * dev ;
171
178
172
179
void __iomem * mmio_coproc ;
173
180
void __iomem * mmio_nvme ;
181
+ const struct apple_nvme_hw * hw ;
174
182
175
183
struct device * * pd_dev ;
176
184
struct device_link * * pd_link ;
@@ -215,10 +223,12 @@ static inline struct apple_nvme *queue_to_apple_nvme(struct apple_nvme_queue *q)
215
223
216
224
static unsigned int apple_nvme_queue_depth (struct apple_nvme_queue * q )
217
225
{
218
- if (q -> is_adminq )
226
+ struct apple_nvme * anv = queue_to_apple_nvme (q );
227
+
228
+ if (q -> is_adminq && anv -> hw -> has_lsq_nvmmu )
219
229
return APPLE_NVME_AQ_DEPTH ;
220
230
221
- return APPLE_ANS_MAX_QUEUE_DEPTH ;
231
+ return anv -> hw -> max_queue_depth ;
222
232
}
223
233
224
234
static void apple_nvme_rtkit_crashed (void * cookie , const void * crashlog , size_t crashlog_size )
@@ -280,7 +290,28 @@ static void apple_nvmmu_inval(struct apple_nvme_queue *q, unsigned int tag)
280
290
"NVMMU TCB invalidation failed\n" );
281
291
}
282
292
283
- static void apple_nvme_submit_cmd (struct apple_nvme_queue * q ,
293
+ static void apple_nvme_submit_cmd_t8015 (struct apple_nvme_queue * q ,
294
+ struct nvme_command * cmd )
295
+ {
296
+ struct apple_nvme * anv = queue_to_apple_nvme (q );
297
+
298
+ spin_lock_irq (& anv -> lock );
299
+
300
+ if (q -> is_adminq )
301
+ memcpy (& q -> sqes [q -> sq_tail ], cmd , sizeof (* cmd ));
302
+ else
303
+ memcpy ((void * )q -> sqes + (q -> sq_tail << APPLE_NVME_IOSQES ),
304
+ cmd , sizeof (* cmd ));
305
+
306
+ if (++ q -> sq_tail == anv -> hw -> max_queue_depth )
307
+ q -> sq_tail = 0 ;
308
+
309
+ writel (q -> sq_tail , q -> sq_db );
310
+ spin_unlock_irq (& anv -> lock );
311
+ }
312
+
313
+
314
+ static void apple_nvme_submit_cmd_t8103 (struct apple_nvme_queue * q ,
284
315
struct nvme_command * cmd )
285
316
{
286
317
struct apple_nvme * anv = queue_to_apple_nvme (q );
@@ -590,7 +621,8 @@ static inline void apple_nvme_handle_cqe(struct apple_nvme_queue *q,
590
621
__u16 command_id = READ_ONCE (cqe -> command_id );
591
622
struct request * req ;
592
623
593
- apple_nvmmu_inval (q , command_id );
624
+ if (anv -> hw -> has_lsq_nvmmu )
625
+ apple_nvmmu_inval (q , command_id );
594
626
595
627
req = nvme_find_rq (apple_nvme_queue_tagset (anv , q ), command_id );
596
628
if (unlikely (!req )) {
@@ -685,7 +717,7 @@ static int apple_nvme_create_cq(struct apple_nvme *anv)
685
717
c .create_cq .opcode = nvme_admin_create_cq ;
686
718
c .create_cq .prp1 = cpu_to_le64 (anv -> ioq .cq_dma_addr );
687
719
c .create_cq .cqid = cpu_to_le16 (1 );
688
- c .create_cq .qsize = cpu_to_le16 (APPLE_ANS_MAX_QUEUE_DEPTH - 1 );
720
+ c .create_cq .qsize = cpu_to_le16 (anv -> hw -> max_queue_depth - 1 );
689
721
c .create_cq .cq_flags = cpu_to_le16 (NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED );
690
722
c .create_cq .irq_vector = cpu_to_le16 (0 );
691
723
@@ -713,7 +745,7 @@ static int apple_nvme_create_sq(struct apple_nvme *anv)
713
745
c .create_sq .opcode = nvme_admin_create_sq ;
714
746
c .create_sq .prp1 = cpu_to_le64 (anv -> ioq .sq_dma_addr );
715
747
c .create_sq .sqid = cpu_to_le16 (1 );
716
- c .create_sq .qsize = cpu_to_le16 (APPLE_ANS_MAX_QUEUE_DEPTH - 1 );
748
+ c .create_sq .qsize = cpu_to_le16 (anv -> hw -> max_queue_depth - 1 );
717
749
c .create_sq .sq_flags = cpu_to_le16 (NVME_QUEUE_PHYS_CONTIG );
718
750
c .create_sq .cqid = cpu_to_le16 (1 );
719
751
@@ -765,7 +797,12 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
765
797
}
766
798
767
799
nvme_start_request (req );
768
- apple_nvme_submit_cmd (q , cmnd );
800
+
801
+ if (anv -> hw -> has_lsq_nvmmu )
802
+ apple_nvme_submit_cmd_t8103 (q , cmnd );
803
+ else
804
+ apple_nvme_submit_cmd_t8015 (q , cmnd );
805
+
769
806
return BLK_STS_OK ;
770
807
771
808
out_free_cmd :
@@ -970,11 +1007,13 @@ static const struct blk_mq_ops apple_nvme_mq_ops = {
970
1007
static void apple_nvme_init_queue (struct apple_nvme_queue * q )
971
1008
{
972
1009
unsigned int depth = apple_nvme_queue_depth (q );
1010
+ struct apple_nvme * anv = queue_to_apple_nvme (q );
973
1011
974
1012
q -> cq_head = 0 ;
975
1013
q -> cq_phase = 1 ;
976
- memset (q -> tcbs , 0 ,
977
- APPLE_ANS_MAX_QUEUE_DEPTH * sizeof (struct apple_nvmmu_tcb ));
1014
+ if (anv -> hw -> has_lsq_nvmmu )
1015
+ memset (q -> tcbs , 0 , anv -> hw -> max_queue_depth
1016
+ * sizeof (struct apple_nvmmu_tcb ));
978
1017
memset (q -> cqes , 0 , depth * sizeof (struct nvme_completion ));
979
1018
WRITE_ONCE (q -> enabled , true);
980
1019
wmb (); /* ensure the first interrupt sees the initialization */
@@ -1069,49 +1108,55 @@ static void apple_nvme_reset_work(struct work_struct *work)
1069
1108
1070
1109
dma_set_max_seg_size (anv -> dev , 0xffffffff );
1071
1110
1072
- /*
1073
- * Enable NVMMU and linear submission queues.
1074
- * While we could keep those disabled and pretend this is slightly
1075
- * more common NVMe controller we'd still need some quirks (e.g.
1076
- * sq entries will be 128 bytes) and Apple might drop support for
1077
- * that mode in the future.
1078
- */
1079
- writel (APPLE_ANS_LINEAR_SQ_EN ,
1080
- anv -> mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL );
1111
+ if (anv -> hw -> has_lsq_nvmmu ) {
1112
+ /*
1113
+ * Enable NVMMU and linear submission queues which is required
1114
+ * since T6000.
1115
+ */
1116
+ writel (APPLE_ANS_LINEAR_SQ_EN ,
1117
+ anv -> mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL );
1081
1118
1082
- /* Allow as many pending command as possible for both queues */
1083
- writel (APPLE_ANS_MAX_QUEUE_DEPTH | (APPLE_ANS_MAX_QUEUE_DEPTH << 16 ),
1084
- anv -> mmio_nvme + APPLE_ANS_MAX_PEND_CMDS_CTRL );
1119
+ /* Allow as many pending command as possible for both queues */
1120
+ writel (anv -> hw -> max_queue_depth
1121
+ | (anv -> hw -> max_queue_depth << 16 ), anv -> mmio_nvme
1122
+ + APPLE_ANS_MAX_PEND_CMDS_CTRL );
1085
1123
1086
- /* Setup the NVMMU for the maximum admin and IO queue depth */
1087
- writel (APPLE_ANS_MAX_QUEUE_DEPTH - 1 ,
1088
- anv -> mmio_nvme + APPLE_NVMMU_NUM_TCBS );
1124
+ /* Setup the NVMMU for the maximum admin and IO queue depth */
1125
+ writel (anv -> hw -> max_queue_depth - 1 ,
1126
+ anv -> mmio_nvme + APPLE_NVMMU_NUM_TCBS );
1089
1127
1090
- /*
1091
- * This is probably a chicken bit: without it all commands where any PRP
1092
- * is set to zero (including those that don't use that field) fail and
1093
- * the co-processor complains about "completed with err BAD_CMD-" or
1094
- * a "NULL_PRP_PTR_ERR" in the syslog
1095
- */
1096
- writel (readl (anv -> mmio_nvme + APPLE_ANS_UNKNOWN_CTRL ) &
1097
- ~APPLE_ANS_PRP_NULL_CHECK ,
1098
- anv -> mmio_nvme + APPLE_ANS_UNKNOWN_CTRL );
1128
+ /*
1129
+ * This is probably a chicken bit: without it all commands
1130
+ * where any PRP is set to zero (including those that don't use
1131
+ * that field) fail and the co-processor complains about
1132
+ * "completed with err BAD_CMD-" or a "NULL_PRP_PTR_ERR" in the
1133
+ * syslog
1134
+ */
1135
+ writel (readl (anv -> mmio_nvme + APPLE_ANS_UNKNOWN_CTRL ) &
1136
+ ~APPLE_ANS_PRP_NULL_CHECK ,
1137
+ anv -> mmio_nvme + APPLE_ANS_UNKNOWN_CTRL );
1138
+ }
1099
1139
1100
1140
/* Setup the admin queue */
1101
- aqa = APPLE_NVME_AQ_DEPTH - 1 ;
1141
+ if (anv -> hw -> has_lsq_nvmmu )
1142
+ aqa = APPLE_NVME_AQ_DEPTH - 1 ;
1143
+ else
1144
+ aqa = anv -> hw -> max_queue_depth - 1 ;
1102
1145
aqa |= aqa << 16 ;
1103
1146
writel (aqa , anv -> mmio_nvme + NVME_REG_AQA );
1104
1147
writeq (anv -> adminq .sq_dma_addr , anv -> mmio_nvme + NVME_REG_ASQ );
1105
1148
writeq (anv -> adminq .cq_dma_addr , anv -> mmio_nvme + NVME_REG_ACQ );
1106
1149
1107
- /* Setup NVMMU for both queues */
1108
- writeq (anv -> adminq .tcb_dma_addr ,
1109
- anv -> mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE );
1110
- writeq (anv -> ioq .tcb_dma_addr ,
1111
- anv -> mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE );
1150
+ if (anv -> hw -> has_lsq_nvmmu ) {
1151
+ /* Setup NVMMU for both queues */
1152
+ writeq (anv -> adminq .tcb_dma_addr ,
1153
+ anv -> mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE );
1154
+ writeq (anv -> ioq .tcb_dma_addr ,
1155
+ anv -> mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE );
1156
+ }
1112
1157
1113
1158
anv -> ctrl .sqsize =
1114
- APPLE_ANS_MAX_QUEUE_DEPTH - 1 ; /* 0's based queue depth */
1159
+ anv -> hw -> max_queue_depth - 1 ; /* 0's based queue depth */
1115
1160
anv -> ctrl .cap = readq (anv -> mmio_nvme + NVME_REG_CAP );
1116
1161
1117
1162
dev_dbg (anv -> dev , "Enabling controller now" );
@@ -1282,8 +1327,9 @@ static int apple_nvme_alloc_tagsets(struct apple_nvme *anv)
1282
1327
* both queues. The admin queue gets the first APPLE_NVME_AQ_DEPTH which
1283
1328
* must be marked as reserved in the IO queue.
1284
1329
*/
1285
- anv -> tagset .reserved_tags = APPLE_NVME_AQ_DEPTH ;
1286
- anv -> tagset .queue_depth = APPLE_ANS_MAX_QUEUE_DEPTH - 1 ;
1330
+ if (anv -> hw -> has_lsq_nvmmu )
1331
+ anv -> tagset .reserved_tags = APPLE_NVME_AQ_DEPTH ;
1332
+ anv -> tagset .queue_depth = anv -> hw -> max_queue_depth - 1 ;
1287
1333
anv -> tagset .timeout = NVME_IO_TIMEOUT ;
1288
1334
anv -> tagset .numa_node = NUMA_NO_NODE ;
1289
1335
anv -> tagset .cmd_size = sizeof (struct apple_nvme_iod );
@@ -1307,29 +1353,36 @@ static int apple_nvme_queue_alloc(struct apple_nvme *anv,
1307
1353
struct apple_nvme_queue * q )
1308
1354
{
1309
1355
unsigned int depth = apple_nvme_queue_depth (q );
1356
+ size_t iosq_size ;
1310
1357
1311
1358
q -> cqes = dmam_alloc_coherent (anv -> dev ,
1312
1359
depth * sizeof (struct nvme_completion ),
1313
1360
& q -> cq_dma_addr , GFP_KERNEL );
1314
1361
if (!q -> cqes )
1315
1362
return - ENOMEM ;
1316
1363
1317
- q -> sqes = dmam_alloc_coherent (anv -> dev ,
1318
- depth * sizeof (struct nvme_command ),
1364
+ if (anv -> hw -> has_lsq_nvmmu )
1365
+ iosq_size = depth * sizeof (struct nvme_command );
1366
+ else
1367
+ iosq_size = depth << APPLE_NVME_IOSQES ;
1368
+
1369
+ q -> sqes = dmam_alloc_coherent (anv -> dev , iosq_size ,
1319
1370
& q -> sq_dma_addr , GFP_KERNEL );
1320
1371
if (!q -> sqes )
1321
1372
return - ENOMEM ;
1322
1373
1323
- /*
1324
- * We need the maximum queue depth here because the NVMMU only has a
1325
- * single depth configuration shared between both queues.
1326
- */
1327
- q -> tcbs = dmam_alloc_coherent (anv -> dev ,
1328
- APPLE_ANS_MAX_QUEUE_DEPTH *
1329
- sizeof (struct apple_nvmmu_tcb ),
1330
- & q -> tcb_dma_addr , GFP_KERNEL );
1331
- if (!q -> tcbs )
1332
- return - ENOMEM ;
1374
+ if (anv -> hw -> has_lsq_nvmmu ) {
1375
+ /*
1376
+ * We need the maximum queue depth here because the NVMMU only
1377
+ * has a single depth configuration shared between both queues.
1378
+ */
1379
+ q -> tcbs = dmam_alloc_coherent (anv -> dev ,
1380
+ anv -> hw -> max_queue_depth *
1381
+ sizeof (struct apple_nvmmu_tcb ),
1382
+ & q -> tcb_dma_addr , GFP_KERNEL );
1383
+ if (!q -> tcbs )
1384
+ return - ENOMEM ;
1385
+ }
1333
1386
1334
1387
/*
1335
1388
* initialize phase to make sure the allocated and empty memory
@@ -1413,6 +1466,12 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
1413
1466
anv -> adminq .is_adminq = true;
1414
1467
platform_set_drvdata (pdev , anv );
1415
1468
1469
+ anv -> hw = of_device_get_match_data (& pdev -> dev );
1470
+ if (!anv -> hw ) {
1471
+ ret = - ENODEV ;
1472
+ goto put_dev ;
1473
+ }
1474
+
1416
1475
ret = apple_nvme_attach_genpd (anv );
1417
1476
if (ret < 0 ) {
1418
1477
dev_err_probe (dev , ret , "Failed to attach power domains" );
@@ -1444,10 +1503,17 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
1444
1503
goto put_dev ;
1445
1504
}
1446
1505
1447
- anv -> adminq .sq_db = anv -> mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB ;
1448
- anv -> adminq .cq_db = anv -> mmio_nvme + APPLE_ANS_ACQ_DB ;
1449
- anv -> ioq .sq_db = anv -> mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB ;
1450
- anv -> ioq .cq_db = anv -> mmio_nvme + APPLE_ANS_IOCQ_DB ;
1506
+ if (anv -> hw -> has_lsq_nvmmu ) {
1507
+ anv -> adminq .sq_db = anv -> mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB ;
1508
+ anv -> adminq .cq_db = anv -> mmio_nvme + APPLE_ANS_ACQ_DB ;
1509
+ anv -> ioq .sq_db = anv -> mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB ;
1510
+ anv -> ioq .cq_db = anv -> mmio_nvme + APPLE_ANS_IOCQ_DB ;
1511
+ } else {
1512
+ anv -> adminq .sq_db = anv -> mmio_nvme + NVME_REG_DBS ;
1513
+ anv -> adminq .cq_db = anv -> mmio_nvme + APPLE_ANS_ACQ_DB ;
1514
+ anv -> ioq .sq_db = anv -> mmio_nvme + NVME_REG_DBS + 8 ;
1515
+ anv -> ioq .cq_db = anv -> mmio_nvme + APPLE_ANS_IOCQ_DB ;
1516
+ }
1451
1517
1452
1518
anv -> sart = devm_apple_sart_get (dev );
1453
1519
if (IS_ERR (anv -> sart )) {
@@ -1625,8 +1691,19 @@ static int apple_nvme_suspend(struct device *dev)
1625
1691
static DEFINE_SIMPLE_DEV_PM_OPS (apple_nvme_pm_ops , apple_nvme_suspend ,
1626
1692
apple_nvme_resume ) ;
1627
1693
1694
+ static const struct apple_nvme_hw apple_nvme_t8015_hw = {
1695
+ .has_lsq_nvmmu = false,
1696
+ .max_queue_depth = 16 ,
1697
+ };
1698
+
1699
+ static const struct apple_nvme_hw apple_nvme_t8103_hw = {
1700
+ .has_lsq_nvmmu = true,
1701
+ .max_queue_depth = 64 ,
1702
+ };
1703
+
1628
1704
static const struct of_device_id apple_nvme_of_match [] = {
1629
- { .compatible = "apple,nvme-ans2" },
1705
+ { .compatible = "apple,t8015-nvme-ans2" , .data = & apple_nvme_t8015_hw },
1706
+ { .compatible = "apple,nvme-ans2" , .data = & apple_nvme_t8103_hw },
1630
1707
{},
1631
1708
};
1632
1709
MODULE_DEVICE_TABLE (of , apple_nvme_of_match );
0 commit comments