Skip to content

Commit d262037

Browse files
awilliams-marvellSomasundaram Krishnasamy
authored andcommitted
mmc: octeontx2: Use flags for hardware differences
Instead of hard-coding the code to look for various SoCs and versions it is better to use flags. This makes it much easier to put all of the flag initialization in one place, in the probe function, as well as make it easier to add noew SoCs witouth having to make modifications all over the place. This patch also moves the hardware maximum speed based on chip revision, etc. to the probe function as well. This patch also cleans up the timing support for HS200 and HS400 and fixes a rounding error when calculating the tap value. This patch also allows the device tree to override the default delays for HS200 and HS400 modes. This also adds support for the CNF95XXMM and LOKI SoCs. Change-Id: Ia3457d56dd4cb38a3fb33bdb08d4e5d611f5c314 Signed-off-by: Aaron Williams <[email protected]> Reviewed-on: https://sj1git1.cavium.com/23236 Reviewed-by: Chandrakala Chavva <[email protected]> Tested-by: sa_ip-sw-jenkins <[email protected]> Reviewed-on: https://sj1git1.cavium.com/23951 Reviewed-on: https://sj1git1.cavium.com/24030 Reviewed-by: Sunil Kovvuri Goutham <[email protected]> Tested-by: Sunil Kovvuri Goutham <[email protected]> Jira: LINUX-4695 Orabug: 30969935 Signed-off-by: Dave Kleikamp <[email protected]> Reviewed-by: Karl Volz <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent b246a3b commit d262037

File tree

4 files changed

+103
-82
lines changed

4 files changed

+103
-82
lines changed

drivers/mmc/host/cavium-octeon.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static int octeon_mmc_probe(struct platform_device *pdev)
172172
host->dmar_fixup_done = octeon_mmc_dmar_fixup_done;
173173
}
174174

175+
host->max_freq = MHZ_52;
175176
host->sys_freq = octeon_get_io_clock_rate();
176177

