Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit faf8180b authored by Ludovic Desroches's avatar Ludovic Desroches Committed by Chris Ball
Browse files

mmc: atmel-mci: add support for odd clock dividers



Add an odd clock divider capability available from v5xx. It also involves
changing the clock divider calculation, and changing the switch-case
statement to use top-down fallthrough.

Signed-off-by: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 33ab4bbb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
# define ATMCI_MR_PDCFBYTE		(  1 << 13)	/* Force Byte Transfer */
# define ATMCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
# define ATMCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
# define ATMCI_MR_CLKODD(x)		((x) << 16)	/* LSB of Clock Divider */
#define ATMCI_DTOR			0x0008	/* Data Timeout */
# define ATMCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
# define ATMCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
+29 −19
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ struct atmel_mci_caps {
	bool    has_cstor_reg;
	bool    has_highspeed;
	bool    has_rwproof;
	bool	has_odd_clk_div;
};

struct atmel_mci_dma {
@@ -1134,6 +1135,17 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
		}

		/* Calculate clock divider */
		if (host->caps.has_odd_clk_div) {
			clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
			if (clkdiv > 511) {
				dev_warn(&mmc->class_dev,
				         "clock %u too slow; using %lu\n",
				         clock_min, host->bus_hz / (511 + 2));
				clkdiv = 511;
			}
			host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
			                 | ATMCI_MR_CLKODD(clkdiv & 1);
		} else {
			clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
			if (clkdiv > 255) {
				dev_warn(&mmc->class_dev,
@@ -1141,8 +1153,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
				         clock_min, host->bus_hz / (2 * 256));
				clkdiv = 255;
			}

			host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
		}

		/*
		 * WRPROOF and RDPROOF prevent overruns/underruns by
@@ -2014,37 +2026,35 @@ static void __init atmci_get_cap(struct atmel_mci *host)
			"version: 0x%x\n", version);

	host->caps.has_dma = 0;
	host->caps.has_pdc = 0;
	host->caps.has_pdc = 1;
	host->caps.has_cfg_reg = 0;
	host->caps.has_cstor_reg = 0;
	host->caps.has_highspeed = 0;
	host->caps.has_rwproof = 0;
	host->caps.has_odd_clk_div = 0;

	/* keep only major version number */
	switch (version & 0xf00) {
	case 0x100:
		host->caps.has_pdc = 1;
		break;
	case 0x200:
		host->caps.has_pdc = 1;
		host->caps.has_rwproof = 1;
		break;
	case 0x300:
	case 0x400:
	case 0x500:
		host->caps.has_odd_clk_div = 1;
	case 0x400:
	case 0x300:
#ifdef CONFIG_AT_HDMAC
		host->caps.has_dma = 1;
#else
		host->caps.has_dma = 0;
		dev_info(&host->pdev->dev,
			"has dma capability but dma engine is not selected, then use pio\n");
#endif
		host->caps.has_pdc = 0;
		host->caps.has_cfg_reg = 1;
		host->caps.has_cstor_reg = 1;
		host->caps.has_highspeed = 1;
	case 0x200:
		host->caps.has_rwproof = 1;
	case 0x100:
		break;
	default:
		host->caps.has_pdc = 0;
		dev_warn(&host->pdev->dev,
				"Unmanaged mci version, set minimum capabilities\n");
		break;