Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * Copyright (C) 2010 Marvell International Ltd.
  3 *		Zhangfei Gao <zhangfei.gao@marvell.com>
  4 *		Kevin Wang <dwang4@marvell.com>
  5 *		Mingwei Wang <mwwang@marvell.com>
  6 *		Philip Rakity <prakity@marvell.com>
  7 *		Mark Brown <markb@marvell.com>
  8 *
  9 * This software is licensed under the terms of the GNU General Public
 10 * License version 2, as published by the Free Software Foundation, and
 11 * may be copied, distributed, and modified under those terms.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 */
 19#include <linux/err.h>
 20#include <linux/init.h>
 21#include <linux/platform_device.h>
 22#include <linux/clk.h>
 23#include <linux/io.h>
 24#include <linux/gpio.h>
 25#include <linux/mmc/card.h>
 26#include <linux/mmc/host.h>
 27#include <linux/mmc/slot-gpio.h>
 28#include <linux/platform_data/pxa_sdhci.h>
 29#include <linux/slab.h>
 30#include <linux/delay.h>
 31#include <linux/module.h>
 32#include <linux/of.h>
 33#include <linux/of_device.h>
 34#include <linux/of_gpio.h>
 35#include <linux/pm.h>
 36#include <linux/pm_runtime.h>
 37#include <linux/mbus.h>
 38
 39#include "sdhci.h"
 40#include "sdhci-pltfm.h"
 41
 42#define PXAV3_RPM_DELAY_MS     50
 43
 44#define SD_CLOCK_BURST_SIZE_SETUP		0x10A
 45#define SDCLK_SEL	0x100
 46#define SDCLK_DELAY_SHIFT	9
 47#define SDCLK_DELAY_MASK	0x1f
 48
 49#define SD_CFG_FIFO_PARAM       0x100
 50#define SDCFG_GEN_PAD_CLK_ON	(1<<6)
 51#define SDCFG_GEN_PAD_CLK_CNT_MASK	0xFF
 52#define SDCFG_GEN_PAD_CLK_CNT_SHIFT	24
 53
 54#define SD_SPI_MODE          0x108
 55#define SD_CE_ATA_1          0x10C
 56
 57#define SD_CE_ATA_2          0x10E
 58#define SDCE_MISC_INT		(1<<2)
 59#define SDCE_MISC_INT_EN	(1<<1)
 60
 61struct sdhci_pxa {
 62	struct clk *clk_core;
 63	struct clk *clk_io;
 64	u8	power_mode;
 65	void __iomem *sdio3_conf_reg;
 66};
 67
 68/*
 69 * These registers are relative to the second register region, for the
 70 * MBus bridge.
 71 */
 72#define SDHCI_WINDOW_CTRL(i)	(0x80 + ((i) << 3))
 73#define SDHCI_WINDOW_BASE(i)	(0x84 + ((i) << 3))
 74#define SDHCI_MAX_WIN_NUM	8
 75
 76/*
 77 * Fields below belong to SDIO3 Configuration Register (third register
 78 * region for the Armada 38x flavor)
 79 */
 80
 81#define SDIO3_CONF_CLK_INV	BIT(0)
 82#define SDIO3_CONF_SD_FB_CLK	BIT(2)
 83
 84static int mv_conf_mbus_windows(struct platform_device *pdev,
 85				const struct mbus_dram_target_info *dram)
 86{
 87	int i;
 88	void __iomem *regs;
 89	struct resource *res;
 90
 91	if (!dram) {
 92		dev_err(&pdev->dev, "no mbus dram info\n");
 93		return -EINVAL;
 94	}
 95
 96	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 97	if (!res) {
 98		dev_err(&pdev->dev, "cannot get mbus registers\n");
 99		return -EINVAL;
100	}
101
102	regs = ioremap(res->start, resource_size(res));
103	if (!regs) {
104		dev_err(&pdev->dev, "cannot map mbus registers\n");
105		return -ENOMEM;
106	}
107
108	for (i = 0; i < SDHCI_MAX_WIN_NUM; i++) {
109		writel(0, regs + SDHCI_WINDOW_CTRL(i));
110		writel(0, regs + SDHCI_WINDOW_BASE(i));
111	}
112
113	for (i = 0; i < dram->num_cs; i++) {
114		const struct mbus_dram_window *cs = dram->cs + i;
115
116		/* Write size, attributes and target id to control register */
117		writel(((cs->size - 1) & 0xffff0000) |
118			(cs->mbus_attr << 8) |
119			(dram->mbus_dram_target_id << 4) | 1,
120			regs + SDHCI_WINDOW_CTRL(i));
121		/* Write base address to base register */
122		writel(cs->base, regs + SDHCI_WINDOW_BASE(i));
123	}
124
125	iounmap(regs);
126
127	return 0;
128}
129
130static int armada_38x_quirks(struct platform_device *pdev,
131			     struct sdhci_host *host)
132{
133	struct device_node *np = pdev->dev.of_node;
134	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
135	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
136	struct resource *res;
137
138	host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
139	host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
140
141	host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
142	host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
143
144	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
145					   "conf-sdio3");
146	if (res) {
147		pxa->sdio3_conf_reg = devm_ioremap_resource(&pdev->dev, res);
148		if (IS_ERR(pxa->sdio3_conf_reg))
149			return PTR_ERR(pxa->sdio3_conf_reg);
150	} else {
151		/*
152		 * According to erratum 'FE-2946959' both SDR50 and DDR50
153		 * modes require specific clock adjustments in SDIO3
154		 * Configuration register, if the adjustment is not done,
155		 * remove them from the capabilities.
156		 */
157		host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50);
158
159		dev_warn(&pdev->dev, "conf-sdio3 register not found: disabling SDR50 and DDR50 modes.\nConsider updating your dtb\n");
160	}
161
162	/*
163	 * According to erratum 'ERR-7878951' Armada 38x SDHCI
164	 * controller has different capabilities than the ones shown
165	 * in its registers
166	 */
167	if (of_property_read_bool(np, "no-1-8-v")) {
168		host->caps &= ~SDHCI_CAN_VDD_180;
169		host->mmc->caps &= ~MMC_CAP_1_8V_DDR;
170	} else {
171		host->caps &= ~SDHCI_CAN_VDD_330;
172	}
173	host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_USE_SDR50_TUNING);
174
175	return 0;
176}
177
178static void pxav3_reset(struct sdhci_host *host, u8 mask)
179{
180	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
181	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
182
183	sdhci_reset(host, mask);
184
185	if (mask == SDHCI_RESET_ALL) {
186		/*
187		 * tune timing of read data/command when crc error happen
188		 * no performance impact
189		 */
190		if (pdata && 0 != pdata->clk_delay_cycles) {
191			u16 tmp;
192
193			tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
194			tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
195				<< SDCLK_DELAY_SHIFT;
196			tmp |= SDCLK_SEL;
197			writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
198		}
199	}
200}
201
202#define MAX_WAIT_COUNT 5
203static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode)
204{
205	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
206	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
207	u16 tmp;
208	int count;
209
210	if (pxa->power_mode == MMC_POWER_UP
211			&& power_mode == MMC_POWER_ON) {
212
213		dev_dbg(mmc_dev(host->mmc),
214				"%s: slot->power_mode = %d,"
215				"ios->power_mode = %d\n",
216				__func__,
217				pxa->power_mode,
218				power_mode);
219
220		/* set we want notice of when 74 clocks are sent */
221		tmp = readw(host->ioaddr + SD_CE_ATA_2);
222		tmp |= SDCE_MISC_INT_EN;
223		writew(tmp, host->ioaddr + SD_CE_ATA_2);
224
225		/* start sending the 74 clocks */
226		tmp = readw(host->ioaddr + SD_CFG_FIFO_PARAM);
227		tmp |= SDCFG_GEN_PAD_CLK_ON;
228		writew(tmp, host->ioaddr + SD_CFG_FIFO_PARAM);
229
230		/* slowest speed is about 100KHz or 10usec per clock */
231		udelay(740);
232		count = 0;
233
234		while (count++ < MAX_WAIT_COUNT) {
235			if ((readw(host->ioaddr + SD_CE_ATA_2)
236						& SDCE_MISC_INT) == 0)
237				break;
238			udelay(10);
239		}
240
241		if (count == MAX_WAIT_COUNT)
242			dev_warn(mmc_dev(host->mmc), "74 clock interrupt not cleared\n");
243
244		/* clear the interrupt bit if posted */
245		tmp = readw(host->ioaddr + SD_CE_ATA_2);
246		tmp |= SDCE_MISC_INT;
247		writew(tmp, host->ioaddr + SD_CE_ATA_2);
248	}
249	pxa->power_mode = power_mode;
250}
251
252static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
253{
254	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
255	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
256	u16 ctrl_2;
257
258	/*
259	 * Set V18_EN -- UHS modes do not work without this.
260	 * does not change signaling voltage
261	 */
262	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
263
264	/* Select Bus Speed Mode for host */
265	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
266	switch (uhs) {
267	case MMC_TIMING_UHS_SDR12:
268		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
269		break;
270	case MMC_TIMING_UHS_SDR25:
271		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
272		break;
273	case MMC_TIMING_UHS_SDR50:
274		ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
275		break;
276	case MMC_TIMING_UHS_SDR104:
277		ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
278		break;
279	case MMC_TIMING_MMC_DDR52:
280	case MMC_TIMING_UHS_DDR50:
281		ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
282		break;
283	}
284
285	/*
286	 * Update SDIO3 Configuration register according to erratum
287	 * FE-2946959
288	 */
289	if (pxa->sdio3_conf_reg) {
290		u8 reg_val  = readb(pxa->sdio3_conf_reg);
291
292		if (uhs == MMC_TIMING_UHS_SDR50 ||
293		    uhs == MMC_TIMING_UHS_DDR50) {
294			reg_val &= ~SDIO3_CONF_CLK_INV;
295			reg_val |= SDIO3_CONF_SD_FB_CLK;
296		} else if (uhs == MMC_TIMING_MMC_HS) {
297			reg_val &= ~SDIO3_CONF_CLK_INV;
298			reg_val &= ~SDIO3_CONF_SD_FB_CLK;
299		} else {
300			reg_val |= SDIO3_CONF_CLK_INV;
301			reg_val &= ~SDIO3_CONF_SD_FB_CLK;
302		}
303		writeb(reg_val, pxa->sdio3_conf_reg);
304	}
305
306	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
307	dev_dbg(mmc_dev(host->mmc),
308		"%s uhs = %d, ctrl_2 = %04X\n",
309		__func__, uhs, ctrl_2);
310}
311
312static void pxav3_set_power(struct sdhci_host *host, unsigned char mode,
313			    unsigned short vdd)
314{
315	struct mmc_host *mmc = host->mmc;
316	u8 pwr = host->pwr;
317
318	sdhci_set_power(host, mode, vdd);
319
320	if (host->pwr == pwr)
321		return;
322
323	if (host->pwr == 0)
324		vdd = 0;
325
326	if (!IS_ERR(mmc->supply.vmmc)) {
327		spin_unlock_irq(&host->lock);
328		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
329		spin_lock_irq(&host->lock);
330	}
331}
332
333static const struct sdhci_ops pxav3_sdhci_ops = {
334	.set_clock = sdhci_set_clock,
335	.set_power = pxav3_set_power,
336	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
337	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
338	.set_bus_width = sdhci_set_bus_width,
339	.reset = pxav3_reset,
340	.set_uhs_signaling = pxav3_set_uhs_signaling,
 
341};
342
343static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
344	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
345		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
346		| SDHCI_QUIRK_32BIT_ADMA_SIZE
347		| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
348	.ops = &pxav3_sdhci_ops,
349};
350
351#ifdef CONFIG_OF
352static const struct of_device_id sdhci_pxav3_of_match[] = {
353	{
354		.compatible = "mrvl,pxav3-mmc",
355	},
356	{
357		.compatible = "marvell,armada-380-sdhci",
358	},
359	{},
360};
361MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match);
362
363static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
364{
365	struct sdhci_pxa_platdata *pdata;
366	struct device_node *np = dev->of_node;
367	u32 clk_delay_cycles;
368
369	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
370	if (!pdata)
371		return NULL;
372
373	if (!of_property_read_u32(np, "mrvl,clk-delay-cycles",
374				  &clk_delay_cycles))
375		pdata->clk_delay_cycles = clk_delay_cycles;
376
377	return pdata;
378}
379#else
380static inline struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
381{
382	return NULL;
383}
384#endif
385
386static int sdhci_pxav3_probe(struct platform_device *pdev)
387{
388	struct sdhci_pltfm_host *pltfm_host;
389	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
390	struct device *dev = &pdev->dev;
391	struct device_node *np = pdev->dev.of_node;
392	struct sdhci_host *host = NULL;
393	struct sdhci_pxa *pxa = NULL;
394	const struct of_device_id *match;
395	int ret;
 
396
397	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, sizeof(*pxa));
398	if (IS_ERR(host))
399		return PTR_ERR(host);
400
 
 
 
 
 