177178
if (of_device_is_compatible(node, "cavium,octeon-7890-mmc")) {

drivers/mmc/host/cavium-thunderx.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ void thunder_calibrate_mmc(struct cvm_mmc_host *host)
6969
return;
7070

7171
/* set _DEBUG[CLK_ON]=1 as workaround for clock issue */
72-
if (is_mmc_otx2_A0(host) || is_mmc_95xx(host))
72+
if (host->cond_clock_glitch)
7373
writeq(1, host->base + MIO_EMM_DEBUG(host));
7474

75-
if (is_mmc_otx2_A0(host) || is_mmc_otx2_C0(host)) {
75+
if (host->calibrate_glitch) {
7676
/*
7777
* Operation of up to 100 MHz may be achieved by skipping the
7878
* steps that establish the tap delays and instead assuming
@@ -106,7 +106,7 @@ void thunder_calibrate_mmc(struct cvm_mmc_host *host)
106106
/* reset controller */
107107
tcfg = emm_cfg;
108108
tcfg &= ~MIO_EMM_CFG_BUS_ENA;
109-
writeq(tcfg, host->base + MIO_EMM_CFG(host));
109+
writeq(0, host->base + MIO_EMM_CFG(host));
110110
udelay(1);
111111

112112
/* restart with phantom slot 3 */
@@ -137,7 +137,8 @@ void thunder_calibrate_mmc(struct cvm_mmc_host *host)
137137
delay = tap & MIO_EMM_TAP_DELAY;
138138
how = "calibrated";
139139
}
140-
140+
writeq(0, host->base + MIO_EMM_CFG(host));
141+
udelay(1);
141142
/* restore old state */
142143
writeq(emm_cfg, host->base + MIO_EMM_CFG(host));
143144
mdelay(1);
@@ -175,6 +176,8 @@ static int thunder_mmc_probe(struct pci_dev *pdev,
175176
struct device_node *child_node;
176177
struct cvm_mmc_host *host;
177178
int ret, i = 0;
179+
u8 chip_id;
180+
u8 rev;
178181

179182
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
180183
if (!host)
@@ -226,6 +229,38 @@ static int thunder_mmc_probe(struct pci_dev *pdev,
226229
if (ret)
227230
goto error;
228231

232+
rev = pdev->revision;
233+
chip_id = (pdev->subsystem_device >> 8) & 0xff;
234+
switch (chip_id) {
235+
case PCI_SUBSYS_DEVID_96XX:
236+
if (rev == REV_ID_0) {
237+
host->calibrate_glitch = true;
238+
host->cond_clock_glitch = true;
239+
host->max_freq = MHZ_100;
240+
} else if (rev == REV_ID_2) {
241+
host->tap_requires_noclk = true;
242+
host->max_freq = MHZ_112_5;
243+
} else if (rev > REV_ID_2) {
244+
host->tap_requires_noclk = true;
245+
host->max_freq = MHZ_200;
246+
}
247+
break;
248+
case PCI_SUBSYS_DEVID_95XXMM:
249+
case PCI_SUBSYS_DEVID_98XX:
250+
host->tap_requires_noclk = true;
251+
host->max_freq = MHZ_200;
252+
break;
253+
case PCI_SUBSYS_DEVID_95XX:
254+
if (rev == REV_ID_0)
255+
host->cond_clock_glitch = true;
256+
host->max_freq = MHZ_167;
257+
break;
258+
case PCI_SUBSYS_DEVID_LOKI:
259+
host->max_freq = MHZ_167;
260+
break;
261+
default:
262+
break;
263+
}
229264
/*
230265
* Clear out any pending interrupts that may be left over from
231266
* bootloader. Writing 1 to the bits clears them.

drivers/mmc/host/cavium.c

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static void cvm_mmc_clk_config(struct cvm_mmc_host *host, bool flag)
152152
{
153153
u64 emm_debug;
154154

155-
if (!is_mmc_otx2_C0(host))
155+
if (!host->tap_requires_noclk)
156156
return;
157157

158158
/* Turn off the clock */
@@ -208,7 +208,7 @@ static int tout(struct cvm_mmc_slot *slot, int ps, int hint)
208208
if (!tap_ps)
209209
return hint;
210210

211-
taps = min((int)(ps * clk_scale) / (tap_ps * 100), 63);
211+
taps = min_t(int, DIV_ROUND_UP(ps * clk_scale, (tap_ps * 100)), 63);
212212

213213
/* when modparam is adjusted, re-announce timing */
214214
if (old_scale != clk_scale) {
@@ -228,6 +228,7 @@ static int cvm_mmc_configure_delay(struct cvm_mmc_slot *slot)
228228
{
229229
struct cvm_mmc_host *host = slot->host;
230230
struct mmc_host *mmc = slot->mmc;
231+
const char *mode;
231232

232233
pr_debug("slot%d.configure_delay\n", slot->bus_id);
233234

@@ -251,48 +252,66 @@ static int cvm_mmc_configure_delay(struct cvm_mmc_slot *slot)
251252
* Typically 3.0 ns at frequencies <= 52 MHz SDR.
252253
* Typically 2.5 ns at frequencies <= 52 MHz DDR.
253254
* Typically 0.8 ns at frequencies > 52 MHz SDR.
254-
* Typically 0.4 ns at frequencies > 52 MHz DDR.
255+
* Typically 0.8 ns at frequencies > 52 MHz DDR.
256+
*
257+
* Note that in DDR cases typically the data hold time is
258+
* half of the command hold time.
255259
*/
256260
switch (mmc->ios.timing) {
257-
case MMC_TIMING_LEGACY:
258261
default:
262+
case MMC_TIMING_LEGACY:
259263
if (mmc->card && mmc_card_mmc(mmc->card))
260264
cout = tout(slot, 5000, 39);
261265
else
262266
cout = tout(slot, 8000, 63);
267+
dout = cout;
268+
mode = "legacy";
263269
break;
264270
case MMC_TIMING_UHS_SDR12:
265271
cout = tout(slot, 3000, 39);
272+
dout = cout;
273+
mode = "SDR 12";
266274
break;
267275
case MMC_TIMING_MMC_HS:
268276
cout = tout(slot, 2500, 32);
277+
dout = cout;
278+
mode = "MMC HS";
269279
break;
270280
case MMC_TIMING_SD_HS:
271281
case MMC_TIMING_UHS_SDR25:
272282
case MMC_TIMING_UHS_SDR50:
273283
cout = tout(slot, 2000, 26);
284+
dout = cout;
285+
mode = "SD HS/25/50";
274286
break;
275287
case MMC_TIMING_UHS_DDR50:
276288
case MMC_TIMING_MMC_DDR52:
289+
mode = "SD DDR50/MMC DDR52";
277290
cout = tout(slot, 1500, 20);
291+
dout = cout / 2;
292+
if (ddr_cmd_taps)
293+
cout = cout / 2;
278294
break;
279295
case MMC_TIMING_UHS_SDR104:
296+
cout = tout(slot, 800, 10);
297+
dout = cout;
298+
mode = "SD UHS104";
299+
break;
280300
case MMC_TIMING_MMC_HS200:
301+
mode = "MMC HS200";
302+
cout = tout(slot, slot->cmd_out_hs200_dly, 10);
303+
dout = tout(slot, slot->data_out_hs200_dly, 10);
304+
break;
281305
case MMC_TIMING_MMC_HS400:
282-
cout = tout(slot, 800, 10);
306+
mode = "MMC HS400";
307+
cout = tout(slot, slot->cmd_out_hs400_dly, 10);
308+
dout = tout(slot, slot->data_out_hs400_dly, 10);
283309
break;
284310
}
285311

286-
if (!is_mmc_95xx(host)) {
287-
if (!cvm_is_mmc_timing_ddr(slot))
288-
dout = cout;
289-
else if (ddr_cmd_taps)
290-
cout = dout = cout / 2;
291-
else
292-
dout = cout / 2;
293-
} else
294-
dout = tout(slot, 800, 10);
295-
312+
dev_dbg(host->dev,
313+
"%s: command in tap: %d, command out tap: %d, data in tap: %d, data out tap: %d\n",
314+
mode, cin, cout, din, dout);
296315
slot->taps =
297316
FIELD_PREP(MIO_EMM_TIMING_CMD_IN, cin) |
298317
FIELD_PREP(MIO_EMM_TIMING_CMD_OUT, cout) |
@@ -1729,16 +1748,10 @@ static u32 max_supported_frequency(struct cvm_mmc_host *host)
17291748
/* Default maximum freqeuncey is 52000000 for chip prior to 9X */
17301749
u32 max_frequency = MHZ_52;
17311750

1732-
if (!is_mmc_8xxx(host)) {
1751+
if (!is_mmc_8xxx(host))
17331752
/* Default max frequency is 200MHz for 9X chips */
1734-
max_frequency = MHZ_200;
1753+
max_frequency = host->max_freq;
17351754

1736-
/* Erratum is only applicable pass A0 */
1737-
if (is_mmc_otx2_A0(host))
1738-
max_frequency = MHZ_100;
1739-
else if (is_mmc_otx2_C0(host))
1740-
max_frequency = MHZ_150;
1741-
}
17421755
return max_frequency;
17431756
}
17441757

@@ -2087,6 +2100,18 @@ static int cvm_mmc_of_parse(struct device *dev, struct cvm_mmc_slot *slot)
20872100
mmc->caps |= MMC_CAP_4_BIT_DATA;
20882101
}
20892102

2103+
slot->cmd_out_hs200_dly = PS_800;
2104+
slot->data_out_hs200_dly = PS_800;
2105+
of_property_read_u32(node, "marvell,cmd-out-hs200-dly",
2106+
&slot->cmd_out_hs200_dly);
2107+
of_property_read_u32(node, "marvell,data-out-hs200-dly",
2108+
&slot->data_out_hs200_dly);
2109+
slot->cmd_out_hs400_dly = PS_800;
2110+
slot->data_out_hs400_dly = PS_400;
2111+
of_property_read_u32(node, "marvell,cmd-out-hs400-dly",
2112+
&slot->cmd_out_hs400_dly);
2113+
of_property_read_u32(node, "marvell,data-out-hs400-dly",
2114+
&slot->data_out_hs400_dly);
20902115
max_frequency = max_supported_frequency(slot->host);
20912116

20922117
/* Set maximum and minimum frequency */

drivers/mmc/host/cavium.h

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
/* Subsystem Device ID */
2828
#define PCI_SUBSYS_DEVID_8XXX 0xA
2929
#define PCI_SUBSYS_DEVID_9XXX 0xB
30+
#define PCI_SUBSYS_DEVID_98XX 0xB1
31+
#define PCI_SUBSYS_DEVID_96XX 0xB2
3032
#define PCI_SUBSYS_DEVID_95XX 0xB3
33+
#define PCI_SUBSYS_DEVID_LOKI 0xB4
34+
#define PCI_SUBSYS_DEVID_95XXMM 0xB5
3135

3236
/* Chip revision Id */
3337
#define REV_ID_0 0
@@ -37,7 +41,9 @@
3741
#define MHZ_26 (26000000)
3842
#define MHZ_52 (52000000)
3943
#define MHZ_100 (100000000)
44+
#define MHZ_112_5 (112500000)
4045
#define MHZ_150 (150000000)
46+
#define MHZ_167 (167000000)
4147
#define MHZ_200 (200000000)
4248

4349
/* octtx2: emmc interface io current drive strength */
@@ -56,6 +62,7 @@
5662
#define PS_10000 (10 * 1000)
5763
#define PS_5000 (5000)
5864
#define PS_2500 (2500)
65+
#define PS_800 (800)
5966
#define PS_400 (400)
6067
#define MAX_NO_OF_TAPS 64
6168

@@ -115,13 +122,16 @@ struct cvm_mmc_host {
115122
int last_slot;
116123
struct clk *clk;
117124
int sys_freq;
118-
125+
int max_freq;
119126
bool use_sg;
120127
bool has_ciu3;
121128
bool powered;
122129
bool use_vqmmc; /* must disable slots over switch */
123130
bool big_dma_addr;
124131
bool need_irq_handler_lock;
132+
bool tap_requires_noclk;
133+
bool calibrate_glitch;
134+
bool cond_clock_glitch;
125135
spinlock_t irq_handler_lock;
126136
struct semaphore mmc_serializer;
127137

@@ -170,6 +180,10 @@ struct cvm_mmc_slot {
170180
u64 want_switch;
171181
u32 hs400_tuning_block; /* Block number used for tuning */
172182
bool hs400_tuning_block_present;
183+
u32 cmd_out_hs200_dly; /* Normally 800ps */
184+
u32 data_out_hs200_dly; /* Normally 800ps */
185+
u32 cmd_out_hs400_dly; /* Normally 800ps */
186+
u32 data_out_hs400_dly; /* Normally 400ps */
173187
};
174188

175189
struct cvm_mmc_cr_type {
@@ -317,58 +331,4 @@ static inline bool is_mmc_8xxx(struct cvm_mmc_host *host)
317331
return (chip_id == PCI_SUBSYS_DEVID_8XXX);
318332
}
319333

320-
static inline bool is_mmc_otx2(struct cvm_mmc_host *host)
321-
{
322-
struct pci_dev *pdev = host->pdev;
323-
u32 chip_id;
324-
325-
if (!pdev)
326-
return 0;
327-
328-
chip_id = (pdev->subsystem_device >> 12) & 0xF;
329-
330-
return (chip_id == PCI_SUBSYS_DEVID_9XXX);
331-
}
332-
333-
static inline bool is_mmc_otx2_A0(struct cvm_mmc_host *host)
334-
{
335-
struct pci_dev *pdev = host->pdev;
336-
u32 chip_id;
337-
338-
if (!pdev)
339-
return 0;
340-
341-
chip_id = (pdev->subsystem_device >> 12) & 0xF;
342-
343-
return (pdev->revision == REV_ID_0) &&
344-
(chip_id == PCI_SUBSYS_DEVID_9XXX);
345-
}
346-
347-
static inline bool is_mmc_otx2_C0(struct cvm_mmc_host *host)
348-
{
349-
struct pci_dev *pdev = host->pdev;
350-
u32 chip_id;
351-
352-
if (!pdev)
353-
return 0;
354-
355-
chip_id = (pdev->subsystem_device >> 12) & 0xF;
356-
357-
return (pdev->revision == REV_ID_2) &&
358-
(chip_id == PCI_SUBSYS_DEVID_9XXX);
359-
}
360-
361-
static inline bool is_mmc_95xx(struct cvm_mmc_host *host)
362-
{
363-
struct pci_dev *pdev = host->pdev;
364-
u32 chip_id;
365-
366-
if (!pdev)
367-
return 0;
368-
369-
chip_id = (pdev->subsystem_device >> 8) & 0xFF;
370-
371-
return (chip_id == PCI_SUBSYS_DEVID_95XX);
372-
}
373-
374334
#endif

0 commit comments

Comments
 (0)