--- zzzz-none-000/linux-2.6.39.4/drivers/mmc/host/sdhci-pltfm.c 2011-08-03 19:43:28.000000000 +0000 +++ puma6-atom-6490-729/linux-2.6.39.4/drivers/mmc/host/sdhci-pltfm.c 2021-11-10 13:38:15.000000000 +0000 @@ -21,6 +21,10 @@ * * Inspired by sdhci-pci.c, by Pierre Ossman */ +/* + * Includes Intel Corporation's changes/modifications dated: 2012. + * Changed/modified portions - Copyright © 2012 , Intel Corporation. + */ #include #include @@ -35,6 +39,14 @@ #include "sdhci.h" #include "sdhci-pltfm.h" +#if defined(CONFIG_ARCH_GEN3_MMC) +#include +#include +#include +#include +#include +#endif + /*****************************************************************************\ * * * SDHCI core callbacks * @@ -58,17 +70,44 @@ struct sdhci_pltfm_host *pltfm_host; struct resource *iomem; int ret; +#if defined(CONFIG_ARCH_GEN3_MMC) + int res = 0; + int loops = 5; +#endif + +#ifdef CONFIG_ARCH_GEN3 + unsigned int np_only_mode = 0; +#endif if (platid && platid->driver_data) pdata = (void *)platid->driver_data; else pdata = pdev->dev.platform_data; +#ifdef CONFIG_ARCH_GEN3_MMC + /* Select Host controller base address to use Phisical or Virtual AEP*/ + if (aep_is_active() != 0) + { + // Use AEP virtual host controller + // printk("[PowerOn] sdhci_alloc_host() Use AEP virtual host controller. \n"); + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + } + else + { +#endif + // Use physical host controller + // printk("[PowerOn] sdhci_alloc_host() Use physical host controller. \n"); iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +#ifdef CONFIG_ARCH_GEN3_MMC + } +#endif + + if (!iomem) { ret = -ENOMEM; goto err; } + // printk("[PowerOn] sdhci_pltfm_probe iomem->start = %p\n",iomem->start); if (resource_size(iomem) < 0x100) dev_err(&pdev->dev, "Invalid iomem size. You may " @@ -76,9 +115,18 @@ /* Some PCI-based MFD need the parent here */ if (pdev->dev.parent != &platform_bus) - host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host)); + { + host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host)); + } else + { host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host)); + } +#ifdef CONFIG_ARCH_GEN3_MMC + if (aep_is_active() != 0) + host->flags |= SDHCI_USE_AEP; +#endif + if (IS_ERR(host)) { ret = PTR_ERR(host); @@ -96,6 +144,20 @@ host->quirks = pdata->quirks; host->irq = platform_get_irq(pdev, 0); +#if defined(CONFIG_MACH_PUMA6) + /* + in Puma6 we do not use ioremap, ioumap, request_mem_region and release_mem_region - virtual addresses are + predefined. + */ + + /* Get virtual address */ + host->ioaddr = (unsigned int __iomem *)(iomem->start); + if (!host->ioaddr) { + dev_err(&pdev->dev, "failed to map registers\n"); + ret = -ENOMEM; + goto err_remap; + } +#else if (!request_mem_region(iomem->start, resource_size(iomem), mmc_hostname(host->mmc))) { dev_err(&pdev->dev, "cannot request region\n"); @@ -109,6 +171,17 @@ ret = -ENOMEM; goto err_remap; } +#endif + +#if defined(CONFIG_MACH_PUMA6) +#if defined(CONFIG_ARCH_GEN3_MMC) + // TEMP REMOVED host->flags |= SDHCI_SUPPORT_DDR; /* Support Dual Data Rate - eMMC 4.4 only*/ + host->flags |= SDHCI_SUPPORT_HW_MUTEX; /* Support HW Mutex */ +#endif + + /* OMER - Copy from sdhci-pci.c - not sure if necessary */ + host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; +#endif if (pdata && pdata->init) { ret = pdata->init(host, pdata); @@ -116,23 +189,66 @@ goto err_plat_init; } +#if defined(CONFIG_ARCH_GEN3_MMC) + printk(KERN_INFO"NP-CPU MBX waits for 'eMMC advance mode ready' notification from APP-CPU ...\n"); + do + { + res = arm_atom_mbx_receive_event_notification(ATOM_EVENT_EMMC_ADVANCE_EXIT,NULL); + if (res) + printk(KERN_INFO"[%s] NP-CPU MBOX - did not get event 'eMMC advance mode ready' notification from APP-CPU, retrying ... \n", __FUNCTION__); + loops--; + }while ((res != 0) && loops); + + if (res != 0) + { + printk(KERN_ERR" NP-CPU MBOX error - did not get event 'eMMC advance mode ready' notification from APP-CPU \n\n"); + printk(KERN_INFO" +----------------------------------------------------------------------------+ \n"); + printk(KERN_INFO" | Detected ARM only boot - waited 15 seconds for Atom, boot continued ... | \n"); + printk(KERN_INFO" +----------------------------------------------------------------------------+ \n\n"); + } + else + { + printk(KERN_INFO"NP-CPU MBX received 'eMMC advance mode ready' notification from APP-CPU.\n"); + } + //printk("[PowerOn] sdhci_pltfm_probe: Taking HW-MUTEX...\n"); + LOCK_EMMC_HW_MUTEX(host->mmc); + //printk("[PowerOn] sdhci_pltfm_probe: Got HW-MUTEX\n"); + ret = sdhci_add_host(host); + + // printk("[PowerOn] sdhci_pltfm_probe: Release HW-MUTEX\n"); + UNLOCK_EMMC_HW_MUTEX(host->mmc); +#else // defined(CONFIG_ARCH_GEN3_MMC) + ret = sdhci_add_host(host); +#endif + if (ret) goto err_add_host; platform_set_drvdata(pdev, host); + // FIXME: find another way to make sure the eMMC has been detected + mdelay(300); + return 0; err_add_host: if (pdata && pdata->exit) pdata->exit(host); + err_plat_init: +#if !defined(CONFIG_MACH_PUMA6) iounmap(host->ioaddr); +#endif + err_remap: +#if !defined(CONFIG_MACH_PUMA6) release_mem_region(iomem->start, resource_size(iomem)); +#endif + err_request: sdhci_free_host(host); + err: printk(KERN_ERR"Probing of sdhci-pltfm failed: %d\n", ret); return ret; @@ -142,9 +258,11 @@ { struct sdhci_pltfm_data *pdata = pdev->dev.platform_data; struct sdhci_host *host = platform_get_drvdata(pdev); - struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); int dead; u32 scratch; +#if !defined(CONFIG_MACH_PUMA6) + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +#endif dead = 0; scratch = readl(host->ioaddr + SDHCI_INT_STATUS); @@ -154,8 +272,10 @@ sdhci_remove_host(host, dead); if (pdata && pdata->exit) pdata->exit(host); +#if !defined(CONFIG_MACH_PUMA6) iounmap(host->ioaddr); release_mem_region(iomem->start, resource_size(iomem)); +#endif sdhci_free_host(host); platform_set_drvdata(pdev, NULL); @@ -176,6 +296,9 @@ #ifdef CONFIG_MMC_SDHCI_TEGRA { "sdhci-tegra", (kernel_ulong_t)&sdhci_tegra_pdata }, #endif +#ifdef CONFIG_MMC_SDHCI_PUMA6 + { "sdhci-puma6", (kernel_ulong_t)&sdhci_puma6_pdata }, +#endif { }, }; MODULE_DEVICE_TABLE(platform, sdhci_pltfm_ids);