401	pltfm_host = sdhci_priv(host);
402	pxa = sdhci_pltfm_priv(pltfm_host);
403
404	pxa->clk_io = devm_clk_get(dev, "io");
405	if (IS_ERR(pxa->clk_io))
406		pxa->clk_io = devm_clk_get(dev, NULL);
407	if (IS_ERR(pxa->clk_io)) {
408		dev_err(dev, "failed to get io clock\n");
409		ret = PTR_ERR(pxa->clk_io);
410		goto err_clk_get;
411	}
412	pltfm_host->clk = pxa->clk_io;
413	clk_prepare_enable(pxa->clk_io);
414
415	pxa->clk_core = devm_clk_get(dev, "core");
416	if (!IS_ERR(pxa->clk_core))
417		clk_prepare_enable(pxa->clk_core);
418
419	/* enable 1/8V DDR capable */
420	host->mmc->caps |= MMC_CAP_1_8V_DDR;
421
422	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
423		ret = armada_38x_quirks(pdev, host);
424		if (ret < 0)
425			goto err_mbus_win;
426		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
427		if (ret < 0)
428			goto err_mbus_win;
429	}
430
431	match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
432	if (match) {
433		ret = mmc_of_parse(host->mmc);
434		if (ret)
435			goto err_of_parse;
436		sdhci_get_of_property(pdev);
437		pdata = pxav3_get_mmc_pdata(dev);
438		pdev->dev.platform_data = pdata;
439	} else if (pdata) {
440		/* on-chip device */
441		if (pdata->flags & PXA_FLAG_CARD_PERMANENT)
442			host->mmc->caps |= MMC_CAP_NONREMOVABLE;
 
443
444		/* If slot design supports 8 bit data, indicate this to MMC. */
445		if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
446			host->mmc->caps |= MMC_CAP_8_BIT_DATA;
447
448		if (pdata->quirks)
449			host->quirks |= pdata->quirks;
450		if (pdata->quirks2)
451			host->quirks2 |= pdata->quirks2;
452		if (pdata->host_caps)
453			host->mmc->caps |= pdata->host_caps;
454		if (pdata->host_caps2)
455			host->mmc->caps2 |= pdata->host_caps2;
456		if (pdata->pm_caps)
457			host->mmc->pm_caps |= pdata->pm_caps;
458
459		if (gpio_is_valid(pdata->ext_cd_gpio)) {
460			ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio,
461						  0);
462			if (ret) {
463				dev_err(mmc_dev(host->mmc),
464					"failed to allocate card detect gpio\n");
465				goto err_cd_req;
466			}
467		}
468	}
469
470	pm_runtime_get_noresume(&pdev->dev);
471	pm_runtime_set_active(&pdev->dev);
472	pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
473	pm_runtime_use_autosuspend(&pdev->dev);
474	pm_runtime_enable(&pdev->dev);
475	pm_suspend_ignore_children(&pdev->dev, 1);
476
477	ret = sdhci_add_host(host);
478	if (ret) {
479		dev_err(&pdev->dev, "failed to add host\n");
480		goto err_add_host;
481	}
482
483	platform_set_drvdata(pdev, host);
484
485	if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)
486		device_init_wakeup(&pdev->dev, 1);
487
488	pm_runtime_put_autosuspend(&pdev->dev);
489
490	return 0;
491
492err_add_host:
493	pm_runtime_disable(&pdev->dev);
494	pm_runtime_put_noidle(&pdev->dev);
495err_of_parse:
496err_cd_req:
497err_mbus_win:
498	clk_disable_unprepare(pxa->clk_io);
499	clk_disable_unprepare(pxa->clk_core);
500err_clk_get:
501	sdhci_pltfm_free(pdev);
 
