1 // SPDX-License-Identifier: GPL-2.0
3 * sdhci-pci-arasan.c - Driver for Arasan PCI Controller with
6 * Copyright (C) 2017 Arasan Chip Systems Inc.
8 * Author: Atul Garg <agarg@arasan.com>
11 #include <linux/pci.h>
12 #include <linux/delay.h>
15 #include "sdhci-pci.h"
17 /* Extra registers for Arasan SD/SDIO/MMC Host Controller with PHY */
18 #define PHY_ADDR_REG 0x300
19 #define PHY_DAT_REG 0x304
21 #define PHY_WRITE BIT(8)
22 #define PHY_BUSY BIT(9)
23 #define DATA_MASK 0xFF
25 /* PHY Specific Registers */
26 #define DLL_STATUS 0x00
27 #define IPAD_CTRL1 0x01
28 #define IPAD_CTRL2 0x02
30 #define IOREN_CTRL1 0x06
31 #define IOREN_CTRL2 0x07
32 #define IOPU_CTRL1 0x08
33 #define IOPU_CTRL2 0x09
34 #define ITAP_DELAY 0x0C
35 #define OTAP_DELAY 0x0D
37 #define CLKBUF_SEL 0x0F
38 #define MODE_CTRL 0x11
41 #define DATA_CTRL 0x21
42 #define STRB_CTRL 0x22
46 #define DLL_ENBL BIT(3)
47 #define RTRIM_EN BIT(1)
48 #define PDB_ENBL BIT(1)
49 #define RETB_ENBL BIT(6)
50 #define ODEN_CMD BIT(1)
52 #define REN_STRB BIT(0)
53 #define REN_CMND BIT(1)
57 #define ITAPDLY_EN BIT(0)
58 #define OTAPDLY_EN BIT(0)
59 #define OD_REL_CMD BIT(1)
60 #define OD_REL_DAT 0xFF
61 #define DLLTRM_ICP 0x8
62 #define PDB_CMND BIT(0)
64 #define PDB_STRB BIT(0)
65 #define PDB_CLOCK BIT(0)
66 #define CALDONE_MASK 0x10
67 #define DLL_RDY_MASK 0x10
68 #define MAX_CLK_BUF 0x7
71 #define ENHSTRB_MODE BIT(0)
72 #define HS400_MODE BIT(1)
73 #define LEGACY_MODE BIT(2)
74 #define DDR50_MODE BIT(3)
77 * Controller has no specific bits for HS200/HS.
78 * Used BIT(4), BIT(5) for software programming.
80 #define HS200_MODE BIT(4)
81 #define HISPD_MODE BIT(5)
83 #define OTAPDLY(x) (((x) << 1) | OTAPDLY_EN)
84 #define ITAPDLY(x) (((x) << 1) | ITAPDLY_EN)
85 #define FREQSEL(x) (((x) << 5) | DLL_ENBL)
86 #define IOPAD(x, y) ((x) | ((y) << 2))
88 /* Arasan private data */
93 static int arasan_phy_addr_poll(struct sdhci_host
*host
, u32 offset
, u32 mask
)
95 ktime_t timeout
= ktime_add_us(ktime_get(), 100);
100 failed
= ktime_after(ktime_get(), timeout
);
101 val
= sdhci_readw(host
, PHY_ADDR_REG
);
109 static int arasan_phy_write(struct sdhci_host
*host
, u8 data
, u8 offset
)
111 sdhci_writew(host
, data
, PHY_DAT_REG
);
112 sdhci_writew(host
, (PHY_WRITE
| offset
), PHY_ADDR_REG
);
113 return arasan_phy_addr_poll(host
, PHY_ADDR_REG
, PHY_BUSY
);
116 static int arasan_phy_read(struct sdhci_host
*host
, u8 offset
, u8
*data
)
120 sdhci_writew(host
, 0, PHY_DAT_REG
);
121 sdhci_writew(host
, offset
, PHY_ADDR_REG
);
122 ret
= arasan_phy_addr_poll(host
, PHY_ADDR_REG
, PHY_BUSY
);
124 /* Masking valid data bits */
125 *data
= sdhci_readw(host
, PHY_DAT_REG
) & DATA_MASK
;
129 static int arasan_phy_sts_poll(struct sdhci_host
*host
, u32 offset
, u32 mask
)
132 ktime_t timeout
= ktime_add_us(ktime_get(), 100);
137 failed
= ktime_after(ktime_get(), timeout
);
138 ret
= arasan_phy_read(host
, offset
, &val
);
148 /* Initialize the Arasan PHY */
149 static int arasan_phy_init(struct sdhci_host
*host
)
154 /* Program IOPADs and wait for calibration to be done */
155 if (arasan_phy_read(host
, IPAD_CTRL1
, &val
) ||
156 arasan_phy_write(host
, val
| RETB_ENBL
| PDB_ENBL
, IPAD_CTRL1
) ||
157 arasan_phy_read(host
, IPAD_CTRL2
, &val
) ||
158 arasan_phy_write(host
, val
| RTRIM_EN
, IPAD_CTRL2
))
160 ret
= arasan_phy_sts_poll(host
, IPAD_STS
, CALDONE_MASK
);
164 /* Program CMD/Data lines */
165 if (arasan_phy_read(host
, IOREN_CTRL1
, &val
) ||
166 arasan_phy_write(host
, val
| REN_CMND
| REN_STRB
, IOREN_CTRL1
) ||
167 arasan_phy_read(host
, IOPU_CTRL1
, &val
) ||
168 arasan_phy_write(host
, val
| PU_CMD
, IOPU_CTRL1
) ||
169 arasan_phy_read(host
, CMD_CTRL
, &val
) ||
170 arasan_phy_write(host
, val
| PDB_CMND
, CMD_CTRL
) ||
171 arasan_phy_read(host
, IOREN_CTRL2
, &val
) ||
172 arasan_phy_write(host
, val
| REN_DATA
, IOREN_CTRL2
) ||
173 arasan_phy_read(host
, IOPU_CTRL2
, &val
) ||
174 arasan_phy_write(host
, val
| PU_DAT
, IOPU_CTRL2
) ||
175 arasan_phy_read(host
, DATA_CTRL
, &val
) ||
176 arasan_phy_write(host
, val
| PDB_DATA
, DATA_CTRL
) ||
177 arasan_phy_read(host
, STRB_CTRL
, &val
) ||
178 arasan_phy_write(host
, val
| PDB_STRB
, STRB_CTRL
) ||
179 arasan_phy_read(host
, CLK_CTRL
, &val
) ||
180 arasan_phy_write(host
, val
| PDB_CLOCK
, CLK_CTRL
) ||
181 arasan_phy_read(host
, CLKBUF_SEL
, &val
) ||
182 arasan_phy_write(host
, val
| MAX_CLK_BUF
, CLKBUF_SEL
) ||
183 arasan_phy_write(host
, LEGACY_MODE
, MODE_CTRL
))
188 /* Set Arasan PHY for different modes */
189 static int arasan_phy_set(struct sdhci_host
*host
, u8 mode
, u8 otap
,
190 u8 drv_type
, u8 itap
, u8 trim
, u8 clk
)
195 if (mode
== HISPD_MODE
|| mode
== HS200_MODE
)
196 ret
= arasan_phy_write(host
, 0x0, MODE_CTRL
);
198 ret
= arasan_phy_write(host
, mode
, MODE_CTRL
);
201 if (mode
== HS400_MODE
|| mode
== HS200_MODE
) {
202 ret
= arasan_phy_read(host
, IPAD_CTRL1
, &val
);
205 ret
= arasan_phy_write(host
, IOPAD(val
, drv_type
), IPAD_CTRL1
);
209 if (mode
== LEGACY_MODE
) {
210 ret
= arasan_phy_write(host
, 0x0, OTAP_DELAY
);
213 ret
= arasan_phy_write(host
, 0x0, ITAP_DELAY
);
215 ret
= arasan_phy_write(host
, OTAPDLY(otap
), OTAP_DELAY
);
218 if (mode
!= HS200_MODE
)
219 ret
= arasan_phy_write(host
, ITAPDLY(itap
), ITAP_DELAY
);
221 ret
= arasan_phy_write(host
, 0x0, ITAP_DELAY
);
225 if (mode
!= LEGACY_MODE
) {
226 ret
= arasan_phy_write(host
, trim
, DLL_TRIM
);
230 ret
= arasan_phy_write(host
, 0, DLL_STATUS
);
233 if (mode
!= LEGACY_MODE
) {
234 ret
= arasan_phy_write(host
, FREQSEL(clk
), DLL_STATUS
);
237 ret
= arasan_phy_sts_poll(host
, DLL_STATUS
, DLL_RDY_MASK
);
244 static int arasan_select_phy_clock(struct sdhci_host
*host
)
246 struct sdhci_pci_slot
*slot
= sdhci_priv(host
);
247 struct arasan_host
*arasan_host
= sdhci_pci_priv(slot
);
250 if (arasan_host
->chg_clk
== host
->mmc
->ios
.clock
)
253 arasan_host
->chg_clk
= host
->mmc
->ios
.clock
;
254 if (host
->mmc
->ios
.clock
== 200000000)
256 else if (host
->mmc
->ios
.clock
== 100000000)
258 else if (host
->mmc
->ios
.clock
== 50000000)
263 if (host
->mmc_host_ops
.hs400_enhanced_strobe
) {
264 arasan_phy_set(host
, ENHSTRB_MODE
, 1, 0x0, 0x0,
267 switch (host
->mmc
->ios
.timing
) {
268 case MMC_TIMING_LEGACY
:
269 arasan_phy_set(host
, LEGACY_MODE
, 0x0, 0x0, 0x0,
272 case MMC_TIMING_MMC_HS
:
273 case MMC_TIMING_SD_HS
:
274 arasan_phy_set(host
, HISPD_MODE
, 0x3, 0x0, 0x2,
277 case MMC_TIMING_MMC_HS200
:
278 case MMC_TIMING_UHS_SDR104
:
279 arasan_phy_set(host
, HS200_MODE
, 0x2,
280 host
->mmc
->ios
.drv_type
, 0x0,
283 case MMC_TIMING_MMC_DDR52
:
284 case MMC_TIMING_UHS_DDR50
:
285 arasan_phy_set(host
, DDR50_MODE
, 0x1, 0x0,
286 0x0, DLLTRM_ICP
, clk
);
288 case MMC_TIMING_MMC_HS400
:
289 arasan_phy_set(host
, HS400_MODE
, 0x1,
290 host
->mmc
->ios
.drv_type
, 0xa,
300 static int arasan_pci_probe_slot(struct sdhci_pci_slot
*slot
)
304 slot
->host
->mmc
->caps
|= MMC_CAP_NONREMOVABLE
| MMC_CAP_8_BIT_DATA
;
305 err
= arasan_phy_init(slot
->host
);
311 static void arasan_sdhci_set_clock(struct sdhci_host
*host
, unsigned int clock
)
313 sdhci_set_clock(host
, clock
);
315 /* Change phy settings for the new clock */
316 arasan_select_phy_clock(host
);
319 static const struct sdhci_ops arasan_sdhci_pci_ops
= {
320 .set_clock
= arasan_sdhci_set_clock
,
321 .enable_dma
= sdhci_pci_enable_dma
,
322 .set_bus_width
= sdhci_set_bus_width
,
323 .reset
= sdhci_reset
,
324 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
327 const struct sdhci_pci_fixes sdhci_arasan
= {
328 .probe_slot
= arasan_pci_probe_slot
,
329 .ops
= &arasan_sdhci_pci_ops
,
330 .priv_size
= sizeof(struct arasan_host
),