Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/mmc/host/sdhci-esdhc.h
15111 views
1
/*
2
* Freescale eSDHC controller driver generics for OF and pltfm.
3
*
4
* Copyright (c) 2007 Freescale Semiconductor, Inc.
5
* Copyright (c) 2009 MontaVista Software, Inc.
6
* Copyright (c) 2010 Pengutronix e.K.
7
* Author: Wolfram Sang <[email protected]>
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License.
12
*/
13
14
#ifndef _DRIVERS_MMC_SDHCI_ESDHC_H
15
#define _DRIVERS_MMC_SDHCI_ESDHC_H
16
17
/*
18
* Ops and quirks for the Freescale eSDHC controller.
19
*/
20
21
#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
22
SDHCI_QUIRK_NO_BUSY_IRQ | \
23
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
24
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
25
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
26
SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
27
28
#define ESDHC_SYSTEM_CONTROL 0x2c
29
#define ESDHC_CLOCK_MASK 0x0000fff0
30
#define ESDHC_PREDIV_SHIFT 8
31
#define ESDHC_DIVIDER_SHIFT 4
32
#define ESDHC_CLOCK_PEREN 0x00000004
33
#define ESDHC_CLOCK_HCKEN 0x00000002
34
#define ESDHC_CLOCK_IPGEN 0x00000001
35
36
/* pltfm-specific */
37
#define ESDHC_HOST_CONTROL_LE 0x20
38
39
/* OF-specific */
40
#define ESDHC_DMA_SYSCTL 0x40c
41
#define ESDHC_DMA_SNOOP 0x00000040
42
43
#define ESDHC_HOST_CONTROL_RES 0x05
44
45
static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
46
{
47
int pre_div = 2;
48
int div = 1;
49
u32 temp;
50
51
temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
52
temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
53
| ESDHC_CLOCK_MASK);
54
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
55
56
if (clock == 0)
57
goto out;
58
59
while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
60
pre_div *= 2;
61
62
while (host->max_clk / pre_div / div > clock && div < 16)
63
div++;
64
65
dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
66
clock, host->max_clk / pre_div / div);
67
68
pre_div >>= 1;
69
div--;
70
71
temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
72
temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
73
| (div << ESDHC_DIVIDER_SHIFT)
74
| (pre_div << ESDHC_PREDIV_SHIFT));
75
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
76
mdelay(100);
77
out:
78
host->clock = clock;
79
}
80
81
#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
82
83