502	return ret;
503}
504
505static int sdhci_pxav3_remove(struct platform_device *pdev)
506{
507	struct sdhci_host *host = platform_get_drvdata(pdev);
508	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
509	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
510
511	pm_runtime_get_sync(&pdev->dev);
512	pm_runtime_disable(&pdev->dev);
513	pm_runtime_put_noidle(&pdev->dev);
514
515	sdhci_remove_host(host, 1);
516
517	clk_disable_unprepare(pxa->clk_io);
518	clk_disable_unprepare(pxa->clk_core);
519
520	sdhci_pltfm_free(pdev);
 
521
522	return 0;
523}
524
525#ifdef CONFIG_PM_SLEEP
526static int sdhci_pxav3_suspend(struct device *dev)
527{
528	int ret;
529	struct sdhci_host *host = dev_get_drvdata(dev);
530
531	pm_runtime_get_sync(dev);
532	ret = sdhci_suspend_host(host);
533	pm_runtime_mark_last_busy(dev);
534	pm_runtime_put_autosuspend(dev);
535
536	return ret;
537}
538
539static int sdhci_pxav3_resume(struct device *dev)
540{
541	int ret;
542	struct sdhci_host *host = dev_get_drvdata(dev);
543
544	pm_runtime_get_sync(dev);
545	ret = sdhci_resume_host(host);
546	pm_runtime_mark_last_busy(dev);
547	pm_runtime_put_autosuspend(dev);
548
549	return ret;
550}
551#endif
552
553#ifdef CONFIG_PM
554static int sdhci_pxav3_runtime_suspend(struct device *dev)
555{
556	struct sdhci_host *host = dev_get_drvdata(dev);
557	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
558	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
559	int ret;
560
561	ret = sdhci_runtime_suspend_host(host);
562	if (ret)
563		return ret;
564
565	clk_disable_unprepare(pxa->clk_io);
566	if (!IS_ERR(pxa->clk_core))
567		clk_disable_unprepare(pxa->clk_core);
568
569	return 0;
570}
571
572static int sdhci_pxav3_runtime_resume(struct device *dev)
573{
574	struct sdhci_host *host = dev_get_drvdata(dev);
575	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
576	struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host);
577
578	clk_prepare_enable(pxa->clk_io);
579	if (!IS_ERR(pxa->clk_core))
580		clk_prepare_enable(pxa->clk_core);
581
582	return sdhci_runtime_resume_host(host);
583}
584#endif
585
586#ifdef CONFIG_PM
587static const struct dev_pm_ops sdhci_pxav3_pmops = {
588	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pxav3_suspend, sdhci_pxav3_resume)
589	SET_RUNTIME_PM_OPS(sdhci_pxav3_runtime_suspend,
590		sdhci_pxav3_runtime_resume, NULL)
591};
592
593#define SDHCI_PXAV3_PMOPS (&sdhci_pxav3_pmops)
594
595#else
596#define SDHCI_PXAV3_PMOPS NULL
597#endif
598
599static struct platform_driver sdhci_pxav3_driver = {
600	.driver		= {
601		.name	= "sdhci-pxav3",
602		.of_match_table = of_match_ptr(sdhci_pxav3_of_match),
603		.pm	= SDHCI_PXAV3_PMOPS,
604	},
605	.probe		= sdhci_pxav3_probe,
606	.remove		= sdhci_pxav3_remove,
607};
608
609module_platform_driver(sdhci_pxav3_driver);
610
611MODULE_DESCRIPTION("SDHCI driver for pxav3");
612MODULE_AUTHOR("Marvell International Ltd.");
613MODULE_LICENSE("GPL v2");
614
v3.5.6
  1/*
  2 * Copyright (C) 2010 Marvell International Ltd.
  3 *		Zhangfei Gao <zhangfei.gao@marvell.com>
  4 *		Kevin Wang <dwang4@marvell.com>
  5 *		Mingwei Wang <mwwang@marvell.com>
  6 *		Philip Rakity <prakity@marvell.com>
  7 *		Mark Brown <markb@marvell.com>
  8 *
  9 * This software is licensed under the terms of the GNU General Public
 10 * License version 2, as published by the Free Software Foundation, and
 11 * may be copied, distributed, and modified under those terms.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 */
 19#include <linux/err.h>
 20#include <linux/init.h>
 21#include <linux/platform_device.h>
 22#include <linux/clk.h>
 23#include <linux/io.h>
 24#include <linux/gpio.h>
 25#include <linux/mmc/card.h>
 26#include <linux/mmc/host.h>
 
 27#include <linux/platform_data/pxa_sdhci.h>
 28#include <linux/slab.h>
 29#include <linux/delay.h>
 30#include <linux/module.h>
 
 
 
 
 
 
 
 31#include "sdhci.h"
 32#include "sdhci-pltfm.h"
 33
 
 
 34#define SD_CLOCK_BURST_SIZE_SETUP		0x10A
 35#define SDCLK_SEL	0x100
 36#define SDCLK_DELAY_SHIFT	9
 37#define SDCLK_DELAY_MASK	0x1f
 38
 39#define SD_CFG_FIFO_PARAM       0x100
 40#define SDCFG_GEN_PAD_CLK_ON	(1<<6)
 41#define SDCFG_GEN_PAD_CLK_CNT_MASK	0xFF
 42#define SDCFG_GEN_PAD_CLK_CNT_SHIFT	24
 43
 44#define SD_SPI_MODE          0x108
 45#define SD_CE_ATA_1          0x10C
 46
 47#define SD_CE_ATA_2          0x10E
 48#define SDCE_MISC_INT		(1<<2)
 49#define SDCE_MISC_INT_EN	(1<<1)
 50
 51static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 52{
 53	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 54	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 55
 
 
 56	if (mask == SDHCI_RESET_ALL) {
 57		/*
 58		 * tune timing of read data/command when crc error happen
 59		 * no performance impact
 60		 */
 61		if (pdata && 0 != pdata->clk_delay_cycles) {
 62			u16 tmp;
 63
 64			tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
 65			tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
 66				<< SDCLK_DELAY_SHIFT;
 67			tmp |= SDCLK_SEL;
 68			writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
 69		}
 70	}
 71}
 72
 73#define MAX_WAIT_COUNT 5
 74static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode)
 75{
 76	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 77	struct sdhci_pxa *pxa = pltfm_host->priv;
 78	u16 tmp;
 79	int count;
 80
 81	if (pxa->power_mode == MMC_POWER_UP
 82			&& power_mode == MMC_POWER_ON) {
 83
 84		dev_dbg(mmc_dev(host->mmc),
 85				"%s: slot->power_mode = %d,"
 86				"ios->power_mode = %d\n",
 87				__func__,
 88				pxa->power_mode,
 89				power_mode);
 90
 91		/* set we want notice of when 74 clocks are sent */
 92		tmp = readw(host->ioaddr + SD_CE_ATA_2);
 93		tmp |= SDCE_MISC_INT_EN;
 94		writew(tmp, host->ioaddr + SD_CE_ATA_2);
 95
 96		/* start sending the 74 clocks */
 97		tmp = readw(host->ioaddr + SD_CFG_FIFO_PARAM);
 98		tmp |= SDCFG_GEN_PAD_CLK_ON;
 99		writew(tmp, host->ioaddr + SD_CFG_FIFO_PARAM);
100
101		/* slowest speed is about 100KHz or 10usec per clock */
102		udelay(740);
103		count = 0;
104
105		while (count++ < MAX_WAIT_COUNT) {
106			if ((readw(host->ioaddr + SD_CE_ATA_2)
107						& SDCE_MISC_INT) == 0)
108				break;
109			udelay(10);
110		}
111
112		if (count == MAX_WAIT_COUNT)
113			dev_warn(mmc_dev(host->mmc), "74 clock interrupt not cleared\n");
114
115		/* clear the interrupt bit if posted */
116		tmp = readw(host->ioaddr + SD_CE_ATA_2);
117		tmp |= SDCE_MISC_INT;
118		writew(tmp, host->ioaddr + SD_CE_ATA_2);
119	}
120	pxa->power_mode = power_mode;
121}
122
123static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
124{
 
 
125	u16 ctrl_2;
126
127	/*
128	 * Set V18_EN -- UHS modes do not work without this.
129	 * does not change signaling voltage
130	 */
131	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
132
133	/* Select Bus Speed Mode for host */
134	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
135	switch (uhs) {
136	case MMC_TIMING_UHS_SDR12:
137		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
138		break;
139	case MMC_TIMING_UHS_SDR25:
140		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
141		break;
142	case MMC_TIMING_UHS_SDR50:
143		ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
144		break;
145	case MMC_TIMING_UHS_SDR104:
146		ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
147		break;
 
148	case MMC_TIMING_UHS_DDR50:
149		ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
150		break;
151	}
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
154	dev_dbg(mmc_dev(host->mmc),
155		"%s uhs = %d, ctrl_2 = %04X\n",
156		__func__, uhs, ctrl_2);
 
 
 
 
 
 
 
157
158	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
159}
160
161static struct sdhci_ops pxav3_sdhci_ops = {
162	.platform_reset_exit = pxav3_set_private_registers,
 
 
 
 
 
163	.set_uhs_signaling = pxav3_set_uhs_signaling,
164	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
165};
166
167static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168{
169	struct sdhci_pltfm_host *pltfm_host;
170	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
171	struct device *dev = &pdev->dev;
 
172	struct sdhci_host *host = NULL;
173	struct sdhci_pxa *pxa = NULL;
 
174	int ret;
175	struct clk *clk;
176
177	pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
178	if (!pxa)
179		return -ENOMEM;
180
181	host = sdhci_pltfm_init(pdev, NULL);
182	if (IS_ERR(host)) {
183		kfree(pxa);
184		return PTR_ERR(host);
185	}
186	pltfm_host = sdhci_priv(host);
187	pltfm_host->priv = pxa;
188
189	clk = clk_get(dev, "PXA-SDHCLK");
190	if (IS_ERR(clk)) {
 
 
191		dev_err(dev, "failed to get io clock\n");
192		ret = PTR_ERR(clk);
193		goto err_clk_get;
194	}
195	pltfm_host->clk = clk;
196	clk_enable(clk);
197
198	host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
199		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
200		| SDHCI_QUIRK_32BIT_ADMA_SIZE;
201
202	/* enable 1/8V DDR capable */
203	host->mmc->caps |= MMC_CAP_1_8V_DDR;
204
205	if (pdata) {
206		if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
207			/* on-chip device */
208			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209			host->mmc->caps |= MMC_CAP_NONREMOVABLE;
210		}
211
212		/* If slot design supports 8 bit data, indicate this to MMC. */
213		if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
214			host->mmc->caps |= MMC_CAP_8_BIT_DATA;
215
216		if (pdata->quirks)
217			host->quirks |= pdata->quirks;
 
 
218		if (pdata->host_caps)
219			host->mmc->caps |= pdata->host_caps;
 
 
220		if (pdata->pm_caps)
221			host->mmc->pm_caps |= pdata->pm_caps;
 
 
 
 
 
 
 
 
 
 
222	}
223
224	host->ops = &pxav3_sdhci_ops;
 
 
 
 
 
