tmio_mmc.h 6.1 KB
Newer Older
I
Ian Molton 已提交
1 2 3 4 5 6 7 8 9 10
/* Definitons for use with the tmio_mmc.c
 *
 * (c) 2004 Ian Molton <spyro@f2s.com>
 * (c) 2007 Ian Molton <spyro@f2s.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */
11 12 13

#include <linux/highmem.h>

I
Ian Molton 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#define CTL_SD_CMD 0x00
#define CTL_ARG_REG 0x04
#define CTL_STOP_INTERNAL_ACTION 0x08
#define CTL_XFER_BLK_COUNT 0xa
#define CTL_RESPONSE 0x0c
#define CTL_STATUS 0x1c
#define CTL_IRQ_MASK 0x20
#define CTL_SD_CARD_CLK_CTL 0x24
#define CTL_SD_XFER_LEN 0x26
#define CTL_SD_MEM_CARD_OPT 0x28
#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
#define CTL_SD_DATA_PORT 0x30
#define CTL_TRANSACTION_CTL 0x34
#define CTL_RESET_SD 0xe0
#define CTL_SDIO_REGS 0x100
#define CTL_CLK_AND_WAIT_CTL 0x138
#define CTL_RESET_SDIO 0x1e0

/* Definitions for values the CTRL_STATUS register can take. */
#define TMIO_STAT_CMDRESPEND    0x00000001
#define TMIO_STAT_DATAEND       0x00000004
#define TMIO_STAT_CARD_REMOVE   0x00000008
#define TMIO_STAT_CARD_INSERT   0x00000010
#define TMIO_STAT_SIGSTATE      0x00000020
#define TMIO_STAT_WRPROTECT     0x00000080
#define TMIO_STAT_CARD_REMOVE_A 0x00000100
#define TMIO_STAT_CARD_INSERT_A 0x00000200
#define TMIO_STAT_SIGSTATE_A    0x00000400
#define TMIO_STAT_CMD_IDX_ERR   0x00010000
#define TMIO_STAT_CRCFAIL       0x00020000
#define TMIO_STAT_STOPBIT_ERR   0x00040000
#define TMIO_STAT_DATATIMEOUT   0x00080000
#define TMIO_STAT_RXOVERFLOW    0x00100000
#define TMIO_STAT_TXUNDERRUN    0x00200000
#define TMIO_STAT_CMDTIMEOUT    0x00400000
#define TMIO_STAT_RXRDY         0x01000000
#define TMIO_STAT_TXRQ          0x02000000
#define TMIO_STAT_ILL_FUNC      0x20000000
#define TMIO_STAT_CMD_BUSY      0x40000000
#define TMIO_STAT_ILL_ACCESS    0x80000000

/* Define some IRQ masks */
/* This is the mask used at reset by the chip */
#define TMIO_MASK_ALL           0x837f031d
#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
#define TMIO_MASK_CMD     (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
#define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)

P
Philipp Zabel 已提交
66 67

#define enable_mmc_irqs(host, i) \
I
Ian Molton 已提交
68 69
	do { \
		u32 mask;\
P
Philipp Zabel 已提交
70
		mask  = sd_ctrl_read32((host), CTL_IRQ_MASK); \
I
Ian Molton 已提交
71
		mask &= ~((i) & TMIO_MASK_IRQ); \
P
Philipp Zabel 已提交
72
		sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
I
Ian Molton 已提交
73 74
	} while (0)

P
Philipp Zabel 已提交
75
#define disable_mmc_irqs(host, i) \
I
Ian Molton 已提交
76 77
	do { \
		u32 mask;\
P
Philipp Zabel 已提交
78
		mask  = sd_ctrl_read32((host), CTL_IRQ_MASK); \
I
Ian Molton 已提交
79
		mask |= ((i) & TMIO_MASK_IRQ); \
P
Philipp Zabel 已提交
80
		sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
I
Ian Molton 已提交
81 82
	} while (0)

P
Philipp Zabel 已提交
83
#define ack_mmc_irqs(host, i) \
I
Ian Molton 已提交
84 85
	do { \
		u32 mask;\
P
Philipp Zabel 已提交
86
		mask  = sd_ctrl_read32((host), CTL_STATUS); \
I
Ian Molton 已提交
87
		mask &= ~((i) & TMIO_MASK_IRQ); \
P
Philipp Zabel 已提交
88
		sd_ctrl_write32((host), CTL_STATUS, mask); \
I
Ian Molton 已提交
89 90 91 92 93
	} while (0)


