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

Commit 4d1a3a0d authored by Ulf Hansson's avatar Ulf Hansson Committed by Russell King
Browse files

ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction



The ST Micro variant supports bus signal direction indication. A new
member in the variant struct is added for this.

Moreover the actual signal direction configuration is board specific,
thus the amba mmci platform data is extended with a new member to be
able provide mmci with these specific board configurations.

This patch is based upon a patch from Sebastian Rasmussen.

Tested-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarSebastian Rasmussen <sebastian.rasmussen@stericsson.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 7d72a1d4
Loading
Loading
Loading
Loading
+21 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ static unsigned int fmax = 515633;
 * @st_clkdiv: true if using a ST-specific clock divider algorithm
 * @st_clkdiv: true if using a ST-specific clock divider algorithm
 * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
 * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
 * @pwrreg_powerup: power up value for MMCIPOWER register
 * @pwrreg_powerup: power up value for MMCIPOWER register
 * @signal_direction: input/out direction of bus signals can be indicated
 */
 */
struct variant_data {
struct variant_data {
	unsigned int		clkreg;
	unsigned int		clkreg;
@@ -65,6 +66,7 @@ struct variant_data {
	bool			st_clkdiv;
	bool			st_clkdiv;
	bool			blksz_datactrl16;
	bool			blksz_datactrl16;
	u32			pwrreg_powerup;
	u32			pwrreg_powerup;
	bool			signal_direction;
};
};


static struct variant_data variant_arm = {
static struct variant_data variant_arm = {
@@ -88,6 +90,7 @@ static struct variant_data variant_u300 = {
	.datalength_bits	= 16,
	.datalength_bits	= 16,
	.sdio			= true,
	.sdio			= true,
	.pwrreg_powerup		= MCI_PWR_ON,
	.pwrreg_powerup		= MCI_PWR_ON,
	.signal_direction	= true,
};
};


static struct variant_data variant_ux500 = {
static struct variant_data variant_ux500 = {
@@ -99,6 +102,7 @@ static struct variant_data variant_ux500 = {
	.sdio			= true,
	.sdio			= true,
	.st_clkdiv		= true,
	.st_clkdiv		= true,
	.pwrreg_powerup		= MCI_PWR_ON,
	.pwrreg_powerup		= MCI_PWR_ON,
	.signal_direction	= true,
};
};


static struct variant_data variant_ux500v2 = {
static struct variant_data variant_ux500v2 = {
@@ -111,6 +115,7 @@ static struct variant_data variant_ux500v2 = {
	.st_clkdiv		= true,
	.st_clkdiv		= true,
	.blksz_datactrl16	= true,
	.blksz_datactrl16	= true,
	.pwrreg_powerup		= MCI_PWR_ON,
	.pwrreg_powerup		= MCI_PWR_ON,
	.signal_direction	= true,
};
};


/*
/*
@@ -1057,6 +1062,22 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
		break;
		break;
	}
	}


	if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
		/*
		 * The ST Micro variant has some additional bits
		 * indicating signal direction for the signals in
		 * the SD/MMC bus and feedback-clock usage.
		 */
		pwr |= host->plat->sigdir;

		if (ios->bus_width == MMC_BUS_WIDTH_4)
			pwr &= ~MCI_ST_DATA74DIREN;
		else if (ios->bus_width == MMC_BUS_WIDTH_1)
			pwr &= (~MCI_ST_DATA74DIREN &
				~MCI_ST_DATA31DIREN &
				~MCI_ST_DATA2DIREN);
	}

	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
		if (host->hw_designer != AMBA_VENDOR_ST)
		if (host->hw_designer != AMBA_VENDOR_ST)
			pwr |= MCI_ROD;
			pwr |= MCI_ROD;
+0 −10
Original line number Original line Diff line number Diff line
@@ -13,16 +13,6 @@
#define MCI_PWR_ON		0x03
#define MCI_PWR_ON		0x03
#define MCI_OD			(1 << 6)
#define MCI_OD			(1 << 6)
#define MCI_ROD			(1 << 7)
#define MCI_ROD			(1 << 7)
/*
 * The ST Micro version does not have ROD and reuse the voltage registers
 * for direction settings
 */
#define MCI_ST_DATA2DIREN	(1 << 2)
#define MCI_ST_CMDDIREN		(1 << 3)
#define MCI_ST_DATA0DIREN	(1 << 4)
#define MCI_ST_DATA31DIREN	(1 << 5)
#define MCI_ST_FBCLKEN		(1 << 7)
#define MCI_ST_DATA74DIREN	(1 << 8)


#define MMCICLOCK		0x004
#define MMCICLOCK		0x004
#define MCI_CLK_ENABLE		(1 << 8)
#define MCI_CLK_ENABLE		(1 << 8)
+16 −0
Original line number Original line Diff line number Diff line
@@ -6,6 +6,19 @@


#include <linux/mmc/host.h>
#include <linux/mmc/host.h>



/*
 * These defines is places here due to access is needed from machine
 * configuration files. The ST Micro version does not have ROD and
 * reuse the voltage registers for direction settings.
 */
#define MCI_ST_DATA2DIREN	(1 << 2)
#define MCI_ST_CMDDIREN		(1 << 3)
#define MCI_ST_DATA0DIREN	(1 << 4)
#define MCI_ST_DATA31DIREN	(1 << 5)
#define MCI_ST_FBCLKEN		(1 << 7)
#define MCI_ST_DATA74DIREN	(1 << 8)

/* Just some dummy forwarding */
/* Just some dummy forwarding */
struct dma_chan;
struct dma_chan;


@@ -31,6 +44,8 @@ struct dma_chan;
 * @capabilities: the capabilities of the block as implemented in
 * @capabilities: the capabilities of the block as implemented in
 * this platform, signify anything MMC_CAP_* from mmc/host.h
 * this platform, signify anything MMC_CAP_* from mmc/host.h
 * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
 * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
 * @sigdir: a bit field indicating for what bits in the MMC bus the host
 * should enable signal direction indication.
 * @dma_filter: function used to select an appropriate RX and TX
 * @dma_filter: function used to select an appropriate RX and TX
 * DMA channel to be used for DMA, if and only if you're deploying the
 * DMA channel to be used for DMA, if and only if you're deploying the
 * generic DMA engine
 * generic DMA engine
@@ -54,6 +69,7 @@ struct mmci_platform_data {
	bool	cd_invert;
	bool	cd_invert;
	unsigned long capabilities;
	unsigned long capabilities;
	unsigned long capabilities2;
	unsigned long capabilities2;
	u32 sigdir;
	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
	void *dma_rx_param;
	void *dma_rx_param;
	void *dma_tx_param;
	void *dma_tx_param;