225
226	ret = sdhci_add_host(host);
227	if (ret) {
228		dev_err(&pdev->dev, "failed to add host\n");
229		goto err_add_host;
230	}
231
232	platform_set_drvdata(pdev, host);
233
 
 
 
 
 
234	return 0;
235
236err_add_host:
237	clk_disable(clk);
238	clk_put(clk);
 
 
 
 
 
239err_clk_get:
240	sdhci_pltfm_free(pdev);
241	kfree(pxa);
242	return ret;
243}
244
245static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
246{
247	struct sdhci_host *host = platform_get_drvdata(pdev);
248	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
249	struct sdhci_pxa *pxa = pltfm_host->priv;
 
 
 
 
250
251	sdhci_remove_host(host, 1);
252
253	clk_disable(pltfm_host->clk);
254	clk_put(pltfm_host->clk);
 
255	sdhci_pltfm_free(pdev);
256	kfree(pxa);
257
258	platform_set_drvdata(pdev, NULL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
260	return 0;
261}
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263static struct platform_driver sdhci_pxav3_driver = {
264	.driver		= {
265		.name	= "sdhci-pxav3",
266		.owner	= THIS_MODULE,
267		.pm	= SDHCI_PLTFM_PMOPS,
268	},
269	.probe		= sdhci_pxav3_probe,
270	.remove		= __devexit_p(sdhci_pxav3_remove),
271};
272
273module_platform_driver(sdhci_pxav3_driver);
274
275MODULE_DESCRIPTION("SDHCI driver for pxav3");
276MODULE_AUTHOR("Marvell International Ltd.");
277MODULE_LICENSE("GPL v2");
278