101acf691SAdam Lee /* 201acf691SAdam Lee * Copyright (C) 2013 BayHub Technology Ltd. 301acf691SAdam Lee * 401acf691SAdam Lee * Authors: Peter Guo <peter.guo@bayhubtech.com> 501acf691SAdam Lee * Adam Lee <adam.lee@canonical.com> 657322d54Sernest.zhang * Ernest Zhang <ernest.zhang@bayhubtech.com> 701acf691SAdam Lee * 801acf691SAdam Lee * This software is licensed under the terms of the GNU General Public 901acf691SAdam Lee * License version 2, as published by the Free Software Foundation, and 1001acf691SAdam Lee * may be copied, distributed, and modified under those terms. 1101acf691SAdam Lee * 1201acf691SAdam Lee * This program is distributed in the hope that it will be useful, 1301acf691SAdam Lee * but WITHOUT ANY WARRANTY; without even the implied warranty of 1401acf691SAdam Lee * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1501acf691SAdam Lee * GNU General Public License for more details. 1601acf691SAdam Lee * 1701acf691SAdam Lee */ 1801acf691SAdam Lee 1901acf691SAdam Lee #include <linux/pci.h> 2001acf691SAdam Lee 2101acf691SAdam Lee #include "sdhci.h" 2201acf691SAdam Lee #include "sdhci-pci.h" 23361eeda0SAdrian Hunter 24361eeda0SAdrian Hunter /* 25361eeda0SAdrian Hunter * O2Micro device registers 26361eeda0SAdrian Hunter */ 27361eeda0SAdrian Hunter 28361eeda0SAdrian Hunter #define O2_SD_MISC_REG5 0x64 29361eeda0SAdrian Hunter #define O2_SD_LD0_CTRL 0x68 30361eeda0SAdrian Hunter #define O2_SD_DEV_CTRL 0x88 31361eeda0SAdrian Hunter #define O2_SD_LOCK_WP 0xD3 32361eeda0SAdrian Hunter #define O2_SD_TEST_REG 0xD4 33361eeda0SAdrian Hunter #define O2_SD_FUNC_REG0 0xDC 34361eeda0SAdrian Hunter #define O2_SD_MULTI_VCC3V 0xEE 35361eeda0SAdrian Hunter #define O2_SD_CLKREQ 0xEC 36361eeda0SAdrian Hunter #define O2_SD_CAPS 0xE0 37361eeda0SAdrian Hunter #define O2_SD_ADMA1 0xE2 38361eeda0SAdrian Hunter #define O2_SD_ADMA2 0xE7 39361eeda0SAdrian Hunter #define O2_SD_INF_MOD 0xF1 40361eeda0SAdrian Hunter #define O2_SD_MISC_CTRL4 0xFC 41361eeda0SAdrian Hunter #define O2_SD_TUNING_CTRL 0x300 42361eeda0SAdrian Hunter #define O2_SD_PLL_SETTING 0x304 4357322d54Sernest.zhang #define O2_SD_MISC_SETTING 0x308 44361eeda0SAdrian Hunter #define O2_SD_CLK_SETTING 0x328 45361eeda0SAdrian Hunter #define O2_SD_CAP_REG2 0x330 46361eeda0SAdrian Hunter #define O2_SD_CAP_REG0 0x334 47361eeda0SAdrian Hunter #define O2_SD_UHS1_CAP_SETTING 0x33C 48361eeda0SAdrian Hunter #define O2_SD_DELAY_CTRL 0x350 49361eeda0SAdrian Hunter #define O2_SD_UHS2_L1_CTRL 0x35C 50361eeda0SAdrian Hunter #define O2_SD_FUNC_REG3 0x3E0 51361eeda0SAdrian Hunter #define O2_SD_FUNC_REG4 0x3E4 52361eeda0SAdrian Hunter #define O2_SD_LED_ENABLE BIT(6) 53361eeda0SAdrian Hunter #define O2_SD_FREG0_LEDOFF BIT(13) 54361eeda0SAdrian Hunter #define O2_SD_FREG4_ENABLE_CLK_SET BIT(22) 55361eeda0SAdrian Hunter 56361eeda0SAdrian Hunter #define O2_SD_VENDOR_SETTING 0x110 57361eeda0SAdrian Hunter #define O2_SD_VENDOR_SETTING2 0x1C8 5801acf691SAdam Lee 59706adf6bSPeter Guo static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value) 60706adf6bSPeter Guo { 61706adf6bSPeter Guo u32 scratch_32; 62706adf6bSPeter Guo pci_read_config_dword(chip->pdev, 63706adf6bSPeter Guo O2_SD_PLL_SETTING, &scratch_32); 64706adf6bSPeter Guo 65706adf6bSPeter Guo scratch_32 &= 0x0000FFFF; 66706adf6bSPeter Guo scratch_32 |= value; 67706adf6bSPeter Guo 68706adf6bSPeter Guo pci_write_config_dword(chip->pdev, 69706adf6bSPeter Guo O2_SD_PLL_SETTING, scratch_32); 70706adf6bSPeter Guo } 71706adf6bSPeter Guo 72706adf6bSPeter Guo static void o2_pci_led_enable(struct sdhci_pci_chip *chip) 73706adf6bSPeter Guo { 74706adf6bSPeter Guo int ret; 75706adf6bSPeter Guo u32 scratch_32; 76706adf6bSPeter Guo 77706adf6bSPeter Guo /* Set led of SD host function enable */ 78706adf6bSPeter Guo ret = pci_read_config_dword(chip->pdev, 79706adf6bSPeter Guo O2_SD_FUNC_REG0, &scratch_32); 80706adf6bSPeter Guo if (ret) 81706adf6bSPeter Guo return; 82706adf6bSPeter Guo 83706adf6bSPeter Guo scratch_32 &= ~O2_SD_FREG0_LEDOFF; 84706adf6bSPeter Guo pci_write_config_dword(chip->pdev, 85706adf6bSPeter Guo O2_SD_FUNC_REG0, scratch_32); 86706adf6bSPeter Guo 87706adf6bSPeter Guo ret = pci_read_config_dword(chip->pdev, 88706adf6bSPeter Guo O2_SD_TEST_REG, &scratch_32); 89706adf6bSPeter Guo if (ret) 90706adf6bSPeter Guo return; 91706adf6bSPeter Guo 92706adf6bSPeter Guo scratch_32 |= O2_SD_LED_ENABLE; 93706adf6bSPeter Guo pci_write_config_dword(chip->pdev, 94706adf6bSPeter Guo O2_SD_TEST_REG, scratch_32); 95706adf6bSPeter Guo 96706adf6bSPeter Guo } 97706adf6bSPeter Guo 98f0cbd780SBen Hutchings static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip) 9901acf691SAdam Lee { 10001acf691SAdam Lee u32 scratch_32; 10101acf691SAdam Lee int ret; 10201acf691SAdam Lee /* Improve write performance for SD3.0 */ 10301acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_DEV_CTRL, &scratch_32); 10401acf691SAdam Lee if (ret) 10501acf691SAdam Lee return; 10601acf691SAdam Lee scratch_32 &= ~((1 << 12) | (1 << 13) | (1 << 14)); 10701acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_DEV_CTRL, scratch_32); 10801acf691SAdam Lee 10901acf691SAdam Lee /* Enable Link abnormal reset generating Reset */ 11001acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_MISC_REG5, &scratch_32); 11101acf691SAdam Lee if (ret) 11201acf691SAdam Lee return; 11301acf691SAdam Lee scratch_32 &= ~((1 << 19) | (1 << 11)); 11401acf691SAdam Lee scratch_32 |= (1 << 10); 11501acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_MISC_REG5, scratch_32); 11601acf691SAdam Lee 11701acf691SAdam Lee /* set card power over current protection */ 11801acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_TEST_REG, &scratch_32); 11901acf691SAdam Lee if (ret) 12001acf691SAdam Lee return; 12101acf691SAdam Lee scratch_32 |= (1 << 4); 12201acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_TEST_REG, scratch_32); 12301acf691SAdam Lee 12401acf691SAdam Lee /* adjust the output delay for SD mode */ 12501acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_DELAY_CTRL, 0x00002492); 12601acf691SAdam Lee 12701acf691SAdam Lee /* Set the output voltage setting of Aux 1.2v LDO */ 12801acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_LD0_CTRL, &scratch_32); 12901acf691SAdam Lee if (ret) 13001acf691SAdam Lee return; 13101acf691SAdam Lee scratch_32 &= ~(3 << 12); 13201acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_LD0_CTRL, scratch_32); 13301acf691SAdam Lee 13401acf691SAdam Lee /* Set Max power supply capability of SD host */ 13501acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_CAP_REG0, &scratch_32); 13601acf691SAdam Lee if (ret) 13701acf691SAdam Lee return; 13801acf691SAdam Lee scratch_32 &= ~(0x01FE); 13901acf691SAdam Lee scratch_32 |= 0x00CC; 14001acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_CAP_REG0, scratch_32); 14101acf691SAdam Lee /* Set DLL Tuning Window */ 14201acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 14301acf691SAdam Lee O2_SD_TUNING_CTRL, &scratch_32); 14401acf691SAdam Lee if (ret) 14501acf691SAdam Lee return; 14601acf691SAdam Lee scratch_32 &= ~(0x000000FF); 14701acf691SAdam Lee scratch_32 |= 0x00000066; 14801acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_TUNING_CTRL, scratch_32); 14901acf691SAdam Lee 15001acf691SAdam Lee /* Set UHS2 T_EIDLE */ 15101acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 15201acf691SAdam Lee O2_SD_UHS2_L1_CTRL, &scratch_32); 15301acf691SAdam Lee if (ret) 15401acf691SAdam Lee return; 15501acf691SAdam Lee scratch_32 &= ~(0x000000FC); 15601acf691SAdam Lee scratch_32 |= 0x00000084; 15701acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_UHS2_L1_CTRL, scratch_32); 15801acf691SAdam Lee 15901acf691SAdam Lee /* Set UHS2 Termination */ 16001acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_FUNC_REG3, &scratch_32); 16101acf691SAdam Lee if (ret) 16201acf691SAdam Lee return; 16301acf691SAdam Lee scratch_32 &= ~((1 << 21) | (1 << 30)); 16401acf691SAdam Lee 16501acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32); 16601acf691SAdam Lee 16701acf691SAdam Lee /* Set L1 Entrance Timer */ 16801acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, O2_SD_CAPS, &scratch_32); 16901acf691SAdam Lee if (ret) 17001acf691SAdam Lee return; 17101acf691SAdam Lee scratch_32 &= ~(0xf0000000); 17201acf691SAdam Lee scratch_32 |= 0x30000000; 17301acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_CAPS, scratch_32); 17401acf691SAdam Lee 17501acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 17601acf691SAdam Lee O2_SD_MISC_CTRL4, &scratch_32); 17701acf691SAdam Lee if (ret) 17801acf691SAdam Lee return; 17901acf691SAdam Lee scratch_32 &= ~(0x000f0000); 18001acf691SAdam Lee scratch_32 |= 0x00080000; 18101acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL4, scratch_32); 18201acf691SAdam Lee } 18301acf691SAdam Lee 18401acf691SAdam Lee int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) 18501acf691SAdam Lee { 18601acf691SAdam Lee struct sdhci_pci_chip *chip; 18701acf691SAdam Lee struct sdhci_host *host; 18801acf691SAdam Lee u32 reg; 18957322d54Sernest.zhang int ret; 19001acf691SAdam Lee 19101acf691SAdam Lee chip = slot->chip; 19201acf691SAdam Lee host = slot->host; 19301acf691SAdam Lee switch (chip->pdev->device) { 19401acf691SAdam Lee case PCI_DEVICE_ID_O2_SDS0: 19501acf691SAdam Lee case PCI_DEVICE_ID_O2_SEABIRD0: 19601acf691SAdam Lee case PCI_DEVICE_ID_O2_SEABIRD1: 19701acf691SAdam Lee case PCI_DEVICE_ID_O2_SDS1: 19801acf691SAdam Lee case PCI_DEVICE_ID_O2_FUJIN2: 19901acf691SAdam Lee reg = sdhci_readl(host, O2_SD_VENDOR_SETTING); 20001acf691SAdam Lee if (reg & 0x1) 20101acf691SAdam Lee host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; 20201acf691SAdam Lee 20357322d54Sernest.zhang if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD0) { 20457322d54Sernest.zhang ret = pci_read_config_dword(chip->pdev, 20557322d54Sernest.zhang O2_SD_MISC_SETTING, ®); 20657322d54Sernest.zhang if (ret) 20757322d54Sernest.zhang return -EIO; 20857322d54Sernest.zhang if (reg & (1 << 4)) { 20957322d54Sernest.zhang pr_info("%s: emmc 1.8v flag is set, force 1.8v signaling voltage\n", 21057322d54Sernest.zhang mmc_hostname(host->mmc)); 21157322d54Sernest.zhang host->flags &= ~SDHCI_SIGNALING_330; 21257322d54Sernest.zhang host->flags |= SDHCI_SIGNALING_180; 21357322d54Sernest.zhang host->mmc->caps2 |= MMC_CAP2_NO_SD; 21457322d54Sernest.zhang host->mmc->caps2 |= MMC_CAP2_NO_SDIO; 21557322d54Sernest.zhang } 21657322d54Sernest.zhang } 21757322d54Sernest.zhang 21801acf691SAdam Lee if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2) 21901acf691SAdam Lee break; 22001acf691SAdam Lee /* set dll watch dog timer */ 22101acf691SAdam Lee reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2); 22201acf691SAdam Lee reg |= (1 << 12); 22301acf691SAdam Lee sdhci_writel(host, reg, O2_SD_VENDOR_SETTING2); 22401acf691SAdam Lee 22501acf691SAdam Lee break; 22601acf691SAdam Lee default: 22701acf691SAdam Lee break; 22801acf691SAdam Lee } 22901acf691SAdam Lee 23001acf691SAdam Lee return 0; 23101acf691SAdam Lee } 23201acf691SAdam Lee 23301acf691SAdam Lee int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) 23401acf691SAdam Lee { 23501acf691SAdam Lee int ret; 23601acf691SAdam Lee u8 scratch; 23701acf691SAdam Lee u32 scratch_32; 23801acf691SAdam Lee 23901acf691SAdam Lee switch (chip->pdev->device) { 24001acf691SAdam Lee case PCI_DEVICE_ID_O2_8220: 24101acf691SAdam Lee case PCI_DEVICE_ID_O2_8221: 24201acf691SAdam Lee case PCI_DEVICE_ID_O2_8320: 24301acf691SAdam Lee case PCI_DEVICE_ID_O2_8321: 24401acf691SAdam Lee /* This extra setup is required due to broken ADMA. */ 24501acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 24601acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 24701acf691SAdam Lee if (ret) 24801acf691SAdam Lee return ret; 24901acf691SAdam Lee scratch &= 0x7f; 25001acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 25101acf691SAdam Lee 25201acf691SAdam Lee /* Set Multi 3 to VCC3V# */ 25301acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08); 25401acf691SAdam Lee 25501acf691SAdam Lee /* Disable CLK_REQ# support after media DET */ 25601acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 25701acf691SAdam Lee O2_SD_CLKREQ, &scratch); 25801acf691SAdam Lee if (ret) 25901acf691SAdam Lee return ret; 26001acf691SAdam Lee scratch |= 0x20; 26101acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch); 26201acf691SAdam Lee 26301acf691SAdam Lee /* Choose capabilities, enable SDMA. We have to write 0x01 26401acf691SAdam Lee * to the capabilities register first to unlock it. 26501acf691SAdam Lee */ 26601acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch); 26701acf691SAdam Lee if (ret) 26801acf691SAdam Lee return ret; 26901acf691SAdam Lee scratch |= 0x01; 27001acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch); 27101acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73); 27201acf691SAdam Lee 27301acf691SAdam Lee /* Disable ADMA1/2 */ 27401acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39); 27501acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08); 27601acf691SAdam Lee 27701acf691SAdam Lee /* Disable the infinite transfer mode */ 27801acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 27901acf691SAdam Lee O2_SD_INF_MOD, &scratch); 28001acf691SAdam Lee if (ret) 28101acf691SAdam Lee return ret; 28201acf691SAdam Lee scratch |= 0x08; 28301acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch); 28401acf691SAdam Lee 28501acf691SAdam Lee /* Lock WP */ 28601acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 28701acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 28801acf691SAdam Lee if (ret) 28901acf691SAdam Lee return ret; 29001acf691SAdam Lee scratch |= 0x80; 29101acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 29201acf691SAdam Lee break; 29301acf691SAdam Lee case PCI_DEVICE_ID_O2_SDS0: 29401acf691SAdam Lee case PCI_DEVICE_ID_O2_SDS1: 29501acf691SAdam Lee case PCI_DEVICE_ID_O2_FUJIN2: 29601acf691SAdam Lee /* UnLock WP */ 29701acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 29801acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 29901acf691SAdam Lee if (ret) 30001acf691SAdam Lee return ret; 30101acf691SAdam Lee 30201acf691SAdam Lee scratch &= 0x7f; 30301acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 30401acf691SAdam Lee 305706adf6bSPeter Guo /* DevId=8520 subId= 0x11 or 0x12 Type Chip support */ 306706adf6bSPeter Guo if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) { 307706adf6bSPeter Guo ret = pci_read_config_dword(chip->pdev, 308706adf6bSPeter Guo O2_SD_FUNC_REG0, 309706adf6bSPeter Guo &scratch_32); 310706adf6bSPeter Guo scratch_32 = ((scratch_32 & 0xFF000000) >> 24); 311706adf6bSPeter Guo 312706adf6bSPeter Guo /* Check Whether subId is 0x11 or 0x12 */ 313706adf6bSPeter Guo if ((scratch_32 == 0x11) || (scratch_32 == 0x12)) { 314*3665ff03Sernest.zhang scratch_32 = 0x25100000; 315706adf6bSPeter Guo 316706adf6bSPeter Guo o2_pci_set_baseclk(chip, scratch_32); 317706adf6bSPeter Guo ret = pci_read_config_dword(chip->pdev, 318706adf6bSPeter Guo O2_SD_FUNC_REG4, 319706adf6bSPeter Guo &scratch_32); 320706adf6bSPeter Guo 321706adf6bSPeter Guo /* Enable Base Clk setting change */ 322706adf6bSPeter Guo scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET; 323706adf6bSPeter Guo pci_write_config_dword(chip->pdev, 324706adf6bSPeter Guo O2_SD_FUNC_REG4, 325706adf6bSPeter Guo scratch_32); 326706adf6bSPeter Guo 327706adf6bSPeter Guo /* Set Tuning Window to 4 */ 328706adf6bSPeter Guo pci_write_config_byte(chip->pdev, 329706adf6bSPeter Guo O2_SD_TUNING_CTRL, 0x44); 330706adf6bSPeter Guo 331706adf6bSPeter Guo break; 332706adf6bSPeter Guo } 333706adf6bSPeter Guo } 334706adf6bSPeter Guo 335706adf6bSPeter Guo /* Enable 8520 led function */ 336706adf6bSPeter Guo o2_pci_led_enable(chip); 337706adf6bSPeter Guo 33801acf691SAdam Lee /* Set timeout CLK */ 33901acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 34001acf691SAdam Lee O2_SD_CLK_SETTING, &scratch_32); 34101acf691SAdam Lee if (ret) 34201acf691SAdam Lee return ret; 34301acf691SAdam Lee 34401acf691SAdam Lee scratch_32 &= ~(0xFF00); 34501acf691SAdam Lee scratch_32 |= 0x07E0C800; 34601acf691SAdam Lee pci_write_config_dword(chip->pdev, 34701acf691SAdam Lee O2_SD_CLK_SETTING, scratch_32); 34801acf691SAdam Lee 34901acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 35001acf691SAdam Lee O2_SD_CLKREQ, &scratch_32); 35101acf691SAdam Lee if (ret) 35201acf691SAdam Lee return ret; 35301acf691SAdam Lee scratch_32 |= 0x3; 35401acf691SAdam Lee pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32); 35501acf691SAdam Lee 35601acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 35701acf691SAdam Lee O2_SD_PLL_SETTING, &scratch_32); 35801acf691SAdam Lee if (ret) 35901acf691SAdam Lee return ret; 36001acf691SAdam Lee 36101acf691SAdam Lee scratch_32 &= ~(0x1F3F070E); 36201acf691SAdam Lee scratch_32 |= 0x18270106; 36301acf691SAdam Lee pci_write_config_dword(chip->pdev, 36401acf691SAdam Lee O2_SD_PLL_SETTING, scratch_32); 36501acf691SAdam Lee 36601acf691SAdam Lee /* Disable UHS1 funciton */ 36701acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 36801acf691SAdam Lee O2_SD_CAP_REG2, &scratch_32); 36901acf691SAdam Lee if (ret) 37001acf691SAdam Lee return ret; 37101acf691SAdam Lee scratch_32 &= ~(0xE0); 37201acf691SAdam Lee pci_write_config_dword(chip->pdev, 37301acf691SAdam Lee O2_SD_CAP_REG2, scratch_32); 37401acf691SAdam Lee 37501acf691SAdam Lee if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) 37601acf691SAdam Lee sdhci_pci_o2_fujin2_pci_init(chip); 37701acf691SAdam Lee 37801acf691SAdam Lee /* Lock WP */ 37901acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 38001acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 38101acf691SAdam Lee if (ret) 38201acf691SAdam Lee return ret; 38301acf691SAdam Lee scratch |= 0x80; 38401acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 38501acf691SAdam Lee break; 38601acf691SAdam Lee case PCI_DEVICE_ID_O2_SEABIRD0: 38701acf691SAdam Lee case PCI_DEVICE_ID_O2_SEABIRD1: 38801acf691SAdam Lee /* UnLock WP */ 38901acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 39001acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 39101acf691SAdam Lee if (ret) 39201acf691SAdam Lee return ret; 39301acf691SAdam Lee 39401acf691SAdam Lee scratch &= 0x7f; 39501acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 39601acf691SAdam Lee 39701acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 398706adf6bSPeter Guo O2_SD_PLL_SETTING, &scratch_32); 39901acf691SAdam Lee 40001acf691SAdam Lee if ((scratch_32 & 0xff000000) == 0x01000000) { 40101acf691SAdam Lee scratch_32 &= 0x0000FFFF; 40201acf691SAdam Lee scratch_32 |= 0x1F340000; 40301acf691SAdam Lee 40401acf691SAdam Lee pci_write_config_dword(chip->pdev, 40501acf691SAdam Lee O2_SD_PLL_SETTING, scratch_32); 40601acf691SAdam Lee } else { 40701acf691SAdam Lee scratch_32 &= 0x0000FFFF; 408*3665ff03Sernest.zhang scratch_32 |= 0x25100000; 40901acf691SAdam Lee 41001acf691SAdam Lee pci_write_config_dword(chip->pdev, 41101acf691SAdam Lee O2_SD_PLL_SETTING, scratch_32); 41201acf691SAdam Lee 41301acf691SAdam Lee ret = pci_read_config_dword(chip->pdev, 41401acf691SAdam Lee O2_SD_FUNC_REG4, 41501acf691SAdam Lee &scratch_32); 41601acf691SAdam Lee scratch_32 |= (1 << 22); 41701acf691SAdam Lee pci_write_config_dword(chip->pdev, 41801acf691SAdam Lee O2_SD_FUNC_REG4, scratch_32); 41901acf691SAdam Lee } 42001acf691SAdam Lee 421706adf6bSPeter Guo /* Set Tuning Windows to 5 */ 422706adf6bSPeter Guo pci_write_config_byte(chip->pdev, 423706adf6bSPeter Guo O2_SD_TUNING_CTRL, 0x55); 42401acf691SAdam Lee /* Lock WP */ 42501acf691SAdam Lee ret = pci_read_config_byte(chip->pdev, 42601acf691SAdam Lee O2_SD_LOCK_WP, &scratch); 42701acf691SAdam Lee if (ret) 42801acf691SAdam Lee return ret; 42901acf691SAdam Lee scratch |= 0x80; 43001acf691SAdam Lee pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); 43101acf691SAdam Lee break; 43201acf691SAdam Lee } 43301acf691SAdam Lee 43401acf691SAdam Lee return 0; 43501acf691SAdam Lee } 43601acf691SAdam Lee 437b7813f0fSAdrian Hunter #ifdef CONFIG_PM_SLEEP 43801acf691SAdam Lee int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip) 43901acf691SAdam Lee { 44001acf691SAdam Lee sdhci_pci_o2_probe(chip); 44130cf2803SAdrian Hunter return sdhci_pci_resume_host(chip); 44201acf691SAdam Lee } 443b7813f0fSAdrian Hunter #endif 444