@@ -259,6 +259,77 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
259
259
.probe_slot = pch_hc_probe_slot ,
260
260
};
261
261
262
+ enum {
263
+ INTEL_DSM_FNS = 0 ,
264
+ INTEL_DSM_D3_RETUNE = 10 ,
265
+ };
266
+
267
+ struct intel_host {
268
+ u32 dsm_fns ;
269
+ bool d3_retune ;
270
+ };
271
+
272
+ const u8 intel_dsm_uuid [] = {
273
+ 0xA5 , 0x3E , 0xC1 , 0xF6 , 0xCD , 0x65 , 0x1F , 0x46 ,
274
+ 0xAB , 0x7A , 0x29 , 0xF7 , 0xE8 , 0xD5 , 0xBD , 0x61 ,
275
+ };
276
+
277
+ static int __intel_dsm (struct intel_host * intel_host , struct device * dev ,
278
+ unsigned int fn , u32 * result )
279
+ {
280
+ union acpi_object * obj ;
281
+ int err = 0 ;
282
+
283
+ obj = acpi_evaluate_dsm (ACPI_HANDLE (dev ), intel_dsm_uuid , 0 , fn , NULL );
284
+ if (!obj )
285
+ return - EOPNOTSUPP ;
286
+
287
+ if (obj -> type != ACPI_TYPE_BUFFER || obj -> buffer .length < 1 ) {
288
+ err = - EINVAL ;
289
+ goto out ;
290
+ }
291
+
292
+ if (obj -> buffer .length >= 4 )
293
+ * result = * (u32 * )obj -> buffer .pointer ;
294
+ else if (obj -> buffer .length >= 2 )
295
+ * result = * (u16 * )obj -> buffer .pointer ;
296
+ else
297
+ * result = * (u8 * )obj -> buffer .pointer ;
298
+ out :
299
+ ACPI_FREE (obj );
300
+
301
+ return err ;
302
+ }
303
+
304
+ static int intel_dsm (struct intel_host * intel_host , struct device * dev ,
305
+ unsigned int fn , u32 * result )
306
+ {
307
+ if (fn > 31 || !(intel_host -> dsm_fns & (1 << fn )))
308
+ return - EOPNOTSUPP ;
309
+
310
+ return __intel_dsm (intel_host , dev , fn , result );
311
+ }
312
+
313
+ static void intel_dsm_init (struct intel_host * intel_host , struct device * dev ,
314
+ struct mmc_host * mmc )
315
+ {
316
+ int err ;
317
+ u32 val ;
318
+
319
+ err = __intel_dsm (intel_host , dev , INTEL_DSM_FNS , & intel_host -> dsm_fns );
320
+ if (err ) {
321
+ pr_debug ("%s: DSM not supported, error %d\n" ,
322
+ mmc_hostname (mmc ), err );
323
+ return ;
324
+ }
325
+
326
+ pr_debug ("%s: DSM function mask %#x\n" ,
327
+ mmc_hostname (mmc ), intel_host -> dsm_fns );
328
+
329
+ err = intel_dsm (intel_host , dev , INTEL_DSM_D3_RETUNE , & val );
330
+ intel_host -> d3_retune = err ? true : !!val ;
331
+ }
332
+
262
333
static void sdhci_pci_int_hw_reset (struct sdhci_host * host )
263
334
{
264
335
u8 reg ;
@@ -359,8 +430,19 @@ static int bxt_get_cd(struct mmc_host *mmc)
359
430
return ret ;
360
431
}
361
432
433
+ static void byt_read_dsm (struct sdhci_pci_slot * slot )
434
+ {
435
+ struct intel_host * intel_host = sdhci_pci_priv (slot );
436
+ struct device * dev = & slot -> chip -> pdev -> dev ;
437
+ struct mmc_host * mmc = slot -> host -> mmc ;
438
+
439
+ intel_dsm_init (intel_host , dev , mmc );
440
+ slot -> chip -> rpm_retune = intel_host -> d3_retune ;
441
+ }
442
+
362
443
static int byt_emmc_probe_slot (struct sdhci_pci_slot * slot )
363
444
{
445
+ byt_read_dsm (slot );
364
446
slot -> host -> mmc -> caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
365
447
MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
366
448
MMC_CAP_CMD_DURING_TFR |
@@ -405,6 +487,8 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
405
487
{
406
488
int err ;
407
489
490
+ byt_read_dsm (slot );
491
+
408
492
err = ni_set_max_freq (slot );
409
493
if (err )
410
494
return err ;
@@ -416,13 +500,15 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
416
500
417
501
static int byt_sdio_probe_slot (struct sdhci_pci_slot * slot )
418
502
{
503
+ byt_read_dsm (slot );
419
504
slot -> host -> mmc -> caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
420
505
MMC_CAP_WAIT_WHILE_BUSY ;
421
506
return 0 ;
422
507
}
423
508
424
509
static int byt_sd_probe_slot (struct sdhci_pci_slot * slot )
425
510
{
511
+ byt_read_dsm (slot );
426
512
slot -> host -> mmc -> caps |= MMC_CAP_WAIT_WHILE_BUSY ;
427
513
slot -> cd_idx = 0 ;
428
514
slot -> cd_override_level = true;
@@ -488,6 +574,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
488
574
SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 |
489
575
SDHCI_QUIRK2_STOP_WITH_TC ,
490
576
.ops = & sdhci_intel_byt_ops ,
577
+ .priv_size = sizeof (struct intel_host ),
491
578
};
492
579
493
580
static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
@@ -497,6 +584,7 @@ static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = {
497
584
.allow_runtime_pm = true,
498
585
.probe_slot = ni_byt_sdio_probe_slot ,
499
586
.ops = & sdhci_intel_byt_ops ,
587
+ .priv_size = sizeof (struct intel_host ),
500
588
};
501
589
502
590
static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
@@ -506,6 +594,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
506
594
.allow_runtime_pm = true,
507
595
.probe_slot = byt_sdio_probe_slot ,
508
596
.ops = & sdhci_intel_byt_ops ,
597
+ .priv_size = sizeof (struct intel_host ),
509
598
};
510
599
511
600
static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
@@ -517,6 +606,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
517
606
.own_cd_for_runtime_pm = true,
518
607
.probe_slot = byt_sd_probe_slot ,
519
608
.ops = & sdhci_intel_byt_ops ,
609
+ .priv_size = sizeof (struct intel_host ),
520
610
};
521
611
522
612
/* Define Host controllers for Intel Merrifield platform */
0 commit comments