1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2013 BayHub Technology Ltd.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Authors: Peter Guo <peter.guo@bayhubtech.com>
6*4882a593Smuzhiyun * Adam Lee <adam.lee@canonical.com>
7*4882a593Smuzhiyun * Ernest Zhang <ernest.zhang@bayhubtech.com>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/pci.h>
11*4882a593Smuzhiyun #include <linux/mmc/host.h>
12*4882a593Smuzhiyun #include <linux/mmc/mmc.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/iopoll.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "sdhci.h"
17*4882a593Smuzhiyun #include "sdhci-pci.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun * O2Micro device registers
21*4882a593Smuzhiyun */
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define O2_SD_MISC_REG5 0x64
24*4882a593Smuzhiyun #define O2_SD_LD0_CTRL 0x68
25*4882a593Smuzhiyun #define O2_SD_DEV_CTRL 0x88
26*4882a593Smuzhiyun #define O2_SD_LOCK_WP 0xD3
27*4882a593Smuzhiyun #define O2_SD_TEST_REG 0xD4
28*4882a593Smuzhiyun #define O2_SD_FUNC_REG0 0xDC
29*4882a593Smuzhiyun #define O2_SD_MULTI_VCC3V 0xEE
30*4882a593Smuzhiyun #define O2_SD_CLKREQ 0xEC
31*4882a593Smuzhiyun #define O2_SD_CAPS 0xE0
32*4882a593Smuzhiyun #define O2_SD_ADMA1 0xE2
33*4882a593Smuzhiyun #define O2_SD_ADMA2 0xE7
34*4882a593Smuzhiyun #define O2_SD_MISC_CTRL2 0xF0
35*4882a593Smuzhiyun #define O2_SD_INF_MOD 0xF1
36*4882a593Smuzhiyun #define O2_SD_MISC_CTRL4 0xFC
37*4882a593Smuzhiyun #define O2_SD_MISC_CTRL 0x1C0
38*4882a593Smuzhiyun #define O2_SD_PWR_FORCE_L0 0x0002
39*4882a593Smuzhiyun #define O2_SD_TUNING_CTRL 0x300
40*4882a593Smuzhiyun #define O2_SD_PLL_SETTING 0x304
41*4882a593Smuzhiyun #define O2_SD_MISC_SETTING 0x308
42*4882a593Smuzhiyun #define O2_SD_CLK_SETTING 0x328
43*4882a593Smuzhiyun #define O2_SD_CAP_REG2 0x330
44*4882a593Smuzhiyun #define O2_SD_CAP_REG0 0x334
45*4882a593Smuzhiyun #define O2_SD_UHS1_CAP_SETTING 0x33C
46*4882a593Smuzhiyun #define O2_SD_DELAY_CTRL 0x350
47*4882a593Smuzhiyun #define O2_SD_UHS2_L1_CTRL 0x35C
48*4882a593Smuzhiyun #define O2_SD_FUNC_REG3 0x3E0
49*4882a593Smuzhiyun #define O2_SD_FUNC_REG4 0x3E4
50*4882a593Smuzhiyun #define O2_SD_LED_ENABLE BIT(6)
51*4882a593Smuzhiyun #define O2_SD_FREG0_LEDOFF BIT(13)
52*4882a593Smuzhiyun #define O2_SD_FREG4_ENABLE_CLK_SET BIT(22)
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define O2_SD_VENDOR_SETTING 0x110
55*4882a593Smuzhiyun #define O2_SD_VENDOR_SETTING2 0x1C8
56*4882a593Smuzhiyun #define O2_SD_HW_TUNING_DISABLE BIT(4)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define O2_PLL_DLL_WDT_CONTROL1 0x1CC
59*4882a593Smuzhiyun #define O2_PLL_FORCE_ACTIVE BIT(18)
60*4882a593Smuzhiyun #define O2_PLL_LOCK_STATUS BIT(14)
61*4882a593Smuzhiyun #define O2_PLL_SOFT_RESET BIT(12)
62*4882a593Smuzhiyun #define O2_DLL_LOCK_STATUS BIT(11)
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define O2_SD_DETECT_SETTING 0x324
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun static const u32 dmdn_table[] = {0x2B1C0000,
67*4882a593Smuzhiyun 0x2C1A0000, 0x371B0000, 0x35100000};
68*4882a593Smuzhiyun #define DMDN_SZ ARRAY_SIZE(dmdn_table)
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun struct o2_host {
71*4882a593Smuzhiyun u8 dll_adjust_count;
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun
sdhci_o2_wait_card_detect_stable(struct sdhci_host * host)74*4882a593Smuzhiyun static void sdhci_o2_wait_card_detect_stable(struct sdhci_host *host)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun ktime_t timeout;
77*4882a593Smuzhiyun u32 scratch32;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /* Wait max 50 ms */
80*4882a593Smuzhiyun timeout = ktime_add_ms(ktime_get(), 50);
81*4882a593Smuzhiyun while (1) {
82*4882a593Smuzhiyun bool timedout = ktime_after(ktime_get(), timeout);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun scratch32 = sdhci_readl(host, SDHCI_PRESENT_STATE);
85*4882a593Smuzhiyun if ((scratch32 & SDHCI_CARD_PRESENT) >> SDHCI_CARD_PRES_SHIFT
86*4882a593Smuzhiyun == (scratch32 & SDHCI_CD_LVL) >> SDHCI_CD_LVL_SHIFT)
87*4882a593Smuzhiyun break;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun if (timedout) {
90*4882a593Smuzhiyun pr_err("%s: Card Detect debounce never finished.\n",
91*4882a593Smuzhiyun mmc_hostname(host->mmc));
92*4882a593Smuzhiyun sdhci_dumpregs(host);
93*4882a593Smuzhiyun return;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun udelay(10);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
sdhci_o2_enable_internal_clock(struct sdhci_host * host)99*4882a593Smuzhiyun static void sdhci_o2_enable_internal_clock(struct sdhci_host *host)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun ktime_t timeout;
102*4882a593Smuzhiyun u16 scratch;
103*4882a593Smuzhiyun u32 scratch32;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* PLL software reset */
106*4882a593Smuzhiyun scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
107*4882a593Smuzhiyun scratch32 |= O2_PLL_SOFT_RESET;
108*4882a593Smuzhiyun sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
109*4882a593Smuzhiyun udelay(1);
110*4882a593Smuzhiyun scratch32 &= ~(O2_PLL_SOFT_RESET);
111*4882a593Smuzhiyun sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* PLL force active */
114*4882a593Smuzhiyun scratch32 |= O2_PLL_FORCE_ACTIVE;
115*4882a593Smuzhiyun sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /* Wait max 20 ms */
118*4882a593Smuzhiyun timeout = ktime_add_ms(ktime_get(), 20);
119*4882a593Smuzhiyun while (1) {
120*4882a593Smuzhiyun bool timedout = ktime_after(ktime_get(), timeout);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun scratch = sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1);
123*4882a593Smuzhiyun if (scratch & O2_PLL_LOCK_STATUS)
124*4882a593Smuzhiyun break;
125*4882a593Smuzhiyun if (timedout) {
126*4882a593Smuzhiyun pr_err("%s: Internal clock never stabilised.\n",
127*4882a593Smuzhiyun mmc_hostname(host->mmc));
128*4882a593Smuzhiyun sdhci_dumpregs(host);
129*4882a593Smuzhiyun goto out;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun udelay(10);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* Wait for card detect finish */
135*4882a593Smuzhiyun udelay(1);
136*4882a593Smuzhiyun sdhci_o2_wait_card_detect_stable(host);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun out:
139*4882a593Smuzhiyun /* Cancel PLL force active */
140*4882a593Smuzhiyun scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
141*4882a593Smuzhiyun scratch32 &= ~O2_PLL_FORCE_ACTIVE;
142*4882a593Smuzhiyun sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
sdhci_o2_get_cd(struct mmc_host * mmc)145*4882a593Smuzhiyun static int sdhci_o2_get_cd(struct mmc_host *mmc)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun struct sdhci_host *host = mmc_priv(mmc);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS))
150*4882a593Smuzhiyun sdhci_o2_enable_internal_clock(host);
151*4882a593Smuzhiyun else
152*4882a593Smuzhiyun sdhci_o2_wait_card_detect_stable(host);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
o2_pci_set_baseclk(struct sdhci_pci_chip * chip,u32 value)157*4882a593Smuzhiyun static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun u32 scratch_32;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun pci_read_config_dword(chip->pdev,
162*4882a593Smuzhiyun O2_SD_PLL_SETTING, &scratch_32);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun scratch_32 &= 0x0000FFFF;
165*4882a593Smuzhiyun scratch_32 |= value;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
168*4882a593Smuzhiyun O2_SD_PLL_SETTING, scratch_32);
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
sdhci_o2_pll_dll_wdt_control(struct sdhci_host * host)171*4882a593Smuzhiyun static u32 sdhci_o2_pll_dll_wdt_control(struct sdhci_host *host)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun return sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /*
177*4882a593Smuzhiyun * This function is used to detect dll lock status.
178*4882a593Smuzhiyun * Since the dll lock status bit will toggle randomly
179*4882a593Smuzhiyun * with very short interval which needs to be polled
180*4882a593Smuzhiyun * as fast as possible. Set sleep_us as 1 microsecond.
181*4882a593Smuzhiyun */
sdhci_o2_wait_dll_detect_lock(struct sdhci_host * host)182*4882a593Smuzhiyun static int sdhci_o2_wait_dll_detect_lock(struct sdhci_host *host)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun u32 scratch32 = 0;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun return readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,
187*4882a593Smuzhiyun scratch32, !(scratch32 & O2_DLL_LOCK_STATUS), 1, 1000000);
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
sdhci_o2_set_tuning_mode(struct sdhci_host * host)190*4882a593Smuzhiyun static void sdhci_o2_set_tuning_mode(struct sdhci_host *host)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun u16 reg;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* enable hardware tuning */
195*4882a593Smuzhiyun reg = sdhci_readw(host, O2_SD_VENDOR_SETTING);
196*4882a593Smuzhiyun reg &= ~O2_SD_HW_TUNING_DISABLE;
197*4882a593Smuzhiyun sdhci_writew(host, reg, O2_SD_VENDOR_SETTING);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
__sdhci_o2_execute_tuning(struct sdhci_host * host,u32 opcode)200*4882a593Smuzhiyun static void __sdhci_o2_execute_tuning(struct sdhci_host *host, u32 opcode)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun int i;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun sdhci_send_tuning(host, opcode);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun for (i = 0; i < 150; i++) {
207*4882a593Smuzhiyun u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
210*4882a593Smuzhiyun if (ctrl & SDHCI_CTRL_TUNED_CLK) {
211*4882a593Smuzhiyun host->tuning_done = true;
212*4882a593Smuzhiyun return;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun pr_warn("%s: HW tuning failed !\n",
215*4882a593Smuzhiyun mmc_hostname(host->mmc));
216*4882a593Smuzhiyun break;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun mdelay(1);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
223*4882a593Smuzhiyun mmc_hostname(host->mmc));
224*4882a593Smuzhiyun sdhci_reset_tuning(host);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /*
228*4882a593Smuzhiyun * This function is used to fix o2 dll shift issue.
229*4882a593Smuzhiyun * It isn't necessary to detect card present before recovery.
230*4882a593Smuzhiyun * Firstly, it is used by bht emmc card, which is embedded.
231*4882a593Smuzhiyun * Second, before call recovery card present will be detected
232*4882a593Smuzhiyun * outside of the execute tuning function.
233*4882a593Smuzhiyun */
sdhci_o2_dll_recovery(struct sdhci_host * host)234*4882a593Smuzhiyun static int sdhci_o2_dll_recovery(struct sdhci_host *host)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun int ret = 0;
237*4882a593Smuzhiyun u8 scratch_8 = 0;
238*4882a593Smuzhiyun u32 scratch_32 = 0;
239*4882a593Smuzhiyun struct sdhci_pci_slot *slot = sdhci_priv(host);
240*4882a593Smuzhiyun struct sdhci_pci_chip *chip = slot->chip;
241*4882a593Smuzhiyun struct o2_host *o2_host = sdhci_pci_priv(slot);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* UnLock WP */
244*4882a593Smuzhiyun pci_read_config_byte(chip->pdev,
245*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch_8);
246*4882a593Smuzhiyun scratch_8 &= 0x7f;
247*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
248*4882a593Smuzhiyun while (o2_host->dll_adjust_count < DMDN_SZ && !ret) {
249*4882a593Smuzhiyun /* Disable clock */
250*4882a593Smuzhiyun sdhci_writeb(host, 0, SDHCI_CLOCK_CONTROL);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* PLL software reset */
253*4882a593Smuzhiyun scratch_32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
254*4882a593Smuzhiyun scratch_32 |= O2_PLL_SOFT_RESET;
255*4882a593Smuzhiyun sdhci_writel(host, scratch_32, O2_PLL_DLL_WDT_CONTROL1);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun pci_read_config_dword(chip->pdev,
258*4882a593Smuzhiyun O2_SD_FUNC_REG4,
259*4882a593Smuzhiyun &scratch_32);
260*4882a593Smuzhiyun /* Enable Base Clk setting change */
261*4882a593Smuzhiyun scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET;
262*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG4, scratch_32);
263*4882a593Smuzhiyun o2_pci_set_baseclk(chip, dmdn_table[o2_host->dll_adjust_count]);
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /* Enable internal clock */
266*4882a593Smuzhiyun scratch_8 = SDHCI_CLOCK_INT_EN;
267*4882a593Smuzhiyun sdhci_writeb(host, scratch_8, SDHCI_CLOCK_CONTROL);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun if (sdhci_o2_get_cd(host->mmc)) {
270*4882a593Smuzhiyun /*
271*4882a593Smuzhiyun * need wait at least 5ms for dll status stable,
272*4882a593Smuzhiyun * after enable internal clock
273*4882a593Smuzhiyun */
274*4882a593Smuzhiyun usleep_range(5000, 6000);
275*4882a593Smuzhiyun if (sdhci_o2_wait_dll_detect_lock(host)) {
276*4882a593Smuzhiyun scratch_8 |= SDHCI_CLOCK_CARD_EN;
277*4882a593Smuzhiyun sdhci_writeb(host, scratch_8,
278*4882a593Smuzhiyun SDHCI_CLOCK_CONTROL);
279*4882a593Smuzhiyun ret = 1;
280*4882a593Smuzhiyun } else {
281*4882a593Smuzhiyun pr_warn("%s: DLL unlocked when dll_adjust_count is %d.\n",
282*4882a593Smuzhiyun mmc_hostname(host->mmc),
283*4882a593Smuzhiyun o2_host->dll_adjust_count);
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun } else {
286*4882a593Smuzhiyun pr_err("%s: card present detect failed.\n",
287*4882a593Smuzhiyun mmc_hostname(host->mmc));
288*4882a593Smuzhiyun break;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun o2_host->dll_adjust_count++;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun if (!ret && o2_host->dll_adjust_count == DMDN_SZ)
294*4882a593Smuzhiyun pr_err("%s: DLL adjust over max times\n",
295*4882a593Smuzhiyun mmc_hostname(host->mmc));
296*4882a593Smuzhiyun /* Lock WP */
297*4882a593Smuzhiyun pci_read_config_byte(chip->pdev,
298*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch_8);
299*4882a593Smuzhiyun scratch_8 |= 0x80;
300*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8);
301*4882a593Smuzhiyun return ret;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
sdhci_o2_execute_tuning(struct mmc_host * mmc,u32 opcode)304*4882a593Smuzhiyun static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun struct sdhci_host *host = mmc_priv(mmc);
307*4882a593Smuzhiyun int current_bus_width = 0;
308*4882a593Smuzhiyun u32 scratch32 = 0;
309*4882a593Smuzhiyun u16 scratch = 0;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun /*
312*4882a593Smuzhiyun * This handler only implements the eMMC tuning that is specific to
313*4882a593Smuzhiyun * this controller. Fall back to the standard method for other TIMING.
314*4882a593Smuzhiyun */
315*4882a593Smuzhiyun if ((host->timing != MMC_TIMING_MMC_HS200) &&
316*4882a593Smuzhiyun (host->timing != MMC_TIMING_UHS_SDR104))
317*4882a593Smuzhiyun return sdhci_execute_tuning(mmc, opcode);
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
320*4882a593Smuzhiyun (opcode != MMC_SEND_TUNING_BLOCK)))
321*4882a593Smuzhiyun return -EINVAL;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /* Force power mode enter L0 */
324*4882a593Smuzhiyun scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
325*4882a593Smuzhiyun scratch |= O2_SD_PWR_FORCE_L0;
326*4882a593Smuzhiyun sdhci_writew(host, scratch, O2_SD_MISC_CTRL);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /* wait DLL lock, timeout value 5ms */
329*4882a593Smuzhiyun if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,
330*4882a593Smuzhiyun scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000))
331*4882a593Smuzhiyun pr_warn("%s: DLL can't lock in 5ms after force L0 during tuning.\n",
332*4882a593Smuzhiyun mmc_hostname(host->mmc));
333*4882a593Smuzhiyun /*
334*4882a593Smuzhiyun * Judge the tuning reason, whether caused by dll shift
335*4882a593Smuzhiyun * If cause by dll shift, should call sdhci_o2_dll_recovery
336*4882a593Smuzhiyun */
337*4882a593Smuzhiyun if (!sdhci_o2_wait_dll_detect_lock(host))
338*4882a593Smuzhiyun if (!sdhci_o2_dll_recovery(host)) {
339*4882a593Smuzhiyun pr_err("%s: o2 dll recovery failed\n",
340*4882a593Smuzhiyun mmc_hostname(host->mmc));
341*4882a593Smuzhiyun return -EINVAL;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun /*
344*4882a593Smuzhiyun * o2 sdhci host didn't support 8bit emmc tuning
345*4882a593Smuzhiyun */
346*4882a593Smuzhiyun if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) {
347*4882a593Smuzhiyun current_bus_width = mmc->ios.bus_width;
348*4882a593Smuzhiyun mmc->ios.bus_width = MMC_BUS_WIDTH_4;
349*4882a593Smuzhiyun sdhci_set_bus_width(host, MMC_BUS_WIDTH_4);
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun sdhci_o2_set_tuning_mode(host);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun sdhci_start_tuning(host);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun __sdhci_o2_execute_tuning(host, opcode);
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun sdhci_end_tuning(host);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun if (current_bus_width == MMC_BUS_WIDTH_8) {
361*4882a593Smuzhiyun mmc->ios.bus_width = MMC_BUS_WIDTH_8;
362*4882a593Smuzhiyun sdhci_set_bus_width(host, current_bus_width);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun /* Cancel force power mode enter L0 */
366*4882a593Smuzhiyun scratch = sdhci_readw(host, O2_SD_MISC_CTRL);
367*4882a593Smuzhiyun scratch &= ~(O2_SD_PWR_FORCE_L0);
368*4882a593Smuzhiyun sdhci_writew(host, scratch, O2_SD_MISC_CTRL);
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun sdhci_reset(host, SDHCI_RESET_CMD);
371*4882a593Smuzhiyun sdhci_reset(host, SDHCI_RESET_DATA);
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun host->flags &= ~SDHCI_HS400_TUNING;
374*4882a593Smuzhiyun return 0;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
o2_pci_led_enable(struct sdhci_pci_chip * chip)377*4882a593Smuzhiyun static void o2_pci_led_enable(struct sdhci_pci_chip *chip)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun int ret;
380*4882a593Smuzhiyun u32 scratch_32;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun /* Set led of SD host function enable */
383*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
384*4882a593Smuzhiyun O2_SD_FUNC_REG0, &scratch_32);
385*4882a593Smuzhiyun if (ret)
386*4882a593Smuzhiyun return;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun scratch_32 &= ~O2_SD_FREG0_LEDOFF;
389*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
390*4882a593Smuzhiyun O2_SD_FUNC_REG0, scratch_32);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
393*4882a593Smuzhiyun O2_SD_TEST_REG, &scratch_32);
394*4882a593Smuzhiyun if (ret)
395*4882a593Smuzhiyun return;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun scratch_32 |= O2_SD_LED_ENABLE;
398*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
399*4882a593Smuzhiyun O2_SD_TEST_REG, scratch_32);
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun
sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip * chip)402*4882a593Smuzhiyun static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun u32 scratch_32;
405*4882a593Smuzhiyun int ret;
406*4882a593Smuzhiyun /* Improve write performance for SD3.0 */
407*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_DEV_CTRL, &scratch_32);
408*4882a593Smuzhiyun if (ret)
409*4882a593Smuzhiyun return;
410*4882a593Smuzhiyun scratch_32 &= ~((1 << 12) | (1 << 13) | (1 << 14));
411*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_DEV_CTRL, scratch_32);
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun /* Enable Link abnormal reset generating Reset */
414*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_MISC_REG5, &scratch_32);
415*4882a593Smuzhiyun if (ret)
416*4882a593Smuzhiyun return;
417*4882a593Smuzhiyun scratch_32 &= ~((1 << 19) | (1 << 11));
418*4882a593Smuzhiyun scratch_32 |= (1 << 10);
419*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_MISC_REG5, scratch_32);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun /* set card power over current protection */
422*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_TEST_REG, &scratch_32);
423*4882a593Smuzhiyun if (ret)
424*4882a593Smuzhiyun return;
425*4882a593Smuzhiyun scratch_32 |= (1 << 4);
426*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_TEST_REG, scratch_32);
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun /* adjust the output delay for SD mode */
429*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_DELAY_CTRL, 0x00002492);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun /* Set the output voltage setting of Aux 1.2v LDO */
432*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_LD0_CTRL, &scratch_32);
433*4882a593Smuzhiyun if (ret)
434*4882a593Smuzhiyun return;
435*4882a593Smuzhiyun scratch_32 &= ~(3 << 12);
436*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_LD0_CTRL, scratch_32);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /* Set Max power supply capability of SD host */
439*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_CAP_REG0, &scratch_32);
440*4882a593Smuzhiyun if (ret)
441*4882a593Smuzhiyun return;
442*4882a593Smuzhiyun scratch_32 &= ~(0x01FE);
443*4882a593Smuzhiyun scratch_32 |= 0x00CC;
444*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_CAP_REG0, scratch_32);
445*4882a593Smuzhiyun /* Set DLL Tuning Window */
446*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
447*4882a593Smuzhiyun O2_SD_TUNING_CTRL, &scratch_32);
448*4882a593Smuzhiyun if (ret)
449*4882a593Smuzhiyun return;
450*4882a593Smuzhiyun scratch_32 &= ~(0x000000FF);
451*4882a593Smuzhiyun scratch_32 |= 0x00000066;
452*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_TUNING_CTRL, scratch_32);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /* Set UHS2 T_EIDLE */
455*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
456*4882a593Smuzhiyun O2_SD_UHS2_L1_CTRL, &scratch_32);
457*4882a593Smuzhiyun if (ret)
458*4882a593Smuzhiyun return;
459*4882a593Smuzhiyun scratch_32 &= ~(0x000000FC);
460*4882a593Smuzhiyun scratch_32 |= 0x00000084;
461*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_UHS2_L1_CTRL, scratch_32);
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun /* Set UHS2 Termination */
464*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_FUNC_REG3, &scratch_32);
465*4882a593Smuzhiyun if (ret)
466*4882a593Smuzhiyun return;
467*4882a593Smuzhiyun scratch_32 &= ~((1 << 21) | (1 << 30));
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32);
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun /* Set L1 Entrance Timer */
472*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev, O2_SD_CAPS, &scratch_32);
473*4882a593Smuzhiyun if (ret)
474*4882a593Smuzhiyun return;
475*4882a593Smuzhiyun scratch_32 &= ~(0xf0000000);
476*4882a593Smuzhiyun scratch_32 |= 0x30000000;
477*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_CAPS, scratch_32);
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
480*4882a593Smuzhiyun O2_SD_MISC_CTRL4, &scratch_32);
481*4882a593Smuzhiyun if (ret)
482*4882a593Smuzhiyun return;
483*4882a593Smuzhiyun scratch_32 &= ~(0x000f0000);
484*4882a593Smuzhiyun scratch_32 |= 0x00080000;
485*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL4, scratch_32);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
sdhci_pci_o2_enable_msi(struct sdhci_pci_chip * chip,struct sdhci_host * host)488*4882a593Smuzhiyun static void sdhci_pci_o2_enable_msi(struct sdhci_pci_chip *chip,
489*4882a593Smuzhiyun struct sdhci_host *host)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun int ret;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun ret = pci_find_capability(chip->pdev, PCI_CAP_ID_MSI);
494*4882a593Smuzhiyun if (!ret) {
495*4882a593Smuzhiyun pr_info("%s: unsupport msi, use INTx irq\n",
496*4882a593Smuzhiyun mmc_hostname(host->mmc));
497*4882a593Smuzhiyun return;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun ret = pci_alloc_irq_vectors(chip->pdev, 1, 1,
501*4882a593Smuzhiyun PCI_IRQ_MSI | PCI_IRQ_MSIX);
502*4882a593Smuzhiyun if (ret < 0) {
503*4882a593Smuzhiyun pr_err("%s: enable PCI MSI failed, err=%d\n",
504*4882a593Smuzhiyun mmc_hostname(host->mmc), ret);
505*4882a593Smuzhiyun return;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun host->irq = pci_irq_vector(chip->pdev, 0);
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun
sdhci_o2_enable_clk(struct sdhci_host * host,u16 clk)511*4882a593Smuzhiyun static void sdhci_o2_enable_clk(struct sdhci_host *host, u16 clk)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun /* Enable internal clock */
514*4882a593Smuzhiyun clk |= SDHCI_CLOCK_INT_EN;
515*4882a593Smuzhiyun sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun sdhci_o2_enable_internal_clock(host);
518*4882a593Smuzhiyun if (sdhci_o2_get_cd(host->mmc)) {
519*4882a593Smuzhiyun clk |= SDHCI_CLOCK_CARD_EN;
520*4882a593Smuzhiyun sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun
sdhci_pci_o2_set_clock(struct sdhci_host * host,unsigned int clock)524*4882a593Smuzhiyun static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun u16 clk;
527*4882a593Smuzhiyun u8 scratch;
528*4882a593Smuzhiyun u32 scratch_32;
529*4882a593Smuzhiyun struct sdhci_pci_slot *slot = sdhci_priv(host);
530*4882a593Smuzhiyun struct sdhci_pci_chip *chip = slot->chip;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun host->mmc->actual_clock = 0;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun if (clock == 0)
537*4882a593Smuzhiyun return;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) {
540*4882a593Smuzhiyun pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun scratch &= 0x7f;
543*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun if ((scratch_32 & 0xFFFF0000) != 0x2c280000)
548*4882a593Smuzhiyun o2_pci_set_baseclk(chip, 0x2c280000);
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun scratch |= 0x80;
553*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
557*4882a593Smuzhiyun sdhci_o2_enable_clk(host, clk);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
sdhci_pci_o2_probe_slot(struct sdhci_pci_slot * slot)560*4882a593Smuzhiyun static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun struct sdhci_pci_chip *chip;
563*4882a593Smuzhiyun struct sdhci_host *host;
564*4882a593Smuzhiyun struct o2_host *o2_host = sdhci_pci_priv(slot);
565*4882a593Smuzhiyun u32 reg, caps;
566*4882a593Smuzhiyun int ret;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun chip = slot->chip;
569*4882a593Smuzhiyun host = slot->host;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun o2_host->dll_adjust_count = 0;
572*4882a593Smuzhiyun caps = sdhci_readl(host, SDHCI_CAPABILITIES);
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /*
575*4882a593Smuzhiyun * mmc_select_bus_width() will test the bus to determine the actual bus
576*4882a593Smuzhiyun * width.
577*4882a593Smuzhiyun */
578*4882a593Smuzhiyun if (caps & SDHCI_CAN_DO_8BIT)
579*4882a593Smuzhiyun host->mmc->caps |= MMC_CAP_8_BIT_DATA;
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun switch (chip->pdev->device) {
582*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SDS0:
583*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SEABIRD0:
584*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SEABIRD1:
585*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SDS1:
586*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_FUJIN2:
587*4882a593Smuzhiyun reg = sdhci_readl(host, O2_SD_VENDOR_SETTING);
588*4882a593Smuzhiyun if (reg & 0x1)
589*4882a593Smuzhiyun host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun sdhci_pci_o2_enable_msi(chip, host);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD0) {
594*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
595*4882a593Smuzhiyun O2_SD_MISC_SETTING, ®);
596*4882a593Smuzhiyun if (ret)
597*4882a593Smuzhiyun return -EIO;
598*4882a593Smuzhiyun if (reg & (1 << 4)) {
599*4882a593Smuzhiyun pr_info("%s: emmc 1.8v flag is set, force 1.8v signaling voltage\n",
600*4882a593Smuzhiyun mmc_hostname(host->mmc));
601*4882a593Smuzhiyun host->flags &= ~SDHCI_SIGNALING_330;
602*4882a593Smuzhiyun host->flags |= SDHCI_SIGNALING_180;
603*4882a593Smuzhiyun host->mmc->caps2 |= MMC_CAP2_NO_SD;
604*4882a593Smuzhiyun host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
605*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
606*4882a593Smuzhiyun O2_SD_DETECT_SETTING, 3);
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD1) {
613*4882a593Smuzhiyun slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd;
614*4882a593Smuzhiyun host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
615*4882a593Smuzhiyun host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning;
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2)
621*4882a593Smuzhiyun break;
622*4882a593Smuzhiyun /* set dll watch dog timer */
623*4882a593Smuzhiyun reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2);
624*4882a593Smuzhiyun reg |= (1 << 12);
625*4882a593Smuzhiyun sdhci_writel(host, reg, O2_SD_VENDOR_SETTING2);
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun break;
628*4882a593Smuzhiyun default:
629*4882a593Smuzhiyun break;
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun return 0;
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun
sdhci_pci_o2_probe(struct sdhci_pci_chip * chip)635*4882a593Smuzhiyun static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
636*4882a593Smuzhiyun {
637*4882a593Smuzhiyun int ret;
638*4882a593Smuzhiyun u8 scratch;
639*4882a593Smuzhiyun u32 scratch_32;
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun switch (chip->pdev->device) {
642*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_8220:
643*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_8221:
644*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_8320:
645*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_8321:
646*4882a593Smuzhiyun /* This extra setup is required due to broken ADMA. */
647*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
648*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
649*4882a593Smuzhiyun if (ret)
650*4882a593Smuzhiyun return ret;
651*4882a593Smuzhiyun scratch &= 0x7f;
652*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun /* Set Multi 3 to VCC3V# */
655*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /* Disable CLK_REQ# support after media DET */
658*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
659*4882a593Smuzhiyun O2_SD_CLKREQ, &scratch);
660*4882a593Smuzhiyun if (ret)
661*4882a593Smuzhiyun return ret;
662*4882a593Smuzhiyun scratch |= 0x20;
663*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun /* Choose capabilities, enable SDMA. We have to write 0x01
666*4882a593Smuzhiyun * to the capabilities register first to unlock it.
667*4882a593Smuzhiyun */
668*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
669*4882a593Smuzhiyun if (ret)
670*4882a593Smuzhiyun return ret;
671*4882a593Smuzhiyun scratch |= 0x01;
672*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
673*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun /* Disable ADMA1/2 */
676*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
677*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* Disable the infinite transfer mode */
680*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
681*4882a593Smuzhiyun O2_SD_INF_MOD, &scratch);
682*4882a593Smuzhiyun if (ret)
683*4882a593Smuzhiyun return ret;
684*4882a593Smuzhiyun scratch |= 0x08;
685*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun /* Lock WP */
688*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
689*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
690*4882a593Smuzhiyun if (ret)
691*4882a593Smuzhiyun return ret;
692*4882a593Smuzhiyun scratch |= 0x80;
693*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
694*4882a593Smuzhiyun break;
695*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SDS0:
696*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SDS1:
697*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_FUJIN2:
698*4882a593Smuzhiyun /* UnLock WP */
699*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
700*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
701*4882a593Smuzhiyun if (ret)
702*4882a593Smuzhiyun return ret;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun scratch &= 0x7f;
705*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun /* DevId=8520 subId= 0x11 or 0x12 Type Chip support */
708*4882a593Smuzhiyun if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) {
709*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
710*4882a593Smuzhiyun O2_SD_FUNC_REG0,
711*4882a593Smuzhiyun &scratch_32);
712*4882a593Smuzhiyun scratch_32 = ((scratch_32 & 0xFF000000) >> 24);
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun /* Check Whether subId is 0x11 or 0x12 */
715*4882a593Smuzhiyun if ((scratch_32 == 0x11) || (scratch_32 == 0x12)) {
716*4882a593Smuzhiyun scratch_32 = 0x25100000;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun o2_pci_set_baseclk(chip, scratch_32);
719*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
720*4882a593Smuzhiyun O2_SD_FUNC_REG4,
721*4882a593Smuzhiyun &scratch_32);
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun /* Enable Base Clk setting change */
724*4882a593Smuzhiyun scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET;
725*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
726*4882a593Smuzhiyun O2_SD_FUNC_REG4,
727*4882a593Smuzhiyun scratch_32);
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun /* Set Tuning Window to 4 */
730*4882a593Smuzhiyun pci_write_config_byte(chip->pdev,
731*4882a593Smuzhiyun O2_SD_TUNING_CTRL, 0x44);
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun break;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun /* Enable 8520 led function */
738*4882a593Smuzhiyun o2_pci_led_enable(chip);
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun /* Set timeout CLK */
741*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
742*4882a593Smuzhiyun O2_SD_CLK_SETTING, &scratch_32);
743*4882a593Smuzhiyun if (ret)
744*4882a593Smuzhiyun return ret;
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun scratch_32 &= ~(0xFF00);
747*4882a593Smuzhiyun scratch_32 |= 0x07E0C800;
748*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
749*4882a593Smuzhiyun O2_SD_CLK_SETTING, scratch_32);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
752*4882a593Smuzhiyun O2_SD_CLKREQ, &scratch_32);
753*4882a593Smuzhiyun if (ret)
754*4882a593Smuzhiyun return ret;
755*4882a593Smuzhiyun scratch_32 |= 0x3;
756*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32);
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
759*4882a593Smuzhiyun O2_SD_PLL_SETTING, &scratch_32);
760*4882a593Smuzhiyun if (ret)
761*4882a593Smuzhiyun return ret;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun scratch_32 &= ~(0x1F3F070E);
764*4882a593Smuzhiyun scratch_32 |= 0x18270106;
765*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
766*4882a593Smuzhiyun O2_SD_PLL_SETTING, scratch_32);
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun /* Disable UHS1 funciton */
769*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
770*4882a593Smuzhiyun O2_SD_CAP_REG2, &scratch_32);
771*4882a593Smuzhiyun if (ret)
772*4882a593Smuzhiyun return ret;
773*4882a593Smuzhiyun scratch_32 &= ~(0xE0);
774*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
775*4882a593Smuzhiyun O2_SD_CAP_REG2, scratch_32);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2)
778*4882a593Smuzhiyun sdhci_pci_o2_fujin2_pci_init(chip);
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun /* Lock WP */
781*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
782*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
783*4882a593Smuzhiyun if (ret)
784*4882a593Smuzhiyun return ret;
785*4882a593Smuzhiyun scratch |= 0x80;
786*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
787*4882a593Smuzhiyun break;
788*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SEABIRD0:
789*4882a593Smuzhiyun case PCI_DEVICE_ID_O2_SEABIRD1:
790*4882a593Smuzhiyun /* UnLock WP */
791*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
792*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
793*4882a593Smuzhiyun if (ret)
794*4882a593Smuzhiyun return ret;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun scratch &= 0x7f;
797*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
800*4882a593Smuzhiyun O2_SD_PLL_SETTING, &scratch_32);
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun if ((scratch_32 & 0xff000000) == 0x01000000) {
803*4882a593Smuzhiyun scratch_32 &= 0x0000FFFF;
804*4882a593Smuzhiyun scratch_32 |= 0x1F340000;
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
807*4882a593Smuzhiyun O2_SD_PLL_SETTING, scratch_32);
808*4882a593Smuzhiyun } else {
809*4882a593Smuzhiyun scratch_32 &= 0x0000FFFF;
810*4882a593Smuzhiyun scratch_32 |= 0x25100000;
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
813*4882a593Smuzhiyun O2_SD_PLL_SETTING, scratch_32);
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun ret = pci_read_config_dword(chip->pdev,
816*4882a593Smuzhiyun O2_SD_FUNC_REG4,
817*4882a593Smuzhiyun &scratch_32);
818*4882a593Smuzhiyun scratch_32 |= (1 << 22);
819*4882a593Smuzhiyun pci_write_config_dword(chip->pdev,
820*4882a593Smuzhiyun O2_SD_FUNC_REG4, scratch_32);
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun /* Set Tuning Windows to 5 */
824*4882a593Smuzhiyun pci_write_config_byte(chip->pdev,
825*4882a593Smuzhiyun O2_SD_TUNING_CTRL, 0x55);
826*4882a593Smuzhiyun //Adjust 1st and 2nd CD debounce time
827*4882a593Smuzhiyun pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32);
828*4882a593Smuzhiyun scratch_32 &= 0xFFE7FFFF;
829*4882a593Smuzhiyun scratch_32 |= 0x00180000;
830*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32);
831*4882a593Smuzhiyun pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1);
832*4882a593Smuzhiyun /* Lock WP */
833*4882a593Smuzhiyun ret = pci_read_config_byte(chip->pdev,
834*4882a593Smuzhiyun O2_SD_LOCK_WP, &scratch);
835*4882a593Smuzhiyun if (ret)
836*4882a593Smuzhiyun return ret;
837*4882a593Smuzhiyun scratch |= 0x80;
838*4882a593Smuzhiyun pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
839*4882a593Smuzhiyun break;
840*4882a593Smuzhiyun }
841*4882a593Smuzhiyun
842*4882a593Smuzhiyun return 0;
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
sdhci_pci_o2_resume(struct sdhci_pci_chip * chip)846*4882a593Smuzhiyun static int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
847*4882a593Smuzhiyun {
848*4882a593Smuzhiyun sdhci_pci_o2_probe(chip);
849*4882a593Smuzhiyun return sdhci_pci_resume_host(chip);
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun #endif
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun static const struct sdhci_ops sdhci_pci_o2_ops = {
854*4882a593Smuzhiyun .set_clock = sdhci_pci_o2_set_clock,
855*4882a593Smuzhiyun .enable_dma = sdhci_pci_enable_dma,
856*4882a593Smuzhiyun .set_bus_width = sdhci_set_bus_width,
857*4882a593Smuzhiyun .reset = sdhci_reset,
858*4882a593Smuzhiyun .set_uhs_signaling = sdhci_set_uhs_signaling,
859*4882a593Smuzhiyun };
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun const struct sdhci_pci_fixes sdhci_o2 = {
862*4882a593Smuzhiyun .probe = sdhci_pci_o2_probe,
863*4882a593Smuzhiyun .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
864*4882a593Smuzhiyun .quirks2 = SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD,
865*4882a593Smuzhiyun .probe_slot = sdhci_pci_o2_probe_slot,
866*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
867*4882a593Smuzhiyun .resume = sdhci_pci_o2_resume,
868*4882a593Smuzhiyun #endif
869*4882a593Smuzhiyun .ops = &sdhci_pci_o2_ops,
870*4882a593Smuzhiyun .priv_size = sizeof(struct o2_host),
871*4882a593Smuzhiyun };
872