@@ -245,35 +245,60 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie,
245
245
resource_size_t cpu_addr ,
246
246
resource_size_t pci_addr ,
247
247
resource_size_t size ,
248
- unsigned long type , int num )
248
+ unsigned long type , int * num )
249
249
{
250
+ resource_size_t remaining = size ;
251
+ resource_size_t table_size ;
252
+ resource_size_t addr_align ;
253
+ const char * range_type ;
250
254
void __iomem * table ;
251
255
u32 val ;
252
256
253
- if (num >= PCIE_MAX_TRANS_TABLES ) {
254
- dev_err (pcie -> dev , "not enough translate table for addr: %#llx, limited to [%d]\n" ,
255
- (unsigned long long )cpu_addr , PCIE_MAX_TRANS_TABLES );
256
- return - ENODEV ;
257
- }
257
+ while (remaining && (* num < PCIE_MAX_TRANS_TABLES )) {
258
+ /* Table size needs to be a power of 2 */
259
+ table_size = BIT (fls (remaining ) - 1 );
260
+
261
+ if (cpu_addr > 0 ) {
262
+ addr_align = BIT (ffs (cpu_addr ) - 1 );
263
+ table_size = min (table_size , addr_align );
264
+ }
265
+
266
+ /* Minimum size of translate table is 4KiB */
267
+ if (table_size < 0x1000 ) {
268
+ dev_err (pcie -> dev , "illegal table size %#llx\n" ,
269
+ (unsigned long long )table_size );
270
+ return - EINVAL ;
271
+ }
258
272
259
- table = pcie -> base + PCIE_TRANS_TABLE_BASE_REG +
260
- num * PCIE_ATR_TLB_SET_OFFSET ;
273
+ table = pcie -> base + PCIE_TRANS_TABLE_BASE_REG + * num * PCIE_ATR_TLB_SET_OFFSET ;
274
+ writel_relaxed (lower_32_bits (cpu_addr ) | PCIE_ATR_SIZE (fls (table_size ) - 1 ), table );
275
+ writel_relaxed (upper_32_bits (cpu_addr ), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET );
276
+ writel_relaxed (lower_32_bits (pci_addr ), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET );
277
+ writel_relaxed (upper_32_bits (pci_addr ), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET );
261
278
262
- writel_relaxed (lower_32_bits (cpu_addr ) | PCIE_ATR_SIZE (fls (size ) - 1 ),
263
- table );
264
- writel_relaxed (upper_32_bits (cpu_addr ),
265
- table + PCIE_ATR_SRC_ADDR_MSB_OFFSET );
266
- writel_relaxed (lower_32_bits (pci_addr ),
267
- table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET );
268
- writel_relaxed (upper_32_bits (pci_addr ),
269
- table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET );
279
+ if (type == IORESOURCE_IO ) {
280
+ val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO ;
281
+ range_type = "IO" ;
282
+ } else {
283
+ val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM ;
284
+ range_type = "MEM" ;
285
+ }
270
286
271
- if (type == IORESOURCE_IO )
272
- val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO ;
273
- else
274
- val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM ;
287
+ writel_relaxed (val , table + PCIE_ATR_TRSL_PARAM_OFFSET );
275
288
276
- writel_relaxed (val , table + PCIE_ATR_TRSL_PARAM_OFFSET );
289
+ dev_dbg (pcie -> dev , "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n" ,
290
+ range_type , * num , (unsigned long long )cpu_addr ,
291
+ (unsigned long long )pci_addr , (unsigned long long )table_size );
292
+
293
+ cpu_addr += table_size ;
294
+ pci_addr += table_size ;
295
+ remaining -= table_size ;
296
+ (* num )++ ;
297
+ }
298
+
299
+ if (remaining )
300
+ dev_warn (pcie -> dev , "not enough translate table for addr: %#llx, limited to [%d]\n" ,
301
+ (unsigned long long )cpu_addr , PCIE_MAX_TRANS_TABLES );
277
302
278
303
return 0 ;
279
304
}
@@ -380,30 +405,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
380
405
resource_size_t cpu_addr ;
381
406
resource_size_t pci_addr ;
382
407
resource_size_t size ;
383
- const char * range_type ;
384
408
385
- if (type == IORESOURCE_IO ) {
409
+ if (type == IORESOURCE_IO )
386
410
cpu_addr = pci_pio_to_address (res -> start );
387
- range_type = "IO" ;
388
- } else if (type == IORESOURCE_MEM ) {
411
+ else if (type == IORESOURCE_MEM )
389
412
cpu_addr = res -> start ;
390
- range_type = "MEM" ;
391
- } else {
413
+ else
392
414
continue ;
393
- }
394
415
395
416
pci_addr = res -> start - entry -> offset ;
396
417
size = resource_size (res );
397
418
err = mtk_pcie_set_trans_table (pcie , cpu_addr , pci_addr , size ,
398
- type , table_index );
419
+ type , & table_index );
399
420
if (err )
400
421
return err ;
401
-
402
- dev_dbg (pcie -> dev , "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n" ,
403
- range_type , table_index , (unsigned long long )cpu_addr ,
404
- (unsigned long long )pci_addr , (unsigned long long )size );
405
-
406
- table_index ++ ;
407
422
}
408
423
409
424
return 0 ;
0 commit comments