struct tmio_mmc_host {
	void __iomem *ctl;
P
Philipp Zabel 已提交
94
	unsigned long bus_shift;
I
Ian Molton 已提交
95 96 97 98 99 100
	struct mmc_command      *cmd;
	struct mmc_request      *mrq;
	struct mmc_data         *data;
	struct mmc_host         *mmc;
	int                     irq;

101 102 103 104
	/* Callbacks for clock / power control */
	void (*set_pwr)(struct platform_device *host, int state);
	void (*set_clk_div)(struct platform_device *host, int state);

I
Ian Molton 已提交
105 106 107 108
	/* pio related stuff */
	struct scatterlist      *sg_ptr;
	unsigned int            sg_len;
	unsigned int            sg_off;
109 110

	struct platform_device *pdev;
I
Ian Molton 已提交
111 112
};

P
Philipp Zabel 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
#include <linux/io.h>

static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
{
	return readw(host->ctl + (addr << host->bus_shift));
}

static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
		u16 *buf, int count)
{
	readsw(host->ctl + (addr << host->bus_shift), buf, count);
}

static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
{
	return readw(host->ctl + (addr << host->bus_shift)) |
	       readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
}

static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr,
		u16 val)
{
	writew(val, host->ctl + (addr << host->bus_shift));
}

static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
		u16 *buf, int count)
{
	writesw(host->ctl + (addr << host->bus_shift), buf, count);
}

static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr,
		u32 val)
{
	writew(val, host->ctl + (addr << host->bus_shift));
	writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
}

I
Ian Molton 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
#include <linux/scatterlist.h>
#include <linux/blkdev.h>

static inline void tmio_mmc_init_sg(struct tmio_mmc_host *host,
	struct mmc_data *data)
{
	host->sg_len = data->sg_len;
	host->sg_ptr = data->sg;
	host->sg_off = 0;
}

static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host)
{
	host->sg_ptr = sg_next(host->sg_ptr);
	host->sg_off = 0;
	return --host->sg_len;
}

static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host,
	unsigned long *flags)
{
	struct scatterlist *sg = host->sg_ptr;

	local_irq_save(*flags);
	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
}

static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host,
	unsigned long *flags)
{
	kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ);
	local_irq_restore(*flags);
}

#ifdef CONFIG_MMC_DEBUG

#define STATUS_TO_TEXT(a) \
	do { \
		if (status & TMIO_STAT_##a) \
190
			printk(#a); \
I
Ian Molton 已提交
191 192
	} while (0)

193
void pr_debug_status(u32 status)
I
Ian Molton 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
{
	printk(KERN_DEBUG "status: %08x = ", status);
	STATUS_TO_TEXT(CARD_REMOVE);
	STATUS_TO_TEXT(CARD_INSERT);
	STATUS_TO_TEXT(SIGSTATE);
	STATUS_TO_TEXT(WRPROTECT);
	STATUS_TO_TEXT(CARD_REMOVE_A);
	STATUS_TO_TEXT(CARD_INSERT_A);
	STATUS_TO_TEXT(SIGSTATE_A);
	STATUS_TO_TEXT(CMD_IDX_ERR);
	STATUS_TO_TEXT(STOPBIT_ERR);
	STATUS_TO_TEXT(ILL_FUNC);
	STATUS_TO_TEXT(CMD_BUSY);
	STATUS_TO_TEXT(CMDRESPEND);
	STATUS_TO_TEXT(DATAEND);
	STATUS_TO_TEXT(CRCFAIL);
	STATUS_TO_TEXT(DATATIMEOUT);
	STATUS_TO_TEXT(CMDTIMEOUT);
	STATUS_TO_TEXT(RXOVERFLOW);
	STATUS_TO_TEXT(TXUNDERRUN);
	STATUS_TO_TEXT(RXRDY);
	STATUS_TO_TEXT(TXRQ);
	STATUS_TO_TEXT(ILL_ACCESS);
	printk("\n");
}

#else
#define pr_debug_status(s)  do { } while (0)
#endif