tmio_mmc.c revision 7ee422dc6e947fcdc153246d47f26ae0b7cf083d
14a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* 24a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * linux/drivers/mmc/tmio_mmc.c 34a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 44a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Copyright (C) 2004 Ian Molton 54a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Copyright (C) 2007 Ian Molton 64a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 74a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * This program is free software; you can redistribute it and/or modify 84a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * it under the terms of the GNU General Public License version 2 as 94a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * published by the Free Software Foundation. 104a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Driver for the MMC / SD / SDIO cell found in: 124a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 13e6f2c7adc1318e233d31d113e6896607c54073a4Philipp Zabel * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3 144a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * This driver draws mainly on scattered spec sheets, Reverse engineering 164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit 174a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * support). (Further 4 bit support from a later datasheet). 184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * TODO: 204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Investigate using a workqueue for PIO transfers 214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Eliminate FIXMEs 224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * SDIO support 234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Better Power management 244a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Handle MMC errors better 254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * double buffer support 264a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/module.h> 294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/irq.h> 304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/device.h> 314a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/delay.h> 324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/mmc/host.h> 334a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/mfd/core.h> 344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include <linux/mfd/tmio.h> 354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 364a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#include "tmio_mmc.h" 374a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 384a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) 394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 40da46a0bd42c81a473618e94871500fb792c98727Ian Molton u32 clk = 0, clock; 414a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 424a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (new_clock) { 43da46a0bd42c81a473618e94871500fb792c98727Ian Molton for (clock = host->mmc->f_min, clk = 0x80000080; 44da46a0bd42c81a473618e94871500fb792c98727Ian Molton new_clock >= (clock<<1); clk >>= 1) 454a48998fa16121d0fe3436cce43afd6f47424103Ian Molton clock <<= 1; 464a48998fa16121d0fe3436cce43afd6f47424103Ian Molton clk |= 0x100; 474a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4964e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (host->set_clk_div) 5064e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->set_clk_div(host->pdev, (clk>>22) & 1); 5164e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton 52da46a0bd42c81a473618e94871500fb792c98727Ian Molton sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); 534a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 544a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 554a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 575e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); 584a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 595e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 & 605e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); 614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 624a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 634a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 644a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void tmio_mmc_clk_start(struct tmio_mmc_host *host) 654a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 665e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 675e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); 684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 695e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); 704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 724a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 734a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void reset(struct tmio_mmc_host *host) 744a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* FIXME - should we set stop clock reg here */ 765e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); 775e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); 784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 795e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 805e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); 814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton msleep(10); 824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 834a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 844a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void 854a48998fa16121d0fe3436cce43afd6f47424103Ian Moltontmio_mmc_finish_request(struct tmio_mmc_host *host) 864a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 874a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_request *mrq = host->mrq; 884a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 894a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->mrq = NULL; 904a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->cmd = NULL; 914a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->data = NULL; 924a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 934a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_request_done(host->mmc, mrq); 944a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 954a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 964a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* These are the bitmasks the tmio chip requires to implement the MMC response 974a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * types. Note that R1 and R6 are the same in this scheme. */ 984a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define APP_CMD 0x0040 994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define RESP_NONE 0x0300 1004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define RESP_R1 0x0400 1014a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define RESP_R1B 0x0500 1024a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define RESP_R2 0x0600 1034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define RESP_R3 0x0700 1044a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define DATA_PRESENT 0x0800 1054a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define TRANSFER_READ 0x1000 1064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define TRANSFER_MULTI 0x2000 1074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define SECURITY_CMD 0x4000 1084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1094a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int 1104a48998fa16121d0fe3436cce43afd6f47424103Ian Moltontmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) 1114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 1124a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_data *data = host->data; 1134a48998fa16121d0fe3436cce43afd6f47424103Ian Molton int c = cmd->opcode; 1144a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Command 12 is handled by hardware */ 1164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (cmd->opcode == 12 && !cmd->arg) { 1175e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001); 1184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return 0; 1194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 1204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton switch (mmc_resp_type(cmd)) { 1224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_RSP_NONE: c |= RESP_NONE; break; 1234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_RSP_R1: c |= RESP_R1; break; 1244a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_RSP_R1B: c |= RESP_R1B; break; 1254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_RSP_R2: c |= RESP_R2; break; 1264a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_RSP_R3: c |= RESP_R3; break; 1274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton default: 1284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Unknown response type %d\n", mmc_resp_type(cmd)); 1294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return -EINVAL; 1304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 1314a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->cmd = cmd; 1334a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* FIXME - this seems to be ok comented out but the spec suggest this bit should 1354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * be set when issuing app commands. 1364a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * if(cmd->flags & MMC_FLAG_ACMD) 1374a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * c |= APP_CMD; 1384a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 1394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data) { 1404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton c |= DATA_PRESENT; 1414a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data->blocks > 1) { 1425e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100); 1434a48998fa16121d0fe3436cce43afd6f47424103Ian Molton c |= TRANSFER_MULTI; 1444a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 1454a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data->flags & MMC_DATA_READ) 1464a48998fa16121d0fe3436cce43afd6f47424103Ian Molton c |= TRANSFER_READ; 1474a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 1484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1495e74672c0925335bb00772530634ac70179e8a19Philipp Zabel enable_mmc_irqs(host, TMIO_MASK_CMD); 1504a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1514a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Fire off the command */ 1525e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg); 1535e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_CMD, c); 1544a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1554a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return 0; 1564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 1574a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1584a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* This chip always returns (at least?) as much data as you ask for. 1594a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * I'm unsure what happens if you ask for less than a block. This should be 1604a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * looked into to ensure that a funny length read doesnt hose the controller. 1614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * 1624a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 1634a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) 1644a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 1654a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_data *data = host->data; 1664a48998fa16121d0fe3436cce43afd6f47424103Ian Molton unsigned short *buf; 1674a48998fa16121d0fe3436cce43afd6f47424103Ian Molton unsigned int count; 1684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton unsigned long flags; 1694a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!data) { 1714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Spurious PIO IRQ\n"); 1724a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 1734a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 1744a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) + 1764a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->sg_off); 1774a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton count = host->sg_ptr->length - host->sg_off; 1794a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (count > data->blksz) 1804a48998fa16121d0fe3436cce43afd6f47424103Ian Molton count = data->blksz; 1814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("count: %08x offset: %08x flags %08x\n", 1834a48998fa16121d0fe3436cce43afd6f47424103Ian Molton count, host->sg_off, data->flags); 1844a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1854a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Transfer the data */ 1864a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data->flags & MMC_DATA_READ) 1875e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); 1884a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 1895e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); 1904a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1914a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->sg_off += count; 1924a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1934a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_kunmap_atomic(host, &flags); 1944a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1954a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (host->sg_off == host->sg_ptr->length) 1964a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_next_sg(host); 1974a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 1984a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 1994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 2004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2014a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) 2024a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 2034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_data *data = host->data; 204a0d045cac9bcb3e9a9796d596415f7ffb64852e2Julia Lawall struct mmc_command *stop; 2054a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->data = NULL; 2074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!data) { 2094a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Spurious data end IRQ\n"); 2104a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 2114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 212a0d045cac9bcb3e9a9796d596415f7ffb64852e2Julia Lawall stop = data->stop; 2134a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2144a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* FIXME - return correct transfer count on errors */ 2154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!data->error) 2164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton data->bytes_xfered = data->blocks * data->blksz; 2174a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 2184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton data->bytes_xfered = 0; 2194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Completed data request\n"); 2214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /*FIXME - other drivers allow an optional stop command of any given type 2234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * which we dont do, as the chip can auto generate them. 2244a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Perhaps we can be smarter about when to use auto CMD12 and 2254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * only issue the auto request when we know this is the desired 2264a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * stop command, allowing fallback to the stop command the 2274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * upper layers expect. For now, we do what works. 2284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 2294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data->flags & MMC_DATA_READ) 2315e74672c0925335bb00772530634ac70179e8a19Philipp Zabel disable_mmc_irqs(host, TMIO_MASK_READOP); 2324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 2335e74672c0925335bb00772530634ac70179e8a19Philipp Zabel disable_mmc_irqs(host, TMIO_MASK_WRITEOP); 2344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (stop) { 2364a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (stop->opcode == 12 && !stop->arg) 2375e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000); 2384a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 2394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton BUG(); 2404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 2414a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2424a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_finish_request(host); 2434a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 2444a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2454a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, 2464a48998fa16121d0fe3436cce43afd6f47424103Ian Molton unsigned int stat) 2474a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 2484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_command *cmd = host->cmd; 2495e74672c0925335bb00772530634ac70179e8a19Philipp Zabel int i, addr; 2504a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2514a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!host->cmd) { 2524a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Spurious CMD irq\n"); 2534a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 2544a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 2554a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->cmd = NULL; 2574a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2584a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* This controller is sicker than the PXA one. Not only do we need to 2594a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * drop the top 8 bits of the first response word, we also need to 2604a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * modify the order of the response for short response command types. 2614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 2624a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2635e74672c0925335bb00772530634ac70179e8a19Philipp Zabel for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4) 2645e74672c0925335bb00772530634ac70179e8a19Philipp Zabel cmd->resp[i] = sd_ctrl_read32(host, addr); 2654a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2664a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (cmd->flags & MMC_RSP_136) { 2674a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); 2684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24); 2694a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24); 2704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->resp[3] <<= 8; 2714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } else if (cmd->flags & MMC_RSP_R3) { 2724a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->resp[0] = cmd->resp[3]; 2734a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 2744a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (stat & TMIO_STAT_CMDTIMEOUT) 2764a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->error = -ETIMEDOUT; 2774a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) 2784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cmd->error = -EILSEQ; 2794a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2804a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* If there is data to handle we enable data IRQs here, and 2814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * we will ultimatley finish the request in the data_end handler. 2824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * If theres no data or we encountered an error, finish now. 2834a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 2844a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (host->data && !cmd->error) { 2854a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (host->data->flags & MMC_DATA_READ) 2865e74672c0925335bb00772530634ac70179e8a19Philipp Zabel enable_mmc_irqs(host, TMIO_MASK_READOP); 2874a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 2885e74672c0925335bb00772530634ac70179e8a19Philipp Zabel enable_mmc_irqs(host, TMIO_MASK_WRITEOP); 2894a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } else { 2904a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_finish_request(host); 2914a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 2924a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2934a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 2944a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 2954a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2964a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 2974a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic irqreturn_t tmio_mmc_irq(int irq, void *devid) 2984a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 2994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host = devid; 3004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton unsigned int ireg, irq_mask, status; 3014a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3024a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("MMC IRQ begin\n"); 3034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3045e74672c0925335bb00772530634ac70179e8a19Philipp Zabel status = sd_ctrl_read32(host, CTL_STATUS); 3055e74672c0925335bb00772530634ac70179e8a19Philipp Zabel irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); 3064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ireg = status & TMIO_MASK_IRQ & ~irq_mask; 3074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug_status(status); 3094a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug_status(ireg); 3104a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!ireg) { 3125e74672c0925335bb00772530634ac70179e8a19Philipp Zabel disable_mmc_irqs(host, status & ~irq_mask); 3134a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3144a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("tmio_mmc: Spurious irq, disabling! " 3154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); 3164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug_status(status); 3174a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto out; 3194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton while (ireg) { 3224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Card insert / remove attempts */ 3234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { 3245e74672c0925335bb00772530634ac70179e8a19Philipp Zabel ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | 3254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton TMIO_STAT_CARD_REMOVE); 3266d9af5af61a6c30676ef6f56a791d4036c92d249Magnus Damm mmc_detect_change(host->mmc, msecs_to_jiffies(100)); 3274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* CRC and other errors */ 3304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* if (ireg & TMIO_STAT_ERR_IRQ) 3314a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * handled |= tmio_error_irq(host, irq, stat); 3324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 3334a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Command completion */ 3354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ireg & TMIO_MASK_CMD) { 3365e74672c0925335bb00772530634ac70179e8a19Philipp Zabel ack_mmc_irqs(host, TMIO_MASK_CMD); 3374a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_cmd_irq(host, status); 3384a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Data transfer */ 3414a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { 3425e74672c0925335bb00772530634ac70179e8a19Philipp Zabel ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); 3434a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_pio_irq(host); 3444a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3454a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3464a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Data transfer completion */ 3474a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ireg & TMIO_STAT_DATAEND) { 3485e74672c0925335bb00772530634ac70179e8a19Philipp Zabel ack_mmc_irqs(host, TMIO_STAT_DATAEND); 3494a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_data_irq(host); 3504a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3514a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3524a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Check status - keep going until we've handled it all */ 3535e74672c0925335bb00772530634ac70179e8a19Philipp Zabel status = sd_ctrl_read32(host, CTL_STATUS); 3545e74672c0925335bb00772530634ac70179e8a19Philipp Zabel irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); 3554a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ireg = status & TMIO_MASK_IRQ & ~irq_mask; 3564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3574a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("Status at end of loop: %08x\n", status); 3584a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug_status(status); 3594a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3604a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("MMC IRQ end\n"); 3614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3624a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonout: 3634a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return IRQ_HANDLED; 3644a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 3654a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3664a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int tmio_mmc_start_data(struct tmio_mmc_host *host, 3674a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_data *data) 3684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 3694a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 3704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton data->blksz, data->blocks); 3714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3724a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Hardware cannot perform 1 and 2 byte requests in 4 bit mode */ 3734a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (data->blksz < 4 && host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) { 3744a48998fa16121d0fe3436cce43afd6f47424103Ian Molton printk(KERN_ERR "%s: %d byte block unsupported in 4 bit mode\n", 3754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_hostname(host->mmc), data->blksz); 3764a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return -EINVAL; 3774a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 3784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3794a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_init_sg(host, data); 3804a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->data = data; 3814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Set transfer length / blocksize */ 3835e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); 3845e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks); 3854a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3864a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return 0; 3874a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 3884a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3894a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* Process requests from the MMC layer */ 3904a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) 3914a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 3924a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host = mmc_priv(mmc); 3934a48998fa16121d0fe3436cce43afd6f47424103Ian Molton int ret; 3944a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3954a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (host->mrq) 3964a48998fa16121d0fe3436cce43afd6f47424103Ian Molton pr_debug("request not null\n"); 3974a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 3984a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->mrq = mrq; 3994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (mrq->data) { 4014a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ret = tmio_mmc_start_data(host, mrq->data); 4024a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ret) 4034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto fail; 4044a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 4054a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ret = tmio_mmc_start_command(host, mrq->cmd); 4074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!ret) 4094a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return; 4104a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4114a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonfail: 4124a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mrq->cmd->error = ret; 4134a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_request_done(mmc, mrq); 4144a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 4154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* Set MMC clock / power. 4174a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * Note: This controller uses a simple divider scheme therefore it cannot 4184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as 4194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * MMC wont run that fast, it has to be clocked at 12MHz which is the next 4204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton * slowest setting. 4214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton */ 4224a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 4234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 4244a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host = mmc_priv(mmc); 4254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4264a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ios->clock) 4274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_set_clock(host, ios->clock); 4284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Power sequence - OFF -> ON -> UP */ 4304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton switch (ios->power_mode) { 4314a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_POWER_OFF: /* power down SD bus */ 43264e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (host->set_pwr) 43364e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->set_pwr(host->pdev, 0); 4344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_clk_stop(host); 4354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton break; 4364a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_POWER_ON: /* power up SD bus */ 43764e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (host->set_pwr) 43864e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->set_pwr(host->pdev, 1); 4394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton break; 4404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_POWER_UP: /* start bus clock */ 4414a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_clk_start(host); 4424a48998fa16121d0fe3436cce43afd6f47424103Ian Molton break; 4434a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 4444a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4454a48998fa16121d0fe3436cce43afd6f47424103Ian Molton switch (ios->bus_width) { 4464a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_BUS_WIDTH_1: 4475e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); 4484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton break; 4494a48998fa16121d0fe3436cce43afd6f47424103Ian Molton case MMC_BUS_WIDTH_4: 4505e74672c0925335bb00772530634ac70179e8a19Philipp Zabel sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); 4514a48998fa16121d0fe3436cce43afd6f47424103Ian Molton break; 4524a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 4534a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4544a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Let things settle. delay taken from winCE driver */ 4554a48998fa16121d0fe3436cce43afd6f47424103Ian Molton udelay(140); 4564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 4574a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4584a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int tmio_mmc_get_ro(struct mmc_host *mmc) 4594a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 4604a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host = mmc_priv(mmc); 4614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4625e74672c0925335bb00772530634ac70179e8a19Philipp Zabel return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; 4634a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 4644a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4654a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic struct mmc_host_ops tmio_mmc_ops = { 4664a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .request = tmio_mmc_request, 4674a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .set_ios = tmio_mmc_set_ios, 4684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .get_ro = tmio_mmc_get_ro, 4694a48998fa16121d0fe3436cce43afd6f47424103Ian Molton}; 4704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#ifdef CONFIG_PM 4724a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) 4734a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 4744a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 4754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_host *mmc = platform_get_drvdata(dev); 4764a48998fa16121d0fe3436cce43afd6f47424103Ian Molton int ret; 4774a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ret = mmc_suspend_host(mmc, state); 4794a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4804a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Tell MFD core it can disable us now.*/ 4814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!ret && cell->disable) 4824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton cell->disable(dev); 4834a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4844a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return ret; 4854a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 4864a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4874a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int tmio_mmc_resume(struct platform_device *dev) 4884a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 4894a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 4904a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_host *mmc = platform_get_drvdata(dev); 4914a48998fa16121d0fe3436cce43afd6f47424103Ian Molton int ret = 0; 4924a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 4934a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Tell the MFD core we are ready to be enabled */ 49464e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (cell->resume) { 49564e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton ret = cell->resume(dev); 4964a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ret) 4974a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto out; 4984a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 4994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_resume_host(mmc); 5014a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5024a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonout: 5034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return ret; 5044a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 5054a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#else 5064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define tmio_mmc_suspend NULL 5074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#define tmio_mmc_resume NULL 5084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton#endif 5094a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5104a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int __devinit tmio_mmc_probe(struct platform_device *dev) 5114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 5124a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 513f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel struct tmio_mmc_data *pdata; 51464e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton struct resource *res_ctl; 5154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host; 5164a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_host *mmc; 517d6c9b5ed37c26503795d241474a17db1d306e7eaPhilipp Zabel int ret = -EINVAL; 5184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 51964e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (dev->num_resources != 2) 5204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto out; 5214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); 52364e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton if (!res_ctl) 5244a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto out; 5254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 526f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel pdata = cell->driver_data; 527d6c9b5ed37c26503795d241474a17db1d306e7eaPhilipp Zabel if (!pdata || !pdata->hclk) 528f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel goto out; 529d6c9b5ed37c26503795d241474a17db1d306e7eaPhilipp Zabel 530d6c9b5ed37c26503795d241474a17db1d306e7eaPhilipp Zabel ret = -ENOMEM; 531f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel 5324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); 5334a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!mmc) 5344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto out; 5354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5364a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host = mmc_priv(mmc); 5374a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->mmc = mmc; 53864e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->pdev = dev; 5394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton platform_set_drvdata(dev, mmc); 5404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 54164e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->set_pwr = pdata->set_pwr; 54264e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton host->set_clk_div = pdata->set_clk_div; 54364e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton 5445e74672c0925335bb00772530634ac70179e8a19Philipp Zabel /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ 5455e74672c0925335bb00772530634ac70179e8a19Philipp Zabel host->bus_shift = resource_size(res_ctl) >> 10; 5465e74672c0925335bb00772530634ac70179e8a19Philipp Zabel 547bc6772a023ceab8df404b18b31c27f764dcf5b3fMagnus Damm host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); 5484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (!host->ctl) 5494a48998fa16121d0fe3436cce43afd6f47424103Ian Molton goto host_free; 5504a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5514a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc->ops = &tmio_mmc_ops; 5524a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc->caps = MMC_CAP_4_BIT_DATA; 553b741d440a97c376af309e902eeb2f3c5673d2c92Yusuke Goda mmc->caps |= pdata->capabilities; 554f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel mmc->f_max = pdata->hclk; 555f0e46cc4971f6be96010d9248e0fc076b229d989Philipp Zabel mmc->f_min = mmc->f_max / 512; 5564a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 5574a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5584a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Tell the MFD core we are ready to be enabled */ 5594a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (cell->enable) { 5604a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ret = cell->enable(dev); 5614a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ret) 56264e8867ba8098b69889c1af94997a5ba2348fb26Ian Molton goto unmap_ctl; 5634a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 5644a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5654a48998fa16121d0fe3436cce43afd6f47424103Ian Molton tmio_mmc_clk_stop(host); 5664a48998fa16121d0fe3436cce43afd6f47424103Ian Molton reset(host); 5674a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5684a48998fa16121d0fe3436cce43afd6f47424103Ian Molton ret = platform_get_irq(dev, 0); 5694a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ret >= 0) 5704a48998fa16121d0fe3436cce43afd6f47424103Ian Molton host->irq = ret; 5714a48998fa16121d0fe3436cce43afd6f47424103Ian Molton else 5727ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm goto cell_disable; 5734a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5745e74672c0925335bb00772530634ac70179e8a19Philipp Zabel disable_mmc_irqs(host, TMIO_MASK_ALL); 5754a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5766c413cc76b893310b3b258b7de47fb74dcc50203Philipp Zabel ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | 57714f1b75b1d31673d7ab6ac6d2f8fe7f23c705229Magnus Damm IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); 5784a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (ret) 5797ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm goto cell_disable; 5804a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5814a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_add_host(mmc); 5824a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5834a48998fa16121d0fe3436cce43afd6f47424103Ian Molton printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), 5844a48998fa16121d0fe3436cce43afd6f47424103Ian Molton (unsigned long)host->ctl, host->irq); 5854a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5864a48998fa16121d0fe3436cce43afd6f47424103Ian Molton /* Unmask the IRQs we want to know about */ 5875e74672c0925335bb00772530634ac70179e8a19Philipp Zabel enable_mmc_irqs(host, TMIO_MASK_IRQ); 5884a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5894a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return 0; 5904a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 5917ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Dammcell_disable: 5927ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm if (cell->disable) 5937ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm cell->disable(dev); 5944a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonunmap_ctl: 5954a48998fa16121d0fe3436cce43afd6f47424103Ian Molton iounmap(host->ctl); 5964a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonhost_free: 5974a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_free_host(mmc); 5984a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonout: 5994a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return ret; 6004a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 6014a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6024a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int __devexit tmio_mmc_remove(struct platform_device *dev) 6034a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 6047ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 6054a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct mmc_host *mmc = platform_get_drvdata(dev); 6064a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6074a48998fa16121d0fe3436cce43afd6f47424103Ian Molton platform_set_drvdata(dev, NULL); 6084a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6094a48998fa16121d0fe3436cce43afd6f47424103Ian Molton if (mmc) { 6104a48998fa16121d0fe3436cce43afd6f47424103Ian Molton struct tmio_mmc_host *host = mmc_priv(mmc); 6114a48998fa16121d0fe3436cce43afd6f47424103Ian Molton mmc_remove_host(mmc); 6124a48998fa16121d0fe3436cce43afd6f47424103Ian Molton free_irq(host->irq, host); 6137ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm if (cell->disable) 6147ee422dc6e947fcdc153246d47f26ae0b7cf083dMagnus Damm cell->disable(dev); 6154a48998fa16121d0fe3436cce43afd6f47424103Ian Molton iounmap(host->ctl); 616bedcc45c2e5d72b1c4b087b725c391441a93eee6Magnus Damm mmc_free_host(mmc); 6174a48998fa16121d0fe3436cce43afd6f47424103Ian Molton } 6184a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6194a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return 0; 6204a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 6214a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6224a48998fa16121d0fe3436cce43afd6f47424103Ian Molton/* ------------------- device registration ----------------------- */ 6234a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6244a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic struct platform_driver tmio_mmc_driver = { 6254a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .driver = { 6264a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .name = "tmio-mmc", 6274a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .owner = THIS_MODULE, 6284a48998fa16121d0fe3436cce43afd6f47424103Ian Molton }, 6294a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .probe = tmio_mmc_probe, 6304a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .remove = __devexit_p(tmio_mmc_remove), 6314a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .suspend = tmio_mmc_suspend, 6324a48998fa16121d0fe3436cce43afd6f47424103Ian Molton .resume = tmio_mmc_resume, 6334a48998fa16121d0fe3436cce43afd6f47424103Ian Molton}; 6344a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6354a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6364a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic int __init tmio_mmc_init(void) 6374a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 6384a48998fa16121d0fe3436cce43afd6f47424103Ian Molton return platform_driver_register(&tmio_mmc_driver); 6394a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 6404a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6414a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonstatic void __exit tmio_mmc_exit(void) 6424a48998fa16121d0fe3436cce43afd6f47424103Ian Molton{ 6434a48998fa16121d0fe3436cce43afd6f47424103Ian Molton platform_driver_unregister(&tmio_mmc_driver); 6444a48998fa16121d0fe3436cce43afd6f47424103Ian Molton} 6454a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6464a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonmodule_init(tmio_mmc_init); 6474a48998fa16121d0fe3436cce43afd6f47424103Ian Moltonmodule_exit(tmio_mmc_exit); 6484a48998fa16121d0fe3436cce43afd6f47424103Ian Molton 6494a48998fa16121d0fe3436cce43afd6f47424103Ian MoltonMODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); 6504a48998fa16121d0fe3436cce43afd6f47424103Ian MoltonMODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); 6514a48998fa16121d0fe3436cce43afd6f47424103Ian MoltonMODULE_LICENSE("GPL v2"); 6524a48998fa16121d0fe3436cce43afd6f47424103Ian MoltonMODULE_ALIAS("platform:tmio-mmc"); 653