--- zzzz-none-000/linux-5.15.111/drivers/mmc/host/sdhci-acpi.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/drivers/mmc/host/sdhci-acpi.c 2024-02-07 10:23:07.000000000 +0000 @@ -2,7 +2,8 @@ /* * Secure Digital Host Controller Interface ACPI driver. * - * Copyright (c) 2012, Intel Corporation. + * Copyright 2020-2022, MaxLinear, Inc. + * Copyright 2012-2020, Intel Corporation. */ #include @@ -39,6 +40,10 @@ #include "sdhci.h" +#ifdef CONFIG_HW_MUTEXES +#include +#endif + enum { SDHCI_ACPI_SD_CD = BIT(0), SDHCI_ACPI_RUNTIME_PM = BIT(1), @@ -219,6 +224,30 @@ usleep_range(300, 1000); } +void puma7_write_l(struct sdhci_host *host, u32 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writel(val, host->ioaddr + reg); +} + +void puma7_write_w(struct sdhci_host *host, u16 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writew(val, host->ioaddr + reg); +} + +void puma7_write_b(struct sdhci_host *host, u8 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writeb(val, host->ioaddr + reg); +} + +unsigned int sdhci_acpi_puma7_get_min_clock(struct sdhci_host *host) +{ + /* PUMA7 host controllers only support down to 200kHz */ + return 200000; +} + static const struct sdhci_ops sdhci_acpi_ops_dflt = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, @@ -234,10 +263,28 @@ .hw_reset = sdhci_acpi_int_hw_reset, }; +static const struct sdhci_ops sdhci_acpi_ops_int_puma7_emmc = { + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .hw_reset = sdhci_acpi_int_hw_reset, + .get_min_clock = sdhci_acpi_puma7_get_min_clock, +#ifdef CONFIG_HW_MUTEXES + .write_l = puma7_write_l, + .write_w = puma7_write_w, + .write_b = puma7_write_b, +#endif +}; + static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { .ops = &sdhci_acpi_ops_int, }; +static const struct sdhci_acpi_chip sdhci_acpi_chip_int_puma7_emmc = { + .ops = &sdhci_acpi_ops_int_puma7_emmc, +}; + #ifdef CONFIG_X86 static bool sdhci_acpi_byt(void) @@ -441,6 +488,31 @@ .priv_size = sizeof(struct intel_host), }; +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_puma7_emmc1 = { + .chip = &sdhci_acpi_chip_int_puma7_emmc, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | + MMC_CAP_CMD_DURING_TFR | MMC_CAP_WAIT_WHILE_BUSY, + .caps2 = MMC_CAP2_NO_SHUTDOWN_BUS, + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_STOP_WITH_TC | + SDHCI_QUIRK2_HW_MUTEX, + .probe_slot = intel_probe_slot, +}; + +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_puma7_emmc2 = { + .chip = &sdhci_acpi_chip_int_puma7_emmc, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | + MMC_CAP_CMD_DURING_TFR | MMC_CAP_WAIT_WHILE_BUSY, + .flags = SDHCI_ACPI_RUNTIME_PM, + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_STOP_WITH_TC, + .probe_slot = intel_probe_slot, +}; + static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_NO_LED | @@ -456,12 +528,10 @@ }; static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { - .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | - SDHCI_ACPI_RUNTIME_PM, + .flags = SDHCI_ACPI_RUNTIME_PM, .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | SDHCI_QUIRK_NO_LED, - .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | - SDHCI_QUIRK2_STOP_WITH_TC, + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC, .caps = MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_AGGRESSIVE_PM, .probe_slot = intel_probe_slot, .setup_host = intel_setup_host, @@ -762,6 +832,9 @@ { "80860F14" , "2" , &sdhci_acpi_slot_int_sdio }, { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, { "80860F16" , NULL, &sdhci_acpi_slot_int_sd }, + { "80862B94" , "1" , &sdhci_acpi_slot_int_puma7_emmc1 }, + { "80862B95" , "1" , &sdhci_acpi_slot_int_puma7_emmc2 }, + { "80862B96" , "1" , &sdhci_acpi_slot_int_sd }, { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, @@ -782,6 +855,7 @@ { "80865AD0" }, { "80860F14" }, { "80860F16" }, + { "80862B94" }, { "INT33BB" }, { "INT33C6" }, { "INT3436" }, @@ -860,6 +934,9 @@ size_t priv_size; int quirks = 0; int err; +#ifdef CONFIG_HW_MUTEXES + bool have_hw_mutex = FALSE; +#endif device = ACPI_COMPANION(dev); if (!device) @@ -962,6 +1039,14 @@ host->mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; } +#ifdef CONFIG_HW_MUTEXES + if (SDHCI_HOST_SUPPORTS_HW_MUTEX(host)) { + MMC_LOCK_HW_MUTEX_INIT(host->mmc); + host->flags |= SDHCI_DISABLE_REGISTER_WRITE; + have_hw_mutex = TRUE; + } +#endif + err = sdhci_setup_host(host); if (err) goto err_free; @@ -973,6 +1058,15 @@ } err = __sdhci_add_host(host); + +#ifdef CONFIG_HW_MUTEXES + if (SDHCI_HOST_SUPPORTS_HW_MUTEX(host)) { + host->flags &= ~SDHCI_DISABLE_REGISTER_WRITE; + MMC_UNLOCK_HW_MUTEX(host->mmc); + have_hw_mutex = FALSE; + } +#endif + if (err) goto err_cleanup; @@ -982,6 +1076,10 @@ pm_runtime_set_autosuspend_delay(dev, 50); pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); + /**Puma power manager will enable runtime pm for + * SD card controller*/ + if (! acpi_dev_hid_uid_match(device, "80862B96", NULL)) + pm_runtime_forbid(dev); } device_enable_async_suspend(dev); @@ -991,6 +1089,13 @@ err_cleanup: sdhci_cleanup_host(c->host); err_free: +#ifdef CONFIG_HW_MUTEXES + if (have_hw_mutex && SDHCI_HOST_SUPPORTS_HW_MUTEX(host)) { + host->flags &= ~SDHCI_DISABLE_REGISTER_WRITE; + MMC_UNLOCK_HW_MUTEX(host->mmc); + have_hw_mutex = FALSE; + } +#endif if (c->slot && c->slot->free_slot) c->slot->free_slot(pdev); @@ -1109,7 +1214,7 @@ static struct platform_driver sdhci_acpi_driver = { .driver = { .name = "sdhci-acpi", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .probe_type = PROBE_FORCE_SYNCHRONOUS, .acpi_match_table = sdhci_acpi_ids, .pm = &sdhci_acpi_pm_ops, },