1 |
commit: c9b7de80c8386cbd1e7033401062a566d8bf90b1 |
2 |
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Apr 16 11:15:24 2021 +0000 |
4 |
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Apr 16 11:15:33 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c9b7de80 |
7 |
|
8 |
linux patch 4.19.188 |
9 |
|
10 |
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1187_linux-4.19.188.patch | 3892 +++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 3896 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 0fdb045..32b1ad4 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -787,6 +787,10 @@ Patch: 1186_linux-4.19.187.patch |
21 |
From: https://www.kernel.org |
22 |
Desc: Linux 4.19.187 |
23 |
|
24 |
+Patch: 1187_linux-4.19.188.patch |
25 |
+From: https://www.kernel.org |
26 |
+Desc: Linux 4.19.188 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1187_linux-4.19.188.patch b/1187_linux-4.19.188.patch |
33 |
new file mode 100644 |
34 |
index 0000000..aa0f999 |
35 |
--- /dev/null |
36 |
+++ b/1187_linux-4.19.188.patch |
37 |
@@ -0,0 +1,3892 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index ceec39b530bbe..85f071709a619 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 4 |
45 |
+ PATCHLEVEL = 19 |
46 |
+-SUBLEVEL = 187 |
47 |
++SUBLEVEL = 188 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = "People's Front" |
50 |
+ |
51 |
+diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h |
52 |
+index a3b6f58d188c9..6d43f7901da23 100644 |
53 |
+--- a/arch/arm64/include/asm/kvm_arm.h |
54 |
++++ b/arch/arm64/include/asm/kvm_arm.h |
55 |
+@@ -198,6 +198,7 @@ |
56 |
+ #define CPTR_EL2_DEFAULT CPTR_EL2_RES1 |
57 |
+ |
58 |
+ /* Hyp Debug Configuration Register bits */ |
59 |
++#define MDCR_EL2_TTRF (1 << 19) |
60 |
+ #define MDCR_EL2_TPMS (1 << 14) |
61 |
+ #define MDCR_EL2_E2PB_MASK (UL(0x3)) |
62 |
+ #define MDCR_EL2_E2PB_SHIFT (UL(12)) |
63 |
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c |
64 |
+index 1719d21a171a9..122d5e843ab6d 100644 |
65 |
+--- a/arch/arm64/kernel/cpufeature.c |
66 |
++++ b/arch/arm64/kernel/cpufeature.c |
67 |
+@@ -258,7 +258,6 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { |
68 |
+ * of support. |
69 |
+ */ |
70 |
+ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0), |
71 |
+- ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0), |
72 |
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6), |
73 |
+ ARM64_FTR_END, |
74 |
+ }; |
75 |
+diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c |
76 |
+index 4e722d73a3c34..3606f6b890942 100644 |
77 |
+--- a/arch/arm64/kvm/debug.c |
78 |
++++ b/arch/arm64/kvm/debug.c |
79 |
+@@ -100,6 +100,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) |
80 |
+ * - Debug ROM Address (MDCR_EL2_TDRA) |
81 |
+ * - OS related registers (MDCR_EL2_TDOSA) |
82 |
+ * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) |
83 |
++ * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) |
84 |
+ * |
85 |
+ * Additionally, KVM only traps guest accesses to the debug registers if |
86 |
+ * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY |
87 |
+@@ -123,6 +124,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) |
88 |
+ vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; |
89 |
+ vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | |
90 |
+ MDCR_EL2_TPMS | |
91 |
++ MDCR_EL2_TTRF | |
92 |
+ MDCR_EL2_TPMCR | |
93 |
+ MDCR_EL2_TDRA | |
94 |
+ MDCR_EL2_TDOSA); |
95 |
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S |
96 |
+index a03821b2656aa..d9de22686e27d 100644 |
97 |
+--- a/arch/riscv/kernel/entry.S |
98 |
++++ b/arch/riscv/kernel/entry.S |
99 |
+@@ -449,6 +449,7 @@ ENDPROC(__fstate_restore) |
100 |
+ |
101 |
+ |
102 |
+ .section ".rodata" |
103 |
++ .align LGREG |
104 |
+ /* Exception vector table */ |
105 |
+ ENTRY(excp_vect_table) |
106 |
+ RISCV_PTR do_trap_insn_misaligned |
107 |
+diff --git a/block/bio.c b/block/bio.c |
108 |
+index 3d757055305f9..fe749404ef93b 100644 |
109 |
+--- a/block/bio.c |
110 |
++++ b/block/bio.c |
111 |
+@@ -314,7 +314,7 @@ static struct bio *__bio_chain_endio(struct bio *bio) |
112 |
+ { |
113 |
+ struct bio *parent = bio->bi_private; |
114 |
+ |
115 |
+- if (!parent->bi_status) |
116 |
++ if (bio->bi_status && !parent->bi_status) |
117 |
+ parent->bi_status = bio->bi_status; |
118 |
+ bio_put(bio); |
119 |
+ return parent; |
120 |
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c |
121 |
+index 4ba9231a6be80..26ba7a99b7d5b 100644 |
122 |
+--- a/drivers/base/dd.c |
123 |
++++ b/drivers/base/dd.c |
124 |
+@@ -254,14 +254,16 @@ int driver_deferred_probe_check_state(struct device *dev) |
125 |
+ |
126 |
+ static void deferred_probe_timeout_work_func(struct work_struct *work) |
127 |
+ { |
128 |
+- struct device_private *private, *p; |
129 |
++ struct device_private *p; |
130 |
+ |
131 |
+ deferred_probe_timeout = 0; |
132 |
+ driver_deferred_probe_trigger(); |
133 |
+ flush_work(&deferred_probe_work); |
134 |
+ |
135 |
+- list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) |
136 |
+- dev_info(private->device, "deferred probe pending"); |
137 |
++ mutex_lock(&deferred_probe_mutex); |
138 |
++ list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) |
139 |
++ dev_info(p->device, "deferred probe pending\n"); |
140 |
++ mutex_unlock(&deferred_probe_mutex); |
141 |
+ } |
142 |
+ static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); |
143 |
+ |
144 |
+diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c |
145 |
+index 221a8cbc57f90..a4dba034dca48 100644 |
146 |
+--- a/drivers/gpu/drm/imx/imx-ldb.c |
147 |
++++ b/drivers/gpu/drm/imx/imx-ldb.c |
148 |
+@@ -206,6 +206,11 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) |
149 |
+ int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; |
150 |
+ int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); |
151 |
+ |
152 |
++ if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { |
153 |
++ dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); |
154 |
++ return; |
155 |
++ } |
156 |
++ |
157 |
+ drm_panel_prepare(imx_ldb_ch->panel); |
158 |
+ |
159 |
+ if (dual) { |
160 |
+@@ -264,6 +269,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder, |
161 |
+ int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); |
162 |
+ u32 bus_format = imx_ldb_ch->bus_format; |
163 |
+ |
164 |
++ if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { |
165 |
++ dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); |
166 |
++ return; |
167 |
++ } |
168 |
++ |
169 |
+ if (mode->clock > 170000) { |
170 |
+ dev_warn(ldb->dev, |
171 |
+ "%s: mode exceeds 170 MHz pixel clock\n", __func__); |
172 |
+diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c |
173 |
+index 965088afcfade..03adb4cf325b9 100644 |
174 |
+--- a/drivers/gpu/drm/tegra/dc.c |
175 |
++++ b/drivers/gpu/drm/tegra/dc.c |
176 |
+@@ -1670,6 +1670,11 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, |
177 |
+ dev_err(dc->dev, |
178 |
+ "failed to set clock rate to %lu Hz\n", |
179 |
+ state->pclk); |
180 |
++ |
181 |
++ err = clk_set_rate(dc->clk, state->pclk); |
182 |
++ if (err < 0) |
183 |
++ dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", |
184 |
++ dc->clk, state->pclk, err); |
185 |
+ } |
186 |
+ |
187 |
+ DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), |
188 |
+@@ -1680,11 +1685,6 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, |
189 |
+ value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1; |
190 |
+ tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); |
191 |
+ } |
192 |
+- |
193 |
+- err = clk_set_rate(dc->clk, state->pclk); |
194 |
+- if (err < 0) |
195 |
+- dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", |
196 |
+- dc->clk, state->pclk, err); |
197 |
+ } |
198 |
+ |
199 |
+ static void tegra_dc_stop(struct tegra_dc *dc) |
200 |
+diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c |
201 |
+index e10e7b54ec4b6..7e5892597533e 100644 |
202 |
+--- a/drivers/net/phy/bcm-phy-lib.c |
203 |
++++ b/drivers/net/phy/bcm-phy-lib.c |
204 |
+@@ -198,7 +198,7 @@ EXPORT_SYMBOL_GPL(bcm_phy_enable_apd); |
205 |
+ |
206 |
+ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) |
207 |
+ { |
208 |
+- int val; |
209 |
++ int val, mask = 0; |
210 |
+ |
211 |
+ /* Enable EEE at PHY level */ |
212 |
+ val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL); |
213 |
+@@ -217,10 +217,15 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) |
214 |
+ if (val < 0) |
215 |
+ return val; |
216 |
+ |
217 |
++ if (phydev->supported & SUPPORTED_1000baseT_Full) |
218 |
++ mask |= MDIO_EEE_1000T; |
219 |
++ if (phydev->supported & SUPPORTED_100baseT_Full) |
220 |
++ mask |= MDIO_EEE_100TX; |
221 |
++ |
222 |
+ if (enable) |
223 |
+- val |= (MDIO_EEE_100TX | MDIO_EEE_1000T); |
224 |
++ val |= mask; |
225 |
+ else |
226 |
+- val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T); |
227 |
++ val &= ~mask; |
228 |
+ |
229 |
+ phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val); |
230 |
+ |
231 |
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig |
232 |
+index 1abf76be2aa8c..58e8140c1f57a 100644 |
233 |
+--- a/drivers/staging/Kconfig |
234 |
++++ b/drivers/staging/Kconfig |
235 |
+@@ -114,8 +114,6 @@ source "drivers/staging/mt7621-spi/Kconfig" |
236 |
+ |
237 |
+ source "drivers/staging/mt7621-dma/Kconfig" |
238 |
+ |
239 |
+-source "drivers/staging/mt7621-mmc/Kconfig" |
240 |
+- |
241 |
+ source "drivers/staging/mt7621-eth/Kconfig" |
242 |
+ |
243 |
+ source "drivers/staging/mt7621-dts/Kconfig" |
244 |
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile |
245 |
+index ab0cbe8815b1c..6f3065569fa00 100644 |
246 |
+--- a/drivers/staging/Makefile |
247 |
++++ b/drivers/staging/Makefile |
248 |
+@@ -47,7 +47,6 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-pci/ |
249 |
+ obj-$(CONFIG_SOC_MT7621) += mt7621-pinctrl/ |
250 |
+ obj-$(CONFIG_SOC_MT7621) += mt7621-spi/ |
251 |
+ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ |
252 |
+-obj-$(CONFIG_SOC_MT7621) += mt7621-mmc/ |
253 |
+ obj-$(CONFIG_SOC_MT7621) += mt7621-eth/ |
254 |
+ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ |
255 |
+ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ |
256 |
+diff --git a/drivers/staging/mt7621-mmc/Kconfig b/drivers/staging/mt7621-mmc/Kconfig |
257 |
+deleted file mode 100644 |
258 |
+index c6dfe8c637dc3..0000000000000 |
259 |
+--- a/drivers/staging/mt7621-mmc/Kconfig |
260 |
++++ /dev/null |
261 |
+@@ -1,16 +0,0 @@ |
262 |
+-config MTK_MMC |
263 |
+- tristate "MTK SD/MMC" |
264 |
+- depends on !MTD_NAND_RALINK && MMC |
265 |
+- |
266 |
+-config MTK_AEE_KDUMP |
267 |
+- bool "MTK AEE KDUMP" |
268 |
+- depends on MTK_MMC |
269 |
+- |
270 |
+-config MTK_MMC_CD_POLL |
271 |
+- bool "Card Detect with Polling" |
272 |
+- depends on MTK_MMC |
273 |
+- |
274 |
+-config MTK_MMC_EMMC_8BIT |
275 |
+- bool "eMMC 8-bit support" |
276 |
+- depends on MTK_MMC && RALINK_MT7628 |
277 |
+- |
278 |
+diff --git a/drivers/staging/mt7621-mmc/Makefile b/drivers/staging/mt7621-mmc/Makefile |
279 |
+deleted file mode 100644 |
280 |
+index caead0b547035..0000000000000 |
281 |
+--- a/drivers/staging/mt7621-mmc/Makefile |
282 |
++++ /dev/null |
283 |
+@@ -1,42 +0,0 @@ |
284 |
+-# Copyright Statement: |
285 |
+-# |
286 |
+-# This software/firmware and related documentation ("MediaTek Software") are |
287 |
+-# protected under relevant copyright laws. The information contained herein |
288 |
+-# is confidential and proprietary to MediaTek Inc. and/or its licensors. |
289 |
+-# Without the prior written permission of MediaTek inc. and/or its licensors, |
290 |
+-# any reproduction, modification, use or disclosure of MediaTek Software, |
291 |
+-# and information contained herein, in whole or in part, shall be strictly prohibited. |
292 |
+-# |
293 |
+-# MediaTek Inc. (C) 2010. All rights reserved. |
294 |
+-# |
295 |
+-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
296 |
+-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
297 |
+-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
298 |
+-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
299 |
+-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
300 |
+-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
301 |
+-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
302 |
+-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
303 |
+-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
304 |
+-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
305 |
+-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
306 |
+-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
307 |
+-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
308 |
+-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
309 |
+-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
310 |
+-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
311 |
+-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
312 |
+-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
313 |
+-# |
314 |
+-# The following software/firmware and/or related documentation ("MediaTek Software") |
315 |
+-# have been modified by MediaTek Inc. All revisions are subject to any receiver's |
316 |
+-# applicable license agreements with MediaTek Inc. |
317 |
+- |
318 |
+-obj-$(CONFIG_MTK_MMC) += mtk_sd.o |
319 |
+-mtk_sd-objs := sd.o dbg.o |
320 |
+-ifeq ($(CONFIG_MTK_AEE_KDUMP),y) |
321 |
+-EXTRA_CFLAGS += -DMT6575_SD_DEBUG |
322 |
+-endif |
323 |
+- |
324 |
+-clean: |
325 |
+- @rm -f *.o modules.order .*.cmd |
326 |
+diff --git a/drivers/staging/mt7621-mmc/TODO b/drivers/staging/mt7621-mmc/TODO |
327 |
+deleted file mode 100644 |
328 |
+index febb32d37e07b..0000000000000 |
329 |
+--- a/drivers/staging/mt7621-mmc/TODO |
330 |
++++ /dev/null |
331 |
+@@ -1,8 +0,0 @@ |
332 |
+- |
333 |
+-- general code review and clean up |
334 |
+-- ensure device-tree requirements are documented |
335 |
+-- should probably be merged with drivers/mmc/host/mtk-sd.c |
336 |
+-- possibly fix to work with highmem pages so a bounce buffer isn't |
337 |
+- needed. |
338 |
+- |
339 |
+-Cc: NeilBrown <neil@×××××.name> |
340 |
+diff --git a/drivers/staging/mt7621-mmc/board.h b/drivers/staging/mt7621-mmc/board.h |
341 |
+deleted file mode 100644 |
342 |
+index 983791ee308dd..0000000000000 |
343 |
+--- a/drivers/staging/mt7621-mmc/board.h |
344 |
++++ /dev/null |
345 |
+@@ -1,63 +0,0 @@ |
346 |
+-/* Copyright Statement: |
347 |
+- * |
348 |
+- * This software/firmware and related documentation ("MediaTek Software") are |
349 |
+- * protected under relevant copyright laws. The information contained herein |
350 |
+- * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
351 |
+- * Without the prior written permission of MediaTek inc. and/or its licensors, |
352 |
+- * any reproduction, modification, use or disclosure of MediaTek Software, |
353 |
+- * and information contained herein, in whole or in part, shall be strictly prohibited. |
354 |
+- */ |
355 |
+-/* MediaTek Inc. (C) 2010. All rights reserved. |
356 |
+- * |
357 |
+- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
358 |
+- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
359 |
+- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
360 |
+- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
361 |
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
362 |
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
363 |
+- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
364 |
+- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
365 |
+- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
366 |
+- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
367 |
+- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
368 |
+- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
369 |
+- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
370 |
+- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
371 |
+- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
372 |
+- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
373 |
+- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
374 |
+- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
375 |
+- * |
376 |
+- * The following software/firmware and/or related documentation ("MediaTek Software") |
377 |
+- * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
378 |
+- * applicable license agreements with MediaTek Inc. |
379 |
+- */ |
380 |
+- |
381 |
+-#ifndef __ARCH_ARM_MACH_BOARD_H |
382 |
+-#define __ARCH_ARM_MACH_BOARD_H |
383 |
+- |
384 |
+-#define MSDC_CD_PIN_EN BIT(0) /* card detection pin is wired */ |
385 |
+-#define MSDC_WP_PIN_EN BIT(1) /* write protection pin is wired */ |
386 |
+-#define MSDC_RST_PIN_EN BIT(2) /* emmc reset pin is wired */ |
387 |
+-#define MSDC_REMOVABLE BIT(5) /* removable slot */ |
388 |
+- |
389 |
+-#define MSDC_SMPL_RISING (0) |
390 |
+-#define MSDC_SMPL_FALLING (1) |
391 |
+- |
392 |
+-#define MSDC_CMD_PIN (0) |
393 |
+-#define MSDC_DAT_PIN (1) |
394 |
+-#define MSDC_CD_PIN (2) |
395 |
+-#define MSDC_WP_PIN (3) |
396 |
+-#define MSDC_RST_PIN (4) |
397 |
+- |
398 |
+-struct msdc_hw { |
399 |
+- unsigned char clk_src; /* host clock source */ |
400 |
+- unsigned long flags; /* hardware capability flags */ |
401 |
+- |
402 |
+- /* config gpio pull mode */ |
403 |
+- void (*config_gpio_pin)(int type, int pull); |
404 |
+-}; |
405 |
+- |
406 |
+-extern struct msdc_hw msdc0_hw; |
407 |
+- |
408 |
+-#endif /* __ARCH_ARM_MACH_BOARD_H */ |
409 |
+diff --git a/drivers/staging/mt7621-mmc/dbg.c b/drivers/staging/mt7621-mmc/dbg.c |
410 |
+deleted file mode 100644 |
411 |
+index 6e518dce9029a..0000000000000 |
412 |
+--- a/drivers/staging/mt7621-mmc/dbg.c |
413 |
++++ /dev/null |
414 |
+@@ -1,307 +0,0 @@ |
415 |
+-/* Copyright Statement: |
416 |
+- * |
417 |
+- * This software/firmware and related documentation ("MediaTek Software") are |
418 |
+- * protected under relevant copyright laws. The information contained herein |
419 |
+- * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
420 |
+- * Without the prior written permission of MediaTek inc. and/or its licensors, |
421 |
+- * any reproduction, modification, use or disclosure of MediaTek Software, |
422 |
+- * and information contained herein, in whole or in part, shall be strictly prohibited. |
423 |
+- * |
424 |
+- * MediaTek Inc. (C) 2010. All rights reserved. |
425 |
+- * |
426 |
+- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
427 |
+- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
428 |
+- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
429 |
+- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
430 |
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
431 |
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
432 |
+- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
433 |
+- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
434 |
+- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
435 |
+- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
436 |
+- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
437 |
+- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
438 |
+- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
439 |
+- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
440 |
+- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
441 |
+- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
442 |
+- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
443 |
+- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
444 |
+- * |
445 |
+- * The following software/firmware and/or related documentation ("MediaTek Software") |
446 |
+- * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
447 |
+- * applicable license agreements with MediaTek Inc. |
448 |
+- */ |
449 |
+- |
450 |
+-#include <linux/version.h> |
451 |
+-#include <linux/kernel.h> |
452 |
+-#include <linux/sched.h> |
453 |
+-#include <linux/kthread.h> |
454 |
+-#include <linux/delay.h> |
455 |
+-#include <linux/module.h> |
456 |
+-#include <linux/init.h> |
457 |
+-#include <linux/proc_fs.h> |
458 |
+-#include <linux/string.h> |
459 |
+-#include <linux/uaccess.h> |
460 |
+-// #include <mach/mt6575_gpt.h> /* --- by chhung */ |
461 |
+-#include "dbg.h" |
462 |
+-#include "mt6575_sd.h" |
463 |
+-#include <linux/seq_file.h> |
464 |
+- |
465 |
+-static char cmd_buf[256]; |
466 |
+- |
467 |
+-/* for debug zone */ |
468 |
+-unsigned int sd_debug_zone[4] = { |
469 |
+- 0, |
470 |
+- 0, |
471 |
+- 0, |
472 |
+- 0 |
473 |
+-}; |
474 |
+- |
475 |
+-#if defined(MT6575_SD_DEBUG) |
476 |
+-/* for driver profile */ |
477 |
+-#define TICKS_ONE_MS (13000) |
478 |
+-u32 gpt_enable; |
479 |
+-u32 sdio_pro_enable; /* make sure gpt is enabled */ |
480 |
+-u32 sdio_pro_time; /* no more than 30s */ |
481 |
+-struct sdio_profile sdio_perfomance = {0}; |
482 |
+- |
483 |
+-#if 0 /* --- chhung */ |
484 |
+-void msdc_init_gpt(void) |
485 |
+-{ |
486 |
+- GPT_CONFIG config; |
487 |
+- |
488 |
+- config.num = GPT6; |
489 |
+- config.mode = GPT_FREE_RUN; |
490 |
+- config.clkSrc = GPT_CLK_SRC_SYS; |
491 |
+- config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */ |
492 |
+- |
493 |
+- if (GPT_Config(config) == FALSE) |
494 |
+- return; |
495 |
+- |
496 |
+- GPT_Start(GPT6); |
497 |
+-} |
498 |
+-#endif /* end of --- */ |
499 |
+- |
500 |
+-u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32) |
501 |
+-{ |
502 |
+- u32 ret = 0; |
503 |
+- |
504 |
+- if (new_H32 == old_H32) { |
505 |
+- ret = new_L32 - old_L32; |
506 |
+- } else if (new_H32 == (old_H32 + 1)) { |
507 |
+- if (new_L32 > old_L32) |
508 |
+- pr_debug("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32); |
509 |
+- ret = (0xffffffff - old_L32); |
510 |
+- ret += new_L32; |
511 |
+- } else { |
512 |
+- pr_debug("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32); |
513 |
+- } |
514 |
+- |
515 |
+- return ret; |
516 |
+-} |
517 |
+- |
518 |
+-void msdc_sdio_profile(struct sdio_profile *result) |
519 |
+-{ |
520 |
+- struct cmd_profile *cmd; |
521 |
+- u32 i; |
522 |
+- |
523 |
+- pr_debug("sdio === performance dump ===\n"); |
524 |
+- pr_debug("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n", |
525 |
+- result->total_tc, result->total_tc / TICKS_ONE_MS, |
526 |
+- result->total_tx_bytes, result->total_rx_bytes); |
527 |
+- |
528 |
+- /* CMD52 Dump */ |
529 |
+- cmd = &result->cmd52_rx; |
530 |
+- pr_debug("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, |
531 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); |
532 |
+- cmd = &result->cmd52_tx; |
533 |
+- pr_debug("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, |
534 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); |
535 |
+- |
536 |
+- /* CMD53 Rx bytes + block mode */ |
537 |
+- for (i = 0; i < 512; i++) { |
538 |
+- cmd = &result->cmd53_rx_byte[i]; |
539 |
+- if (cmd->count) { |
540 |
+- pr_debug("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
541 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, |
542 |
+- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); |
543 |
+- } |
544 |
+- } |
545 |
+- for (i = 0; i < 100; i++) { |
546 |
+- cmd = &result->cmd53_rx_blk[i]; |
547 |
+- if (cmd->count) { |
548 |
+- pr_debug("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
549 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, |
550 |
+- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); |
551 |
+- } |
552 |
+- } |
553 |
+- |
554 |
+- /* CMD53 Tx bytes + block mode */ |
555 |
+- for (i = 0; i < 512; i++) { |
556 |
+- cmd = &result->cmd53_tx_byte[i]; |
557 |
+- if (cmd->count) { |
558 |
+- pr_debug("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
559 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, |
560 |
+- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); |
561 |
+- } |
562 |
+- } |
563 |
+- for (i = 0; i < 100; i++) { |
564 |
+- cmd = &result->cmd53_tx_blk[i]; |
565 |
+- if (cmd->count) { |
566 |
+- pr_debug("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
567 |
+- cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, |
568 |
+- cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); |
569 |
+- } |
570 |
+- } |
571 |
+- |
572 |
+- pr_debug("sdio === performance dump done ===\n"); |
573 |
+-} |
574 |
+- |
575 |
+-//========= sdio command table =========== |
576 |
+-void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks) |
577 |
+-{ |
578 |
+- struct sdio_profile *result = &sdio_perfomance; |
579 |
+- struct cmd_profile *cmd; |
580 |
+- u32 block; |
581 |
+- |
582 |
+- if (sdio_pro_enable == 0) |
583 |
+- return; |
584 |
+- |
585 |
+- if (opcode == 52) { |
586 |
+- cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx; |
587 |
+- } else if (opcode == 53) { |
588 |
+- if (sizes < 512) { |
589 |
+- cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes]; |
590 |
+- } else { |
591 |
+- block = sizes / 512; |
592 |
+- if (block >= 99) { |
593 |
+- pr_err("cmd53 error blocks\n"); |
594 |
+- while (1) |
595 |
+- ; |
596 |
+- } |
597 |
+- cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block]; |
598 |
+- } |
599 |
+- } else { |
600 |
+- return; |
601 |
+- } |
602 |
+- |
603 |
+- /* update the members */ |
604 |
+- if (ticks > cmd->max_tc) |
605 |
+- cmd->max_tc = ticks; |
606 |
+- if (cmd->min_tc == 0 || ticks < cmd->min_tc) |
607 |
+- cmd->min_tc = ticks; |
608 |
+- cmd->tot_tc += ticks; |
609 |
+- cmd->tot_bytes += sizes; |
610 |
+- cmd->count++; |
611 |
+- |
612 |
+- if (bRx) |
613 |
+- result->total_rx_bytes += sizes; |
614 |
+- else |
615 |
+- result->total_tx_bytes += sizes; |
616 |
+- result->total_tc += ticks; |
617 |
+- |
618 |
+- /* dump when total_tc > 30s */ |
619 |
+- if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) { |
620 |
+- msdc_sdio_profile(result); |
621 |
+- memset(result, 0, sizeof(struct sdio_profile)); |
622 |
+- } |
623 |
+-} |
624 |
+- |
625 |
+-//========== driver proc interface =========== |
626 |
+-static int msdc_debug_proc_read(struct seq_file *s, void *p) |
627 |
+-{ |
628 |
+- seq_puts(s, "\n=========================================\n"); |
629 |
+- seq_puts(s, "Index<0> + Id + Zone\n"); |
630 |
+- seq_puts(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n"); |
631 |
+- seq_puts(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n"); |
632 |
+- seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]); |
633 |
+- seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]); |
634 |
+- seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]); |
635 |
+- seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]); |
636 |
+- |
637 |
+- seq_puts(s, "Index<3> + SDIO_PROFILE + TIME\n"); |
638 |
+- seq_puts(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n"); |
639 |
+- seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time); |
640 |
+- seq_puts(s, "=========================================\n\n"); |
641 |
+- |
642 |
+- return 0; |
643 |
+-} |
644 |
+- |
645 |
+-static ssize_t msdc_debug_proc_write(struct file *file, |
646 |
+- const char __user *buf, |
647 |
+- size_t count, loff_t *data) |
648 |
+-{ |
649 |
+- int ret; |
650 |
+- |
651 |
+- int cmd, p1, p2; |
652 |
+- int id, zone; |
653 |
+- int mode, size; |
654 |
+- |
655 |
+- if (count == 0) |
656 |
+- return -1; |
657 |
+- if (count > 255) |
658 |
+- count = 255; |
659 |
+- |
660 |
+- if (copy_from_user(cmd_buf, buf, count)) |
661 |
+- return -EFAULT; |
662 |
+- |
663 |
+- cmd_buf[count] = '\0'; |
664 |
+- pr_debug("msdc Write %s\n", cmd_buf); |
665 |
+- |
666 |
+- sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2); |
667 |
+- |
668 |
+- if (cmd == SD_TOOL_ZONE) { |
669 |
+- id = p1; |
670 |
+- zone = p2; |
671 |
+- zone &= 0x3ff; |
672 |
+- pr_debug("msdc host_id<%d> zone<0x%.8x>\n", id, zone); |
673 |
+- if (id >= 0 && id <= 3) { |
674 |
+- sd_debug_zone[id] = zone; |
675 |
+- } else if (id == 4) { |
676 |
+- sd_debug_zone[0] = sd_debug_zone[1] = zone; |
677 |
+- sd_debug_zone[2] = sd_debug_zone[3] = zone; |
678 |
+- } else { |
679 |
+- pr_err("msdc host_id error when set debug zone\n"); |
680 |
+- } |
681 |
+- } else if (cmd == SD_TOOL_SDIO_PROFILE) { |
682 |
+- if (p1 == 1) { /* enable profile */ |
683 |
+- if (gpt_enable == 0) { |
684 |
+- // msdc_init_gpt(); /* --- by chhung */ |
685 |
+- gpt_enable = 1; |
686 |
+- } |
687 |
+- sdio_pro_enable = 1; |
688 |
+- if (p2 == 0) |
689 |
+- p2 = 1; |
690 |
+- if (p2 >= 30) |
691 |
+- p2 = 30; |
692 |
+- sdio_pro_time = p2; |
693 |
+- } else if (p1 == 0) { |
694 |
+- /* todo */ |
695 |
+- sdio_pro_enable = 0; |
696 |
+- } |
697 |
+- } |
698 |
+- |
699 |
+- return count; |
700 |
+-} |
701 |
+- |
702 |
+-static int msdc_debug_show(struct inode *inode, struct file *file) |
703 |
+-{ |
704 |
+- return single_open(file, msdc_debug_proc_read, NULL); |
705 |
+-} |
706 |
+- |
707 |
+-static const struct file_operations msdc_debug_fops = { |
708 |
+- .owner = THIS_MODULE, |
709 |
+- .open = msdc_debug_show, |
710 |
+- .read = seq_read, |
711 |
+- .write = msdc_debug_proc_write, |
712 |
+- .llseek = seq_lseek, |
713 |
+- .release = single_release, |
714 |
+-}; |
715 |
+- |
716 |
+-void msdc_debug_proc_init(void) |
717 |
+-{ |
718 |
+- proc_create("msdc_debug", 0660, NULL, &msdc_debug_fops); |
719 |
+-} |
720 |
+-EXPORT_SYMBOL_GPL(msdc_debug_proc_init); |
721 |
+-#endif |
722 |
+diff --git a/drivers/staging/mt7621-mmc/dbg.h b/drivers/staging/mt7621-mmc/dbg.h |
723 |
+deleted file mode 100644 |
724 |
+index 2f2c56b739874..0000000000000 |
725 |
+--- a/drivers/staging/mt7621-mmc/dbg.h |
726 |
++++ /dev/null |
727 |
+@@ -1,149 +0,0 @@ |
728 |
+-/* Copyright Statement: |
729 |
+- * |
730 |
+- * This software/firmware and related documentation ("MediaTek Software") are |
731 |
+- * protected under relevant copyright laws. The information contained herein |
732 |
+- * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
733 |
+- * Without the prior written permission of MediaTek inc. and/or its licensors, |
734 |
+- * any reproduction, modification, use or disclosure of MediaTek Software, |
735 |
+- * and information contained herein, in whole or in part, shall be strictly prohibited. |
736 |
+- * |
737 |
+- * MediaTek Inc. (C) 2010. All rights reserved. |
738 |
+- * |
739 |
+- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
740 |
+- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
741 |
+- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
742 |
+- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
743 |
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
744 |
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
745 |
+- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
746 |
+- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
747 |
+- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
748 |
+- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
749 |
+- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
750 |
+- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
751 |
+- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
752 |
+- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
753 |
+- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
754 |
+- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
755 |
+- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
756 |
+- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
757 |
+- * |
758 |
+- * The following software/firmware and/or related documentation ("MediaTek Software") |
759 |
+- * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
760 |
+- * applicable license agreements with MediaTek Inc. |
761 |
+- */ |
762 |
+-#ifndef __MT_MSDC_DEUBG__ |
763 |
+-#define __MT_MSDC_DEUBG__ |
764 |
+- |
765 |
+-//========================== |
766 |
+-extern u32 sdio_pro_enable; |
767 |
+-/* for a type command, e.g. CMD53, 2 blocks */ |
768 |
+-struct cmd_profile { |
769 |
+- u32 max_tc; /* Max tick count */ |
770 |
+- u32 min_tc; |
771 |
+- u32 tot_tc; /* total tick count */ |
772 |
+- u32 tot_bytes; |
773 |
+- u32 count; /* the counts of the command */ |
774 |
+-}; |
775 |
+- |
776 |
+-/* dump when total_tc and total_bytes */ |
777 |
+-struct sdio_profile { |
778 |
+- u32 total_tc; /* total tick count of CMD52 and CMD53 */ |
779 |
+- u32 total_tx_bytes; /* total bytes of CMD53 Tx */ |
780 |
+- u32 total_rx_bytes; /* total bytes of CMD53 Rx */ |
781 |
+- |
782 |
+- /*CMD52*/ |
783 |
+- struct cmd_profile cmd52_tx; |
784 |
+- struct cmd_profile cmd52_rx; |
785 |
+- |
786 |
+- /*CMD53 in byte unit */ |
787 |
+- struct cmd_profile cmd53_tx_byte[512]; |
788 |
+- struct cmd_profile cmd53_rx_byte[512]; |
789 |
+- |
790 |
+- /*CMD53 in block unit */ |
791 |
+- struct cmd_profile cmd53_tx_blk[100]; |
792 |
+- struct cmd_profile cmd53_rx_blk[100]; |
793 |
+-}; |
794 |
+- |
795 |
+-//========================== |
796 |
+-enum msdc_dbg { |
797 |
+- SD_TOOL_ZONE = 0, |
798 |
+- SD_TOOL_DMA_SIZE = 1, |
799 |
+- SD_TOOL_PM_ENABLE = 2, |
800 |
+- SD_TOOL_SDIO_PROFILE = 3, |
801 |
+-}; |
802 |
+- |
803 |
+-/* Debug message event */ |
804 |
+-#define DBG_EVT_NONE (0) /* No event */ |
805 |
+-#define DBG_EVT_DMA (1 << 0) /* DMA related event */ |
806 |
+-#define DBG_EVT_CMD (1 << 1) /* MSDC CMD related event */ |
807 |
+-#define DBG_EVT_RSP (1 << 2) /* MSDC CMD RSP related event */ |
808 |
+-#define DBG_EVT_INT (1 << 3) /* MSDC INT event */ |
809 |
+-#define DBG_EVT_CFG (1 << 4) /* MSDC CFG event */ |
810 |
+-#define DBG_EVT_FUC (1 << 5) /* Function event */ |
811 |
+-#define DBG_EVT_OPS (1 << 6) /* Read/Write operation event */ |
812 |
+-#define DBG_EVT_FIO (1 << 7) /* FIFO operation event */ |
813 |
+-#define DBG_EVT_WRN (1 << 8) /* Warning event */ |
814 |
+-#define DBG_EVT_PWR (1 << 9) /* Power event */ |
815 |
+-#define DBG_EVT_ALL (0xffffffff) |
816 |
+- |
817 |
+-#define DBG_EVT_MASK (DBG_EVT_ALL) |
818 |
+- |
819 |
+-extern unsigned int sd_debug_zone[4]; |
820 |
+-#define TAG "msdc" |
821 |
+-#if 0 /* +++ chhung */ |
822 |
+-#define BUG_ON(x) \ |
823 |
+-do { \ |
824 |
+- if (x) { \ |
825 |
+- printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \ |
826 |
+- while (1) \ |
827 |
+- ; \ |
828 |
+- } \ |
829 |
+-} while (0) |
830 |
+-#endif /* end of +++ */ |
831 |
+- |
832 |
+-#define N_MSG(evt, fmt, args...) |
833 |
+-/* |
834 |
+-do { \ |
835 |
+- if ((DBG_EVT_##evt) & sd_debug_zone[host->id]) { \ |
836 |
+- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ |
837 |
+- host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \ |
838 |
+- } \ |
839 |
+-} while(0) |
840 |
+-*/ |
841 |
+- |
842 |
+-#define ERR_MSG(fmt, args...) \ |
843 |
+-do { \ |
844 |
+- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ |
845 |
+- host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ |
846 |
+-} while (0); |
847 |
+- |
848 |
+-#if 1 |
849 |
+-//defined CONFIG_MTK_MMC_CD_POLL |
850 |
+-#define INIT_MSG(fmt, args...) |
851 |
+-#define IRQ_MSG(fmt, args...) |
852 |
+-#else |
853 |
+-#define INIT_MSG(fmt, args...) \ |
854 |
+-do { \ |
855 |
+- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ |
856 |
+- host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ |
857 |
+-} while (0); |
858 |
+- |
859 |
+-/* PID in ISR in not corrent */ |
860 |
+-#define IRQ_MSG(fmt, args...) \ |
861 |
+-do { \ |
862 |
+- printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ |
863 |
+- host->id, ##args, __FUNCTION__, __LINE__); \ |
864 |
+-} while (0); |
865 |
+-#endif |
866 |
+- |
867 |
+-void msdc_debug_proc_init(void); |
868 |
+- |
869 |
+-#if 0 /* --- chhung */ |
870 |
+-void msdc_init_gpt(void); |
871 |
+-extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32); |
872 |
+-#endif /* end of --- */ |
873 |
+-u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32); |
874 |
+-void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks); |
875 |
+- |
876 |
+-#endif |
877 |
+diff --git a/drivers/staging/mt7621-mmc/mt6575_sd.h b/drivers/staging/mt7621-mmc/mt6575_sd.h |
878 |
+deleted file mode 100644 |
879 |
+index 4e287c140acb4..0000000000000 |
880 |
+--- a/drivers/staging/mt7621-mmc/mt6575_sd.h |
881 |
++++ /dev/null |
882 |
+@@ -1,488 +0,0 @@ |
883 |
+-/* Copyright Statement: |
884 |
+- * |
885 |
+- * This software/firmware and related documentation ("MediaTek Software") are |
886 |
+- * protected under relevant copyright laws. The information contained herein |
887 |
+- * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
888 |
+- * Without the prior written permission of MediaTek inc. and/or its licensors, |
889 |
+- * any reproduction, modification, use or disclosure of MediaTek Software, |
890 |
+- * and information contained herein, in whole or in part, shall be strictly prohibited. |
891 |
+- */ |
892 |
+-/* MediaTek Inc. (C) 2010. All rights reserved. |
893 |
+- * |
894 |
+- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
895 |
+- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
896 |
+- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
897 |
+- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
898 |
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
899 |
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
900 |
+- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
901 |
+- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
902 |
+- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
903 |
+- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
904 |
+- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
905 |
+- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
906 |
+- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
907 |
+- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
908 |
+- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
909 |
+- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
910 |
+- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
911 |
+- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
912 |
+- * |
913 |
+- * The following software/firmware and/or related documentation ("MediaTek Software") |
914 |
+- * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
915 |
+- * applicable license agreements with MediaTek Inc. |
916 |
+- */ |
917 |
+- |
918 |
+-#ifndef MT6575_SD_H |
919 |
+-#define MT6575_SD_H |
920 |
+- |
921 |
+-#include <linux/bitops.h> |
922 |
+-#include <linux/mmc/host.h> |
923 |
+- |
924 |
+-// #include <mach/mt6575_reg_base.h> /* --- by chhung */ |
925 |
+- |
926 |
+-/*--------------------------------------------------------------------------*/ |
927 |
+-/* Common Definition */ |
928 |
+-/*--------------------------------------------------------------------------*/ |
929 |
+-#define MSDC_FIFO_SZ (128) |
930 |
+-#define MSDC_FIFO_THD (64) // (128) |
931 |
+-#define MSDC_NUM (4) |
932 |
+- |
933 |
+-#define MSDC_MS (0) |
934 |
+-#define MSDC_SDMMC (1) |
935 |
+- |
936 |
+-#define MSDC_BUS_1BITS (0) |
937 |
+-#define MSDC_BUS_4BITS (1) |
938 |
+-#define MSDC_BUS_8BITS (2) |
939 |
+- |
940 |
+-#define MSDC_BRUST_8B (3) |
941 |
+-#define MSDC_BRUST_16B (4) |
942 |
+-#define MSDC_BRUST_32B (5) |
943 |
+-#define MSDC_BRUST_64B (6) |
944 |
+- |
945 |
+-#define MSDC_PIN_PULL_NONE (0) |
946 |
+-#define MSDC_PIN_PULL_DOWN (1) |
947 |
+-#define MSDC_PIN_PULL_UP (2) |
948 |
+-#define MSDC_PIN_KEEP (3) |
949 |
+- |
950 |
+-#define MSDC_MAX_SCLK (48000000) /* +/- by chhung */ |
951 |
+-#define MSDC_MIN_SCLK (260000) |
952 |
+- |
953 |
+-#define MSDC_AUTOCMD12 (0x0001) |
954 |
+-#define MSDC_AUTOCMD23 (0x0002) |
955 |
+-#define MSDC_AUTOCMD19 (0x0003) |
956 |
+- |
957 |
+-#define MSDC_EMMC_BOOTMODE0 (0) /* Pull low CMD mode */ |
958 |
+-#define MSDC_EMMC_BOOTMODE1 (1) /* Reset CMD mode */ |
959 |
+- |
960 |
+-enum { |
961 |
+- RESP_NONE = 0, |
962 |
+- RESP_R1, |
963 |
+- RESP_R2, |
964 |
+- RESP_R3, |
965 |
+- RESP_R4, |
966 |
+- RESP_R5, |
967 |
+- RESP_R6, |
968 |
+- RESP_R7, |
969 |
+- RESP_R1B |
970 |
+-}; |
971 |
+- |
972 |
+-/*--------------------------------------------------------------------------*/ |
973 |
+-/* Register Offset */ |
974 |
+-/*--------------------------------------------------------------------------*/ |
975 |
+-#define MSDC_CFG (0x0) |
976 |
+-#define MSDC_IOCON (0x04) |
977 |
+-#define MSDC_PS (0x08) |
978 |
+-#define MSDC_INT (0x0c) |
979 |
+-#define MSDC_INTEN (0x10) |
980 |
+-#define MSDC_FIFOCS (0x14) |
981 |
+-#define MSDC_TXDATA (0x18) |
982 |
+-#define MSDC_RXDATA (0x1c) |
983 |
+-#define SDC_CFG (0x30) |
984 |
+-#define SDC_CMD (0x34) |
985 |
+-#define SDC_ARG (0x38) |
986 |
+-#define SDC_STS (0x3c) |
987 |
+-#define SDC_RESP0 (0x40) |
988 |
+-#define SDC_RESP1 (0x44) |
989 |
+-#define SDC_RESP2 (0x48) |
990 |
+-#define SDC_RESP3 (0x4c) |
991 |
+-#define SDC_BLK_NUM (0x50) |
992 |
+-#define SDC_CSTS (0x58) |
993 |
+-#define SDC_CSTS_EN (0x5c) |
994 |
+-#define SDC_DCRC_STS (0x60) |
995 |
+-#define EMMC_CFG0 (0x70) |
996 |
+-#define EMMC_CFG1 (0x74) |
997 |
+-#define EMMC_STS (0x78) |
998 |
+-#define EMMC_IOCON (0x7c) |
999 |
+-#define SDC_ACMD_RESP (0x80) |
1000 |
+-#define SDC_ACMD19_TRG (0x84) |
1001 |
+-#define SDC_ACMD19_STS (0x88) |
1002 |
+-#define MSDC_DMA_SA (0x90) |
1003 |
+-#define MSDC_DMA_CA (0x94) |
1004 |
+-#define MSDC_DMA_CTRL (0x98) |
1005 |
+-#define MSDC_DMA_CFG (0x9c) |
1006 |
+-#define MSDC_DBG_SEL (0xa0) |
1007 |
+-#define MSDC_DBG_OUT (0xa4) |
1008 |
+-#define MSDC_PATCH_BIT (0xb0) |
1009 |
+-#define MSDC_PATCH_BIT0 MSDC_PATCH_BIT |
1010 |
+-#define MSDC_PATCH_BIT1 (0xb4) |
1011 |
+-#define MSDC_PAD_CTL0 (0xe0) |
1012 |
+-#define MSDC_PAD_CTL1 (0xe4) |
1013 |
+-#define MSDC_PAD_CTL2 (0xe8) |
1014 |
+-#define MSDC_PAD_TUNE (0xec) |
1015 |
+-#define MSDC_DAT_RDDLY0 (0xf0) |
1016 |
+-#define MSDC_DAT_RDDLY1 (0xf4) |
1017 |
+-#define MSDC_HW_DBG (0xf8) |
1018 |
+-#define MSDC_VERSION (0x100) |
1019 |
+-#define MSDC_ECO_VER (0x104) |
1020 |
+- |
1021 |
+-/*--------------------------------------------------------------------------*/ |
1022 |
+-/* Register Mask */ |
1023 |
+-/*--------------------------------------------------------------------------*/ |
1024 |
+- |
1025 |
+-/* MSDC_CFG mask */ |
1026 |
+-#define MSDC_CFG_MODE (0x1 << 0) /* RW */ |
1027 |
+-#define MSDC_CFG_CKPDN (0x1 << 1) /* RW */ |
1028 |
+-#define MSDC_CFG_RST (0x1 << 2) /* RW */ |
1029 |
+-#define MSDC_CFG_PIO (0x1 << 3) /* RW */ |
1030 |
+-#define MSDC_CFG_CKDRVEN (0x1 << 4) /* RW */ |
1031 |
+-#define MSDC_CFG_BV18SDT (0x1 << 5) /* RW */ |
1032 |
+-#define MSDC_CFG_BV18PSS (0x1 << 6) /* R */ |
1033 |
+-#define MSDC_CFG_CKSTB (0x1 << 7) /* R */ |
1034 |
+-#define MSDC_CFG_CKDIV (0xff << 8) /* RW */ |
1035 |
+-#define MSDC_CFG_CKMOD (0x3 << 16) /* RW */ |
1036 |
+- |
1037 |
+-/* MSDC_IOCON mask */ |
1038 |
+-#define MSDC_IOCON_SDR104CKS (0x1 << 0) /* RW */ |
1039 |
+-#define MSDC_IOCON_RSPL (0x1 << 1) /* RW */ |
1040 |
+-#define MSDC_IOCON_DSPL (0x1 << 2) /* RW */ |
1041 |
+-#define MSDC_IOCON_DDLSEL (0x1 << 3) /* RW */ |
1042 |
+-#define MSDC_IOCON_DDR50CKD (0x1 << 4) /* RW */ |
1043 |
+-#define MSDC_IOCON_DSPLSEL (0x1 << 5) /* RW */ |
1044 |
+-#define MSDC_IOCON_D0SPL (0x1 << 16) /* RW */ |
1045 |
+-#define MSDC_IOCON_D1SPL (0x1 << 17) /* RW */ |
1046 |
+-#define MSDC_IOCON_D2SPL (0x1 << 18) /* RW */ |
1047 |
+-#define MSDC_IOCON_D3SPL (0x1 << 19) /* RW */ |
1048 |
+-#define MSDC_IOCON_D4SPL (0x1 << 20) /* RW */ |
1049 |
+-#define MSDC_IOCON_D5SPL (0x1 << 21) /* RW */ |
1050 |
+-#define MSDC_IOCON_D6SPL (0x1 << 22) /* RW */ |
1051 |
+-#define MSDC_IOCON_D7SPL (0x1 << 23) /* RW */ |
1052 |
+-#define MSDC_IOCON_RISCSZ (0x3 << 24) /* RW */ |
1053 |
+- |
1054 |
+-/* MSDC_PS mask */ |
1055 |
+-#define MSDC_PS_CDEN (0x1 << 0) /* RW */ |
1056 |
+-#define MSDC_PS_CDSTS (0x1 << 1) /* R */ |
1057 |
+-#define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */ |
1058 |
+-#define MSDC_PS_DAT (0xff << 16) /* R */ |
1059 |
+-#define MSDC_PS_CMD (0x1 << 24) /* R */ |
1060 |
+-#define MSDC_PS_WP (0x1UL << 31) /* R */ |
1061 |
+- |
1062 |
+-/* MSDC_INT mask */ |
1063 |
+-#define MSDC_INT_MMCIRQ (0x1 << 0) /* W1C */ |
1064 |
+-#define MSDC_INT_CDSC (0x1 << 1) /* W1C */ |
1065 |
+-#define MSDC_INT_ACMDRDY (0x1 << 3) /* W1C */ |
1066 |
+-#define MSDC_INT_ACMDTMO (0x1 << 4) /* W1C */ |
1067 |
+-#define MSDC_INT_ACMDCRCERR (0x1 << 5) /* W1C */ |
1068 |
+-#define MSDC_INT_DMAQ_EMPTY (0x1 << 6) /* W1C */ |
1069 |
+-#define MSDC_INT_SDIOIRQ (0x1 << 7) /* W1C */ |
1070 |
+-#define MSDC_INT_CMDRDY (0x1 << 8) /* W1C */ |
1071 |
+-#define MSDC_INT_CMDTMO (0x1 << 9) /* W1C */ |
1072 |
+-#define MSDC_INT_RSPCRCERR (0x1 << 10) /* W1C */ |
1073 |
+-#define MSDC_INT_CSTA (0x1 << 11) /* R */ |
1074 |
+-#define MSDC_INT_XFER_COMPL (0x1 << 12) /* W1C */ |
1075 |
+-#define MSDC_INT_DXFER_DONE (0x1 << 13) /* W1C */ |
1076 |
+-#define MSDC_INT_DATTMO (0x1 << 14) /* W1C */ |
1077 |
+-#define MSDC_INT_DATCRCERR (0x1 << 15) /* W1C */ |
1078 |
+-#define MSDC_INT_ACMD19_DONE (0x1 << 16) /* W1C */ |
1079 |
+- |
1080 |
+-/* MSDC_INTEN mask */ |
1081 |
+-#define MSDC_INTEN_MMCIRQ (0x1 << 0) /* RW */ |
1082 |
+-#define MSDC_INTEN_CDSC (0x1 << 1) /* RW */ |
1083 |
+-#define MSDC_INTEN_ACMDRDY (0x1 << 3) /* RW */ |
1084 |
+-#define MSDC_INTEN_ACMDTMO (0x1 << 4) /* RW */ |
1085 |
+-#define MSDC_INTEN_ACMDCRCERR (0x1 << 5) /* RW */ |
1086 |
+-#define MSDC_INTEN_DMAQ_EMPTY (0x1 << 6) /* RW */ |
1087 |
+-#define MSDC_INTEN_SDIOIRQ (0x1 << 7) /* RW */ |
1088 |
+-#define MSDC_INTEN_CMDRDY (0x1 << 8) /* RW */ |
1089 |
+-#define MSDC_INTEN_CMDTMO (0x1 << 9) /* RW */ |
1090 |
+-#define MSDC_INTEN_RSPCRCERR (0x1 << 10) /* RW */ |
1091 |
+-#define MSDC_INTEN_CSTA (0x1 << 11) /* RW */ |
1092 |
+-#define MSDC_INTEN_XFER_COMPL (0x1 << 12) /* RW */ |
1093 |
+-#define MSDC_INTEN_DXFER_DONE (0x1 << 13) /* RW */ |
1094 |
+-#define MSDC_INTEN_DATTMO (0x1 << 14) /* RW */ |
1095 |
+-#define MSDC_INTEN_DATCRCERR (0x1 << 15) /* RW */ |
1096 |
+-#define MSDC_INTEN_ACMD19_DONE (0x1 << 16) /* RW */ |
1097 |
+- |
1098 |
+-/* MSDC_FIFOCS mask */ |
1099 |
+-#define MSDC_FIFOCS_RXCNT (0xff << 0) /* R */ |
1100 |
+-#define MSDC_FIFOCS_TXCNT (0xff << 16) /* R */ |
1101 |
+-#define MSDC_FIFOCS_CLR (0x1UL << 31) /* RW */ |
1102 |
+- |
1103 |
+-/* SDC_CFG mask */ |
1104 |
+-#define SDC_CFG_SDIOINTWKUP (0x1 << 0) /* RW */ |
1105 |
+-#define SDC_CFG_INSWKUP (0x1 << 1) /* RW */ |
1106 |
+-#define SDC_CFG_BUSWIDTH (0x3 << 16) /* RW */ |
1107 |
+-#define SDC_CFG_SDIO (0x1 << 19) /* RW */ |
1108 |
+-#define SDC_CFG_SDIOIDE (0x1 << 20) /* RW */ |
1109 |
+-#define SDC_CFG_INTATGAP (0x1 << 21) /* RW */ |
1110 |
+-#define SDC_CFG_DTOC (0xffUL << 24) /* RW */ |
1111 |
+- |
1112 |
+-/* SDC_CMD mask */ |
1113 |
+-#define SDC_CMD_OPC (0x3f << 0) /* RW */ |
1114 |
+-#define SDC_CMD_BRK (0x1 << 6) /* RW */ |
1115 |
+-#define SDC_CMD_RSPTYP (0x7 << 7) /* RW */ |
1116 |
+-#define SDC_CMD_DTYP (0x3 << 11) /* RW */ |
1117 |
+-#define SDC_CMD_DTYP (0x3 << 11) /* RW */ |
1118 |
+-#define SDC_CMD_RW (0x1 << 13) /* RW */ |
1119 |
+-#define SDC_CMD_STOP (0x1 << 14) /* RW */ |
1120 |
+-#define SDC_CMD_GOIRQ (0x1 << 15) /* RW */ |
1121 |
+-#define SDC_CMD_BLKLEN (0xfff << 16) /* RW */ |
1122 |
+-#define SDC_CMD_AUTOCMD (0x3 << 28) /* RW */ |
1123 |
+-#define SDC_CMD_VOLSWTH (0x1 << 30) /* RW */ |
1124 |
+- |
1125 |
+-/* SDC_STS mask */ |
1126 |
+-#define SDC_STS_SDCBUSY (0x1 << 0) /* RW */ |
1127 |
+-#define SDC_STS_CMDBUSY (0x1 << 1) /* RW */ |
1128 |
+-#define SDC_STS_SWR_COMPL (0x1 << 31) /* RW */ |
1129 |
+- |
1130 |
+-/* SDC_DCRC_STS mask */ |
1131 |
+-#define SDC_DCRC_STS_NEG (0xf << 8) /* RO */ |
1132 |
+-#define SDC_DCRC_STS_POS (0xff << 0) /* RO */ |
1133 |
+- |
1134 |
+-/* EMMC_CFG0 mask */ |
1135 |
+-#define EMMC_CFG0_BOOTSTART (0x1 << 0) /* W */ |
1136 |
+-#define EMMC_CFG0_BOOTSTOP (0x1 << 1) /* W */ |
1137 |
+-#define EMMC_CFG0_BOOTMODE (0x1 << 2) /* RW */ |
1138 |
+-#define EMMC_CFG0_BOOTACKDIS (0x1 << 3) /* RW */ |
1139 |
+-#define EMMC_CFG0_BOOTWDLY (0x7 << 12) /* RW */ |
1140 |
+-#define EMMC_CFG0_BOOTSUPP (0x1 << 15) /* RW */ |
1141 |
+- |
1142 |
+-/* EMMC_CFG1 mask */ |
1143 |
+-#define EMMC_CFG1_BOOTDATTMC (0xfffff << 0) /* RW */ |
1144 |
+-#define EMMC_CFG1_BOOTACKTMC (0xfffUL << 20) /* RW */ |
1145 |
+- |
1146 |
+-/* EMMC_STS mask */ |
1147 |
+-#define EMMC_STS_BOOTCRCERR (0x1 << 0) /* W1C */ |
1148 |
+-#define EMMC_STS_BOOTACKERR (0x1 << 1) /* W1C */ |
1149 |
+-#define EMMC_STS_BOOTDATTMO (0x1 << 2) /* W1C */ |
1150 |
+-#define EMMC_STS_BOOTACKTMO (0x1 << 3) /* W1C */ |
1151 |
+-#define EMMC_STS_BOOTUPSTATE (0x1 << 4) /* R */ |
1152 |
+-#define EMMC_STS_BOOTACKRCV (0x1 << 5) /* W1C */ |
1153 |
+-#define EMMC_STS_BOOTDATRCV (0x1 << 6) /* R */ |
1154 |
+- |
1155 |
+-/* EMMC_IOCON mask */ |
1156 |
+-#define EMMC_IOCON_BOOTRST (0x1 << 0) /* RW */ |
1157 |
+- |
1158 |
+-/* SDC_ACMD19_TRG mask */ |
1159 |
+-#define SDC_ACMD19_TRG_TUNESEL (0xf << 0) /* RW */ |
1160 |
+- |
1161 |
+-/* MSDC_DMA_CTRL mask */ |
1162 |
+-#define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ |
1163 |
+-#define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ |
1164 |
+-#define MSDC_DMA_CTRL_RESUME (0x1 << 2) /* W */ |
1165 |
+-#define MSDC_DMA_CTRL_MODE (0x1 << 8) /* RW */ |
1166 |
+-#define MSDC_DMA_CTRL_LASTBUF (0x1 << 10) /* RW */ |
1167 |
+-#define MSDC_DMA_CTRL_BRUSTSZ (0x7 << 12) /* RW */ |
1168 |
+-#define MSDC_DMA_CTRL_XFERSZ (0xffffUL << 16)/* RW */ |
1169 |
+- |
1170 |
+-/* MSDC_DMA_CFG mask */ |
1171 |
+-#define MSDC_DMA_CFG_STS (0x1 << 0) /* R */ |
1172 |
+-#define MSDC_DMA_CFG_DECSEN (0x1 << 1) /* RW */ |
1173 |
+-#define MSDC_DMA_CFG_BDCSERR (0x1 << 4) /* R */ |
1174 |
+-#define MSDC_DMA_CFG_GPDCSERR (0x1 << 5) /* R */ |
1175 |
+- |
1176 |
+-/* MSDC_PATCH_BIT mask */ |
1177 |
+-#define MSDC_PATCH_BIT_WFLSMODE (0x1 << 0) /* RW */ |
1178 |
+-#define MSDC_PATCH_BIT_ODDSUPP (0x1 << 1) /* RW */ |
1179 |
+-#define MSDC_PATCH_BIT_CKGEN_CK (0x1 << 6) /* E2: Fixed to 1 */ |
1180 |
+-#define MSDC_PATCH_BIT_IODSSEL (0x1 << 16) /* RW */ |
1181 |
+-#define MSDC_PATCH_BIT_IOINTSEL (0x1 << 17) /* RW */ |
1182 |
+-#define MSDC_PATCH_BIT_BUSYDLY (0xf << 18) /* RW */ |
1183 |
+-#define MSDC_PATCH_BIT_WDOD (0xf << 22) /* RW */ |
1184 |
+-#define MSDC_PATCH_BIT_IDRTSEL (0x1 << 26) /* RW */ |
1185 |
+-#define MSDC_PATCH_BIT_CMDFSEL (0x1 << 27) /* RW */ |
1186 |
+-#define MSDC_PATCH_BIT_INTDLSEL (0x1 << 28) /* RW */ |
1187 |
+-#define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ |
1188 |
+-#define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ |
1189 |
+- |
1190 |
+-/* MSDC_PATCH_BIT1 mask */ |
1191 |
+-#define MSDC_PATCH_BIT1_WRDAT_CRCS (0x7 << 3) |
1192 |
+-#define MSDC_PATCH_BIT1_CMD_RSP (0x7 << 0) |
1193 |
+- |
1194 |
+-/* MSDC_PAD_CTL0 mask */ |
1195 |
+-#define MSDC_PAD_CTL0_CLKDRVN (0x7 << 0) /* RW */ |
1196 |
+-#define MSDC_PAD_CTL0_CLKDRVP (0x7 << 4) /* RW */ |
1197 |
+-#define MSDC_PAD_CTL0_CLKSR (0x1 << 8) /* RW */ |
1198 |
+-#define MSDC_PAD_CTL0_CLKPD (0x1 << 16) /* RW */ |
1199 |
+-#define MSDC_PAD_CTL0_CLKPU (0x1 << 17) /* RW */ |
1200 |
+-#define MSDC_PAD_CTL0_CLKSMT (0x1 << 18) /* RW */ |
1201 |
+-#define MSDC_PAD_CTL0_CLKIES (0x1 << 19) /* RW */ |
1202 |
+-#define MSDC_PAD_CTL0_CLKTDSEL (0xf << 20) /* RW */ |
1203 |
+-#define MSDC_PAD_CTL0_CLKRDSEL (0xffUL << 24) /* RW */ |
1204 |
+- |
1205 |
+-/* MSDC_PAD_CTL1 mask */ |
1206 |
+-#define MSDC_PAD_CTL1_CMDDRVN (0x7 << 0) /* RW */ |
1207 |
+-#define MSDC_PAD_CTL1_CMDDRVP (0x7 << 4) /* RW */ |
1208 |
+-#define MSDC_PAD_CTL1_CMDSR (0x1 << 8) /* RW */ |
1209 |
+-#define MSDC_PAD_CTL1_CMDPD (0x1 << 16) /* RW */ |
1210 |
+-#define MSDC_PAD_CTL1_CMDPU (0x1 << 17) /* RW */ |
1211 |
+-#define MSDC_PAD_CTL1_CMDSMT (0x1 << 18) /* RW */ |
1212 |
+-#define MSDC_PAD_CTL1_CMDIES (0x1 << 19) /* RW */ |
1213 |
+-#define MSDC_PAD_CTL1_CMDTDSEL (0xf << 20) /* RW */ |
1214 |
+-#define MSDC_PAD_CTL1_CMDRDSEL (0xffUL << 24) /* RW */ |
1215 |
+- |
1216 |
+-/* MSDC_PAD_CTL2 mask */ |
1217 |
+-#define MSDC_PAD_CTL2_DATDRVN (0x7 << 0) /* RW */ |
1218 |
+-#define MSDC_PAD_CTL2_DATDRVP (0x7 << 4) /* RW */ |
1219 |
+-#define MSDC_PAD_CTL2_DATSR (0x1 << 8) /* RW */ |
1220 |
+-#define MSDC_PAD_CTL2_DATPD (0x1 << 16) /* RW */ |
1221 |
+-#define MSDC_PAD_CTL2_DATPU (0x1 << 17) /* RW */ |
1222 |
+-#define MSDC_PAD_CTL2_DATIES (0x1 << 19) /* RW */ |
1223 |
+-#define MSDC_PAD_CTL2_DATSMT (0x1 << 18) /* RW */ |
1224 |
+-#define MSDC_PAD_CTL2_DATTDSEL (0xf << 20) /* RW */ |
1225 |
+-#define MSDC_PAD_CTL2_DATRDSEL (0xffUL << 24) /* RW */ |
1226 |
+- |
1227 |
+-/* MSDC_PAD_TUNE mask */ |
1228 |
+-#define MSDC_PAD_TUNE_DATWRDLY (0x1F << 0) /* RW */ |
1229 |
+-#define MSDC_PAD_TUNE_DATRRDLY (0x1F << 8) /* RW */ |
1230 |
+-#define MSDC_PAD_TUNE_CMDRDLY (0x1F << 16) /* RW */ |
1231 |
+-#define MSDC_PAD_TUNE_CMDRRDLY (0x1FUL << 22) /* RW */ |
1232 |
+-#define MSDC_PAD_TUNE_CLKTXDLY (0x1FUL << 27) /* RW */ |
1233 |
+- |
1234 |
+-/* MSDC_DAT_RDDLY0/1 mask */ |
1235 |
+-#define MSDC_DAT_RDDLY0_D0 (0x1F << 0) /* RW */ |
1236 |
+-#define MSDC_DAT_RDDLY0_D1 (0x1F << 8) /* RW */ |
1237 |
+-#define MSDC_DAT_RDDLY0_D2 (0x1F << 16) /* RW */ |
1238 |
+-#define MSDC_DAT_RDDLY0_D3 (0x1F << 24) /* RW */ |
1239 |
+- |
1240 |
+-#define MSDC_DAT_RDDLY1_D4 (0x1F << 0) /* RW */ |
1241 |
+-#define MSDC_DAT_RDDLY1_D5 (0x1F << 8) /* RW */ |
1242 |
+-#define MSDC_DAT_RDDLY1_D6 (0x1F << 16) /* RW */ |
1243 |
+-#define MSDC_DAT_RDDLY1_D7 (0x1F << 24) /* RW */ |
1244 |
+- |
1245 |
+-#define MSDC_CKGEN_MSDC_DLY_SEL (0x1F << 10) |
1246 |
+-#define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) |
1247 |
+-#define MSDC_CKGEN_MSDC_CK_SEL (0x1 << 6) |
1248 |
+-#define CARD_READY_FOR_DATA (1 << 8) |
1249 |
+-#define CARD_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) |
1250 |
+- |
1251 |
+-/*--------------------------------------------------------------------------*/ |
1252 |
+-/* Descriptor Structure */ |
1253 |
+-/*--------------------------------------------------------------------------*/ |
1254 |
+-struct gpd { |
1255 |
+- u32 hwo:1; /* could be changed by hw */ |
1256 |
+- u32 bdp:1; |
1257 |
+- u32 rsv0:6; |
1258 |
+- u32 chksum:8; |
1259 |
+- u32 intr:1; |
1260 |
+- u32 rsv1:15; |
1261 |
+- void *next; |
1262 |
+- void *ptr; |
1263 |
+- u32 buflen:16; |
1264 |
+- u32 extlen:8; |
1265 |
+- u32 rsv2:8; |
1266 |
+- u32 arg; |
1267 |
+- u32 blknum; |
1268 |
+- u32 cmd; |
1269 |
+-}; |
1270 |
+- |
1271 |
+-struct bd { |
1272 |
+- u32 eol:1; |
1273 |
+- u32 rsv0:7; |
1274 |
+- u32 chksum:8; |
1275 |
+- u32 rsv1:1; |
1276 |
+- u32 blkpad:1; |
1277 |
+- u32 dwpad:1; |
1278 |
+- u32 rsv2:13; |
1279 |
+- void *next; |
1280 |
+- void *ptr; |
1281 |
+- u32 buflen:16; |
1282 |
+- u32 rsv3:16; |
1283 |
+-}; |
1284 |
+- |
1285 |
+-struct msdc_dma { |
1286 |
+- struct gpd *gpd; /* pointer to gpd array */ |
1287 |
+- struct bd *bd; /* pointer to bd array */ |
1288 |
+- dma_addr_t gpd_addr; /* the physical address of gpd array */ |
1289 |
+- dma_addr_t bd_addr; /* the physical address of bd array */ |
1290 |
+-}; |
1291 |
+- |
1292 |
+-struct msdc_host { |
1293 |
+- struct msdc_hw *hw; |
1294 |
+- |
1295 |
+- struct mmc_host *mmc; /* mmc structure */ |
1296 |
+- struct mmc_command *cmd; |
1297 |
+- struct mmc_data *data; |
1298 |
+- struct mmc_request *mrq; |
1299 |
+- int cmd_rsp; |
1300 |
+- |
1301 |
+- int error; |
1302 |
+- spinlock_t lock; /* mutex */ |
1303 |
+- struct semaphore sem; |
1304 |
+- |
1305 |
+- u32 blksz; /* host block size */ |
1306 |
+- void __iomem *base; /* host base address */ |
1307 |
+- int id; /* host id */ |
1308 |
+- int pwr_ref; /* core power reference count */ |
1309 |
+- |
1310 |
+- u32 xfer_size; /* total transferred size */ |
1311 |
+- |
1312 |
+- struct msdc_dma dma; /* dma channel */ |
1313 |
+- u32 dma_xfer_size; /* dma transfer size in bytes */ |
1314 |
+- |
1315 |
+- u32 timeout_ns; /* data timeout ns */ |
1316 |
+- u32 timeout_clks; /* data timeout clks */ |
1317 |
+- |
1318 |
+- int irq; /* host interrupt */ |
1319 |
+- |
1320 |
+- struct delayed_work card_delaywork; |
1321 |
+- |
1322 |
+- struct completion cmd_done; |
1323 |
+- struct completion xfer_done; |
1324 |
+- struct pm_message pm_state; |
1325 |
+- |
1326 |
+- u32 mclk; /* mmc subsystem clock */ |
1327 |
+- u32 hclk; /* host clock speed */ |
1328 |
+- u32 sclk; /* SD/MS clock speed */ |
1329 |
+- u8 core_clkon; /* Host core clock on ? */ |
1330 |
+- u8 card_clkon; /* Card clock on ? */ |
1331 |
+- u8 core_power; /* core power */ |
1332 |
+- u8 power_mode; /* host power mode */ |
1333 |
+- u8 card_inserted; /* card inserted ? */ |
1334 |
+- u8 suspend; /* host suspended ? */ |
1335 |
+- u8 app_cmd; /* for app command */ |
1336 |
+- u32 app_cmd_arg; |
1337 |
+-}; |
1338 |
+- |
1339 |
+-static inline void sdr_set_bits(void __iomem *reg, u32 bs) |
1340 |
+-{ |
1341 |
+- u32 val = readl(reg); |
1342 |
+- |
1343 |
+- val |= bs; |
1344 |
+- writel(val, reg); |
1345 |
+-} |
1346 |
+- |
1347 |
+-static inline void sdr_clr_bits(void __iomem *reg, u32 bs) |
1348 |
+-{ |
1349 |
+- u32 val = readl(reg); |
1350 |
+- |
1351 |
+- val &= ~bs; |
1352 |
+- writel(val, reg); |
1353 |
+-} |
1354 |
+- |
1355 |
+-static inline void sdr_set_field(void __iomem *reg, u32 field, u32 val) |
1356 |
+-{ |
1357 |
+- unsigned int tv = readl(reg); |
1358 |
+- |
1359 |
+- tv &= ~field; |
1360 |
+- tv |= ((val) << (ffs((unsigned int)field) - 1)); |
1361 |
+- writel(tv, reg); |
1362 |
+-} |
1363 |
+- |
1364 |
+-static inline void sdr_get_field(void __iomem *reg, u32 field, u32 *val) |
1365 |
+-{ |
1366 |
+- unsigned int tv = readl(reg); |
1367 |
+- *val = ((tv & field) >> (ffs((unsigned int)field) - 1)); |
1368 |
+-} |
1369 |
+- |
1370 |
+-#endif |
1371 |
+diff --git a/drivers/staging/mt7621-mmc/sd.c b/drivers/staging/mt7621-mmc/sd.c |
1372 |
+deleted file mode 100644 |
1373 |
+index 04d23cc7cd4a6..0000000000000 |
1374 |
+--- a/drivers/staging/mt7621-mmc/sd.c |
1375 |
++++ /dev/null |
1376 |
+@@ -1,2392 +0,0 @@ |
1377 |
+-/* Copyright Statement: |
1378 |
+- * |
1379 |
+- * This software/firmware and related documentation ("MediaTek Software") are |
1380 |
+- * protected under relevant copyright laws. The information contained herein |
1381 |
+- * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
1382 |
+- * Without the prior written permission of MediaTek inc. and/or its licensors, |
1383 |
+- * any reproduction, modification, use or disclosure of MediaTek Software, |
1384 |
+- * and information contained herein, in whole or in part, shall be strictly prohibited. |
1385 |
+- * |
1386 |
+- * MediaTek Inc. (C) 2010. All rights reserved. |
1387 |
+- * |
1388 |
+- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
1389 |
+- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
1390 |
+- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
1391 |
+- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
1392 |
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
1393 |
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
1394 |
+- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
1395 |
+- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
1396 |
+- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
1397 |
+- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
1398 |
+- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
1399 |
+- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
1400 |
+- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
1401 |
+- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
1402 |
+- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
1403 |
+- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
1404 |
+- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
1405 |
+- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
1406 |
+- * |
1407 |
+- * The following software/firmware and/or related documentation ("MediaTek Software") |
1408 |
+- * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
1409 |
+- * applicable license agreements with MediaTek Inc. |
1410 |
+- */ |
1411 |
+- |
1412 |
+-#include <linux/module.h> |
1413 |
+-#include <linux/delay.h> |
1414 |
+-#include <linux/dma-mapping.h> |
1415 |
+-#include <linux/spinlock.h> |
1416 |
+-#include <linux/platform_device.h> |
1417 |
+- |
1418 |
+-#include <linux/mmc/host.h> |
1419 |
+-#include <linux/mmc/mmc.h> |
1420 |
+-#include <linux/mmc/sd.h> |
1421 |
+-#include <linux/mmc/sdio.h> |
1422 |
+- |
1423 |
+-#include <asm/mach-ralink/ralink_regs.h> |
1424 |
+- |
1425 |
+-#include "board.h" |
1426 |
+-#include "dbg.h" |
1427 |
+-#include "mt6575_sd.h" |
1428 |
+- |
1429 |
+-#ifdef CONFIG_SOC_MT7621 |
1430 |
+-#define RALINK_SYSCTL_BASE 0xbe000000 |
1431 |
+-#else |
1432 |
+-#define RALINK_SYSCTL_BASE 0xb0000000 |
1433 |
+-#endif |
1434 |
+- |
1435 |
+-#define DRV_NAME "mtk-sd" |
1436 |
+- |
1437 |
+-#if defined(CONFIG_SOC_MT7620) |
1438 |
+-#define HOST_MAX_MCLK (48000000) /* +/- by chhung */ |
1439 |
+-#elif defined(CONFIG_SOC_MT7621) |
1440 |
+-#define HOST_MAX_MCLK (50000000) /* +/- by chhung */ |
1441 |
+-#endif |
1442 |
+-#define HOST_MIN_MCLK (260000) |
1443 |
+- |
1444 |
+-#define HOST_MAX_BLKSZ (2048) |
1445 |
+- |
1446 |
+-#define MSDC_OCR_AVAIL (MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33) |
1447 |
+- |
1448 |
+-#define GPIO_PULL_DOWN (0) |
1449 |
+-#define GPIO_PULL_UP (1) |
1450 |
+- |
1451 |
+-#if 0 /* --- by chhung */ |
1452 |
+-#define MSDC_CLKSRC_REG (0xf100000C) |
1453 |
+-#define PDN_REG (0xF1000010) |
1454 |
+-#endif /* end of --- */ |
1455 |
+- |
1456 |
+-#define DEFAULT_DEBOUNCE (8) /* 8 cycles */ |
1457 |
+-#define DEFAULT_DTOC (40) /* data timeout counter. 65536x40 sclk. */ |
1458 |
+- |
1459 |
+-#define CMD_TIMEOUT (HZ / 10) /* 100ms */ |
1460 |
+-#define DAT_TIMEOUT (HZ / 2 * 5) /* 500ms x5 */ |
1461 |
+- |
1462 |
+-#define MAX_DMA_CNT (64 * 1024 - 512) /* a single transaction for WIFI may be 50K*/ |
1463 |
+- |
1464 |
+-#define MAX_GPD_NUM (1 + 1) /* one null gpd */ |
1465 |
+-#define MAX_BD_NUM (1024) |
1466 |
+- |
1467 |
+-#define MAX_HW_SGMTS (MAX_BD_NUM) |
1468 |
+-#define MAX_SGMT_SZ (MAX_DMA_CNT) |
1469 |
+-#define MAX_REQ_SZ (MAX_SGMT_SZ * 8) |
1470 |
+- |
1471 |
+-static int cd_active_low = 1; |
1472 |
+- |
1473 |
+-//================================= |
1474 |
+-#define PERI_MSDC0_PDN (15) |
1475 |
+-//#define PERI_MSDC1_PDN (16) |
1476 |
+-//#define PERI_MSDC2_PDN (17) |
1477 |
+-//#define PERI_MSDC3_PDN (18) |
1478 |
+- |
1479 |
+-#if 0 /* --- by chhung */ |
1480 |
+-/* gate means clock power down */ |
1481 |
+-static int g_clk_gate = 0; |
1482 |
+-#define msdc_gate_clock(id) \ |
1483 |
+- do { \ |
1484 |
+- g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN)); \ |
1485 |
+- } while (0) |
1486 |
+-/* not like power down register. 1 means clock on. */ |
1487 |
+-#define msdc_ungate_clock(id) \ |
1488 |
+- do { \ |
1489 |
+- g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN); \ |
1490 |
+- } while (0) |
1491 |
+- |
1492 |
+-// do we need sync object or not |
1493 |
+-void msdc_clk_status(int *status) |
1494 |
+-{ |
1495 |
+- *status = g_clk_gate; |
1496 |
+-} |
1497 |
+-#endif /* end of --- */ |
1498 |
+- |
1499 |
+-/* +++ by chhung */ |
1500 |
+-struct msdc_hw msdc0_hw = { |
1501 |
+- .clk_src = 0, |
1502 |
+- .flags = MSDC_CD_PIN_EN | MSDC_REMOVABLE, |
1503 |
+-// .flags = MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE, |
1504 |
+-}; |
1505 |
+- |
1506 |
+-/* end of +++ */ |
1507 |
+- |
1508 |
+-static int msdc_rsp[] = { |
1509 |
+- 0, /* RESP_NONE */ |
1510 |
+- 1, /* RESP_R1 */ |
1511 |
+- 2, /* RESP_R2 */ |
1512 |
+- 3, /* RESP_R3 */ |
1513 |
+- 4, /* RESP_R4 */ |
1514 |
+- 1, /* RESP_R5 */ |
1515 |
+- 1, /* RESP_R6 */ |
1516 |
+- 1, /* RESP_R7 */ |
1517 |
+- 7, /* RESP_R1b */ |
1518 |
+-}; |
1519 |
+- |
1520 |
+-#define msdc_dma_on() sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_PIO) |
1521 |
+- |
1522 |
+-static void msdc_reset_hw(struct msdc_host *host) |
1523 |
+-{ |
1524 |
+- sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); |
1525 |
+- while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST) |
1526 |
+- cpu_relax(); |
1527 |
+-} |
1528 |
+- |
1529 |
+-#define msdc_clr_int() \ |
1530 |
+- do { \ |
1531 |
+- volatile u32 val = readl(host->base + MSDC_INT); \ |
1532 |
+- writel(val, host->base + MSDC_INT); \ |
1533 |
+- } while (0) |
1534 |
+- |
1535 |
+-static void msdc_clr_fifo(struct msdc_host *host) |
1536 |
+-{ |
1537 |
+- sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); |
1538 |
+- while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR) |
1539 |
+- cpu_relax(); |
1540 |
+-} |
1541 |
+- |
1542 |
+-#define msdc_irq_save(val) \ |
1543 |
+- do { \ |
1544 |
+- val = readl(host->base + MSDC_INTEN); \ |
1545 |
+- sdr_clr_bits(host->base + MSDC_INTEN, val); \ |
1546 |
+- } while (0) |
1547 |
+- |
1548 |
+-#define msdc_irq_restore(val) \ |
1549 |
+- do { \ |
1550 |
+- sdr_set_bits(host->base + MSDC_INTEN, val); \ |
1551 |
+- } while (0) |
1552 |
+- |
1553 |
+-/* clock source for host: global */ |
1554 |
+-#if defined(CONFIG_SOC_MT7620) |
1555 |
+-static u32 hclks[] = {48000000}; /* +/- by chhung */ |
1556 |
+-#elif defined(CONFIG_SOC_MT7621) |
1557 |
+-static u32 hclks[] = {50000000}; /* +/- by chhung */ |
1558 |
+-#endif |
1559 |
+- |
1560 |
+-//============================================ |
1561 |
+-// the power for msdc host controller: global |
1562 |
+-// always keep the VMC on. |
1563 |
+-//============================================ |
1564 |
+-#define msdc_vcore_on(host) \ |
1565 |
+- do { \ |
1566 |
+- INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref); \ |
1567 |
+- (void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD"); \ |
1568 |
+- } while (0) |
1569 |
+-#define msdc_vcore_off(host) \ |
1570 |
+- do { \ |
1571 |
+- INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref); \ |
1572 |
+- (void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD"); \ |
1573 |
+- } while (0) |
1574 |
+- |
1575 |
+-//==================================== |
1576 |
+-// the vdd output for card: global |
1577 |
+-// always keep the VMCH on. |
1578 |
+-//==================================== |
1579 |
+-#define msdc_vdd_on(host) \ |
1580 |
+- do { \ |
1581 |
+- (void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \ |
1582 |
+- } while (0) |
1583 |
+-#define msdc_vdd_off(host) \ |
1584 |
+- do { \ |
1585 |
+- (void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \ |
1586 |
+- } while (0) |
1587 |
+- |
1588 |
+-#define sdc_is_busy() (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) |
1589 |
+-#define sdc_is_cmd_busy() (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) |
1590 |
+- |
1591 |
+-#define sdc_send_cmd(cmd, arg) \ |
1592 |
+- do { \ |
1593 |
+- writel((arg), host->base + SDC_ARG); \ |
1594 |
+- writel((cmd), host->base + SDC_CMD); \ |
1595 |
+- } while (0) |
1596 |
+- |
1597 |
+-/* +++ by chhung */ |
1598 |
+-#ifndef __ASSEMBLY__ |
1599 |
+-#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) |
1600 |
+-#else |
1601 |
+-#define PHYSADDR(a) ((a) & 0x1fffffff) |
1602 |
+-#endif |
1603 |
+-/* end of +++ */ |
1604 |
+-static unsigned int msdc_do_command(struct msdc_host *host, |
1605 |
+- struct mmc_command *cmd, |
1606 |
+- int tune, |
1607 |
+- unsigned long timeout); |
1608 |
+- |
1609 |
+-static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd); |
1610 |
+- |
1611 |
+-#ifdef MT6575_SD_DEBUG |
1612 |
+-static void msdc_dump_card_status(struct msdc_host *host, u32 status) |
1613 |
+-{ |
1614 |
+-/* N_MSG is currently a no-op */ |
1615 |
+-#if 0 |
1616 |
+- static char *state[] = { |
1617 |
+- "Idle", /* 0 */ |
1618 |
+- "Ready", /* 1 */ |
1619 |
+- "Ident", /* 2 */ |
1620 |
+- "Stby", /* 3 */ |
1621 |
+- "Tran", /* 4 */ |
1622 |
+- "Data", /* 5 */ |
1623 |
+- "Rcv", /* 6 */ |
1624 |
+- "Prg", /* 7 */ |
1625 |
+- "Dis", /* 8 */ |
1626 |
+- "Reserved", /* 9 */ |
1627 |
+- "Reserved", /* 10 */ |
1628 |
+- "Reserved", /* 11 */ |
1629 |
+- "Reserved", /* 12 */ |
1630 |
+- "Reserved", /* 13 */ |
1631 |
+- "Reserved", /* 14 */ |
1632 |
+- "I/O mode", /* 15 */ |
1633 |
+- }; |
1634 |
+-#endif |
1635 |
+- if (status & R1_OUT_OF_RANGE) |
1636 |
+- N_MSG(RSP, "[CARD_STATUS] Out of Range"); |
1637 |
+- if (status & R1_ADDRESS_ERROR) |
1638 |
+- N_MSG(RSP, "[CARD_STATUS] Address Error"); |
1639 |
+- if (status & R1_BLOCK_LEN_ERROR) |
1640 |
+- N_MSG(RSP, "[CARD_STATUS] Block Len Error"); |
1641 |
+- if (status & R1_ERASE_SEQ_ERROR) |
1642 |
+- N_MSG(RSP, "[CARD_STATUS] Erase Seq Error"); |
1643 |
+- if (status & R1_ERASE_PARAM) |
1644 |
+- N_MSG(RSP, "[CARD_STATUS] Erase Param"); |
1645 |
+- if (status & R1_WP_VIOLATION) |
1646 |
+- N_MSG(RSP, "[CARD_STATUS] WP Violation"); |
1647 |
+- if (status & R1_CARD_IS_LOCKED) |
1648 |
+- N_MSG(RSP, "[CARD_STATUS] Card is Locked"); |
1649 |
+- if (status & R1_LOCK_UNLOCK_FAILED) |
1650 |
+- N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed"); |
1651 |
+- if (status & R1_COM_CRC_ERROR) |
1652 |
+- N_MSG(RSP, "[CARD_STATUS] Command CRC Error"); |
1653 |
+- if (status & R1_ILLEGAL_COMMAND) |
1654 |
+- N_MSG(RSP, "[CARD_STATUS] Illegal Command"); |
1655 |
+- if (status & R1_CARD_ECC_FAILED) |
1656 |
+- N_MSG(RSP, "[CARD_STATUS] Card ECC Failed"); |
1657 |
+- if (status & R1_CC_ERROR) |
1658 |
+- N_MSG(RSP, "[CARD_STATUS] CC Error"); |
1659 |
+- if (status & R1_ERROR) |
1660 |
+- N_MSG(RSP, "[CARD_STATUS] Error"); |
1661 |
+- if (status & R1_UNDERRUN) |
1662 |
+- N_MSG(RSP, "[CARD_STATUS] Underrun"); |
1663 |
+- if (status & R1_OVERRUN) |
1664 |
+- N_MSG(RSP, "[CARD_STATUS] Overrun"); |
1665 |
+- if (status & R1_CID_CSD_OVERWRITE) |
1666 |
+- N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite"); |
1667 |
+- if (status & R1_WP_ERASE_SKIP) |
1668 |
+- N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip"); |
1669 |
+- if (status & R1_CARD_ECC_DISABLED) |
1670 |
+- N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled"); |
1671 |
+- if (status & R1_ERASE_RESET) |
1672 |
+- N_MSG(RSP, "[CARD_STATUS] Erase Reset"); |
1673 |
+- if (status & R1_READY_FOR_DATA) |
1674 |
+- N_MSG(RSP, "[CARD_STATUS] Ready for Data"); |
1675 |
+- if (status & R1_SWITCH_ERROR) |
1676 |
+- N_MSG(RSP, "[CARD_STATUS] Switch error"); |
1677 |
+- if (status & R1_APP_CMD) |
1678 |
+- N_MSG(RSP, "[CARD_STATUS] App Command"); |
1679 |
+- |
1680 |
+- N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]); |
1681 |
+-} |
1682 |
+- |
1683 |
+-static void msdc_dump_ocr_reg(struct msdc_host *host, u32 resp) |
1684 |
+-{ |
1685 |
+- if (resp & (1 << 7)) |
1686 |
+- N_MSG(RSP, "[OCR] Low Voltage Range"); |
1687 |
+- if (resp & (1 << 15)) |
1688 |
+- N_MSG(RSP, "[OCR] 2.7-2.8 volt"); |
1689 |
+- if (resp & (1 << 16)) |
1690 |
+- N_MSG(RSP, "[OCR] 2.8-2.9 volt"); |
1691 |
+- if (resp & (1 << 17)) |
1692 |
+- N_MSG(RSP, "[OCR] 2.9-3.0 volt"); |
1693 |
+- if (resp & (1 << 18)) |
1694 |
+- N_MSG(RSP, "[OCR] 3.0-3.1 volt"); |
1695 |
+- if (resp & (1 << 19)) |
1696 |
+- N_MSG(RSP, "[OCR] 3.1-3.2 volt"); |
1697 |
+- if (resp & (1 << 20)) |
1698 |
+- N_MSG(RSP, "[OCR] 3.2-3.3 volt"); |
1699 |
+- if (resp & (1 << 21)) |
1700 |
+- N_MSG(RSP, "[OCR] 3.3-3.4 volt"); |
1701 |
+- if (resp & (1 << 22)) |
1702 |
+- N_MSG(RSP, "[OCR] 3.4-3.5 volt"); |
1703 |
+- if (resp & (1 << 23)) |
1704 |
+- N_MSG(RSP, "[OCR] 3.5-3.6 volt"); |
1705 |
+- if (resp & (1 << 24)) |
1706 |
+- N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)"); |
1707 |
+- if (resp & (1 << 30)) |
1708 |
+- N_MSG(RSP, "[OCR] Card Capacity Status (CCS)"); |
1709 |
+- if (resp & (1 << 31)) |
1710 |
+- N_MSG(RSP, "[OCR] Card Power Up Status (Idle)"); |
1711 |
+- else |
1712 |
+- N_MSG(RSP, "[OCR] Card Power Up Status (Busy)"); |
1713 |
+-} |
1714 |
+- |
1715 |
+-static void msdc_dump_rca_resp(struct msdc_host *host, u32 resp) |
1716 |
+-{ |
1717 |
+- u32 status = (((resp >> 15) & 0x1) << 23) | |
1718 |
+- (((resp >> 14) & 0x1) << 22) | |
1719 |
+- (((resp >> 13) & 0x1) << 19) | |
1720 |
+- (resp & 0x1fff); |
1721 |
+- |
1722 |
+- N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16); |
1723 |
+- msdc_dump_card_status(host, status); |
1724 |
+-} |
1725 |
+- |
1726 |
+-static void msdc_dump_io_resp(struct msdc_host *host, u32 resp) |
1727 |
+-{ |
1728 |
+- u32 flags = (resp >> 8) & 0xFF; |
1729 |
+-#if 0 |
1730 |
+- char *state[] = {"DIS", "CMD", "TRN", "RFU"}; |
1731 |
+-#endif |
1732 |
+- if (flags & (1 << 7)) |
1733 |
+- N_MSG(RSP, "[IO] COM_CRC_ERR"); |
1734 |
+- if (flags & (1 << 6)) |
1735 |
+- N_MSG(RSP, "[IO] Illegal command"); |
1736 |
+- if (flags & (1 << 3)) |
1737 |
+- N_MSG(RSP, "[IO] Error"); |
1738 |
+- if (flags & (1 << 2)) |
1739 |
+- N_MSG(RSP, "[IO] RFU"); |
1740 |
+- if (flags & (1 << 1)) |
1741 |
+- N_MSG(RSP, "[IO] Function number error"); |
1742 |
+- if (flags & (1 << 0)) |
1743 |
+- N_MSG(RSP, "[IO] Out of range"); |
1744 |
+- |
1745 |
+- N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF); |
1746 |
+-} |
1747 |
+-#endif |
1748 |
+- |
1749 |
+-static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) |
1750 |
+-{ |
1751 |
+- u32 timeout, clk_ns; |
1752 |
+- |
1753 |
+- host->timeout_ns = ns; |
1754 |
+- host->timeout_clks = clks; |
1755 |
+- |
1756 |
+- clk_ns = 1000000000UL / host->sclk; |
1757 |
+- timeout = ns / clk_ns + clks; |
1758 |
+- timeout = timeout >> 16; /* in 65536 sclk cycle unit */ |
1759 |
+- timeout = timeout > 1 ? timeout - 1 : 0; |
1760 |
+- timeout = timeout > 255 ? 255 : timeout; |
1761 |
+- |
1762 |
+- sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, timeout); |
1763 |
+- |
1764 |
+- N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles", |
1765 |
+- ns, clks, timeout + 1); |
1766 |
+-} |
1767 |
+- |
1768 |
+-static void msdc_tasklet_card(struct work_struct *work) |
1769 |
+-{ |
1770 |
+- struct msdc_host *host = (struct msdc_host *)container_of(work, |
1771 |
+- struct msdc_host, card_delaywork.work); |
1772 |
+- u32 inserted; |
1773 |
+- u32 status = 0; |
1774 |
+- //u32 change = 0; |
1775 |
+- |
1776 |
+- spin_lock(&host->lock); |
1777 |
+- |
1778 |
+- status = readl(host->base + MSDC_PS); |
1779 |
+- if (cd_active_low) |
1780 |
+- inserted = (status & MSDC_PS_CDSTS) ? 0 : 1; |
1781 |
+- else |
1782 |
+- inserted = (status & MSDC_PS_CDSTS) ? 1 : 0; |
1783 |
+- |
1784 |
+-#if 0 |
1785 |
+- change = host->card_inserted ^ inserted; |
1786 |
+- host->card_inserted = inserted; |
1787 |
+- |
1788 |
+- if (change && !host->suspend) { |
1789 |
+- if (inserted) |
1790 |
+- host->mmc->f_max = HOST_MAX_MCLK; // work around |
1791 |
+- mmc_detect_change(host->mmc, msecs_to_jiffies(20)); |
1792 |
+- } |
1793 |
+-#else /* Make sure: handle the last interrupt */ |
1794 |
+- host->card_inserted = inserted; |
1795 |
+- |
1796 |
+- if (!host->suspend) { |
1797 |
+- host->mmc->f_max = HOST_MAX_MCLK; |
1798 |
+- mmc_detect_change(host->mmc, msecs_to_jiffies(20)); |
1799 |
+- } |
1800 |
+- |
1801 |
+- IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); |
1802 |
+-#endif |
1803 |
+- |
1804 |
+- spin_unlock(&host->lock); |
1805 |
+-} |
1806 |
+- |
1807 |
+-#if 0 /* --- by chhung */ |
1808 |
+-/* For E2 only */ |
1809 |
+-static u8 clk_src_bit[4] = { |
1810 |
+- 0, 3, 5, 7 |
1811 |
+-}; |
1812 |
+- |
1813 |
+-static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc) |
1814 |
+-{ |
1815 |
+- u32 val; |
1816 |
+- |
1817 |
+- BUG_ON(clksrc > 3); |
1818 |
+- INIT_MSG("set clock source to <%d>", clksrc); |
1819 |
+- |
1820 |
+- val = readl(host->base + MSDC_CLKSRC_REG); |
1821 |
+- if (readl(host->base + MSDC_ECO_VER) >= 4) { |
1822 |
+- val &= ~(0x3 << clk_src_bit[host->id]); |
1823 |
+- val |= clksrc << clk_src_bit[host->id]; |
1824 |
+- } else { |
1825 |
+- val &= ~0x3; val |= clksrc; |
1826 |
+- } |
1827 |
+- writel(val, host->base + MSDC_CLKSRC_REG); |
1828 |
+- |
1829 |
+- host->hclk = hclks[clksrc]; |
1830 |
+- host->hw->clk_src = clksrc; |
1831 |
+-} |
1832 |
+-#endif /* end of --- */ |
1833 |
+- |
1834 |
+-static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz) |
1835 |
+-{ |
1836 |
+- //struct msdc_hw *hw = host->hw; |
1837 |
+- u32 mode; |
1838 |
+- u32 flags; |
1839 |
+- u32 div; |
1840 |
+- u32 sclk; |
1841 |
+- u32 hclk = host->hclk; |
1842 |
+- //u8 clksrc = hw->clk_src; |
1843 |
+- |
1844 |
+- if (!hz) { // set mmc system clock to 0 ? |
1845 |
+- //ERR_MSG("set mclk to 0!!!"); |
1846 |
+- msdc_reset_hw(host); |
1847 |
+- return; |
1848 |
+- } |
1849 |
+- |
1850 |
+- msdc_irq_save(flags); |
1851 |
+- |
1852 |
+- if (ddr) { |
1853 |
+- mode = 0x2; /* ddr mode and use divisor */ |
1854 |
+- if (hz >= (hclk >> 2)) { |
1855 |
+- div = 1; /* mean div = 1/4 */ |
1856 |
+- sclk = hclk >> 2; /* sclk = clk / 4 */ |
1857 |
+- } else { |
1858 |
+- div = (hclk + ((hz << 2) - 1)) / (hz << 2); |
1859 |
+- sclk = (hclk >> 2) / div; |
1860 |
+- } |
1861 |
+- } else if (hz >= hclk) { /* bug fix */ |
1862 |
+- mode = 0x1; /* no divisor and divisor is ignored */ |
1863 |
+- div = 0; |
1864 |
+- sclk = hclk; |
1865 |
+- } else { |
1866 |
+- mode = 0x0; /* use divisor */ |
1867 |
+- if (hz >= (hclk >> 1)) { |
1868 |
+- div = 0; /* mean div = 1/2 */ |
1869 |
+- sclk = hclk >> 1; /* sclk = clk / 2 */ |
1870 |
+- } else { |
1871 |
+- div = (hclk + ((hz << 2) - 1)) / (hz << 2); |
1872 |
+- sclk = (hclk >> 2) / div; |
1873 |
+- } |
1874 |
+- } |
1875 |
+- |
1876 |
+- /* set clock mode and divisor */ |
1877 |
+- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, mode); |
1878 |
+- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKDIV, div); |
1879 |
+- |
1880 |
+- /* wait clock stable */ |
1881 |
+- while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) |
1882 |
+- cpu_relax(); |
1883 |
+- |
1884 |
+- host->sclk = sclk; |
1885 |
+- host->mclk = hz; |
1886 |
+- msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need? |
1887 |
+- |
1888 |
+- INIT_MSG("================"); |
1889 |
+- INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz / 1000, hclk / 1000, sclk / 1000); |
1890 |
+- INIT_MSG("================"); |
1891 |
+- |
1892 |
+- msdc_irq_restore(flags); |
1893 |
+-} |
1894 |
+- |
1895 |
+-/* Fix me. when need to abort */ |
1896 |
+-static void msdc_abort_data(struct msdc_host *host) |
1897 |
+-{ |
1898 |
+- struct mmc_command *stop = host->mrq->stop; |
1899 |
+- |
1900 |
+- ERR_MSG("Need to Abort."); |
1901 |
+- |
1902 |
+- msdc_reset_hw(host); |
1903 |
+- msdc_clr_fifo(host); |
1904 |
+- msdc_clr_int(); |
1905 |
+- |
1906 |
+- // need to check FIFO count 0 ? |
1907 |
+- |
1908 |
+- if (stop) { /* try to stop, but may not success */ |
1909 |
+- ERR_MSG("stop when abort CMD<%d>", stop->opcode); |
1910 |
+- (void)msdc_do_command(host, stop, 0, CMD_TIMEOUT); |
1911 |
+- } |
1912 |
+- |
1913 |
+- //if (host->mclk >= 25000000) { |
1914 |
+- // msdc_set_mclk(host, 0, host->mclk >> 1); |
1915 |
+- //} |
1916 |
+-} |
1917 |
+- |
1918 |
+-#if 0 /* --- by chhung */ |
1919 |
+-static void msdc_pin_config(struct msdc_host *host, int mode) |
1920 |
+-{ |
1921 |
+- struct msdc_hw *hw = host->hw; |
1922 |
+- int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; |
1923 |
+- |
1924 |
+- /* Config WP pin */ |
1925 |
+- if (hw->flags & MSDC_WP_PIN_EN) { |
1926 |
+- if (hw->config_gpio_pin) /* NULL */ |
1927 |
+- hw->config_gpio_pin(MSDC_WP_PIN, pull); |
1928 |
+- } |
1929 |
+- |
1930 |
+- switch (mode) { |
1931 |
+- case MSDC_PIN_PULL_UP: |
1932 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */ |
1933 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ |
1934 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1); |
1935 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); |
1936 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1); |
1937 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); |
1938 |
+- break; |
1939 |
+- case MSDC_PIN_PULL_DOWN: |
1940 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ |
1941 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */ |
1942 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); |
1943 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1); |
1944 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); |
1945 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1); |
1946 |
+- break; |
1947 |
+- case MSDC_PIN_PULL_NONE: |
1948 |
+- default: |
1949 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ |
1950 |
+- //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ |
1951 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); |
1952 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); |
1953 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); |
1954 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); |
1955 |
+- break; |
1956 |
+- } |
1957 |
+- |
1958 |
+- N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)", |
1959 |
+- mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP); |
1960 |
+-} |
1961 |
+- |
1962 |
+-void msdc_pin_reset(struct msdc_host *host, int mode) |
1963 |
+-{ |
1964 |
+- struct msdc_hw *hw = (struct msdc_hw *)host->hw; |
1965 |
+- int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; |
1966 |
+- |
1967 |
+- /* Config reset pin */ |
1968 |
+- if (hw->flags & MSDC_RST_PIN_EN) { |
1969 |
+- if (hw->config_gpio_pin) /* NULL */ |
1970 |
+- hw->config_gpio_pin(MSDC_RST_PIN, pull); |
1971 |
+- |
1972 |
+- if (mode == MSDC_PIN_PULL_UP) |
1973 |
+- sdr_clr_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST); |
1974 |
+- else |
1975 |
+- sdr_set_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST); |
1976 |
+- } |
1977 |
+-} |
1978 |
+- |
1979 |
+-static void msdc_core_power(struct msdc_host *host, int on) |
1980 |
+-{ |
1981 |
+- N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)", |
1982 |
+- on ? "on" : "off", "core", host->core_power, on); |
1983 |
+- |
1984 |
+- if (on && host->core_power == 0) { |
1985 |
+- msdc_vcore_on(host); |
1986 |
+- host->core_power = 1; |
1987 |
+- msleep(1); |
1988 |
+- } else if (!on && host->core_power == 1) { |
1989 |
+- msdc_vcore_off(host); |
1990 |
+- host->core_power = 0; |
1991 |
+- msleep(1); |
1992 |
+- } |
1993 |
+-} |
1994 |
+- |
1995 |
+-static void msdc_host_power(struct msdc_host *host, int on) |
1996 |
+-{ |
1997 |
+- N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host"); |
1998 |
+- |
1999 |
+- if (on) { |
2000 |
+- //msdc_core_power(host, 1); // need do card detection. |
2001 |
+- msdc_pin_reset(host, MSDC_PIN_PULL_UP); |
2002 |
+- } else { |
2003 |
+- msdc_pin_reset(host, MSDC_PIN_PULL_DOWN); |
2004 |
+- //msdc_core_power(host, 0); |
2005 |
+- } |
2006 |
+-} |
2007 |
+- |
2008 |
+-static void msdc_card_power(struct msdc_host *host, int on) |
2009 |
+-{ |
2010 |
+- N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card"); |
2011 |
+- |
2012 |
+- if (on) { |
2013 |
+- msdc_pin_config(host, MSDC_PIN_PULL_UP); |
2014 |
+- //msdc_vdd_on(host); // need todo card detection. |
2015 |
+- msleep(1); |
2016 |
+- } else { |
2017 |
+- //msdc_vdd_off(host); |
2018 |
+- msdc_pin_config(host, MSDC_PIN_PULL_DOWN); |
2019 |
+- msleep(1); |
2020 |
+- } |
2021 |
+-} |
2022 |
+- |
2023 |
+-static void msdc_set_power_mode(struct msdc_host *host, u8 mode) |
2024 |
+-{ |
2025 |
+- N_MSG(CFG, "Set power mode(%d)", mode); |
2026 |
+- |
2027 |
+- if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) { |
2028 |
+- msdc_host_power(host, 1); |
2029 |
+- msdc_card_power(host, 1); |
2030 |
+- } else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) { |
2031 |
+- msdc_card_power(host, 0); |
2032 |
+- msdc_host_power(host, 0); |
2033 |
+- } |
2034 |
+- host->power_mode = mode; |
2035 |
+-} |
2036 |
+-#endif /* end of --- */ |
2037 |
+- |
2038 |
+-#ifdef CONFIG_PM |
2039 |
+-/* |
2040 |
+- register as callback function of WIFI(combo_sdio_register_pm) . |
2041 |
+- can called by msdc_drv_suspend/resume too. |
2042 |
+-*/ |
2043 |
+-static void msdc_pm(pm_message_t state, void *data) |
2044 |
+-{ |
2045 |
+- struct msdc_host *host = (struct msdc_host *)data; |
2046 |
+- int evt = state.event; |
2047 |
+- |
2048 |
+- if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) { |
2049 |
+- INIT_MSG("USR_%s: suspend<%d> power<%d>", |
2050 |
+- evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND", |
2051 |
+- host->suspend, host->power_mode); |
2052 |
+- } |
2053 |
+- |
2054 |
+- if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) { |
2055 |
+- if (host->suspend) /* already suspend */ /* default 0*/ |
2056 |
+- return; |
2057 |
+- |
2058 |
+- /* for memory card. already power off by mmc */ |
2059 |
+- if (evt == PM_EVENT_SUSPEND && host->power_mode == MMC_POWER_OFF) |
2060 |
+- return; |
2061 |
+- |
2062 |
+- host->suspend = 1; |
2063 |
+- host->pm_state = state; /* default PMSG_RESUME */ |
2064 |
+- |
2065 |
+- } else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) { |
2066 |
+- if (!host->suspend) { |
2067 |
+- //ERR_MSG("warning: already resume"); |
2068 |
+- return; |
2069 |
+- } |
2070 |
+- |
2071 |
+- /* No PM resume when USR suspend */ |
2072 |
+- if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) { |
2073 |
+- ERR_MSG("PM Resume when in USR Suspend"); /* won't happen. */ |
2074 |
+- return; |
2075 |
+- } |
2076 |
+- |
2077 |
+- host->suspend = 0; |
2078 |
+- host->pm_state = state; |
2079 |
+- |
2080 |
+- } |
2081 |
+-} |
2082 |
+-#endif |
2083 |
+- |
2084 |
+-static inline u32 msdc_cmd_find_resp(struct mmc_command *cmd) |
2085 |
+-{ |
2086 |
+- u32 opcode = cmd->opcode; |
2087 |
+- u32 resp; |
2088 |
+- |
2089 |
+- if (opcode == MMC_SET_RELATIVE_ADDR) { |
2090 |
+- resp = (mmc_cmd_type(cmd) == MMC_CMD_BCR) ? RESP_R6 : RESP_R1; |
2091 |
+- } else if (opcode == MMC_FAST_IO) { |
2092 |
+- resp = RESP_R4; |
2093 |
+- } else if (opcode == MMC_GO_IRQ_STATE) { |
2094 |
+- resp = RESP_R5; |
2095 |
+- } else if (opcode == MMC_SELECT_CARD) { |
2096 |
+- resp = (cmd->arg != 0) ? RESP_R1B : RESP_NONE; |
2097 |
+- } else if (opcode == SD_IO_RW_DIRECT || opcode == SD_IO_RW_EXTENDED) { |
2098 |
+- resp = RESP_R1; /* SDIO workaround. */ |
2099 |
+- } else if (opcode == SD_SEND_IF_COND && (mmc_cmd_type(cmd) == MMC_CMD_BCR)) { |
2100 |
+- resp = RESP_R1; |
2101 |
+- } else { |
2102 |
+- switch (mmc_resp_type(cmd)) { |
2103 |
+- case MMC_RSP_R1: |
2104 |
+- resp = RESP_R1; |
2105 |
+- break; |
2106 |
+- case MMC_RSP_R1B: |
2107 |
+- resp = RESP_R1B; |
2108 |
+- break; |
2109 |
+- case MMC_RSP_R2: |
2110 |
+- resp = RESP_R2; |
2111 |
+- break; |
2112 |
+- case MMC_RSP_R3: |
2113 |
+- resp = RESP_R3; |
2114 |
+- break; |
2115 |
+- case MMC_RSP_NONE: |
2116 |
+- default: |
2117 |
+- resp = RESP_NONE; |
2118 |
+- break; |
2119 |
+- } |
2120 |
+- } |
2121 |
+- |
2122 |
+- return resp; |
2123 |
+-} |
2124 |
+- |
2125 |
+-/*--------------------------------------------------------------------------*/ |
2126 |
+-/* mmc_host_ops members */ |
2127 |
+-/*--------------------------------------------------------------------------*/ |
2128 |
+-static unsigned int msdc_command_start(struct msdc_host *host, |
2129 |
+- struct mmc_command *cmd, |
2130 |
+- unsigned long timeout) |
2131 |
+-{ |
2132 |
+- u32 opcode = cmd->opcode; |
2133 |
+- u32 rawcmd; |
2134 |
+- u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | |
2135 |
+- MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | |
2136 |
+- MSDC_INT_ACMD19_DONE; |
2137 |
+- |
2138 |
+- u32 resp; |
2139 |
+- unsigned long tmo; |
2140 |
+- |
2141 |
+- /* Protocol layer does not provide response type, but our hardware needs |
2142 |
+- * to know exact type, not just size! |
2143 |
+- */ |
2144 |
+- resp = msdc_cmd_find_resp(cmd); |
2145 |
+- |
2146 |
+- cmd->error = 0; |
2147 |
+- /* rawcmd : |
2148 |
+- * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 | |
2149 |
+- * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode |
2150 |
+- */ |
2151 |
+- rawcmd = opcode | msdc_rsp[resp] << 7 | host->blksz << 16; |
2152 |
+- |
2153 |
+- if (opcode == MMC_READ_MULTIPLE_BLOCK) { |
2154 |
+- rawcmd |= (2 << 11); |
2155 |
+- } else if (opcode == MMC_READ_SINGLE_BLOCK) { |
2156 |
+- rawcmd |= (1 << 11); |
2157 |
+- } else if (opcode == MMC_WRITE_MULTIPLE_BLOCK) { |
2158 |
+- rawcmd |= ((2 << 11) | (1 << 13)); |
2159 |
+- } else if (opcode == MMC_WRITE_BLOCK) { |
2160 |
+- rawcmd |= ((1 << 11) | (1 << 13)); |
2161 |
+- } else if (opcode == SD_IO_RW_EXTENDED) { |
2162 |
+- if (cmd->data->flags & MMC_DATA_WRITE) |
2163 |
+- rawcmd |= (1 << 13); |
2164 |
+- if (cmd->data->blocks > 1) |
2165 |
+- rawcmd |= (2 << 11); |
2166 |
+- else |
2167 |
+- rawcmd |= (1 << 11); |
2168 |
+- } else if (opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int)-1) { |
2169 |
+- rawcmd |= (1 << 14); |
2170 |
+- } else if ((opcode == SD_APP_SEND_SCR) || |
2171 |
+- (opcode == SD_APP_SEND_NUM_WR_BLKS) || |
2172 |
+- (opcode == SD_SWITCH && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || |
2173 |
+- (opcode == SD_APP_SD_STATUS && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || |
2174 |
+- (opcode == MMC_SEND_EXT_CSD && (mmc_cmd_type(cmd) == MMC_CMD_ADTC))) { |
2175 |
+- rawcmd |= (1 << 11); |
2176 |
+- } else if (opcode == MMC_STOP_TRANSMISSION) { |
2177 |
+- rawcmd |= (1 << 14); |
2178 |
+- rawcmd &= ~(0x0FFF << 16); |
2179 |
+- } |
2180 |
+- |
2181 |
+- N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode, rawcmd, cmd->arg); |
2182 |
+- |
2183 |
+- tmo = jiffies + timeout; |
2184 |
+- |
2185 |
+- if (opcode == MMC_SEND_STATUS) { |
2186 |
+- for (;;) { |
2187 |
+- if (!sdc_is_cmd_busy()) |
2188 |
+- break; |
2189 |
+- |
2190 |
+- if (time_after(jiffies, tmo)) { |
2191 |
+- ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode); |
2192 |
+- cmd->error = -ETIMEDOUT; |
2193 |
+- msdc_reset_hw(host); |
2194 |
+- goto end; |
2195 |
+- } |
2196 |
+- } |
2197 |
+- } else { |
2198 |
+- for (;;) { |
2199 |
+- if (!sdc_is_busy()) |
2200 |
+- break; |
2201 |
+- if (time_after(jiffies, tmo)) { |
2202 |
+- ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode); |
2203 |
+- cmd->error = -ETIMEDOUT; |
2204 |
+- msdc_reset_hw(host); |
2205 |
+- goto end; |
2206 |
+- } |
2207 |
+- } |
2208 |
+- } |
2209 |
+- |
2210 |
+- //BUG_ON(in_interrupt()); |
2211 |
+- host->cmd = cmd; |
2212 |
+- host->cmd_rsp = resp; |
2213 |
+- |
2214 |
+- init_completion(&host->cmd_done); |
2215 |
+- |
2216 |
+- sdr_set_bits(host->base + MSDC_INTEN, wints); |
2217 |
+- sdc_send_cmd(rawcmd, cmd->arg); |
2218 |
+- |
2219 |
+-end: |
2220 |
+- return cmd->error; |
2221 |
+-} |
2222 |
+- |
2223 |
+-static unsigned int msdc_command_resp(struct msdc_host *host, |
2224 |
+- struct mmc_command *cmd, |
2225 |
+- int tune, |
2226 |
+- unsigned long timeout) |
2227 |
+- __must_hold(&host->lock) |
2228 |
+-{ |
2229 |
+- u32 opcode = cmd->opcode; |
2230 |
+- //u32 rawcmd; |
2231 |
+- u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | |
2232 |
+- MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | |
2233 |
+- MSDC_INT_ACMD19_DONE; |
2234 |
+- |
2235 |
+- BUG_ON(in_interrupt()); |
2236 |
+- //init_completion(&host->cmd_done); |
2237 |
+- //sdr_set_bits(host->base + MSDC_INTEN, wints); |
2238 |
+- |
2239 |
+- spin_unlock(&host->lock); |
2240 |
+- if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) { |
2241 |
+- ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg); |
2242 |
+- cmd->error = -ETIMEDOUT; |
2243 |
+- msdc_reset_hw(host); |
2244 |
+- } |
2245 |
+- spin_lock(&host->lock); |
2246 |
+- |
2247 |
+- sdr_clr_bits(host->base + MSDC_INTEN, wints); |
2248 |
+- host->cmd = NULL; |
2249 |
+- |
2250 |
+-//end: |
2251 |
+-#ifdef MT6575_SD_DEBUG |
2252 |
+- switch (resp) { |
2253 |
+- case RESP_NONE: |
2254 |
+- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp); |
2255 |
+- break; |
2256 |
+- case RESP_R2: |
2257 |
+- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x", |
2258 |
+- opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1], |
2259 |
+- cmd->resp[2], cmd->resp[3]); |
2260 |
+- break; |
2261 |
+- default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ |
2262 |
+- N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x", |
2263 |
+- opcode, cmd->error, resp, cmd->resp[0]); |
2264 |
+- if (cmd->error == 0) { |
2265 |
+- switch (resp) { |
2266 |
+- case RESP_R1: |
2267 |
+- case RESP_R1B: |
2268 |
+- msdc_dump_card_status(host, cmd->resp[0]); |
2269 |
+- break; |
2270 |
+- case RESP_R3: |
2271 |
+- msdc_dump_ocr_reg(host, cmd->resp[0]); |
2272 |
+- break; |
2273 |
+- case RESP_R5: |
2274 |
+- msdc_dump_io_resp(host, cmd->resp[0]); |
2275 |
+- break; |
2276 |
+- case RESP_R6: |
2277 |
+- msdc_dump_rca_resp(host, cmd->resp[0]); |
2278 |
+- break; |
2279 |
+- } |
2280 |
+- } |
2281 |
+- break; |
2282 |
+- } |
2283 |
+-#endif |
2284 |
+- |
2285 |
+- /* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */ |
2286 |
+- |
2287 |
+- if (!tune) |
2288 |
+- return cmd->error; |
2289 |
+- |
2290 |
+- /* memory card CRC */ |
2291 |
+- if (host->hw->flags & MSDC_REMOVABLE && cmd->error == -EIO) { |
2292 |
+- /* check if has data phase */ |
2293 |
+- if (readl(host->base + SDC_CMD) & 0x1800) { |
2294 |
+- msdc_abort_data(host); |
2295 |
+- } else { |
2296 |
+- /* do basic: reset*/ |
2297 |
+- msdc_reset_hw(host); |
2298 |
+- msdc_clr_fifo(host); |
2299 |
+- msdc_clr_int(); |
2300 |
+- } |
2301 |
+- cmd->error = msdc_tune_cmdrsp(host, cmd); |
2302 |
+- } |
2303 |
+- |
2304 |
+- // check DAT0 |
2305 |
+- /* if (resp == RESP_R1B) { |
2306 |
+- while ((readl(host->base + MSDC_PS) & 0x10000) != 0x10000); |
2307 |
+- } */ |
2308 |
+- /* CMD12 Error Handle */ |
2309 |
+- |
2310 |
+- return cmd->error; |
2311 |
+-} |
2312 |
+- |
2313 |
+-static unsigned int msdc_do_command(struct msdc_host *host, |
2314 |
+- struct mmc_command *cmd, |
2315 |
+- int tune, |
2316 |
+- unsigned long timeout) |
2317 |
+-{ |
2318 |
+- if (msdc_command_start(host, cmd, timeout)) |
2319 |
+- goto end; |
2320 |
+- |
2321 |
+- if (msdc_command_resp(host, cmd, tune, timeout)) |
2322 |
+- goto end; |
2323 |
+- |
2324 |
+-end: |
2325 |
+- |
2326 |
+- N_MSG(CMD, " return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]); |
2327 |
+- return cmd->error; |
2328 |
+-} |
2329 |
+- |
2330 |
+-#if 0 /* --- by chhung */ |
2331 |
+-// DMA resume / start / stop |
2332 |
+-static void msdc_dma_resume(struct msdc_host *host) |
2333 |
+-{ |
2334 |
+- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1); |
2335 |
+- |
2336 |
+- N_MSG(DMA, "DMA resume"); |
2337 |
+-} |
2338 |
+-#endif /* end of --- */ |
2339 |
+- |
2340 |
+-static void msdc_dma_start(struct msdc_host *host) |
2341 |
+-{ |
2342 |
+- u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; |
2343 |
+- |
2344 |
+- sdr_set_bits(host->base + MSDC_INTEN, wints); |
2345 |
+- //dsb(); /* --- by chhung */ |
2346 |
+- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1); |
2347 |
+- |
2348 |
+- N_MSG(DMA, "DMA start"); |
2349 |
+-} |
2350 |
+- |
2351 |
+-static void msdc_dma_stop(struct msdc_host *host) |
2352 |
+-{ |
2353 |
+- //u32 retries=500; |
2354 |
+- u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; |
2355 |
+- |
2356 |
+- N_MSG(DMA, "DMA status: 0x%.8x", readl(host->base + MSDC_DMA_CFG)); |
2357 |
+- //while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS); |
2358 |
+- |
2359 |
+- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1); |
2360 |
+- while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) |
2361 |
+- ; |
2362 |
+- |
2363 |
+- //dsb(); /* --- by chhung */ |
2364 |
+- sdr_clr_bits(host->base + MSDC_INTEN, wints); /* Not just xfer_comp */ |
2365 |
+- |
2366 |
+- N_MSG(DMA, "DMA stop"); |
2367 |
+-} |
2368 |
+- |
2369 |
+-/* calc checksum */ |
2370 |
+-static u8 msdc_dma_calcs(u8 *buf, u32 len) |
2371 |
+-{ |
2372 |
+- u32 i, sum = 0; |
2373 |
+- |
2374 |
+- for (i = 0; i < len; i++) |
2375 |
+- sum += buf[i]; |
2376 |
+- return 0xFF - (u8)sum; |
2377 |
+-} |
2378 |
+- |
2379 |
+-static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, |
2380 |
+- struct scatterlist *sg_cmd, unsigned int sglen) |
2381 |
+-{ |
2382 |
+- struct scatterlist *sg; |
2383 |
+- struct gpd *gpd; |
2384 |
+- struct bd *bd; |
2385 |
+- u32 j; |
2386 |
+- |
2387 |
+- BUG_ON(sglen > MAX_BD_NUM); /* not support currently */ |
2388 |
+- |
2389 |
+- N_MSG(DMA, "DMA sglen<%d> xfersz<%d>", sglen, host->xfer_size); |
2390 |
+- |
2391 |
+- gpd = dma->gpd; |
2392 |
+- bd = dma->bd; |
2393 |
+- |
2394 |
+- /* modify gpd*/ |
2395 |
+- //gpd->intr = 0; |
2396 |
+- gpd->hwo = 1; /* hw will clear it */ |
2397 |
+- gpd->bdp = 1; |
2398 |
+- gpd->chksum = 0; /* need to clear first. */ |
2399 |
+- gpd->chksum = msdc_dma_calcs((u8 *)gpd, 16); |
2400 |
+- |
2401 |
+- /* modify bd*/ |
2402 |
+- for_each_sg(sg_cmd, sg, sglen, j) { |
2403 |
+- bd[j].blkpad = 0; |
2404 |
+- bd[j].dwpad = 0; |
2405 |
+- bd[j].ptr = (void *)sg_dma_address(sg); |
2406 |
+- bd[j].buflen = sg_dma_len(sg); |
2407 |
+- |
2408 |
+- if (j == sglen - 1) |
2409 |
+- bd[j].eol = 1; /* the last bd */ |
2410 |
+- else |
2411 |
+- bd[j].eol = 0; |
2412 |
+- |
2413 |
+- bd[j].chksum = 0; /* checksume need to clear first */ |
2414 |
+- bd[j].chksum = msdc_dma_calcs((u8 *)(&bd[j]), 16); |
2415 |
+- } |
2416 |
+- |
2417 |
+- sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1); |
2418 |
+- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, |
2419 |
+- MSDC_BRUST_64B); |
2420 |
+- sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1); |
2421 |
+- |
2422 |
+- writel(PHYSADDR((u32)dma->gpd_addr), host->base + MSDC_DMA_SA); |
2423 |
+- |
2424 |
+- N_MSG(DMA, "DMA_CTRL = 0x%x", readl(host->base + MSDC_DMA_CTRL)); |
2425 |
+- N_MSG(DMA, "DMA_CFG = 0x%x", readl(host->base + MSDC_DMA_CFG)); |
2426 |
+- N_MSG(DMA, "DMA_SA = 0x%x", readl(host->base + MSDC_DMA_SA)); |
2427 |
+-} |
2428 |
+- |
2429 |
+-static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq) |
2430 |
+- __must_hold(&host->lock) |
2431 |
+-{ |
2432 |
+- struct msdc_host *host = mmc_priv(mmc); |
2433 |
+- struct mmc_command *cmd; |
2434 |
+- struct mmc_data *data; |
2435 |
+- //u32 intsts = 0; |
2436 |
+- int read = 1, send_type = 0; |
2437 |
+- |
2438 |
+-#define SND_DAT 0 |
2439 |
+-#define SND_CMD 1 |
2440 |
+- |
2441 |
+- BUG_ON(mmc == NULL); |
2442 |
+- BUG_ON(mrq == NULL); |
2443 |
+- |
2444 |
+- host->error = 0; |
2445 |
+- |
2446 |
+- cmd = mrq->cmd; |
2447 |
+- data = mrq->cmd->data; |
2448 |
+- |
2449 |
+-#if 0 /* --- by chhung */ |
2450 |
+- //if(host->id ==1){ |
2451 |
+- N_MSG(OPS, "enable clock!"); |
2452 |
+- msdc_ungate_clock(host->id); |
2453 |
+- //} |
2454 |
+-#endif /* end of --- */ |
2455 |
+- |
2456 |
+- if (!data) { |
2457 |
+- send_type = SND_CMD; |
2458 |
+- if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0) |
2459 |
+- goto done; |
2460 |
+- } else { |
2461 |
+- BUG_ON(data->blksz > HOST_MAX_BLKSZ); |
2462 |
+- send_type = SND_DAT; |
2463 |
+- |
2464 |
+- data->error = 0; |
2465 |
+- read = data->flags & MMC_DATA_READ ? 1 : 0; |
2466 |
+- host->data = data; |
2467 |
+- host->xfer_size = data->blocks * data->blksz; |
2468 |
+- host->blksz = data->blksz; |
2469 |
+- |
2470 |
+- if (read) { |
2471 |
+- if ((host->timeout_ns != data->timeout_ns) || |
2472 |
+- (host->timeout_clks != data->timeout_clks)) { |
2473 |
+- msdc_set_timeout(host, data->timeout_ns, data->timeout_clks); |
2474 |
+- } |
2475 |
+- } |
2476 |
+- |
2477 |
+- writel(data->blocks, host->base + SDC_BLK_NUM); |
2478 |
+- //msdc_clr_fifo(host); /* no need */ |
2479 |
+- |
2480 |
+- msdc_dma_on(); /* enable DMA mode first!! */ |
2481 |
+- init_completion(&host->xfer_done); |
2482 |
+- |
2483 |
+- /* start the command first*/ |
2484 |
+- if (msdc_command_start(host, cmd, CMD_TIMEOUT) != 0) |
2485 |
+- goto done; |
2486 |
+- |
2487 |
+- data->sg_count = dma_map_sg(mmc_dev(mmc), data->sg, |
2488 |
+- data->sg_len, |
2489 |
+- mmc_get_dma_dir(data)); |
2490 |
+- msdc_dma_setup(host, &host->dma, data->sg, |
2491 |
+- data->sg_count); |
2492 |
+- |
2493 |
+- /* then wait command done */ |
2494 |
+- if (msdc_command_resp(host, cmd, 1, CMD_TIMEOUT) != 0) |
2495 |
+- goto done; |
2496 |
+- |
2497 |
+- /* for read, the data coming too fast, then CRC error |
2498 |
+- start DMA no business with CRC. */ |
2499 |
+- //init_completion(&host->xfer_done); |
2500 |
+- msdc_dma_start(host); |
2501 |
+- |
2502 |
+- spin_unlock(&host->lock); |
2503 |
+- if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) { |
2504 |
+- ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz); |
2505 |
+- ERR_MSG(" DMA_SA = 0x%x", |
2506 |
+- readl(host->base + MSDC_DMA_SA)); |
2507 |
+- ERR_MSG(" DMA_CA = 0x%x", |
2508 |
+- readl(host->base + MSDC_DMA_CA)); |
2509 |
+- ERR_MSG(" DMA_CTRL = 0x%x", |
2510 |
+- readl(host->base + MSDC_DMA_CTRL)); |
2511 |
+- ERR_MSG(" DMA_CFG = 0x%x", |
2512 |
+- readl(host->base + MSDC_DMA_CFG)); |
2513 |
+- data->error = -ETIMEDOUT; |
2514 |
+- |
2515 |
+- msdc_reset_hw(host); |
2516 |
+- msdc_clr_fifo(host); |
2517 |
+- msdc_clr_int(); |
2518 |
+- } |
2519 |
+- spin_lock(&host->lock); |
2520 |
+- msdc_dma_stop(host); |
2521 |
+- |
2522 |
+- /* Last: stop transfer */ |
2523 |
+- if (data->stop) { |
2524 |
+- if (msdc_do_command(host, data->stop, 0, CMD_TIMEOUT) != 0) |
2525 |
+- goto done; |
2526 |
+- } |
2527 |
+- } |
2528 |
+- |
2529 |
+-done: |
2530 |
+- if (data != NULL) { |
2531 |
+- host->data = NULL; |
2532 |
+- dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, |
2533 |
+- mmc_get_dma_dir(data)); |
2534 |
+- host->blksz = 0; |
2535 |
+- |
2536 |
+-#if 0 // don't stop twice! |
2537 |
+- if (host->hw->flags & MSDC_REMOVABLE && data->error) { |
2538 |
+- msdc_abort_data(host); |
2539 |
+- /* reset in IRQ, stop command has issued. -> No need */ |
2540 |
+- } |
2541 |
+-#endif |
2542 |
+- |
2543 |
+- N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>", cmd->opcode, (dma ? "dma" : "pio"), |
2544 |
+- (read ? "read " : "write"), data->blksz, data->blocks, data->error); |
2545 |
+- } |
2546 |
+- |
2547 |
+-#if 0 /* --- by chhung */ |
2548 |
+-#if 1 |
2549 |
+- //if(host->id==1) { |
2550 |
+- if (send_type == SND_CMD) { |
2551 |
+- if (cmd->opcode == MMC_SEND_STATUS) { |
2552 |
+- if ((cmd->resp[0] & CARD_READY_FOR_DATA) || (CARD_CURRENT_STATE(cmd->resp[0]) != 7)) { |
2553 |
+- N_MSG(OPS, "disable clock, CMD13 IDLE"); |
2554 |
+- msdc_gate_clock(host->id); |
2555 |
+- } |
2556 |
+- } else { |
2557 |
+- N_MSG(OPS, "disable clock, CMD<%d>", cmd->opcode); |
2558 |
+- msdc_gate_clock(host->id); |
2559 |
+- } |
2560 |
+- } else { |
2561 |
+- if (read) { |
2562 |
+- N_MSG(OPS, "disable clock!!! Read CMD<%d>", cmd->opcode); |
2563 |
+- msdc_gate_clock(host->id); |
2564 |
+- } |
2565 |
+- } |
2566 |
+- //} |
2567 |
+-#else |
2568 |
+- msdc_gate_clock(host->id); |
2569 |
+-#endif |
2570 |
+-#endif /* end of --- */ |
2571 |
+- |
2572 |
+- if (mrq->cmd->error) |
2573 |
+- host->error = 0x001; |
2574 |
+- if (mrq->data && mrq->data->error) |
2575 |
+- host->error |= 0x010; |
2576 |
+- if (mrq->stop && mrq->stop->error) |
2577 |
+- host->error |= 0x100; |
2578 |
+- |
2579 |
+- //if (host->error) ERR_MSG("host->error<%d>", host->error); |
2580 |
+- |
2581 |
+- return host->error; |
2582 |
+-} |
2583 |
+- |
2584 |
+-static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host) |
2585 |
+-{ |
2586 |
+- struct mmc_command cmd; |
2587 |
+- struct mmc_request mrq; |
2588 |
+- u32 err; |
2589 |
+- |
2590 |
+- memset(&cmd, 0, sizeof(struct mmc_command)); |
2591 |
+- cmd.opcode = MMC_APP_CMD; |
2592 |
+-#if 0 /* bug: we meet mmc->card is null when ACMD6 */ |
2593 |
+- cmd.arg = mmc->card->rca << 16; |
2594 |
+-#else |
2595 |
+- cmd.arg = host->app_cmd_arg; |
2596 |
+-#endif |
2597 |
+- cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
2598 |
+- |
2599 |
+- memset(&mrq, 0, sizeof(struct mmc_request)); |
2600 |
+- mrq.cmd = &cmd; cmd.mrq = &mrq; |
2601 |
+- cmd.data = NULL; |
2602 |
+- |
2603 |
+- err = msdc_do_command(host, &cmd, 0, CMD_TIMEOUT); |
2604 |
+- return err; |
2605 |
+-} |
2606 |
+- |
2607 |
+-static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd) |
2608 |
+-{ |
2609 |
+- int result = -1; |
2610 |
+- u32 rsmpl, cur_rsmpl, orig_rsmpl; |
2611 |
+- u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly; |
2612 |
+- u32 skip = 1; |
2613 |
+- |
2614 |
+- /* ==== don't support 3.0 now ==== |
2615 |
+- 1: R_SMPL[1] |
2616 |
+- 2: PAD_CMD_RESP_RXDLY[26:22] |
2617 |
+- ==========================*/ |
2618 |
+- |
2619 |
+- // save the previous tune result |
2620 |
+- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl); |
2621 |
+- sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, |
2622 |
+- &orig_rrdly); |
2623 |
+- |
2624 |
+- rrdly = 0; |
2625 |
+- do { |
2626 |
+- for (rsmpl = 0; rsmpl < 2; rsmpl++) { |
2627 |
+- /* Lv1: R_SMPL[1] */ |
2628 |
+- cur_rsmpl = (orig_rsmpl + rsmpl) % 2; |
2629 |
+- if (skip == 1) { |
2630 |
+- skip = 0; |
2631 |
+- continue; |
2632 |
+- } |
2633 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, |
2634 |
+- cur_rsmpl); |
2635 |
+- |
2636 |
+- if (host->app_cmd) { |
2637 |
+- result = msdc_app_cmd(host->mmc, host); |
2638 |
+- if (result) { |
2639 |
+- ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>", |
2640 |
+- host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl); |
2641 |
+- continue; |
2642 |
+- } |
2643 |
+- } |
2644 |
+- result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune. |
2645 |
+- ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode, |
2646 |
+- (result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl); |
2647 |
+- |
2648 |
+- if (result == 0) |
2649 |
+- return 0; |
2650 |
+- if (result != -EIO) { |
2651 |
+- ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result); |
2652 |
+- return result; |
2653 |
+- } |
2654 |
+- |
2655 |
+- /* should be EIO */ |
2656 |
+- /* check if has data phase */ |
2657 |
+- if (readl(host->base + SDC_CMD) & 0x1800) |
2658 |
+- msdc_abort_data(host); |
2659 |
+- } |
2660 |
+- |
2661 |
+- /* Lv2: PAD_CMD_RESP_RXDLY[26:22] */ |
2662 |
+- cur_rrdly = (orig_rrdly + rrdly + 1) % 32; |
2663 |
+- sdr_set_field(host->base + MSDC_PAD_TUNE, |
2664 |
+- MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly); |
2665 |
+- } while (++rrdly < 32); |
2666 |
+- |
2667 |
+- return result; |
2668 |
+-} |
2669 |
+- |
2670 |
+-/* Support SD2.0 Only */ |
2671 |
+-static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq) |
2672 |
+-{ |
2673 |
+- struct msdc_host *host = mmc_priv(mmc); |
2674 |
+- u32 ddr = 0; |
2675 |
+- u32 dcrc = 0; |
2676 |
+- u32 rxdly, cur_rxdly0, cur_rxdly1; |
2677 |
+- u32 dsmpl, cur_dsmpl, orig_dsmpl; |
2678 |
+- u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; |
2679 |
+- u32 cur_dat4, cur_dat5, cur_dat6, cur_dat7; |
2680 |
+- u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; |
2681 |
+- u32 orig_dat4, orig_dat5, orig_dat6, orig_dat7; |
2682 |
+- int result = -1; |
2683 |
+- u32 skip = 1; |
2684 |
+- |
2685 |
+- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); |
2686 |
+- |
2687 |
+- /* Tune Method 2. */ |
2688 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); |
2689 |
+- |
2690 |
+- rxdly = 0; |
2691 |
+- do { |
2692 |
+- for (dsmpl = 0; dsmpl < 2; dsmpl++) { |
2693 |
+- cur_dsmpl = (orig_dsmpl + dsmpl) % 2; |
2694 |
+- if (skip == 1) { |
2695 |
+- skip = 0; |
2696 |
+- continue; |
2697 |
+- } |
2698 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, |
2699 |
+- cur_dsmpl); |
2700 |
+- |
2701 |
+- if (host->app_cmd) { |
2702 |
+- result = msdc_app_cmd(host->mmc, host); |
2703 |
+- if (result) { |
2704 |
+- ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode); |
2705 |
+- continue; |
2706 |
+- } |
2707 |
+- } |
2708 |
+- result = msdc_do_request(mmc, mrq); |
2709 |
+- |
2710 |
+- sdr_get_field(host->base + SDC_DCRC_STS, |
2711 |
+- SDC_DCRC_STS_POS | SDC_DCRC_STS_NEG, |
2712 |
+- &dcrc); /* RO */ |
2713 |
+- if (!ddr) |
2714 |
+- dcrc &= ~SDC_DCRC_STS_NEG; |
2715 |
+- ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>", |
2716 |
+- (result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc, |
2717 |
+- readl(host->base + MSDC_DAT_RDDLY0), |
2718 |
+- readl(host->base + MSDC_DAT_RDDLY1), cur_dsmpl); |
2719 |
+- |
2720 |
+- /* Fix me: result is 0, but dcrc is still exist */ |
2721 |
+- if (result == 0 && dcrc == 0) { |
2722 |
+- goto done; |
2723 |
+- } else { |
2724 |
+- /* there is a case: command timeout, and data phase not processed */ |
2725 |
+- if (mrq->data->error != 0 && |
2726 |
+- mrq->data->error != -EIO) { |
2727 |
+- ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", |
2728 |
+- result, mrq->cmd->error, mrq->data->error); |
2729 |
+- goto done; |
2730 |
+- } |
2731 |
+- } |
2732 |
+- } |
2733 |
+- |
2734 |
+- cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0); |
2735 |
+- cur_rxdly1 = readl(host->base + MSDC_DAT_RDDLY1); |
2736 |
+- |
2737 |
+- /* E1 ECO. YD: Reverse */ |
2738 |
+- if (readl(host->base + MSDC_ECO_VER) >= 4) { |
2739 |
+- orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; |
2740 |
+- orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; |
2741 |
+- orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; |
2742 |
+- orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; |
2743 |
+- orig_dat4 = (cur_rxdly1 >> 24) & 0x1F; |
2744 |
+- orig_dat5 = (cur_rxdly1 >> 16) & 0x1F; |
2745 |
+- orig_dat6 = (cur_rxdly1 >> 8) & 0x1F; |
2746 |
+- orig_dat7 = (cur_rxdly1 >> 0) & 0x1F; |
2747 |
+- } else { |
2748 |
+- orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; |
2749 |
+- orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; |
2750 |
+- orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; |
2751 |
+- orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; |
2752 |
+- orig_dat4 = (cur_rxdly1 >> 0) & 0x1F; |
2753 |
+- orig_dat5 = (cur_rxdly1 >> 8) & 0x1F; |
2754 |
+- orig_dat6 = (cur_rxdly1 >> 16) & 0x1F; |
2755 |
+- orig_dat7 = (cur_rxdly1 >> 24) & 0x1F; |
2756 |
+- } |
2757 |
+- |
2758 |
+- if (ddr) { |
2759 |
+- cur_dat0 = (dcrc & (1 << 0) || dcrc & (1 << 8)) ? ((orig_dat0 + 1) % 32) : orig_dat0; |
2760 |
+- cur_dat1 = (dcrc & (1 << 1) || dcrc & (1 << 9)) ? ((orig_dat1 + 1) % 32) : orig_dat1; |
2761 |
+- cur_dat2 = (dcrc & (1 << 2) || dcrc & (1 << 10)) ? ((orig_dat2 + 1) % 32) : orig_dat2; |
2762 |
+- cur_dat3 = (dcrc & (1 << 3) || dcrc & (1 << 11)) ? ((orig_dat3 + 1) % 32) : orig_dat3; |
2763 |
+- } else { |
2764 |
+- cur_dat0 = (dcrc & (1 << 0)) ? ((orig_dat0 + 1) % 32) : orig_dat0; |
2765 |
+- cur_dat1 = (dcrc & (1 << 1)) ? ((orig_dat1 + 1) % 32) : orig_dat1; |
2766 |
+- cur_dat2 = (dcrc & (1 << 2)) ? ((orig_dat2 + 1) % 32) : orig_dat2; |
2767 |
+- cur_dat3 = (dcrc & (1 << 3)) ? ((orig_dat3 + 1) % 32) : orig_dat3; |
2768 |
+- } |
2769 |
+- cur_dat4 = (dcrc & (1 << 4)) ? ((orig_dat4 + 1) % 32) : orig_dat4; |
2770 |
+- cur_dat5 = (dcrc & (1 << 5)) ? ((orig_dat5 + 1) % 32) : orig_dat5; |
2771 |
+- cur_dat6 = (dcrc & (1 << 6)) ? ((orig_dat6 + 1) % 32) : orig_dat6; |
2772 |
+- cur_dat7 = (dcrc & (1 << 7)) ? ((orig_dat7 + 1) % 32) : orig_dat7; |
2773 |
+- |
2774 |
+- cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); |
2775 |
+- cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0); |
2776 |
+- |
2777 |
+- writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0); |
2778 |
+- writel(cur_rxdly1, host->base + MSDC_DAT_RDDLY1); |
2779 |
+- |
2780 |
+- } while (++rxdly < 32); |
2781 |
+- |
2782 |
+-done: |
2783 |
+- return result; |
2784 |
+-} |
2785 |
+- |
2786 |
+-static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq) |
2787 |
+-{ |
2788 |
+- struct msdc_host *host = mmc_priv(mmc); |
2789 |
+- |
2790 |
+- u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly; |
2791 |
+- u32 dsmpl, cur_dsmpl, orig_dsmpl; |
2792 |
+- u32 rxdly, cur_rxdly0; |
2793 |
+- u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; |
2794 |
+- u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; |
2795 |
+- int result = -1; |
2796 |
+- u32 skip = 1; |
2797 |
+- |
2798 |
+- // MSDC_IOCON_DDR50CKD need to check. [Fix me] |
2799 |
+- |
2800 |
+- sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, |
2801 |
+- &orig_wrrdly); |
2802 |
+- sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); |
2803 |
+- |
2804 |
+- /* Tune Method 2. just DAT0 */ |
2805 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); |
2806 |
+- cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0); |
2807 |
+- |
2808 |
+- /* E1 ECO. YD: Reverse */ |
2809 |
+- if (readl(host->base + MSDC_ECO_VER) >= 4) { |
2810 |
+- orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; |
2811 |
+- orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; |
2812 |
+- orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; |
2813 |
+- orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; |
2814 |
+- } else { |
2815 |
+- orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; |
2816 |
+- orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; |
2817 |
+- orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; |
2818 |
+- orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; |
2819 |
+- } |
2820 |
+- |
2821 |
+- rxdly = 0; |
2822 |
+- do { |
2823 |
+- wrrdly = 0; |
2824 |
+- do { |
2825 |
+- for (dsmpl = 0; dsmpl < 2; dsmpl++) { |
2826 |
+- cur_dsmpl = (orig_dsmpl + dsmpl) % 2; |
2827 |
+- if (skip == 1) { |
2828 |
+- skip = 0; |
2829 |
+- continue; |
2830 |
+- } |
2831 |
+- sdr_set_field(host->base + MSDC_IOCON, |
2832 |
+- MSDC_IOCON_DSPL, cur_dsmpl); |
2833 |
+- |
2834 |
+- if (host->app_cmd) { |
2835 |
+- result = msdc_app_cmd(host->mmc, host); |
2836 |
+- if (result) { |
2837 |
+- ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode); |
2838 |
+- continue; |
2839 |
+- } |
2840 |
+- } |
2841 |
+- result = msdc_do_request(mmc, mrq); |
2842 |
+- |
2843 |
+- ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>", |
2844 |
+- result == 0 ? "PASS" : "FAIL", |
2845 |
+- cur_dsmpl, cur_wrrdly, cur_rxdly0); |
2846 |
+- |
2847 |
+- if (result == 0) { |
2848 |
+- goto done; |
2849 |
+- } else { |
2850 |
+- /* there is a case: command timeout, and data phase not processed */ |
2851 |
+- if (mrq->data->error != -EIO) { |
2852 |
+- ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", |
2853 |
+- result, mrq->cmd->error, mrq->data->error); |
2854 |
+- goto done; |
2855 |
+- } |
2856 |
+- } |
2857 |
+- } |
2858 |
+- cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32; |
2859 |
+- sdr_set_field(host->base + MSDC_PAD_TUNE, |
2860 |
+- MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly); |
2861 |
+- } while (++wrrdly < 32); |
2862 |
+- |
2863 |
+- cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */ |
2864 |
+- cur_dat1 = orig_dat1; |
2865 |
+- cur_dat2 = orig_dat2; |
2866 |
+- cur_dat3 = orig_dat3; |
2867 |
+- |
2868 |
+- cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); |
2869 |
+- writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0); |
2870 |
+- } while (++rxdly < 32); |
2871 |
+- |
2872 |
+-done: |
2873 |
+- return result; |
2874 |
+-} |
2875 |
+- |
2876 |
+-static int msdc_get_card_status(struct mmc_host *mmc, struct msdc_host *host, u32 *status) |
2877 |
+-{ |
2878 |
+- struct mmc_command cmd; |
2879 |
+- struct mmc_request mrq; |
2880 |
+- u32 err; |
2881 |
+- |
2882 |
+- memset(&cmd, 0, sizeof(struct mmc_command)); |
2883 |
+- cmd.opcode = MMC_SEND_STATUS; |
2884 |
+- if (mmc->card) { |
2885 |
+- cmd.arg = mmc->card->rca << 16; |
2886 |
+- } else { |
2887 |
+- ERR_MSG("cmd13 mmc card is null"); |
2888 |
+- cmd.arg = host->app_cmd_arg; |
2889 |
+- } |
2890 |
+- cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; |
2891 |
+- |
2892 |
+- memset(&mrq, 0, sizeof(struct mmc_request)); |
2893 |
+- mrq.cmd = &cmd; cmd.mrq = &mrq; |
2894 |
+- cmd.data = NULL; |
2895 |
+- |
2896 |
+- err = msdc_do_command(host, &cmd, 1, CMD_TIMEOUT); |
2897 |
+- |
2898 |
+- if (status) |
2899 |
+- *status = cmd.resp[0]; |
2900 |
+- |
2901 |
+- return err; |
2902 |
+-} |
2903 |
+- |
2904 |
+-static int msdc_check_busy(struct mmc_host *mmc, struct msdc_host *host) |
2905 |
+-{ |
2906 |
+- u32 err = 0; |
2907 |
+- u32 status = 0; |
2908 |
+- |
2909 |
+- do { |
2910 |
+- err = msdc_get_card_status(mmc, host, &status); |
2911 |
+- if (err) |
2912 |
+- return err; |
2913 |
+- /* need cmd12? */ |
2914 |
+- ERR_MSG("cmd<13> resp<0x%x>", status); |
2915 |
+- } while (R1_CURRENT_STATE(status) == 7); |
2916 |
+- |
2917 |
+- return err; |
2918 |
+-} |
2919 |
+- |
2920 |
+-/* failed when msdc_do_request */ |
2921 |
+-static int msdc_tune_request(struct mmc_host *mmc, struct mmc_request *mrq) |
2922 |
+-{ |
2923 |
+- struct msdc_host *host = mmc_priv(mmc); |
2924 |
+- struct mmc_data *data; |
2925 |
+- //u32 base = host->base; |
2926 |
+- int ret = 0, read; |
2927 |
+- |
2928 |
+- data = mrq->cmd->data; |
2929 |
+- |
2930 |
+- read = data->flags & MMC_DATA_READ ? 1 : 0; |
2931 |
+- |
2932 |
+- if (read) { |
2933 |
+- if (data->error == -EIO) |
2934 |
+- ret = msdc_tune_bread(mmc, mrq); |
2935 |
+- } else { |
2936 |
+- ret = msdc_check_busy(mmc, host); |
2937 |
+- if (ret) { |
2938 |
+- ERR_MSG("XXX cmd13 wait program done failed"); |
2939 |
+- return ret; |
2940 |
+- } |
2941 |
+- /* CRC and TO */ |
2942 |
+- /* Fix me: don't care card status? */ |
2943 |
+- ret = msdc_tune_bwrite(mmc, mrq); |
2944 |
+- } |
2945 |
+- |
2946 |
+- return ret; |
2947 |
+-} |
2948 |
+- |
2949 |
+-/* ops.request */ |
2950 |
+-static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) |
2951 |
+-{ |
2952 |
+- struct msdc_host *host = mmc_priv(mmc); |
2953 |
+- |
2954 |
+- //=== for sdio profile === |
2955 |
+-#if 0 /* --- by chhung */ |
2956 |
+- u32 old_H32, old_L32, new_H32, new_L32; |
2957 |
+- u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0; |
2958 |
+-#endif /* end of --- */ |
2959 |
+- |
2960 |
+- WARN_ON(host->mrq); |
2961 |
+- |
2962 |
+- /* start to process */ |
2963 |
+- spin_lock(&host->lock); |
2964 |
+-#if 0 /* --- by chhung */ |
2965 |
+- if (sdio_pro_enable) { //=== for sdio profile === |
2966 |
+- if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) |
2967 |
+- GPT_GetCounter64(&old_L32, &old_H32); |
2968 |
+- } |
2969 |
+-#endif /* end of --- */ |
2970 |
+- |
2971 |
+- host->mrq = mrq; |
2972 |
+- |
2973 |
+- if (msdc_do_request(mmc, mrq)) { |
2974 |
+- if (host->hw->flags & MSDC_REMOVABLE && ralink_soc == MT762X_SOC_MT7621AT && mrq->data && mrq->data->error) |
2975 |
+- msdc_tune_request(mmc, mrq); |
2976 |
+- } |
2977 |
+- |
2978 |
+- /* ==== when request done, check if app_cmd ==== */ |
2979 |
+- if (mrq->cmd->opcode == MMC_APP_CMD) { |
2980 |
+- host->app_cmd = 1; |
2981 |
+- host->app_cmd_arg = mrq->cmd->arg; /* save the RCA */ |
2982 |
+- } else { |
2983 |
+- host->app_cmd = 0; |
2984 |
+- //host->app_cmd_arg = 0; |
2985 |
+- } |
2986 |
+- |
2987 |
+- host->mrq = NULL; |
2988 |
+- |
2989 |
+-#if 0 /* --- by chhung */ |
2990 |
+- //=== for sdio profile === |
2991 |
+- if (sdio_pro_enable) { |
2992 |
+- if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) { |
2993 |
+- GPT_GetCounter64(&new_L32, &new_H32); |
2994 |
+- ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32); |
2995 |
+- |
2996 |
+- opcode = mrq->cmd->opcode; |
2997 |
+- if (mrq->cmd->data) { |
2998 |
+- sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz; |
2999 |
+- bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0; |
3000 |
+- } else { |
3001 |
+- bRx = mrq->cmd->arg & 0x80000000 ? 1 : 0; |
3002 |
+- } |
3003 |
+- |
3004 |
+- if (!mrq->cmd->error) |
3005 |
+- msdc_performance(opcode, sizes, bRx, ticks); |
3006 |
+- } |
3007 |
+- } |
3008 |
+-#endif /* end of --- */ |
3009 |
+- spin_unlock(&host->lock); |
3010 |
+- |
3011 |
+- mmc_request_done(mmc, mrq); |
3012 |
+- |
3013 |
+- return; |
3014 |
+-} |
3015 |
+- |
3016 |
+-/* called by ops.set_ios */ |
3017 |
+-static void msdc_set_buswidth(struct msdc_host *host, u32 width) |
3018 |
+-{ |
3019 |
+- u32 val = readl(host->base + SDC_CFG); |
3020 |
+- |
3021 |
+- val &= ~SDC_CFG_BUSWIDTH; |
3022 |
+- |
3023 |
+- switch (width) { |
3024 |
+- default: |
3025 |
+- case MMC_BUS_WIDTH_1: |
3026 |
+- width = 1; |
3027 |
+- val |= (MSDC_BUS_1BITS << 16); |
3028 |
+- break; |
3029 |
+- case MMC_BUS_WIDTH_4: |
3030 |
+- val |= (MSDC_BUS_4BITS << 16); |
3031 |
+- break; |
3032 |
+- case MMC_BUS_WIDTH_8: |
3033 |
+- val |= (MSDC_BUS_8BITS << 16); |
3034 |
+- break; |
3035 |
+- } |
3036 |
+- |
3037 |
+- writel(val, host->base + SDC_CFG); |
3038 |
+- |
3039 |
+- N_MSG(CFG, "Bus Width = %d", width); |
3040 |
+-} |
3041 |
+- |
3042 |
+-/* ops.set_ios */ |
3043 |
+-static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
3044 |
+-{ |
3045 |
+- struct msdc_host *host = mmc_priv(mmc); |
3046 |
+- u32 ddr = 0; |
3047 |
+- |
3048 |
+-#ifdef MT6575_SD_DEBUG |
3049 |
+- static char *vdd[] = { |
3050 |
+- "1.50v", "1.55v", "1.60v", "1.65v", "1.70v", "1.80v", "1.90v", |
3051 |
+- "2.00v", "2.10v", "2.20v", "2.30v", "2.40v", "2.50v", "2.60v", |
3052 |
+- "2.70v", "2.80v", "2.90v", "3.00v", "3.10v", "3.20v", "3.30v", |
3053 |
+- "3.40v", "3.50v", "3.60v" |
3054 |
+- }; |
3055 |
+- static char *power_mode[] = { |
3056 |
+- "OFF", "UP", "ON" |
3057 |
+- }; |
3058 |
+- static char *bus_mode[] = { |
3059 |
+- "UNKNOWN", "OPENDRAIN", "PUSHPULL" |
3060 |
+- }; |
3061 |
+- static char *timing[] = { |
3062 |
+- "LEGACY", "MMC_HS", "SD_HS" |
3063 |
+- }; |
3064 |
+- |
3065 |
+- printk("SET_IOS: CLK(%dkHz), BUS(%s), BW(%u), PWR(%s), VDD(%s), TIMING(%s)", |
3066 |
+- ios->clock / 1000, bus_mode[ios->bus_mode], |
3067 |
+- (ios->bus_width == MMC_BUS_WIDTH_4) ? 4 : 1, |
3068 |
+- power_mode[ios->power_mode], vdd[ios->vdd], timing[ios->timing]); |
3069 |
+-#endif |
3070 |
+- |
3071 |
+- msdc_set_buswidth(host, ios->bus_width); |
3072 |
+- |
3073 |
+- /* Power control ??? */ |
3074 |
+- switch (ios->power_mode) { |
3075 |
+- case MMC_POWER_OFF: |
3076 |
+- case MMC_POWER_UP: |
3077 |
+- // msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */ |
3078 |
+- break; |
3079 |
+- case MMC_POWER_ON: |
3080 |
+- host->power_mode = MMC_POWER_ON; |
3081 |
+- break; |
3082 |
+- default: |
3083 |
+- break; |
3084 |
+- } |
3085 |
+- |
3086 |
+- /* Clock control */ |
3087 |
+- if (host->mclk != ios->clock) { |
3088 |
+- if (ios->clock > 25000000) { |
3089 |
+- //if (!(host->hw->flags & MSDC_REMOVABLE)) { |
3090 |
+- INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING); |
3091 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, |
3092 |
+- MSDC_SMPL_FALLING); |
3093 |
+- sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, |
3094 |
+- MSDC_SMPL_FALLING); |
3095 |
+- //} /* for tuning debug */ |
3096 |
+- } else { /* default value */ |
3097 |
+- writel(0x00000000, host->base + MSDC_IOCON); |
3098 |
+- // writel(0x00000000, host->base + MSDC_DAT_RDDLY0); |
3099 |
+- |
3100 |
+- // for MT7620 E2 and afterward |
3101 |
+- writel(0x10101010, host->base + MSDC_DAT_RDDLY0); |
3102 |
+- |
3103 |
+- writel(0x00000000, host->base + MSDC_DAT_RDDLY1); |
3104 |
+- // writel(0x00000000, host->base + MSDC_PAD_TUNE); |
3105 |
+- |
3106 |
+- // for MT7620 E2 and afterward |
3107 |
+- writel(0x84101010, host->base + MSDC_PAD_TUNE); |
3108 |
+- } |
3109 |
+- msdc_set_mclk(host, ddr, ios->clock); |
3110 |
+- } |
3111 |
+-} |
3112 |
+- |
3113 |
+-/* ops.get_ro */ |
3114 |
+-static int msdc_ops_get_ro(struct mmc_host *mmc) |
3115 |
+-{ |
3116 |
+- struct msdc_host *host = mmc_priv(mmc); |
3117 |
+- unsigned long flags; |
3118 |
+- int ro = 0; |
3119 |
+- |
3120 |
+- if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */ |
3121 |
+- spin_lock_irqsave(&host->lock, flags); |
3122 |
+- ro = (readl(host->base + MSDC_PS) >> 31); |
3123 |
+- spin_unlock_irqrestore(&host->lock, flags); |
3124 |
+- } |
3125 |
+- return ro; |
3126 |
+-} |
3127 |
+- |
3128 |
+-/* ops.get_cd */ |
3129 |
+-static int msdc_ops_get_cd(struct mmc_host *mmc) |
3130 |
+-{ |
3131 |
+- struct msdc_host *host = mmc_priv(mmc); |
3132 |
+- unsigned long flags; |
3133 |
+- int present = 1; |
3134 |
+- |
3135 |
+- /* for sdio, MSDC_REMOVABLE not set, always return 1 */ |
3136 |
+- if (!(host->hw->flags & MSDC_REMOVABLE)) { |
3137 |
+- /* For sdio, read H/W always get<1>, but may timeout some times */ |
3138 |
+-#if 1 |
3139 |
+- host->card_inserted = 1; |
3140 |
+- return 1; |
3141 |
+-#else |
3142 |
+- host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0; |
3143 |
+- INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted); |
3144 |
+- return host->card_inserted; |
3145 |
+-#endif |
3146 |
+- } |
3147 |
+- |
3148 |
+- /* MSDC_CD_PIN_EN set for card */ |
3149 |
+- if (host->hw->flags & MSDC_CD_PIN_EN) { |
3150 |
+- spin_lock_irqsave(&host->lock, flags); |
3151 |
+-#if 0 |
3152 |
+- present = host->card_inserted; /* why not read from H/W: Fix me*/ |
3153 |
+-#else |
3154 |
+- // CD |
3155 |
+- present = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS; |
3156 |
+- if (cd_active_low) |
3157 |
+- present = present ? 0 : 1; |
3158 |
+- else |
3159 |
+- present = present ? 1 : 0; |
3160 |
+- host->card_inserted = present; |
3161 |
+-#endif |
3162 |
+- spin_unlock_irqrestore(&host->lock, flags); |
3163 |
+- } else { |
3164 |
+- present = 0; /* TODO? Check DAT3 pins for card detection */ |
3165 |
+- } |
3166 |
+- |
3167 |
+- INIT_MSG("ops_get_cd return<%d>", present); |
3168 |
+- return present; |
3169 |
+-} |
3170 |
+- |
3171 |
+-static struct mmc_host_ops mt_msdc_ops = { |
3172 |
+- .request = msdc_ops_request, |
3173 |
+- .set_ios = msdc_ops_set_ios, |
3174 |
+- .get_ro = msdc_ops_get_ro, |
3175 |
+- .get_cd = msdc_ops_get_cd, |
3176 |
+-}; |
3177 |
+- |
3178 |
+-/*--------------------------------------------------------------------------*/ |
3179 |
+-/* interrupt handler */ |
3180 |
+-/*--------------------------------------------------------------------------*/ |
3181 |
+-static irqreturn_t msdc_irq(int irq, void *dev_id) |
3182 |
+-{ |
3183 |
+- struct msdc_host *host = (struct msdc_host *)dev_id; |
3184 |
+- struct mmc_data *data = host->data; |
3185 |
+- struct mmc_command *cmd = host->cmd; |
3186 |
+- |
3187 |
+- u32 cmdsts = MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | MSDC_INT_CMDRDY | |
3188 |
+- MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY | |
3189 |
+- MSDC_INT_ACMD19_DONE; |
3190 |
+- u32 datsts = MSDC_INT_DATCRCERR | MSDC_INT_DATTMO; |
3191 |
+- |
3192 |
+- u32 intsts = readl(host->base + MSDC_INT); |
3193 |
+- u32 inten = readl(host->base + MSDC_INTEN); inten &= intsts; |
3194 |
+- |
3195 |
+- writel(intsts, host->base + MSDC_INT); /* clear interrupts */ |
3196 |
+- /* MSG will cause fatal error */ |
3197 |
+- |
3198 |
+- /* card change interrupt */ |
3199 |
+- if (intsts & MSDC_INT_CDSC) { |
3200 |
+- if (host->mmc->caps & MMC_CAP_NEEDS_POLL) |
3201 |
+- return IRQ_HANDLED; |
3202 |
+- IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts); |
3203 |
+- schedule_delayed_work(&host->card_delaywork, HZ); |
3204 |
+- /* tuning when plug card ? */ |
3205 |
+- } |
3206 |
+- |
3207 |
+- /* sdio interrupt */ |
3208 |
+- if (intsts & MSDC_INT_SDIOIRQ) { |
3209 |
+- IRQ_MSG("XXX MSDC_INT_SDIOIRQ"); /* seems not sdio irq */ |
3210 |
+- //mmc_signal_sdio_irq(host->mmc); |
3211 |
+- } |
3212 |
+- |
3213 |
+- /* transfer complete interrupt */ |
3214 |
+- if (data != NULL) { |
3215 |
+- if (inten & MSDC_INT_XFER_COMPL) { |
3216 |
+- data->bytes_xfered = host->xfer_size; |
3217 |
+- complete(&host->xfer_done); |
3218 |
+- } |
3219 |
+- |
3220 |
+- if (intsts & datsts) { |
3221 |
+- /* do basic reset, or stop command will sdc_busy */ |
3222 |
+- msdc_reset_hw(host); |
3223 |
+- msdc_clr_fifo(host); |
3224 |
+- msdc_clr_int(); |
3225 |
+- |
3226 |
+- if (intsts & MSDC_INT_DATTMO) { |
3227 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode); |
3228 |
+- data->error = -ETIMEDOUT; |
3229 |
+- } else if (intsts & MSDC_INT_DATCRCERR) { |
3230 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(host->base + SDC_DCRC_STS)); |
3231 |
+- data->error = -EIO; |
3232 |
+- } |
3233 |
+- |
3234 |
+- //if(readl(MSDC_INTEN) & MSDC_INT_XFER_COMPL) { |
3235 |
+- complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */ |
3236 |
+- } |
3237 |
+- } |
3238 |
+- |
3239 |
+- /* command interrupts */ |
3240 |
+- if ((cmd != NULL) && (intsts & cmdsts)) { |
3241 |
+- if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) || |
3242 |
+- (intsts & MSDC_INT_ACMD19_DONE)) { |
3243 |
+- u32 *rsp = &cmd->resp[0]; |
3244 |
+- |
3245 |
+- switch (host->cmd_rsp) { |
3246 |
+- case RESP_NONE: |
3247 |
+- break; |
3248 |
+- case RESP_R2: |
3249 |
+- *rsp++ = readl(host->base + SDC_RESP3); |
3250 |
+- *rsp++ = readl(host->base + SDC_RESP2); |
3251 |
+- *rsp++ = readl(host->base + SDC_RESP1); |
3252 |
+- *rsp++ = readl(host->base + SDC_RESP0); |
3253 |
+- break; |
3254 |
+- default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ |
3255 |
+- if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE)) |
3256 |
+- *rsp = readl(host->base + SDC_ACMD_RESP); |
3257 |
+- else |
3258 |
+- *rsp = readl(host->base + SDC_RESP0); |
3259 |
+- break; |
3260 |
+- } |
3261 |
+- } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) { |
3262 |
+- if (intsts & MSDC_INT_ACMDCRCERR) |
3263 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode); |
3264 |
+- else |
3265 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode); |
3266 |
+- cmd->error = -EIO; |
3267 |
+- } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) { |
3268 |
+- if (intsts & MSDC_INT_ACMDTMO) |
3269 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode); |
3270 |
+- else |
3271 |
+- IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode); |
3272 |
+- cmd->error = -ETIMEDOUT; |
3273 |
+- msdc_reset_hw(host); |
3274 |
+- msdc_clr_fifo(host); |
3275 |
+- msdc_clr_int(); |
3276 |
+- } |
3277 |
+- complete(&host->cmd_done); |
3278 |
+- } |
3279 |
+- |
3280 |
+- /* mmc irq interrupts */ |
3281 |
+- if (intsts & MSDC_INT_MMCIRQ) |
3282 |
+- printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", |
3283 |
+- host->id, readl(host->base + SDC_CSTS)); |
3284 |
+- |
3285 |
+-#ifdef MT6575_SD_DEBUG |
3286 |
+- { |
3287 |
+-/* msdc_int_reg *int_reg = (msdc_int_reg*)&intsts;*/ |
3288 |
+- N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)", |
3289 |
+- intsts, |
3290 |
+- int_reg->mmcirq, |
3291 |
+- int_reg->cdsc, |
3292 |
+- int_reg->atocmdrdy, |
3293 |
+- int_reg->atocmdtmo, |
3294 |
+- int_reg->atocmdcrc, |
3295 |
+- int_reg->atocmd19done); |
3296 |
+- N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)", |
3297 |
+- intsts, |
3298 |
+- int_reg->sdioirq, |
3299 |
+- int_reg->cmdrdy, |
3300 |
+- int_reg->cmdtmo, |
3301 |
+- int_reg->rspcrc, |
3302 |
+- int_reg->csta); |
3303 |
+- N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)", |
3304 |
+- intsts, |
3305 |
+- int_reg->xfercomp, |
3306 |
+- int_reg->dxferdone, |
3307 |
+- int_reg->dattmo, |
3308 |
+- int_reg->datcrc, |
3309 |
+- int_reg->dmaqempty); |
3310 |
+- } |
3311 |
+-#endif |
3312 |
+- |
3313 |
+- return IRQ_HANDLED; |
3314 |
+-} |
3315 |
+- |
3316 |
+-/*--------------------------------------------------------------------------*/ |
3317 |
+-/* platform_driver members */ |
3318 |
+-/*--------------------------------------------------------------------------*/ |
3319 |
+-/* called by msdc_drv_probe/remove */ |
3320 |
+-static void msdc_enable_cd_irq(struct msdc_host *host, int enable) |
3321 |
+-{ |
3322 |
+- struct msdc_hw *hw = host->hw; |
3323 |
+- |
3324 |
+- /* for sdio, not set */ |
3325 |
+- if ((hw->flags & MSDC_CD_PIN_EN) == 0) { |
3326 |
+- /* Pull down card detection pin since it is not avaiable */ |
3327 |
+- /* |
3328 |
+- if (hw->config_gpio_pin) |
3329 |
+- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); |
3330 |
+- */ |
3331 |
+- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); |
3332 |
+- sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); |
3333 |
+- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); |
3334 |
+- return; |
3335 |
+- } |
3336 |
+- |
3337 |
+- N_MSG(CFG, "CD IRQ Enable(%d)", enable); |
3338 |
+- |
3339 |
+- if (enable) { |
3340 |
+- /* card detection circuit relies on the core power so that the core power |
3341 |
+- * shouldn't be turned off. Here adds a reference count to keep |
3342 |
+- * the core power alive. |
3343 |
+- */ |
3344 |
+- //msdc_vcore_on(host); //did in msdc_init_hw() |
3345 |
+- |
3346 |
+- if (hw->config_gpio_pin) /* NULL */ |
3347 |
+- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP); |
3348 |
+- |
3349 |
+- sdr_set_field(host->base + MSDC_PS, MSDC_PS_CDDEBOUNCE, |
3350 |
+- DEFAULT_DEBOUNCE); |
3351 |
+- sdr_set_bits(host->base + MSDC_PS, MSDC_PS_CDEN); |
3352 |
+- sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); |
3353 |
+- |
3354 |
+- /* not in document! Fix me */ |
3355 |
+- sdr_set_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); |
3356 |
+- } else { |
3357 |
+- if (hw->config_gpio_pin) /* NULL */ |
3358 |
+- hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); |
3359 |
+- |
3360 |
+- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP); |
3361 |
+- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); |
3362 |
+- sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC); |
3363 |
+- |
3364 |
+- /* Here decreases a reference count to core power since card |
3365 |
+- * detection circuit is shutdown. |
3366 |
+- */ |
3367 |
+- //msdc_vcore_off(host); |
3368 |
+- } |
3369 |
+-} |
3370 |
+- |
3371 |
+-/* called by msdc_drv_probe */ |
3372 |
+-static void msdc_init_hw(struct msdc_host *host) |
3373 |
+-{ |
3374 |
+- |
3375 |
+- /* Power on */ |
3376 |
+-#if 0 /* --- by chhung */ |
3377 |
+- msdc_vcore_on(host); |
3378 |
+- msdc_pin_reset(host, MSDC_PIN_PULL_UP); |
3379 |
+- msdc_select_clksrc(host, hw->clk_src); |
3380 |
+- enable_clock(PERI_MSDC0_PDN + host->id, "SD"); |
3381 |
+- msdc_vdd_on(host); |
3382 |
+-#endif /* end of --- */ |
3383 |
+- /* Configure to MMC/SD mode */ |
3384 |
+- sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC); |
3385 |
+- |
3386 |
+- /* Reset */ |
3387 |
+- msdc_reset_hw(host); |
3388 |
+- msdc_clr_fifo(host); |
3389 |
+- |
3390 |
+- /* Disable card detection */ |
3391 |
+- sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); |
3392 |
+- |
3393 |
+- /* Disable and clear all interrupts */ |
3394 |
+- sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN)); |
3395 |
+- writel(readl(host->base + MSDC_INT), host->base + MSDC_INT); |
3396 |
+- |
3397 |
+-#if 1 |
3398 |
+- /* reset tuning parameter */ |
3399 |
+- writel(0x00090000, host->base + MSDC_PAD_CTL0); |
3400 |
+- writel(0x000A0000, host->base + MSDC_PAD_CTL1); |
3401 |
+- writel(0x000A0000, host->base + MSDC_PAD_CTL2); |
3402 |
+- // writel( 0x00000000, host->base + MSDC_PAD_TUNE); |
3403 |
+- |
3404 |
+- // for MT7620 E2 and afterward |
3405 |
+- writel(0x84101010, host->base + MSDC_PAD_TUNE); |
3406 |
+- |
3407 |
+- // writel(0x00000000, host->base + MSDC_DAT_RDDLY0); |
3408 |
+- |
3409 |
+- // for MT7620 E2 and afterward |
3410 |
+- writel(0x10101010, host->base + MSDC_DAT_RDDLY0); |
3411 |
+- |
3412 |
+- writel(0x00000000, host->base + MSDC_DAT_RDDLY1); |
3413 |
+- writel(0x00000000, host->base + MSDC_IOCON); |
3414 |
+-#if 0 // use MT7620 default value: 0x403c004f |
3415 |
+- /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/ |
3416 |
+- writel(0x003C000F, host->base + MSDC_PATCH_BIT0); |
3417 |
+-#endif |
3418 |
+- |
3419 |
+- if (readl(host->base + MSDC_ECO_VER) >= 4) { |
3420 |
+- if (host->id == 1) { |
3421 |
+- sdr_set_field(host->base + MSDC_PATCH_BIT1, |
3422 |
+- MSDC_PATCH_BIT1_WRDAT_CRCS, 1); |
3423 |
+- sdr_set_field(host->base + MSDC_PATCH_BIT1, |
3424 |
+- MSDC_PATCH_BIT1_CMD_RSP, 1); |
3425 |
+- |
3426 |
+- /* internal clock: latch read data */ |
3427 |
+- sdr_set_bits(host->base + MSDC_PATCH_BIT0, |
3428 |
+- MSDC_PATCH_BIT_CKGEN_CK); |
3429 |
+- } |
3430 |
+- } |
3431 |
+-#endif |
3432 |
+- |
3433 |
+- /* for safety, should clear SDC_CFG.SDIO_INT_DET_EN & set SDC_CFG.SDIO in |
3434 |
+- pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only |
3435 |
+- set when kernel driver wants to use SDIO bus interrupt */ |
3436 |
+- /* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */ |
3437 |
+- sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO); |
3438 |
+- |
3439 |
+- /* disable detect SDIO device interupt function */ |
3440 |
+- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); |
3441 |
+- |
3442 |
+- /* eneable SMT for glitch filter */ |
3443 |
+- sdr_set_bits(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT); |
3444 |
+- sdr_set_bits(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT); |
3445 |
+- sdr_set_bits(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT); |
3446 |
+- |
3447 |
+-#if 1 |
3448 |
+- /* set clk, cmd, dat pad driving */ |
3449 |
+- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4); |
3450 |
+- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4); |
3451 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4); |
3452 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4); |
3453 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4); |
3454 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4); |
3455 |
+-#else |
3456 |
+- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0); |
3457 |
+- sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0); |
3458 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0); |
3459 |
+- sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0); |
3460 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0); |
3461 |
+- sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0); |
3462 |
+-#endif |
3463 |
+- |
3464 |
+- /* set sampling edge */ |
3465 |
+- |
3466 |
+- /* write crc timeout detection */ |
3467 |
+- sdr_set_field(host->base + MSDC_PATCH_BIT0, 1 << 30, 1); |
3468 |
+- |
3469 |
+- /* Configure to default data timeout */ |
3470 |
+- sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC); |
3471 |
+- |
3472 |
+- msdc_set_buswidth(host, MMC_BUS_WIDTH_1); |
3473 |
+- |
3474 |
+- N_MSG(FUC, "init hardware done!"); |
3475 |
+-} |
3476 |
+- |
3477 |
+-/* called by msdc_drv_remove */ |
3478 |
+-static void msdc_deinit_hw(struct msdc_host *host) |
3479 |
+-{ |
3480 |
+- /* Disable and clear all interrupts */ |
3481 |
+- sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN)); |
3482 |
+- writel(readl(host->base + MSDC_INT), host->base + MSDC_INT); |
3483 |
+- |
3484 |
+- /* Disable card detection */ |
3485 |
+- msdc_enable_cd_irq(host, 0); |
3486 |
+- // msdc_set_power_mode(host, MMC_POWER_OFF); /* make sure power down */ /* --- by chhung */ |
3487 |
+-} |
3488 |
+- |
3489 |
+-/* init gpd and bd list in msdc_drv_probe */ |
3490 |
+-static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) |
3491 |
+-{ |
3492 |
+- struct gpd *gpd = dma->gpd; |
3493 |
+- struct bd *bd = dma->bd; |
3494 |
+- int i; |
3495 |
+- |
3496 |
+- /* we just support one gpd, but gpd->next must be set for desc |
3497 |
+- * DMA. That's why we alloc 2 gpd structurs. |
3498 |
+- */ |
3499 |
+- |
3500 |
+- memset(gpd, 0, sizeof(struct gpd) * 2); |
3501 |
+- |
3502 |
+- gpd->bdp = 1; /* hwo, cs, bd pointer */ |
3503 |
+- gpd->ptr = (void *)dma->bd_addr; /* physical address */ |
3504 |
+- gpd->next = (void *)((u32)dma->gpd_addr + sizeof(struct gpd)); |
3505 |
+- |
3506 |
+- memset(bd, 0, sizeof(struct bd) * MAX_BD_NUM); |
3507 |
+- for (i = 0; i < (MAX_BD_NUM - 1); i++) |
3508 |
+- bd[i].next = (void *)(dma->bd_addr + sizeof(*bd) * (i + 1)); |
3509 |
+-} |
3510 |
+- |
3511 |
+-static int msdc_drv_probe(struct platform_device *pdev) |
3512 |
+-{ |
3513 |
+- struct resource *res; |
3514 |
+- __iomem void *base; |
3515 |
+- struct mmc_host *mmc; |
3516 |
+- struct msdc_host *host; |
3517 |
+- struct msdc_hw *hw; |
3518 |
+- int ret; |
3519 |
+- |
3520 |
+- hw = &msdc0_hw; |
3521 |
+- |
3522 |
+- if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en")) |
3523 |
+- msdc0_hw.flags |= MSDC_WP_PIN_EN; |
3524 |
+- |
3525 |
+- /* Allocate MMC host for this device */ |
3526 |
+- mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); |
3527 |
+- if (!mmc) |
3528 |
+- return -ENOMEM; |
3529 |
+- |
3530 |
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
3531 |
+- base = devm_ioremap_resource(&pdev->dev, res); |
3532 |
+- if (IS_ERR(base)) { |
3533 |
+- ret = PTR_ERR(base); |
3534 |
+- goto host_free; |
3535 |
+- } |
3536 |
+- |
3537 |
+- /* Set host parameters to mmc */ |
3538 |
+- mmc->ops = &mt_msdc_ops; |
3539 |
+- mmc->f_min = HOST_MIN_MCLK; |
3540 |
+- mmc->f_max = HOST_MAX_MCLK; |
3541 |
+- mmc->ocr_avail = MSDC_OCR_AVAIL; |
3542 |
+- |
3543 |
+- mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; |
3544 |
+- |
3545 |
+- //TODO: read this as bus-width from dt (via mmc_of_parse) |
3546 |
+- mmc->caps |= MMC_CAP_4_BIT_DATA; |
3547 |
+- |
3548 |
+- cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high"); |
3549 |
+- |
3550 |
+- if (of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll")) |
3551 |
+- mmc->caps |= MMC_CAP_NEEDS_POLL; |
3552 |
+- |
3553 |
+- /* MMC core transfer sizes tunable parameters */ |
3554 |
+- mmc->max_segs = MAX_HW_SGMTS; |
3555 |
+- |
3556 |
+- mmc->max_seg_size = MAX_SGMT_SZ; |
3557 |
+- mmc->max_blk_size = HOST_MAX_BLKSZ; |
3558 |
+- mmc->max_req_size = MAX_REQ_SZ; |
3559 |
+- mmc->max_blk_count = mmc->max_req_size; |
3560 |
+- |
3561 |
+- host = mmc_priv(mmc); |
3562 |
+- host->hw = hw; |
3563 |
+- host->mmc = mmc; |
3564 |
+- host->id = pdev->id; |
3565 |
+- if (host->id < 0 || host->id >= 4) |
3566 |
+- host->id = 0; |
3567 |
+- host->error = 0; |
3568 |
+- |
3569 |
+- host->irq = platform_get_irq(pdev, 0); |
3570 |
+- if (host->irq < 0) { |
3571 |
+- ret = -EINVAL; |
3572 |
+- goto host_free; |
3573 |
+- } |
3574 |
+- |
3575 |
+- host->base = base; |
3576 |
+- host->mclk = 0; /* mclk: the request clock of mmc sub-system */ |
3577 |
+- host->hclk = hclks[hw->clk_src]; /* hclk: clock of clock source to msdc controller */ |
3578 |
+- host->sclk = 0; /* sclk: the really clock after divition */ |
3579 |
+- host->pm_state = PMSG_RESUME; |
3580 |
+- host->suspend = 0; |
3581 |
+- host->core_clkon = 0; |
3582 |
+- host->card_clkon = 0; |
3583 |
+- host->core_power = 0; |
3584 |
+- host->power_mode = MMC_POWER_OFF; |
3585 |
+-// host->card_inserted = hw->flags & MSDC_REMOVABLE ? 0 : 1; |
3586 |
+- host->timeout_ns = 0; |
3587 |
+- host->timeout_clks = DEFAULT_DTOC * 65536; |
3588 |
+- |
3589 |
+- host->mrq = NULL; |
3590 |
+- //init_MUTEX(&host->sem); /* we don't need to support multiple threads access */ |
3591 |
+- |
3592 |
+- mmc_dev(mmc)->dma_mask = NULL; |
3593 |
+- |
3594 |
+- /* using dma_alloc_coherent*/ /* todo: using 1, for all 4 slots */ |
3595 |
+- host->dma.gpd = dma_alloc_coherent(&pdev->dev, |
3596 |
+- MAX_GPD_NUM * sizeof(struct gpd), |
3597 |
+- &host->dma.gpd_addr, GFP_KERNEL); |
3598 |
+- host->dma.bd = dma_alloc_coherent(&pdev->dev, |
3599 |
+- MAX_BD_NUM * sizeof(struct bd), |
3600 |
+- &host->dma.bd_addr, GFP_KERNEL); |
3601 |
+- if (!host->dma.gpd || !host->dma.bd) { |
3602 |
+- ret = -ENOMEM; |
3603 |
+- goto release_mem; |
3604 |
+- } |
3605 |
+- msdc_init_gpd_bd(host, &host->dma); |
3606 |
+- |
3607 |
+- INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card); |
3608 |
+- spin_lock_init(&host->lock); |
3609 |
+- msdc_init_hw(host); |
3610 |
+- |
3611 |
+- /* TODO check weather flags 0 is correct, the mtk-sd driver uses |
3612 |
+- * IRQF_TRIGGER_LOW | IRQF_ONESHOT for flags |
3613 |
+- * |
3614 |
+- * for flags 0 the trigger polarity is determined by the |
3615 |
+- * device tree, but not the oneshot flag, but maybe it is also |
3616 |
+- * not needed because the soc could be oneshot safe. |
3617 |
+- */ |
3618 |
+- ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, 0, pdev->name, |
3619 |
+- host); |
3620 |
+- if (ret) |
3621 |
+- goto release; |
3622 |
+- |
3623 |
+- platform_set_drvdata(pdev, mmc); |
3624 |
+- |
3625 |
+- ret = mmc_add_host(mmc); |
3626 |
+- if (ret) |
3627 |
+- goto release; |
3628 |
+- |
3629 |
+- /* Config card detection pin and enable interrupts */ |
3630 |
+- if (hw->flags & MSDC_CD_PIN_EN) { /* set for card */ |
3631 |
+- msdc_enable_cd_irq(host, 1); |
3632 |
+- } else { |
3633 |
+- msdc_enable_cd_irq(host, 0); |
3634 |
+- } |
3635 |
+- |
3636 |
+- return 0; |
3637 |
+- |
3638 |
+-release: |
3639 |
+- platform_set_drvdata(pdev, NULL); |
3640 |
+- msdc_deinit_hw(host); |
3641 |
+- cancel_delayed_work_sync(&host->card_delaywork); |
3642 |
+- |
3643 |
+-release_mem: |
3644 |
+- if (host->dma.gpd) |
3645 |
+- dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), |
3646 |
+- host->dma.gpd, host->dma.gpd_addr); |
3647 |
+- if (host->dma.bd) |
3648 |
+- dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), |
3649 |
+- host->dma.bd, host->dma.bd_addr); |
3650 |
+-host_free: |
3651 |
+- mmc_free_host(mmc); |
3652 |
+- |
3653 |
+- return ret; |
3654 |
+-} |
3655 |
+- |
3656 |
+-/* 4 device share one driver, using "drvdata" to show difference */ |
3657 |
+-static int msdc_drv_remove(struct platform_device *pdev) |
3658 |
+-{ |
3659 |
+- struct mmc_host *mmc; |
3660 |
+- struct msdc_host *host; |
3661 |
+- |
3662 |
+- mmc = platform_get_drvdata(pdev); |
3663 |
+- BUG_ON(!mmc); |
3664 |
+- |
3665 |
+- host = mmc_priv(mmc); |
3666 |
+- BUG_ON(!host); |
3667 |
+- |
3668 |
+- ERR_MSG("removed !!!"); |
3669 |
+- |
3670 |
+- platform_set_drvdata(pdev, NULL); |
3671 |
+- mmc_remove_host(host->mmc); |
3672 |
+- msdc_deinit_hw(host); |
3673 |
+- |
3674 |
+- cancel_delayed_work_sync(&host->card_delaywork); |
3675 |
+- |
3676 |
+- dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), |
3677 |
+- host->dma.gpd, host->dma.gpd_addr); |
3678 |
+- dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), |
3679 |
+- host->dma.bd, host->dma.bd_addr); |
3680 |
+- |
3681 |
+- mmc_free_host(host->mmc); |
3682 |
+- |
3683 |
+- return 0; |
3684 |
+-} |
3685 |
+- |
3686 |
+-/* Fix me: Power Flow */ |
3687 |
+-#ifdef CONFIG_PM |
3688 |
+- |
3689 |
+-static void msdc_drv_pm(struct platform_device *pdev, pm_message_t state) |
3690 |
+-{ |
3691 |
+- struct mmc_host *mmc = platform_get_drvdata(pdev); |
3692 |
+- if (mmc) { |
3693 |
+- struct msdc_host *host = mmc_priv(mmc); |
3694 |
+- msdc_pm(state, (void *)host); |
3695 |
+- } |
3696 |
+-} |
3697 |
+- |
3698 |
+-static int msdc_drv_suspend(struct platform_device *pdev, pm_message_t state) |
3699 |
+-{ |
3700 |
+- if (state.event == PM_EVENT_SUSPEND) |
3701 |
+- msdc_drv_pm(pdev, state); |
3702 |
+- return 0; |
3703 |
+-} |
3704 |
+- |
3705 |
+-static int msdc_drv_resume(struct platform_device *pdev) |
3706 |
+-{ |
3707 |
+- struct pm_message state; |
3708 |
+- |
3709 |
+- state.event = PM_EVENT_RESUME; |
3710 |
+- msdc_drv_pm(pdev, state); |
3711 |
+- return 0; |
3712 |
+-} |
3713 |
+-#endif |
3714 |
+- |
3715 |
+-static const struct of_device_id mt7620_sdhci_match[] = { |
3716 |
+- { .compatible = "ralink,mt7620-sdhci" }, |
3717 |
+- {}, |
3718 |
+-}; |
3719 |
+-MODULE_DEVICE_TABLE(of, mt7620_sdhci_match); |
3720 |
+- |
3721 |
+-static struct platform_driver mt_msdc_driver = { |
3722 |
+- .probe = msdc_drv_probe, |
3723 |
+- .remove = msdc_drv_remove, |
3724 |
+-#ifdef CONFIG_PM |
3725 |
+- .suspend = msdc_drv_suspend, |
3726 |
+- .resume = msdc_drv_resume, |
3727 |
+-#endif |
3728 |
+- .driver = { |
3729 |
+- .name = DRV_NAME, |
3730 |
+- .of_match_table = mt7620_sdhci_match, |
3731 |
+- }, |
3732 |
+-}; |
3733 |
+- |
3734 |
+-/*--------------------------------------------------------------------------*/ |
3735 |
+-/* module init/exit */ |
3736 |
+-/*--------------------------------------------------------------------------*/ |
3737 |
+-static int __init mt_msdc_init(void) |
3738 |
+-{ |
3739 |
+- int ret; |
3740 |
+- u32 reg; |
3741 |
+- |
3742 |
+- // Set the pins for sdxc to sdxc mode |
3743 |
+- //FIXME: this should be done by pinctl and not by the sd driver |
3744 |
+- reg = readl((void __iomem *)(RALINK_SYSCTL_BASE + 0x60)) & ~(0x3 << 18); |
3745 |
+- writel(reg, (void __iomem *)(RALINK_SYSCTL_BASE + 0x60)); |
3746 |
+- |
3747 |
+- ret = platform_driver_register(&mt_msdc_driver); |
3748 |
+- if (ret) { |
3749 |
+- printk(KERN_ERR DRV_NAME ": Can't register driver"); |
3750 |
+- return ret; |
3751 |
+- } |
3752 |
+- |
3753 |
+-#if defined(MT6575_SD_DEBUG) |
3754 |
+- msdc_debug_proc_init(); |
3755 |
+-#endif |
3756 |
+- return 0; |
3757 |
+-} |
3758 |
+- |
3759 |
+-static void __exit mt_msdc_exit(void) |
3760 |
+-{ |
3761 |
+- platform_driver_unregister(&mt_msdc_driver); |
3762 |
+-} |
3763 |
+- |
3764 |
+-module_init(mt_msdc_init); |
3765 |
+-module_exit(mt_msdc_exit); |
3766 |
+-MODULE_LICENSE("GPL"); |
3767 |
+-MODULE_DESCRIPTION("MediaTek MT6575 SD/MMC Card Driver"); |
3768 |
+-MODULE_AUTHOR("Infinity Chen <infinity.chen@××××××××.com>"); |
3769 |
+diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c |
3770 |
+index 8c577f0ae2bb3..b370144682ed5 100644 |
3771 |
+--- a/drivers/xen/events/events_base.c |
3772 |
++++ b/drivers/xen/events/events_base.c |
3773 |
+@@ -1782,7 +1782,7 @@ static void lateeoi_ack_dynirq(struct irq_data *data) |
3774 |
+ |
3775 |
+ if (VALID_EVTCHN(evtchn)) { |
3776 |
+ do_mask(info, EVT_MASK_REASON_EOI_PENDING); |
3777 |
+- event_handler_exit(info); |
3778 |
++ ack_dynirq(data); |
3779 |
+ } |
3780 |
+ } |
3781 |
+ |
3782 |
+@@ -1793,7 +1793,7 @@ static void lateeoi_mask_ack_dynirq(struct irq_data *data) |
3783 |
+ |
3784 |
+ if (VALID_EVTCHN(evtchn)) { |
3785 |
+ do_mask(info, EVT_MASK_REASON_EXPLICIT); |
3786 |
+- event_handler_exit(info); |
3787 |
++ ack_dynirq(data); |
3788 |
+ } |
3789 |
+ } |
3790 |
+ |
3791 |
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c |
3792 |
+index 22cd68bd8c9b0..3cc2237e58967 100644 |
3793 |
+--- a/fs/gfs2/super.c |
3794 |
++++ b/fs/gfs2/super.c |
3795 |
+@@ -1000,11 +1000,13 @@ void gfs2_freeze_func(struct work_struct *work) |
3796 |
+ static int gfs2_freeze(struct super_block *sb) |
3797 |
+ { |
3798 |
+ struct gfs2_sbd *sdp = sb->s_fs_info; |
3799 |
+- int error = 0; |
3800 |
++ int error; |
3801 |
+ |
3802 |
+ mutex_lock(&sdp->sd_freeze_mutex); |
3803 |
+- if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) |
3804 |
++ if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) { |
3805 |
++ error = -EBUSY; |
3806 |
+ goto out; |
3807 |
++ } |
3808 |
+ |
3809 |
+ if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { |
3810 |
+ error = -EINVAL; |
3811 |
+@@ -1046,10 +1048,10 @@ static int gfs2_unfreeze(struct super_block *sb) |
3812 |
+ struct gfs2_sbd *sdp = sb->s_fs_info; |
3813 |
+ |
3814 |
+ mutex_lock(&sdp->sd_freeze_mutex); |
3815 |
+- if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || |
3816 |
++ if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || |
3817 |
+ !gfs2_holder_initialized(&sdp->sd_freeze_gh)) { |
3818 |
+ mutex_unlock(&sdp->sd_freeze_mutex); |
3819 |
+- return 0; |
3820 |
++ return -EINVAL; |
3821 |
+ } |
3822 |
+ |
3823 |
+ gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); |
3824 |
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c |
3825 |
+index 10d8f95eb7712..fba56cd958961 100644 |
3826 |
+--- a/net/ipv4/netfilter/arp_tables.c |
3827 |
++++ b/net/ipv4/netfilter/arp_tables.c |
3828 |
+@@ -1195,6 +1195,8 @@ static int translate_compat_table(struct net *net, |
3829 |
+ if (!newinfo) |
3830 |
+ goto out_unlock; |
3831 |
+ |
3832 |
++ memset(newinfo->entries, 0, size); |
3833 |
++ |
3834 |
+ newinfo->number = compatr->num_entries; |
3835 |
+ for (i = 0; i < NF_ARP_NUMHOOKS; i++) { |
3836 |
+ newinfo->hook_entry[i] = compatr->hook_entry[i]; |
3837 |
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c |
3838 |
+index e77872c93c206..730a40dc829aa 100644 |
3839 |
+--- a/net/ipv4/netfilter/ip_tables.c |
3840 |
++++ b/net/ipv4/netfilter/ip_tables.c |
3841 |
+@@ -1433,6 +1433,8 @@ translate_compat_table(struct net *net, |
3842 |
+ if (!newinfo) |
3843 |
+ goto out_unlock; |
3844 |
+ |
3845 |
++ memset(newinfo->entries, 0, size); |
3846 |
++ |
3847 |
+ newinfo->number = compatr->num_entries; |
3848 |
+ for (i = 0; i < NF_INET_NUMHOOKS; i++) { |
3849 |
+ newinfo->hook_entry[i] = compatr->hook_entry[i]; |
3850 |
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c |
3851 |
+index daf2e9e9193d1..dd0c1073dc8ee 100644 |
3852 |
+--- a/net/ipv6/netfilter/ip6_tables.c |
3853 |
++++ b/net/ipv6/netfilter/ip6_tables.c |
3854 |
+@@ -1448,6 +1448,8 @@ translate_compat_table(struct net *net, |
3855 |
+ if (!newinfo) |
3856 |
+ goto out_unlock; |
3857 |
+ |
3858 |
++ memset(newinfo->entries, 0, size); |
3859 |
++ |
3860 |
+ newinfo->number = compatr->num_entries; |
3861 |
+ for (i = 0; i < NF_INET_NUMHOOKS; i++) { |
3862 |
+ newinfo->hook_entry[i] = compatr->hook_entry[i]; |
3863 |
+diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c |
3864 |
+index c9fe35118b33a..5dd6f6ce92e6b 100644 |
3865 |
+--- a/net/netfilter/x_tables.c |
3866 |
++++ b/net/netfilter/x_tables.c |
3867 |
+@@ -738,7 +738,7 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, |
3868 |
+ { |
3869 |
+ const struct xt_match *match = m->u.kernel.match; |
3870 |
+ struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m; |
3871 |
+- int pad, off = xt_compat_match_offset(match); |
3872 |
++ int off = xt_compat_match_offset(match); |
3873 |
+ u_int16_t msize = cm->u.user.match_size; |
3874 |
+ char name[sizeof(m->u.user.name)]; |
3875 |
+ |
3876 |
+@@ -748,9 +748,6 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, |
3877 |
+ match->compat_from_user(m->data, cm->data); |
3878 |
+ else |
3879 |
+ memcpy(m->data, cm->data, msize - sizeof(*cm)); |
3880 |
+- pad = XT_ALIGN(match->matchsize) - match->matchsize; |
3881 |
+- if (pad > 0) |
3882 |
+- memset(m->data + match->matchsize, 0, pad); |
3883 |
+ |
3884 |
+ msize += off; |
3885 |
+ m->u.user.match_size = msize; |
3886 |
+@@ -1121,7 +1118,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, |
3887 |
+ { |
3888 |
+ const struct xt_target *target = t->u.kernel.target; |
3889 |
+ struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t; |
3890 |
+- int pad, off = xt_compat_target_offset(target); |
3891 |
++ int off = xt_compat_target_offset(target); |
3892 |
+ u_int16_t tsize = ct->u.user.target_size; |
3893 |
+ char name[sizeof(t->u.user.name)]; |
3894 |
+ |
3895 |
+@@ -1131,9 +1128,6 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, |
3896 |
+ target->compat_from_user(t->data, ct->data); |
3897 |
+ else |
3898 |
+ memcpy(t->data, ct->data, tsize - sizeof(*ct)); |
3899 |
+- pad = XT_ALIGN(target->targetsize) - target->targetsize; |
3900 |
+- if (pad > 0) |
3901 |
+- memset(t->data + target->targetsize, 0, pad); |
3902 |
+ |
3903 |
+ tsize += off; |
3904 |
+ t->u.user.target_size = tsize; |
3905 |
+diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c |
3906 |
+index d3d3601f41cc6..769d11575a7b3 100644 |
3907 |
+--- a/tools/perf/util/map.c |
3908 |
++++ b/tools/perf/util/map.c |
3909 |
+@@ -88,8 +88,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) |
3910 |
+ if (!strncmp(filename, "/system/lib/", 12)) { |
3911 |
+ char *ndk, *app; |
3912 |
+ const char *arch; |
3913 |
+- size_t ndk_length; |
3914 |
+- size_t app_length; |
3915 |
++ int ndk_length, app_length; |
3916 |
+ |
3917 |
+ ndk = getenv("NDK_ROOT"); |
3918 |
+ app = getenv("APP_PLATFORM"); |
3919 |
+@@ -117,8 +116,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) |
3920 |
+ if (new_length > PATH_MAX) |
3921 |
+ return false; |
3922 |
+ snprintf(newfilename, new_length, |
3923 |
+- "%s/platforms/%s/arch-%s/usr/lib/%s", |
3924 |
+- ndk, app, arch, libname); |
3925 |
++ "%.*s/platforms/%.*s/arch-%s/usr/lib/%s", |
3926 |
++ ndk_length, ndk, app_length, app, arch, libname); |
3927 |
+ |
3928 |
+ return true; |
3929 |
+ } |