xref: /OK3568_Linux_fs/kernel/drivers/mmc/host/sdhci-pci-o2micro.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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, &reg);
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