029-Add-eSDHC-driver-for-MCF5441x.patch 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214
  1. From 73c65ac21faf1b016f8f8ddfab2dc3e58a5618f9 Mon Sep 17 00:00:00 2001
  2. From: Alison Wang <[email protected]>
  3. Date: Thu, 4 Aug 2011 09:59:46 +0800
  4. Subject: [PATCH 29/52] Add eSDHC driver for MCF5441x
  5. Add eSDHC PIO mode(read and write) and DMA mode(read and write) support.
  6. Add card detect using extern irq.
  7. Signed-off-by: Alison Wang <[email protected]>
  8. ---
  9. drivers/mmc/host/Kconfig | 35 +
  10. drivers/mmc/host/Makefile | 1 +
  11. drivers/mmc/host/esdhc.c | 1826 +++++++++++++++++++++++++++++++++++++++++++++
  12. drivers/mmc/host/esdhc.h | 310 ++++++++
  13. 4 files changed, 2172 insertions(+), 0 deletions(-)
  14. create mode 100644 drivers/mmc/host/esdhc.c
  15. create mode 100644 drivers/mmc/host/esdhc.h
  16. --- a/drivers/mmc/host/Kconfig
  17. +++ b/drivers/mmc/host/Kconfig
  18. @@ -403,6 +403,41 @@ config DETECT_USE_EXTERN_IRQ1
  19. endchoice
  20. +config MMC_ESDHC
  21. + tristate "Enhanced Secure Digital Host Controller Interface support"
  22. + depends on M5441X
  23. + help
  24. + This select Freescale Enhanced SD Host Controller Interface.
  25. + The controller is used in MCF5441x.
  26. + If unsure, say N.
  27. +
  28. +config ESDHC_FORCE_PIO
  29. + tristate "eSDHC force to use PIO (no DMA) mode"
  30. + depends on MMC_ESDHC
  31. + help
  32. + This select Freescale Enhanced SD Host Controller Interface.
  33. + The controller is used in MCF5441x.
  34. + If unsure, say N.
  35. +
  36. +choice
  37. + prompt "MMC/SD card detect "
  38. + depends on MMC_ESDHC
  39. +
  40. +config ESDHC_DETECT_USE_EXTERN_IRQ7
  41. + bool "based extern IRQ7"
  42. + depends on MMC_ESDHC
  43. + help
  44. + MMC/SD cards using esdhc controller,
  45. + we use the extern irq7 to detect card.
  46. +config ESDHC_DETECT_USE_EXTERN_IRQ1
  47. + bool "based extern IRQ1"
  48. + depends on MMC_ESDHC
  49. + help
  50. + MMC/SD cards using esdhc controller,
  51. + we use the extern irq7 to detect card.
  52. +
  53. +endchoice
  54. +
  55. config MMC_S3C
  56. tristate "Samsung S3C SD/MMC Card Interface support"
  57. depends on ARCH_S3C2410
  58. --- a/drivers/mmc/host/Makefile
  59. +++ b/drivers/mmc/host/Makefile
  60. @@ -28,6 +28,7 @@ endif
  61. obj-$(CONFIG_MMC_S3C) += s3cmci.o
  62. obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
  63. obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
  64. +obj-$(CONFIG_MMC_ESDHC) += esdhc.o
  65. obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
  66. obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
  67. obj-$(CONFIG_GPIOMMC) += gpiommc.o
  68. --- /dev/null
  69. +++ b/drivers/mmc/host/esdhc.c
  70. @@ -0,0 +1,1826 @@
  71. +/*
  72. + * drivers/mmc/host/esdhc.c
  73. + *
  74. + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
  75. + * Author: Chenghu Wu <[email protected]>
  76. + * Xiaobo Xie <[email protected]>
  77. + *
  78. + * Freescale Enhanced Secure Digital Host Controller driver.
  79. + * Based on mpc837x/driver/mmc/host/esdhc.c done by Xiaobo Xie
  80. + * Ported to Coldfire platform by Chenghu Wu
  81. + *
  82. + * This program is free software; you can redistribute it and/or modify it
  83. + * under the terms of the GNU General Public License as published by the
  84. + * Free Software Foundation; either version 2 of the License, or (at your
  85. + * option) any later version.
  86. + */
  87. +
  88. +#include <linux/module.h>
  89. +#include <linux/init.h>
  90. +#include <linux/ioport.h>
  91. +#include <linux/interrupt.h>
  92. +#include <linux/delay.h>
  93. +#include <linux/highmem.h>
  94. +#include <linux/dma-mapping.h>
  95. +#include <linux/scatterlist.h>
  96. +#include <linux/uaccess.h>
  97. +#include <linux/irq.h>
  98. +#include <linux/io.h>
  99. +#include <linux/slab.h>
  100. +#include <linux/mmc/host.h>
  101. +
  102. +#include <asm/dma.h>
  103. +#include <asm/page.h>
  104. +
  105. +#include <linux/platform_device.h>
  106. +#include <asm/coldfire.h>
  107. +#include <asm/mcfsim.h>
  108. +
  109. +#include "esdhc.h"
  110. +#define DRIVER_NAME "esdhc"
  111. +
  112. +
  113. +#if defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ1)
  114. +#define card_detect_extern_irq (64 + 1)
  115. +#elif defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ7)
  116. +#define card_detect_extern_irq (64 + 7)
  117. +#else
  118. +#define card_detect_extern_irq (64 + 7)
  119. +#endif
  120. +
  121. +#undef ESDHC_DMA_KMALLOC
  122. +
  123. +#define SYS_BUSCLOCK 80000000
  124. +#define ESDHC_DMA_SIZE 0x10000
  125. +
  126. +#undef MMC_ESDHC_DEBUG
  127. +#undef MMC_ESDHC_DEBUG_REG
  128. +
  129. +#ifdef MMC_ESDHC_DEBUG
  130. +#define DBG(fmt, args...) printk(KERN_INFO "[%s] " fmt "\n", __func__, ## args)
  131. +#else
  132. +#define DBG(fmt, args...) do {} while (0)
  133. +#endif
  134. +
  135. +#ifdef MMC_ESDHC_DEBUG_REG
  136. +static void esdhc_dumpregs(struct esdhc_host *host)
  137. +{
  138. + printk(KERN_INFO "========= REGISTER DUMP ==========\n");
  139. +
  140. + printk(KERN_INFO "Sysaddr: 0x%08x | Blkattr: 0x%08x\n",
  141. + fsl_readl(host->ioaddr + ESDHC_DMA_ADDRESS),
  142. + fsl_readl(host->ioaddr + ESDHC_BLOCK_ATTR));
  143. + printk(KERN_INFO "Argument: 0x%08x | COMMAND: 0x%08x\n",
  144. + fsl_readl(host->ioaddr + ESDHC_ARGUMENT),
  145. + fsl_readl(host->ioaddr + ESDHC_COMMAND));
  146. + printk(KERN_INFO "Present: 0x%08x | DMA ctl: 0x%08x\n",
  147. + fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE),
  148. + fsl_readl(host->ioaddr + ESDHC_DMA_SYSCTL));
  149. + printk(KERN_INFO "PROCTL: 0x%08x | SYSCTL: 0x%08x\n",
  150. + fsl_readl(host->ioaddr + ESDHC_PROTOCOL_CONTROL),
  151. + fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL));
  152. + printk(KERN_INFO "Int stat: 0x%08x\n",
  153. + fsl_readl(host->ioaddr + ESDHC_INT_STATUS));
  154. + printk(KERN_INFO "Intenab: 0x%08x | Sigenab: 0x%08x\n",
  155. + fsl_readl(host->ioaddr + ESDHC_INT_ENABLE),
  156. + fsl_readl(host->ioaddr + ESDHC_SIGNAL_ENABLE));
  157. + printk(KERN_INFO "AC12 err: 0x%08x | Version: 0x%08x\n",
  158. + fsl_readl(host->ioaddr + ESDHC_ACMD12_ERR),
  159. + fsl_readl(host->ioaddr + ESDHC_HOST_VERSION));
  160. + printk(KERN_INFO "Caps: 0x%08x | Watermark: 0x%08x\n",
  161. + fsl_readl(host->ioaddr + ESDHC_CAPABILITIES),
  162. + fsl_readl(host->ioaddr + ESDHC_WML));
  163. + printk(KERN_INFO "MCF_INTC1_IPRH: 0x%08x | MCF_INTC1_IPRL: 0x%08x\n",
  164. + (unsigned int)MCF_INTC1_IPRH,
  165. + (unsigned int)MCF_INTC1_IPRL);
  166. + printk(KERN_INFO "MCF_INTC1_IMRH: 0x%08x | MCF_INTC1_IMRL: 0x%08x\n",
  167. + (unsigned int)MCF_INTC1_IMRH,
  168. + (unsigned int)MCF_INTC1_IMRL);
  169. + printk(KERN_INFO "MCF_INTC1_INTFRCH: 0x%08x | MCF_INTC1_INTFRCL: 0x%08x\n",
  170. + (unsigned int)MCF_INTC1_INTFRCH,
  171. + (unsigned int)MCF_INTC1_INTFRCL);
  172. + printk(KERN_INFO "MCF_INTC1_INTFRCH: 0x%08x | MCF_INTC1_INTFRCL: 0x%08x\n",
  173. + (unsigned int)MCF_INTC1_INTFRCH,
  174. + (unsigned int)MCF_INTC1_INTFRCL);
  175. + printk(KERN_INFO "MCF_INTC1_ICR63: 0x%08x | MCF_INTC0_ICR36: 0x%08x\n",
  176. + (unsigned int)MCF_INTC1_ICR63,
  177. + (unsigned int)MCF_INTC0_ICR36);
  178. +
  179. + printk(KERN_INFO "==================================\n");
  180. +}
  181. +#else
  182. +static void esdhc_dumpregs(struct esdhc_host *host)
  183. +{
  184. + do {} while (0);
  185. +}
  186. +#endif
  187. +
  188. +
  189. +static unsigned int debug_nodma;
  190. +static unsigned int debug_forcedma;
  191. +static unsigned int debug_quirks;
  192. +
  193. +#define ESDHC_QUIRK_CLOCK_BEFORE_RESET (1<<0)
  194. +#define ESDHC_QUIRK_FORCE_DMA (1<<1)
  195. +#define ESDHC_QUIRK_NO_CARD_NO_RESET (1<<2)
  196. +#define ESDHC_QUIRK_SINGLE_POWER_WRITE (1<<3)
  197. +
  198. +static void esdhc_prepare_data(struct esdhc_host *, struct mmc_data *);
  199. +static void esdhc_finish_data(struct esdhc_host *);
  200. +static irqreturn_t esdhc_irq(int irq, void *dev_id);
  201. +static void esdhc_send_command(struct esdhc_host *, struct mmc_command *);
  202. +static void esdhc_finish_command(struct esdhc_host *);
  203. +
  204. +/*****************************************************************************\
  205. + * *
  206. + * Low level functions *
  207. + * *
  208. +\*****************************************************************************/
  209. +
  210. +static void esdhc_reset(struct esdhc_host *host, u8 mask)
  211. +{
  212. + unsigned long timeout;
  213. + unsigned int sysctl;
  214. +
  215. + if (host->chip->quirks & ESDHC_QUIRK_NO_CARD_NO_RESET) {
  216. + if (!(fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE) &
  217. + ESDHC_CARD_PRESENT))
  218. + return;
  219. + }
  220. +
  221. + timeout = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  222. + timeout = timeout | (mask << ESDHC_RESET_SHIFT);
  223. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, timeout);
  224. +
  225. + if (mask & ESDHC_RESET_ALL) {
  226. + host->clock = 0;
  227. + host->bus_width = 0;
  228. + }
  229. +
  230. + /* Wait max 100 ms */
  231. + timeout = 100;
  232. +
  233. + /* hw clears the bit when it's done */
  234. + sysctl = (mask << ESDHC_RESET_SHIFT);
  235. + while (fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL) & sysctl) {
  236. + if (timeout == 0) {
  237. + printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
  238. + mmc_hostname(host->mmc), (int)mask);
  239. + esdhc_dumpregs(host);
  240. + return;
  241. + }
  242. + timeout--;
  243. + mdelay(1);
  244. + }
  245. +}
  246. +
  247. +static void esdhc_init(struct esdhc_host *host)
  248. +{
  249. + u32 intmask;
  250. + /*reset eSDHC chip*/
  251. + esdhc_reset(host, ESDHC_RESET_ALL);
  252. +
  253. + intmask = fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE);
  254. + intmask = intmask & 0xF7000000;
  255. + fsl_writel(host->ioaddr + ESDHC_PRESENT_STATE, intmask);
  256. +
  257. + intmask = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  258. + intmask = intmask | ESDHC_CLOCK_INT_EN | ESDHC_CLOCK_INT_STABLE;
  259. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, intmask);
  260. +
  261. + intmask = fsl_readl(host->ioaddr + ESDHC_INT_STATUS);
  262. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS, intmask);
  263. +
  264. + intmask = fsl_readl(host->ioaddr + ESDHC_INT_ENABLE);
  265. +
  266. + fsl_writel(host->ioaddr + ESDHC_INT_ENABLE, intmask);
  267. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, intmask);
  268. + /* Modelo does not support */
  269. + /*MCF_ESDHC_SCR = MCF_ESDHC_SCR | ESDHC_DMA_SNOOP | 0xC0;*/
  270. +
  271. + intmask = fsl_readl(host->ioaddr + ESDHC_PROTOCOL_CONTROL);
  272. + intmask &= ~ESDHC_CTRL_D3_DETEC;
  273. +
  274. + fsl_writel(host->ioaddr + ESDHC_PROTOCOL_CONTROL, intmask);
  275. + DBG(" init %x\n", fsl_readl(host->ioaddr + ESDHC_PROTOCOL_CONTROL));
  276. +}
  277. +
  278. +static void reset_regs(struct esdhc_host *host)
  279. +{
  280. + u32 intmask;
  281. +
  282. + intmask = fsl_readl(host->ioaddr + ESDHC_INT_STATUS);
  283. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS, intmask);
  284. +
  285. + intmask = ESDHC_INT_DATA_END_BIT | ESDHC_INT_DATA_CRC |
  286. + ESDHC_INT_DATA_TIMEOUT | ESDHC_INT_INDEX |
  287. + ESDHC_INT_END_BIT | ESDHC_INT_CRC | ESDHC_INT_TIMEOUT |
  288. + ESDHC_INT_DATA_AVAIL | ESDHC_INT_SPACE_AVAIL |
  289. + ESDHC_INT_DMA_END | ESDHC_INT_DATA_END | ESDHC_INT_RESPONSE;
  290. +
  291. + fsl_writel(host->ioaddr + ESDHC_INT_ENABLE, intmask);
  292. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, intmask);
  293. +
  294. + if (host->bus_width == MMC_BUS_WIDTH_4) {
  295. + intmask = fsl_readl(host->ioaddr + ESDHC_PROTOCOL_CONTROL);
  296. + intmask |= ESDHC_CTRL_4BITBUS;
  297. + fsl_writel(host->ioaddr + ESDHC_PROTOCOL_CONTROL, intmask);
  298. + }
  299. +}
  300. +
  301. +/*****************************************************************************
  302. + * *
  303. + * Core functions *
  304. + * *
  305. + *****************************************************************************/
  306. +/* Return the SG's virtual address */
  307. +static inline char *esdhc_sg_to_buffer(struct esdhc_host *host)
  308. +{
  309. + DBG("cur_sg %x virt %x\n", host->cur_sg, sg_virt(host->cur_sg));
  310. + return sg_virt(host->cur_sg);
  311. +}
  312. +
  313. +static inline int esdhc_next_sg(struct esdhc_host *host)
  314. +{
  315. + /*
  316. + * Skip to next SG entry.
  317. + */
  318. + host->cur_sg = sg_next(host->cur_sg);
  319. + host->num_sg--;
  320. +
  321. + /*
  322. + * Any entries left?
  323. + */
  324. + if (host->num_sg > 0) {
  325. + host->offset = 0;
  326. + host->remain = host->cur_sg->length;
  327. + }
  328. +
  329. + DBG("%s: host->remain %x %x\n", __func__, host->remain, host->num_sg);
  330. + return host->num_sg;
  331. +}
  332. +
  333. +static void esdhc_read_block_pio(struct esdhc_host *host)
  334. +{
  335. + int blksize, chunk_remain;
  336. + u32 data;
  337. + char *buffer;
  338. + int size;
  339. +
  340. + DBG("PIO reading\n");
  341. +
  342. + /* Delay prevents data read error in big files */
  343. + udelay(100);
  344. +
  345. + blksize = host->data->blksz;
  346. + chunk_remain = 0;
  347. + data = 0;
  348. +
  349. + buffer = esdhc_sg_to_buffer(host) + host->offset;
  350. +
  351. + while (blksize) {
  352. + if (chunk_remain == 0) {
  353. + data = fsl_readl(host->ioaddr + ESDHC_BUFFER);
  354. + chunk_remain = min(blksize, 4);
  355. + }
  356. +
  357. + size = min(host->remain, chunk_remain);
  358. +
  359. + chunk_remain -= size;
  360. + blksize -= size;
  361. + host->offset += size;
  362. + host->remain -= size;
  363. +
  364. + while (size) {
  365. + *buffer = data & 0xFF;
  366. + buffer++;
  367. + data >>= 8;
  368. + size--;
  369. + }
  370. +
  371. + if (host->remain == 0) {
  372. + if (esdhc_next_sg(host) == 0) {
  373. + BUG_ON(blksize != 0);
  374. + return;
  375. + }
  376. + buffer = esdhc_sg_to_buffer(host);
  377. + }
  378. + }
  379. +}
  380. +
  381. +static void esdhc_write_block_pio(struct esdhc_host *host)
  382. +{
  383. + int blksize, chunk_remain;
  384. + u32 data;
  385. + char *buffer;
  386. + int bytes, size;
  387. +
  388. + DBG("PIO writing\n");
  389. +
  390. + /* Delay necessary when writing large data blocks to SD card */
  391. + udelay(100);
  392. +
  393. + blksize = host->data->blksz;
  394. + chunk_remain = 4;
  395. + data = 0;
  396. +
  397. + bytes = 0;
  398. + buffer = esdhc_sg_to_buffer(host) + host->offset;
  399. +
  400. + while (blksize) {
  401. + size = min(host->remain, chunk_remain);
  402. +
  403. + chunk_remain -= size;
  404. + blksize -= size;
  405. + host->offset += size;
  406. + host->remain -= size;
  407. +
  408. + while (size) {
  409. + data >>= 8;
  410. + data |= (u32)*buffer << 24;
  411. + buffer++;
  412. + size--;
  413. + }
  414. +
  415. + if (chunk_remain == 0) {
  416. + fsl_writel(host->ioaddr + ESDHC_BUFFER, data);
  417. + chunk_remain = min(blksize, 4);
  418. + }
  419. +
  420. + if (host->remain == 0) {
  421. + if (esdhc_next_sg(host) == 0) {
  422. + BUG_ON(blksize != 0);
  423. + return;
  424. + }
  425. + buffer = esdhc_sg_to_buffer(host);
  426. + }
  427. + }
  428. +}
  429. +
  430. +static void esdhc_transfer_pio(struct esdhc_host *host)
  431. +{
  432. + u32 mask;
  433. +
  434. + BUG_ON(!host->data);
  435. +
  436. + if (host->num_sg == 0)
  437. + return;
  438. +
  439. + if (host->data->flags & MMC_DATA_READ)
  440. + mask = ESDHC_DATA_AVAILABLE;
  441. + else
  442. + mask = ESDHC_SPACE_AVAILABLE;
  443. +
  444. + while (fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE) & mask) {
  445. + if (host->data->flags & MMC_DATA_READ)
  446. + esdhc_read_block_pio(host);
  447. + else
  448. + esdhc_write_block_pio(host);
  449. +
  450. + if (host->num_sg == 0)
  451. + break;
  452. + }
  453. +
  454. + DBG("PIO transfer complete.\n");
  455. + /* Delay necessary when writing large data blocks to SD card */
  456. + udelay(100);
  457. +}
  458. +
  459. +static void esdhc_prepare_data(struct esdhc_host *host, struct mmc_data *data)
  460. +{
  461. + u8 count;
  462. + unsigned blkattr = 0;
  463. + unsigned target_timeout, current_timeout;
  464. + unsigned int sysctl;
  465. +
  466. + WARN_ON(host->data);
  467. +
  468. + if (data == NULL)
  469. + return;
  470. +
  471. + DBG("blksz %04x blks %04x flags %08x",
  472. + data->blksz, data->blocks, data->flags);
  473. + DBG("tsac %d ms nsac %d clk",
  474. + data->timeout_ns / 1000000, data->timeout_clks);
  475. +
  476. + /* Sanity checks */
  477. + BUG_ON(data->blksz * data->blocks > 524288);
  478. + BUG_ON(data->blksz > host->mmc->max_blk_size);
  479. + BUG_ON(data->blocks > 65535);
  480. +
  481. + if (host->clock == 0)
  482. + return;
  483. +
  484. + /* timeout in us */
  485. + target_timeout = data->timeout_ns / 1000 +
  486. + (data->timeout_clks * 1000000) / host->clock;
  487. +
  488. + /*
  489. + * Figure out needed cycles.
  490. + * We do this in steps in order to fit inside a 32 bit int.
  491. + * The first step is the minimum timeout, which will have a
  492. + * minimum resolution of 6 bits:
  493. + * (1) 2^13*1000 > 2^22,
  494. + * (2) host->timeout_clk < 2^16
  495. + * =>
  496. + * (1) / (2) > 2^6
  497. + */
  498. + count = 0;
  499. + host->timeout_clk = host->clock/1000;
  500. + current_timeout = (1 << 13) * 1000 / host->timeout_clk;
  501. + while (current_timeout < target_timeout) {
  502. + count++;
  503. + current_timeout <<= 1;
  504. + if (count >= 0xF)
  505. + break;
  506. + }
  507. +
  508. + if (count >= 0xF) {
  509. + DBG("%s:Timeout requested is too large!\n",
  510. + mmc_hostname(host->mmc));
  511. + count = 0xE;
  512. + }
  513. +
  514. + if (data->blocks >= 0x50) {
  515. + DBG("%s:Blocks %x are too large!\n",
  516. + mmc_hostname(host->mmc),
  517. + data->blocks);
  518. + count = 0xE;
  519. + }
  520. +
  521. + if ((data->blocks == 1) && (data->blksz >= 0x200)) {
  522. + DBG("%s:Blocksize %x is too large\n",
  523. + mmc_hostname(host->mmc),
  524. + data->blksz);
  525. + count = 0xE;
  526. + }
  527. + count = 0xE;
  528. +
  529. + sysctl = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  530. + sysctl &= (~ESDHC_TIMEOUT_MASK);
  531. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL,
  532. + sysctl | (count<<ESDHC_TIMEOUT_SHIFT));
  533. +
  534. + /* Data transfer*/
  535. + if (host->flags & ESDHC_USE_DMA) {
  536. + int sg_count;
  537. + unsigned int wml;
  538. + unsigned int wml_value;
  539. + unsigned int timeout;
  540. +
  541. + /* DMA address eSDHC in Modelo must be 4 bytes aligned */
  542. + if ((data->sg->offset & 0x3) == 0)
  543. + host->offset = 0;
  544. + else
  545. + host->offset = 0x4 - (data->sg->offset & 0x3);
  546. +
  547. + sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg,
  548. + data->sg_len,
  549. + (data->flags & MMC_DATA_READ)
  550. + ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
  551. +
  552. + BUG_ON(sg_count != 1);
  553. + /* The data in SD card is little endian,
  554. + the SD controller is big endian */
  555. + if ((data->flags & MMC_DATA_WRITE) == MMC_DATA_WRITE) {
  556. + unsigned char *buffer = sg_virt(data->sg);
  557. + unsigned char *buffer_tx =
  558. + (unsigned char *)host->dma_tx_buf;
  559. + int i;
  560. + /* Each sector is 512 Bytes, write 0x200 sectors */
  561. + memset(host->dma_tx_buf, 0, ESDHC_DMA_SIZE);
  562. + for (i = 0; i < data->sg->length; i = i + 4) {
  563. + *(buffer_tx + i + 3) = *(buffer + i);
  564. + *(buffer_tx + i + 2) = *(buffer + i + 1);
  565. + *(buffer_tx + i + 1) = *(buffer + i + 2);
  566. + *(buffer_tx + i) = *(buffer + i + 3);
  567. + }
  568. +
  569. + fsl_writel(host->ioaddr + ESDHC_DMA_ADDRESS,
  570. + (unsigned long)host->dma_tx_dmahandle);
  571. + } else {
  572. + fsl_writel(host->ioaddr + ESDHC_DMA_ADDRESS,
  573. + sg_dma_address(data->sg) + host->offset);
  574. + }
  575. +
  576. + /* Disable the BRR and BWR interrupt */
  577. + timeout = fsl_readl(host->ioaddr + ESDHC_INT_ENABLE);
  578. + timeout = timeout & (~(ESDHC_INT_DATA_AVAIL |
  579. + ESDHC_INT_SPACE_AVAIL));
  580. + fsl_writel(host->ioaddr + ESDHC_INT_ENABLE, timeout);
  581. +
  582. + timeout = fsl_readl(host->ioaddr + ESDHC_SIGNAL_ENABLE);
  583. + timeout = timeout & (~(ESDHC_INT_DATA_AVAIL |
  584. + ESDHC_INT_SPACE_AVAIL));
  585. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, timeout);
  586. +
  587. + wml_value = data->blksz / 4;
  588. + if (data->flags & MMC_DATA_READ) {
  589. + /* Read watermask level, max is 0x10*/
  590. + if (wml_value > 0x10)
  591. + wml_value = 0x10;
  592. + wml = (wml_value & ESDHC_WML_MASK) |
  593. + ((0x10 & ESDHC_WML_MASK)
  594. + << ESDHC_WML_WRITE_SHIFT);
  595. + } else {
  596. + if (wml_value > 0x80)
  597. + wml_value = 0x80;
  598. + wml = (0x10 & ESDHC_WML_MASK) |
  599. + (((wml_value) & ESDHC_WML_MASK)
  600. + << ESDHC_WML_WRITE_SHIFT);
  601. + }
  602. +
  603. + fsl_writel(host->ioaddr + ESDHC_WML, wml);
  604. + } else {
  605. + unsigned long timeout;
  606. +
  607. + host->cur_sg = data->sg;
  608. + host->num_sg = data->sg_len;
  609. +
  610. + host->offset = 0;
  611. + host->remain = host->cur_sg->length;
  612. +
  613. + timeout = fsl_readl(host->ioaddr + ESDHC_INT_ENABLE);
  614. + timeout = timeout | ESDHC_INT_DATA_AVAIL
  615. + | ESDHC_INT_SPACE_AVAIL;
  616. + fsl_writel(host->ioaddr + ESDHC_INT_ENABLE, timeout);
  617. +
  618. + timeout = fsl_readl(host->ioaddr + ESDHC_SIGNAL_ENABLE);
  619. + timeout = timeout | ESDHC_INT_DATA_AVAIL
  620. + | ESDHC_INT_SPACE_AVAIL;
  621. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, timeout);
  622. + }
  623. +
  624. + /* We do not handle DMA boundaries */
  625. + blkattr = data->blksz;
  626. + blkattr |= (data->blocks << 16);
  627. + fsl_writel(host->ioaddr + ESDHC_BLOCK_ATTR, blkattr);
  628. + esdhc_dumpregs(host);
  629. +}
  630. +
  631. +static unsigned int esdhc_set_transfer_mode(struct esdhc_host *host,
  632. + struct mmc_data *data)
  633. +{
  634. + u32 mode = 0;
  635. +
  636. + WARN_ON(host->data);
  637. +
  638. + if (data == NULL)
  639. + return 0;
  640. +
  641. + mode = ESDHC_TRNS_BLK_CNT_EN;
  642. + if (data->blocks > 1) {
  643. + if (data->flags & MMC_DATA_READ)
  644. + mode |= ESDHC_TRNS_MULTI | ESDHC_TRNS_ACMD12;
  645. + else
  646. + mode |= ESDHC_TRNS_MULTI;
  647. + }
  648. + if (data->flags & MMC_DATA_READ)
  649. + mode |= ESDHC_TRNS_READ;
  650. + if (host->flags & ESDHC_USE_DMA)
  651. + mode |= ESDHC_TRNS_DMA;
  652. +
  653. + return mode;
  654. +}
  655. +
  656. +static void esdhc_finish_data(struct esdhc_host *host)
  657. +{
  658. + struct mmc_data *data;
  659. + u16 blocks;
  660. +
  661. + BUG_ON(!host->data);
  662. +
  663. + data = host->data;
  664. + host->data = NULL;
  665. +
  666. + if (host->flags & ESDHC_USE_DMA) {
  667. + unsigned char *buffer = sg_virt(data->sg);
  668. + unsigned char C0, C1, C2, C3;
  669. + int i;
  670. + /* Data in SD card is little endian,
  671. + SD controller is big endian */
  672. +
  673. + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
  674. + (data->flags & MMC_DATA_READ)
  675. + ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
  676. + if (((data->flags & MMC_DATA_READ) == MMC_DATA_READ)) {
  677. + for (i = 0; i < data->sg->length; i = i + 4) {
  678. + C0 = *(buffer + host->offset + i);
  679. + C1 = *(buffer + host->offset + i + 1);
  680. + C2 = *(buffer + host->offset + i + 2);
  681. + C3 = *(buffer + host->offset + i + 3);
  682. + *(buffer+i) = C3;
  683. + *(buffer+i+1) = C2;
  684. + *(buffer+i+2) = C1;
  685. + *(buffer+i+3) = C0;
  686. + }
  687. + }
  688. + }
  689. + /*
  690. + * Controller doesn't count down when in single block mode.
  691. + */
  692. + if ((data->blocks == 1) && (data->error == MMC_ERR_NONE))
  693. + blocks = 0;
  694. + else {
  695. + blocks = fsl_readl(host->ioaddr + ESDHC_BLOCK_ATTR) >> 16;
  696. + blocks = 0;
  697. + if (data->flags & MMC_DATA_READ)
  698. + data->stop = 0;
  699. + }
  700. +
  701. + data->bytes_xfered = data->blksz * (data->blocks - blocks);
  702. +
  703. + if ((data->error == MMC_ERR_NONE) && blocks) {
  704. + printk(KERN_ERR"%s: Controller signaled completion even "
  705. + "though there were blocks left.\n",
  706. + mmc_hostname(host->mmc));
  707. + data->error = MMC_ERR_FAILED;
  708. + }
  709. +
  710. + if ((blocks == 0) && (data->error & MMC_ERR_TIMEOUT)) {
  711. + printk(KERN_ERR "Controller transmitted completion even "
  712. + "though there was a timeout error.\n");
  713. + data->error &= ~MMC_ERR_TIMEOUT;
  714. + }
  715. +
  716. + if (data->stop) {
  717. + DBG("%s data->stop %x\n", __func__, data->stop);
  718. + /*
  719. + * The controller needs a reset of internal state machines
  720. + * upon error conditions.
  721. + */
  722. + if (data->error != MMC_ERR_NONE) {
  723. + printk("%s: The controller needs a "
  724. + "reset of internal state machines\n",
  725. + __func__);
  726. + esdhc_reset(host, ESDHC_RESET_CMD);
  727. + esdhc_reset(host, ESDHC_RESET_DATA);
  728. + reset_regs(host);
  729. + }
  730. +
  731. + esdhc_send_command(host, data->stop);
  732. + } else
  733. + tasklet_schedule(&host->finish_tasklet);
  734. +}
  735. +
  736. +static void esdhc_send_command(struct esdhc_host *host, struct mmc_command *cmd)
  737. +{
  738. + unsigned int flags;
  739. + u32 mask;
  740. + unsigned long timeout;
  741. +
  742. + WARN_ON(host->cmd);
  743. +
  744. + /* Wait max 10 ms */
  745. + timeout = 10;
  746. +
  747. + mask = ESDHC_CMD_INHIBIT;
  748. + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
  749. + mask |= ESDHC_DATA_INHIBIT;
  750. +
  751. + /* We shouldn't wait for data inihibit for stop commands, even
  752. + though they might use busy signaling */
  753. + if (host->mrq->data && (cmd == host->mrq->data->stop))
  754. + mask &= ~ESDHC_DATA_INHIBIT;
  755. +
  756. + while (fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE) & mask) {
  757. + if (timeout == 0) {
  758. + printk(KERN_ERR "%s: Controller never released "
  759. + "inhibit bit(s).\n", mmc_hostname(host->mmc));
  760. + esdhc_dumpregs(host);
  761. + cmd->error = MMC_ERR_FAILED;
  762. + tasklet_schedule(&host->finish_tasklet);
  763. + return;
  764. + }
  765. + timeout--;
  766. + mdelay(1);
  767. + }
  768. +
  769. + mod_timer(&host->timer, jiffies + 15 * HZ);
  770. +
  771. + host->cmd = cmd;
  772. +
  773. + esdhc_prepare_data(host, cmd->data);
  774. +
  775. + fsl_writel(host->ioaddr + ESDHC_ARGUMENT, cmd->arg);
  776. +
  777. + flags = esdhc_set_transfer_mode(host, cmd->data);
  778. +
  779. + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
  780. + printk(KERN_ERR "%s: Unsupported response type!\n",
  781. + mmc_hostname(host->mmc));
  782. + cmd->error = MMC_ERR_INVALID;
  783. + tasklet_schedule(&host->finish_tasklet);
  784. + return;
  785. + }
  786. +
  787. + if (!(cmd->flags & MMC_RSP_PRESENT))
  788. + flags |= ESDHC_CMD_RESP_NONE;
  789. + else if (cmd->flags & MMC_RSP_136)
  790. + flags |= ESDHC_CMD_RESP_LONG;
  791. + else if (cmd->flags & MMC_RSP_BUSY)
  792. + flags |= ESDHC_CMD_RESP_SHORT_BUSY;
  793. + else
  794. + flags |= ESDHC_CMD_RESP_SHORT;
  795. +
  796. + if (cmd->flags & MMC_RSP_CRC)
  797. + flags |= ESDHC_CMD_CRC_EN;
  798. + if (cmd->flags & MMC_RSP_OPCODE)
  799. + flags |= ESDHC_CMD_INDEX_EN;
  800. + if (cmd->data)
  801. + flags |= ESDHC_CMD_DATA;
  802. +
  803. + fsl_writel(host->ioaddr + ESDHC_COMMAND,
  804. + ESDHC_MAKE_CMD(cmd->opcode, flags));
  805. +}
  806. +
  807. +static void esdhc_finish_command(struct esdhc_host *host)
  808. +{
  809. + int i;
  810. +
  811. + BUG_ON(host->cmd == NULL);
  812. +
  813. + if (host->cmd->flags & MMC_RSP_PRESENT) {
  814. + if (host->cmd->flags & MMC_RSP_136) {
  815. + /* CRC is stripped so we need to do some shifting. */
  816. + for (i = 0; i < 4; i++) {
  817. + host->cmd->resp[i] = fsl_readl(host->ioaddr +
  818. + ESDHC_RESPONSE + (3-i)*4) << 8;
  819. + if (i != 3)
  820. + host->cmd->resp[i] |=
  821. + (fsl_readl(host->ioaddr
  822. + + ESDHC_RESPONSE
  823. + + (2-i)*4) >> 24);
  824. + }
  825. + } else
  826. + host->cmd->resp[0] = fsl_readl(host->ioaddr +
  827. + ESDHC_RESPONSE);
  828. + }
  829. +
  830. + host->cmd->error = MMC_ERR_NONE;
  831. +
  832. + if (host->cmd->data)
  833. + host->data = host->cmd->data;
  834. + else
  835. + tasklet_schedule(&host->finish_tasklet);
  836. +
  837. + host->cmd = NULL;
  838. +}
  839. +
  840. +#define MYCLOCK 1
  841. +static void esdhc_set_clock(struct esdhc_host *host, unsigned int clock)
  842. +{
  843. +#if MYCLOCK
  844. + unsigned long sdrefclk, vco, bestmatch = -1, temp, diff;
  845. + int dvs, sdclkfs, outdiv;
  846. + int best_dvs, best_sdclkfs, best_outdiv;
  847. +#else
  848. + int div, pre_div;
  849. + unsigned long sys_busclock = SYS_BUSCLOCK;
  850. +#endif
  851. + unsigned long timeout;
  852. + u16 clk;
  853. +
  854. + DBG("esdhc_set_clock %x\n", clock);
  855. + if (clock == host->clock)
  856. + return;
  857. +
  858. + timeout = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  859. + timeout = timeout & (~ESDHC_CLOCK_MASK);
  860. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, timeout);
  861. +
  862. + if (clock == 0)
  863. + goto out;
  864. +
  865. +#if MYCLOCK
  866. + /* TC: The VCO must obtain from u-boot */
  867. + /*
  868. + * First set the outdiv3 to min 1, then walk through all to
  869. + * get closer value with SDCLKDIV and DIV combination
  870. + */
  871. + vco = 500000000;
  872. + MCF_CLOCK_PLL_DR &= 0xFFFF83FF; /* Disable SD Clock */
  873. +
  874. + for (outdiv = 2; outdiv <= 32; outdiv++) {
  875. + sdrefclk = vco / outdiv;
  876. +
  877. + for (sdclkfs = 2; sdclkfs < 257; sdclkfs <<= 1) {
  878. + for (dvs = 1; dvs < 17; dvs++) {
  879. + temp = sdrefclk / (sdclkfs * dvs);
  880. +
  881. + if (temp > clock)
  882. + diff = temp - clock;
  883. + else
  884. + diff = clock - temp;
  885. +
  886. + if (diff <= bestmatch) {
  887. + bestmatch = diff;
  888. + best_outdiv = outdiv;
  889. + best_sdclkfs = sdclkfs;
  890. + best_dvs = dvs;
  891. +
  892. + if (bestmatch == 0)
  893. + goto end;
  894. + }
  895. + }
  896. + }
  897. + }
  898. +
  899. +end:
  900. +#ifdef CONFIG_M5441X
  901. + best_outdiv = 3;
  902. + best_sdclkfs = 2;
  903. + best_dvs = 5;
  904. +#endif
  905. + MCF_CLOCK_PLL_DR |= ((best_outdiv - 1) << 10);
  906. + clk = ((best_sdclkfs >> 1) << 8) | ((best_dvs - 1) << 4);
  907. +#else
  908. +
  909. + if (sys_busclock / 16 > clock) {
  910. + for (pre_div = 1; pre_div < 256; pre_div *= 2) {
  911. + if ((sys_busclock / pre_div) < (clock*16))
  912. + break;
  913. + }
  914. + } else
  915. + pre_div = 1;
  916. +
  917. + for (div = 1; div <= 16; div++) {
  918. + if ((sys_busclock / (div*pre_div)) <= clock)
  919. + break;
  920. + }
  921. +
  922. + pre_div >>= 1;
  923. + div -= 1;
  924. +
  925. + clk = (div << ESDHC_DIVIDER_SHIFT) | (pre_div << ESDHC_PREDIV_SHIFT);
  926. +#endif
  927. +
  928. + timeout = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  929. + timeout = timeout | clk;
  930. +
  931. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, timeout);
  932. +
  933. + /* Wait max 10 ms */
  934. + timeout = 10;
  935. + while (timeout) {
  936. + timeout--;
  937. + mdelay(1);
  938. + }
  939. +
  940. + timeout = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  941. + timeout = timeout | ESDHC_CLOCK_CARD_EN;
  942. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, timeout);
  943. +
  944. + esdhc_dumpregs(host);
  945. +
  946. +out:
  947. + host->clock = clock;
  948. + if (host->clock == 0) {
  949. + timeout = fsl_readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  950. + timeout = timeout | ESDHC_CLOCK_DEFAULT;
  951. + fsl_writel(host->ioaddr + ESDHC_SYSTEM_CONTROL, timeout);
  952. + }
  953. +}
  954. +
  955. +static void esdhc_set_power(struct esdhc_host *host, unsigned short power)
  956. +{
  957. + if (host->power == power)
  958. + return;
  959. +
  960. + if (power == (unsigned short)-1)
  961. + host->power = power;
  962. +}
  963. +
  964. +/*****************************************************************************\
  965. + * *
  966. + * MMC callbacks *
  967. + * *
  968. +\*****************************************************************************/
  969. +
  970. +static void esdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
  971. +{
  972. + struct esdhc_host *host;
  973. + unsigned long flags;
  974. +
  975. + DBG("esdhc_request\n");
  976. + host = mmc_priv(mmc);
  977. +
  978. + spin_lock_irqsave(&host->lock, flags);
  979. +
  980. + WARN_ON(host->mrq != NULL);
  981. +
  982. + host->mrq = mrq;
  983. +
  984. + esdhc_send_command(host, mrq->cmd);
  985. +
  986. + mmiowb();
  987. + spin_unlock_irqrestore(&host->lock, flags);
  988. +}
  989. +
  990. +static void esdhc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
  991. +{
  992. + struct esdhc_host *host;
  993. + unsigned long flags;
  994. + u32 ctrl, irq_status_ena, irq_signal_ena;
  995. +
  996. + DBG("ios->power_mode %x, ios->bus_width %x\n",
  997. + ios->power_mode, ios->bus_width);
  998. + host = mmc_priv(mmc);
  999. +
  1000. + spin_lock_irqsave(&host->lock, flags);
  1001. +
  1002. + /*
  1003. + * Reset the chip on each power off.
  1004. + * Should clear out any weird states.
  1005. + */
  1006. +
  1007. + if (ios->power_mode == MMC_POWER_OFF) {
  1008. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, 0);
  1009. + esdhc_init(host);
  1010. + }
  1011. +
  1012. + esdhc_set_clock(host, ios->clock);
  1013. +
  1014. + if (ios->power_mode == MMC_POWER_OFF)
  1015. + esdhc_set_power(host, -1);
  1016. + else
  1017. + esdhc_set_power(host, ios->vdd);
  1018. +
  1019. + ctrl = fsl_readl(host->ioaddr + ESDHC_PROTOCOL_CONTROL);
  1020. +
  1021. + if (ios->bus_width == MMC_BUS_WIDTH_4) {
  1022. + ctrl |= ESDHC_CTRL_4BITBUS;
  1023. + host->bus_width = MMC_BUS_WIDTH_4;
  1024. +
  1025. + ctrl &= ~ESDHC_CTRL_D3_DETEC;
  1026. +
  1027. + /*when change the config of the CD,
  1028. + * will involve card remove interrupt
  1029. + * So try disable the card remove interrupt.
  1030. + */
  1031. + irq_status_ena = fsl_readl(host->ioaddr + ESDHC_INT_ENABLE);
  1032. + irq_status_ena &= ~ESDHC_INT_CARD_REMOVE;
  1033. + fsl_writel(host->ioaddr + ESDHC_INT_ENABLE, irq_status_ena);
  1034. +
  1035. + irq_signal_ena = fsl_readl(host->ioaddr + ESDHC_SIGNAL_ENABLE);
  1036. + irq_signal_ena &= ~ESDHC_INT_CARD_REMOVE;
  1037. + fsl_writel(host->ioaddr + ESDHC_SIGNAL_ENABLE, irq_signal_ena);
  1038. +
  1039. + DBG("host->card_insert = 0x%x\n", host->card_insert);
  1040. +
  1041. +
  1042. + } else {
  1043. + ctrl &= ~ESDHC_CTRL_4BITBUS;
  1044. + host->bus_width = MMC_BUS_WIDTH_1;
  1045. + }
  1046. +
  1047. + fsl_writel(host->ioaddr + ESDHC_PROTOCOL_CONTROL, ctrl);
  1048. + mmiowb();
  1049. + spin_unlock_irqrestore(&host->lock, flags);
  1050. +
  1051. + esdhc_dumpregs(host);
  1052. +}
  1053. +
  1054. +static int esdhc_get_ro(struct mmc_host *mmc)
  1055. +{
  1056. + return 0;
  1057. +}
  1058. +
  1059. +static const struct mmc_host_ops esdhc_ops = {
  1060. + .request = esdhc_request,
  1061. + .set_ios = esdhc_set_ios,
  1062. + .get_ro = esdhc_get_ro,
  1063. +};
  1064. +
  1065. +/*****************************************************************************\
  1066. + * *
  1067. + * Tasklets *
  1068. + * *
  1069. +\*****************************************************************************/
  1070. +
  1071. +static void esdhc_tasklet_card(unsigned long param)
  1072. +{
  1073. + struct esdhc_host *host;
  1074. +
  1075. + host = (struct esdhc_host *)param;
  1076. +
  1077. + spin_lock(&host->lock);
  1078. +
  1079. + DBG("esdhc_tasklet_card\n");
  1080. + if (!(fsl_readl(host->ioaddr + ESDHC_PRESENT_STATE) &
  1081. + ESDHC_CARD_PRESENT)) {
  1082. + if (host->mrq) {
  1083. + printk(KERN_ERR "%s: Card removed during transfer!\n",
  1084. + mmc_hostname(host->mmc));
  1085. + printk(KERN_ERR "%s: Resetting controller.\n",
  1086. + mmc_hostname(host->mmc));
  1087. +
  1088. + esdhc_reset(host, ESDHC_RESET_CMD);
  1089. + esdhc_reset(host, ESDHC_RESET_DATA);
  1090. +
  1091. + host->mrq->cmd->error = MMC_ERR_FAILED;
  1092. + tasklet_schedule(&host->finish_tasklet);
  1093. + }
  1094. + host->card_insert = 0;
  1095. + } else {
  1096. + esdhc_reset(host, ESDHC_INIT_CARD);
  1097. + host->card_insert = 1;
  1098. + }
  1099. +
  1100. + spin_unlock(&host->lock);
  1101. +
  1102. + mmc_detect_change(host->mmc, msecs_to_jiffies(500));
  1103. +}
  1104. +
  1105. +static void esdhc_tasklet_finish(unsigned long param)
  1106. +{
  1107. + struct esdhc_host *host;
  1108. + unsigned long flags;
  1109. + struct mmc_request *mrq;
  1110. +
  1111. + host = (struct esdhc_host *)param;
  1112. + DBG("esdhc_tasklet_finish\n");
  1113. +
  1114. + spin_lock_irqsave(&host->lock, flags);
  1115. +
  1116. + del_timer(&host->timer);
  1117. +
  1118. + mrq = host->mrq;
  1119. +
  1120. + /*
  1121. + * The controller needs a reset of internal state machines
  1122. + * upon error conditions.
  1123. + */
  1124. + if ((mrq->cmd->error != MMC_ERR_NONE) ||
  1125. + (mrq->data && ((mrq->data->error != MMC_ERR_NONE) ||
  1126. + (mrq->data->stop &&
  1127. + (mrq->data->stop->error != MMC_ERR_NONE))))) {
  1128. +
  1129. + /* Some controllers need this kick or reset won't work here */
  1130. + if (host->chip->quirks & ESDHC_QUIRK_CLOCK_BEFORE_RESET) {
  1131. + unsigned int clock;
  1132. +
  1133. + /* This is to force an update */
  1134. + clock = host->clock;
  1135. + host->clock = 0;
  1136. + esdhc_set_clock(host, clock);
  1137. + }
  1138. +
  1139. + if (mrq->cmd->error != MMC_ERR_TIMEOUT) {
  1140. + esdhc_reset(host, ESDHC_RESET_CMD);
  1141. + esdhc_reset(host, ESDHC_RESET_DATA);
  1142. + reset_regs(host);
  1143. + esdhc_dumpregs(host);
  1144. + }
  1145. + }
  1146. +
  1147. + host->mrq = NULL;
  1148. + host->cmd = NULL;
  1149. + host->data = NULL;
  1150. +
  1151. + spin_unlock_irqrestore(&host->lock, flags);
  1152. +
  1153. + mmc_request_done(host->mmc, mrq);
  1154. +}
  1155. +
  1156. +static void esdhc_timeout_timer(unsigned long data)
  1157. +{
  1158. + struct esdhc_host *host;
  1159. + unsigned long flags;
  1160. +
  1161. + host = (struct esdhc_host *)data;
  1162. + printk(KERN_INFO "esdhc_timeout_timer\n");
  1163. + spin_lock_irqsave(&host->lock, flags);
  1164. +
  1165. + if (host->mrq) {
  1166. + if (host->data) {
  1167. + host->data->error = MMC_ERR_TIMEOUT;
  1168. + esdhc_finish_data(host);
  1169. + } else {
  1170. + if (host->cmd)
  1171. + host->cmd->error = MMC_ERR_TIMEOUT;
  1172. + else
  1173. + host->mrq->cmd->error = MMC_ERR_TIMEOUT;
  1174. + tasklet_schedule(&host->finish_tasklet);
  1175. + }
  1176. + }
  1177. +
  1178. + mmiowb();
  1179. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS, 0);
  1180. + spin_unlock_irqrestore(&host->lock, flags);
  1181. +}
  1182. +
  1183. +/*****************************************************************************\
  1184. + * *
  1185. + * Interrupt handling *
  1186. + * *
  1187. +\*****************************************************************************/
  1188. +
  1189. +static void esdhc_cmd_irq(struct esdhc_host *host, u32 intmask)
  1190. +{
  1191. + BUG_ON(intmask == 0);
  1192. +
  1193. + if (!host->cmd) {
  1194. + printk(KERN_ERR "%s: Got command interrupt even though no "
  1195. + "command operation was in progress.\n",
  1196. + mmc_hostname(host->mmc));
  1197. + esdhc_dumpregs(host);
  1198. + return;
  1199. + }
  1200. +
  1201. + if (intmask & ESDHC_INT_TIMEOUT) {
  1202. + host->cmd->error = MMC_ERR_TIMEOUT;
  1203. + DBG("esdhc_cmd_irq MMC_ERR_TIMEOUT\n");
  1204. + tasklet_schedule(&host->finish_tasklet);
  1205. + } else if (intmask & ESDHC_INT_RESPONSE)
  1206. + esdhc_finish_command(host);
  1207. + else {
  1208. + if (intmask & ESDHC_INT_CRC)
  1209. + host->cmd->error = MMC_ERR_BADCRC;
  1210. + else if (intmask & (ESDHC_INT_END_BIT | ESDHC_INT_INDEX))
  1211. + host->cmd->error = MMC_ERR_FAILED;
  1212. + else
  1213. + host->cmd->error = MMC_ERR_INVALID;
  1214. +
  1215. + tasklet_schedule(&host->finish_tasklet);
  1216. + }
  1217. +}
  1218. +
  1219. +static void esdhc_data_irq(struct esdhc_host *host, u32 intmask)
  1220. +{
  1221. + BUG_ON(intmask == 0);
  1222. + if (!host->data) {
  1223. + /*
  1224. + * A data end interrupt is sent together with the response
  1225. + * for the stop command.
  1226. + */
  1227. + if ((intmask & ESDHC_INT_DATA_END) ||
  1228. + (intmask & ESDHC_INT_DMA_END)) {
  1229. + return;
  1230. + }
  1231. + DBG("%s: Got data interrupt even though no "
  1232. + "data operation was in progress.\n",
  1233. + mmc_hostname(host->mmc));
  1234. + esdhc_dumpregs(host);
  1235. +
  1236. + return;
  1237. + }
  1238. +
  1239. + if (intmask & ESDHC_INT_DATA_TIMEOUT)
  1240. + host->data->error = MMC_ERR_TIMEOUT;
  1241. + else if (intmask & ESDHC_INT_DATA_CRC)
  1242. + host->data->error = MMC_ERR_BADCRC;
  1243. + else if (intmask & ESDHC_INT_DATA_END_BIT)
  1244. + host->data->error = MMC_ERR_FAILED;
  1245. +
  1246. + if (host->data->error != MMC_ERR_NONE) {
  1247. + esdhc_finish_data(host);
  1248. + } else {
  1249. + if (intmask & (ESDHC_INT_DATA_AVAIL | ESDHC_INT_SPACE_AVAIL))
  1250. + esdhc_transfer_pio(host);
  1251. + /*
  1252. + * We currently don't do anything fancy with DMA
  1253. + * boundaries, but as we can't disable the feature
  1254. + * we need to at least restart the transfer.
  1255. + */
  1256. + if (intmask & ESDHC_INT_DMA_END)
  1257. + fsl_writel(host->ioaddr + ESDHC_DMA_ADDRESS,
  1258. + fsl_readl(host->ioaddr + ESDHC_DMA_ADDRESS));
  1259. + if (intmask & ESDHC_INT_DATA_END)
  1260. + esdhc_finish_data(host);
  1261. + }
  1262. +}
  1263. +
  1264. +static irqreturn_t esdhc_detect_irq(int irq, void *dev_id)
  1265. +{
  1266. + irqreturn_t result;
  1267. + struct esdhc_host *host = dev_id;
  1268. + u8 irq_status = 0;
  1269. +
  1270. + spin_lock(&host->lock);
  1271. +
  1272. + irq_status = MCF_EPORT_EPPDR & 0x2;
  1273. + DBG("***Extern IRQ %x %x %x %x %x %x\n", MCF_EPORT_EPPAR,
  1274. + MCF_EPORT_EPDDR, MCF_EPORT_EPDR, MCF_EPORT_EPFR,
  1275. + MCF_EPORT_EPIER, MCF_EPORT_EPPDR);
  1276. +#if defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ1)
  1277. + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE1);
  1278. +#elif defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ7)
  1279. + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE7);
  1280. +#else
  1281. + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE7);
  1282. +#endif
  1283. + if (irq_status == 0x0) {
  1284. + DBG("*** Card insert interrupt Extern IRQ\n");
  1285. + esdhc_reset(host, ESDHC_INIT_CARD);
  1286. + host->card_insert = 1;
  1287. + } else /*irq_status == 0x2) */{
  1288. + DBG("*** Card removed interrupt Extern IRQ\n");
  1289. + if (host->mrq) {
  1290. + printk(KERN_ERR "%s: Card removed during transfer!\n",
  1291. + mmc_hostname(host->mmc));
  1292. + printk(KERN_ERR "%s: Resetting controller.\n",
  1293. + mmc_hostname(host->mmc));
  1294. +
  1295. + esdhc_reset(host, ESDHC_RESET_CMD);
  1296. + esdhc_reset(host, ESDHC_RESET_DATA);
  1297. +
  1298. + host->mrq->cmd->error = MMC_ERR_FAILED;
  1299. + tasklet_schedule(&host->finish_tasklet);
  1300. + }
  1301. + host->card_insert = 0;
  1302. + }
  1303. +
  1304. + mmc_detect_change(host->mmc, msecs_to_jiffies(500));
  1305. +#if defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ1)
  1306. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA1_BOTH;
  1307. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE1;
  1308. + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF1;
  1309. +#elif defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ7)
  1310. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
  1311. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
  1312. + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF7;
  1313. +#else
  1314. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
  1315. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
  1316. + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF7;
  1317. +#endif
  1318. + DBG("***Extern IRQ return %x %x %x %x %x %x\n", MCF_EPORT_EPPAR,
  1319. + MCF_EPORT_EPDDR, MCF_EPORT_EPDR, MCF_EPORT_EPFR,
  1320. + MCF_EPORT_EPIER, MCF_EPORT_EPPDR);
  1321. +
  1322. + result = IRQ_HANDLED;
  1323. + spin_unlock(&host->lock);
  1324. +
  1325. + return result;
  1326. +}
  1327. +
  1328. +static irqreturn_t esdhc_irq(int irq, void *dev_id)
  1329. +{
  1330. + irqreturn_t result;
  1331. + struct esdhc_host *host = dev_id;
  1332. + u32 status;
  1333. +
  1334. + spin_lock(&host->lock);
  1335. +
  1336. + status = fsl_readl(host->ioaddr + ESDHC_INT_STATUS);
  1337. +
  1338. + if (!status || status == 0xffffffff) {
  1339. + result = IRQ_NONE;
  1340. + goto out;
  1341. + }
  1342. +
  1343. + if (status & ESDHC_INT_CMD_MASK) {
  1344. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS,
  1345. + status & ESDHC_INT_CMD_MASK);
  1346. + esdhc_cmd_irq(host, status & ESDHC_INT_CMD_MASK);
  1347. + }
  1348. +
  1349. + if (status & ESDHC_INT_DATA_MASK) {
  1350. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS,
  1351. + status & ESDHC_INT_DATA_MASK);
  1352. + esdhc_data_irq(host, status & ESDHC_INT_DATA_MASK);
  1353. + }
  1354. +
  1355. + status &= ~(ESDHC_INT_CMD_MASK | ESDHC_INT_DATA_MASK);
  1356. +
  1357. + if (status) {
  1358. + printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
  1359. + mmc_hostname(host->mmc), status);
  1360. + esdhc_dumpregs(host);
  1361. +
  1362. + fsl_writel(host->ioaddr + ESDHC_INT_STATUS, status);
  1363. + }
  1364. +
  1365. + result = IRQ_HANDLED;
  1366. +
  1367. + mmiowb();
  1368. +out:
  1369. + spin_unlock(&host->lock);
  1370. +
  1371. + return result;
  1372. +}
  1373. +
  1374. +/*****************************************************************************\
  1375. + * *
  1376. + * Suspend/resume *
  1377. + * *
  1378. +\*****************************************************************************/
  1379. +
  1380. +#ifdef CONFIG_PM
  1381. +
  1382. +static int esdhc_suspend(struct platform_device *pdev, pm_message_t state)
  1383. +{
  1384. + struct esdhc_chip *chip;
  1385. + int i, ret;
  1386. +
  1387. + chip = platform_get_drvdata(pdev);
  1388. + if (!chip)
  1389. + return 0;
  1390. +
  1391. + DBG("Suspending...");
  1392. +
  1393. + for (i = 0; i < chip->num_slots; i++) {
  1394. + if (!chip->hosts[i])
  1395. + continue;
  1396. + ret = mmc_suspend_host(chip->hosts[i]->mmc);
  1397. + if (ret) {
  1398. + for (i--; i >= 0; i--)
  1399. + mmc_resume_host(chip->hosts[i]->mmc);
  1400. + return ret;
  1401. + }
  1402. + }
  1403. +
  1404. + for (i = 0; i < chip->num_slots; i++) {
  1405. + if (!chip->hosts[i])
  1406. + continue;
  1407. + free_irq(chip->hosts[i]->irq, chip->hosts[i]);
  1408. + }
  1409. +
  1410. + return 0;
  1411. +}
  1412. +
  1413. +static int esdhc_resume(struct platform_device *pdev)
  1414. +{
  1415. + struct esdhc_chip *chip;
  1416. + int i, ret;
  1417. +
  1418. + chip = platform_get_drvdata(pdev);
  1419. + if (!chip)
  1420. + return 0;
  1421. +
  1422. + DBG("Resuming...");
  1423. +
  1424. + for (i = 0; i < chip->num_slots; i++) {
  1425. + if (!chip->hosts[i])
  1426. + continue;
  1427. + ret = request_irq(chip->hosts[i]->irq, esdhc_irq,
  1428. + IRQF_SHARED, chip->hosts[i]->slot_descr,
  1429. + chip->hosts[i]);
  1430. + if (ret)
  1431. + return ret;
  1432. + esdhc_init(chip->hosts[i]);
  1433. + mmiowb();
  1434. + ret = mmc_resume_host(chip->hosts[i]->mmc);
  1435. + if (ret)
  1436. + return ret;
  1437. + }
  1438. +
  1439. + return 0;
  1440. +}
  1441. +
  1442. +#else
  1443. +
  1444. +#define esdhc_suspend NULL
  1445. +#define esdhc_resume NULL
  1446. +
  1447. +#endif
  1448. +
  1449. +/*****************************************************************************\
  1450. + * *
  1451. + * Device probing/removal *
  1452. + * *
  1453. +\*****************************************************************************/
  1454. +
  1455. +static int esdhc_probe_slot(struct platform_device *pdev, int slot)
  1456. +{
  1457. + int ret;
  1458. + unsigned int version;
  1459. + struct esdhc_chip *chip;
  1460. + struct mmc_host *mmc;
  1461. + struct esdhc_host *host;
  1462. + struct resource *res;
  1463. +
  1464. + unsigned int caps;
  1465. +
  1466. + chip = platform_get_drvdata(pdev);
  1467. + BUG_ON(!chip);
  1468. +
  1469. + mmc = mmc_alloc_host(sizeof(struct esdhc_host), &(pdev->dev));
  1470. + if (!mmc) {
  1471. + printk(KERN_ERR "%s mmc_alloc_host failed %x\n",
  1472. + __func__, (unsigned int)mmc);
  1473. + return -ENOMEM;
  1474. + }
  1475. +
  1476. + host = mmc_priv(mmc);
  1477. + host->mmc = mmc;
  1478. +
  1479. + host->chip = chip;
  1480. + chip->hosts[slot] = host;
  1481. +
  1482. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1483. + if (res == NULL) {
  1484. + printk(KERN_ERR "%s platform_get_resource MEM failed %x\n",
  1485. + __func__, (unsigned int)res);
  1486. + goto free;
  1487. + }
  1488. +
  1489. + host->addr = res->start;
  1490. + host->size = res->end - res->start + 1;
  1491. +
  1492. + host->irq = platform_get_irq(pdev, 0);
  1493. + if (host->irq <= 0) {
  1494. + printk(KERN_ERR "%s platform_get_irq failed %x\n",
  1495. + __func__, host->irq);
  1496. + goto free;
  1497. + }
  1498. +
  1499. + printk(KERN_INFO "slot %d at 0x%08lx, irq %d\n",
  1500. + slot, host->addr, host->irq);
  1501. +
  1502. + snprintf(host->slot_descr, 20, "esdhc:slot%d", slot);
  1503. +
  1504. + ret = (int)request_mem_region(host->addr, host->size, DRIVER_NAME);
  1505. + if (!ret) {
  1506. + ret = -EBUSY;
  1507. + printk(KERN_INFO "%s request_mem_region failed %x\n",
  1508. + __func__, (unsigned int)res);
  1509. + goto release;
  1510. + }
  1511. +
  1512. + host->ioaddr = ioremap_nocache(host->addr, host->size);
  1513. + if (!host->ioaddr) {
  1514. + ret = -ENOMEM;
  1515. + printk(KERN_INFO "%s ioremap_nocache failed %x\n",
  1516. + __func__, (unsigned int)host->ioaddr);
  1517. + goto release;
  1518. + }
  1519. +
  1520. + esdhc_reset(host, ESDHC_RESET_ALL);
  1521. +
  1522. + version = fsl_readl(host->ioaddr + ESDHC_HOST_VERSION);
  1523. + if ((version & 1) != 0x01)
  1524. + printk(KERN_INFO "%s: Unknown controller version (%d). "
  1525. + "You may experience problems.\n", host->slot_descr,
  1526. + version);
  1527. +
  1528. + caps = fsl_readl(host->ioaddr + ESDHC_CAPABILITIES);
  1529. + printk(KERN_INFO "%s caps %x %x\n",
  1530. + __func__, caps, (unsigned int)MCF_ESDHC_HOSTCAPBLT);
  1531. +
  1532. +#if defined(CONFIG_ESDHC_FORCE_PIO)
  1533. + debug_nodma = 1;
  1534. +#endif
  1535. + if (debug_nodma)
  1536. + DBG("DMA forced off\n");
  1537. + else if (debug_forcedma) {
  1538. + DBG("DMA forced on\n");
  1539. + host->flags |= ESDHC_USE_DMA;
  1540. + } else if (chip->quirks & ESDHC_QUIRK_FORCE_DMA) {
  1541. + DBG("Controller force DMA capability\n");
  1542. + host->flags |= ESDHC_USE_DMA;
  1543. + } else if (!(caps & ESDHC_CAN_DO_DMA))
  1544. + DBG("Controller doesn't have DMA capability\n");
  1545. + else {
  1546. + host->flags |= ESDHC_USE_DMA;
  1547. + DBG("Controller have DMA capability\n");
  1548. + }
  1549. +
  1550. + /*
  1551. + * Set host parameters.
  1552. + */
  1553. +#ifdef CONFIG_MPC5441X
  1554. + host->max_clk = 17000000;
  1555. +#else
  1556. + host->max_clk = 25000000;
  1557. +#endif
  1558. +
  1559. + /* if 4 bit , freq can be 50MHz */
  1560. + mmc->ops = &esdhc_ops;
  1561. + mmc->f_min = 400000;
  1562. + mmc->f_max = min((int)host->max_clk, 50000000);
  1563. +
  1564. + mmc->caps = MMC_CAP_4_BIT_DATA;
  1565. +
  1566. + mmc->ocr_avail = 0;
  1567. + if (caps & ESDHC_CAN_VDD_330)
  1568. + mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
  1569. + if (caps & ESDHC_CAN_VDD_300)
  1570. + mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
  1571. + if (caps & ESDHC_CAN_VDD_180)
  1572. + mmc->ocr_avail |= MMC_VDD_165_195;
  1573. +
  1574. + if (mmc->ocr_avail == 0) {
  1575. + printk(KERN_INFO "%s: Hardware doesn't report any "
  1576. + "support voltages.\n", host->slot_descr);
  1577. + ret = -ENODEV;
  1578. + goto unmap;
  1579. + }
  1580. +
  1581. + spin_lock_init(&host->lock);
  1582. +
  1583. + /*
  1584. + * Maximum number of segments. Hardware cannot do scatter lists.
  1585. + */
  1586. + if (host->flags & ESDHC_USE_DMA)
  1587. + mmc->max_segs = 1;
  1588. + else
  1589. + mmc->max_segs = 16;
  1590. +
  1591. + /*
  1592. + * Maximum number of sectors in one transfer. Limited by DMA boundary
  1593. + * size (512KiB).
  1594. + */
  1595. + mmc->max_req_size = 524288;
  1596. +
  1597. + /*
  1598. + * Maximum segment size. Could be one segment with the maximum number
  1599. + * of bytes.
  1600. + */
  1601. + mmc->max_seg_size = mmc->max_req_size;
  1602. +
  1603. + /*
  1604. + * Maximum block size. This varies from controller to controller and
  1605. + * is specified in the capabilities register.
  1606. + */
  1607. + mmc->max_blk_size = (caps & ESDHC_MAX_BLOCK_MASK) >>
  1608. + ESDHC_MAX_BLOCK_SHIFT;
  1609. + if (mmc->max_blk_size > 3) {
  1610. + printk(KERN_INFO "%s: Invalid maximum block size.\n",
  1611. + host->slot_descr);
  1612. + ret = -ENODEV;
  1613. + goto unmap;
  1614. + }
  1615. + mmc->max_blk_size = 512 << mmc->max_blk_size;
  1616. +
  1617. + /*
  1618. + * Maximum block count.
  1619. + */
  1620. + mmc->max_blk_count = /*65535*/0x80;
  1621. +
  1622. + /*
  1623. + * Init tasklets.
  1624. + */
  1625. + tasklet_init(&host->card_tasklet,
  1626. + esdhc_tasklet_card, (unsigned long)host);
  1627. + tasklet_init(&host->finish_tasklet,
  1628. + esdhc_tasklet_finish, (unsigned long)host);
  1629. +
  1630. + setup_timer(&host->timer, esdhc_timeout_timer, (unsigned long)host);
  1631. +
  1632. + esdhc_init(host);
  1633. +
  1634. + esdhc_dumpregs(host);
  1635. +
  1636. + ret = request_irq(host->irq, esdhc_irq, IRQF_DISABLED,
  1637. + host->slot_descr, host);
  1638. + if (ret) {
  1639. + printk(KERN_INFO "%s: request irq fail %x\n", __func__, ret);
  1640. + goto untasklet;
  1641. + }
  1642. +
  1643. + ret = request_irq(card_detect_extern_irq,
  1644. + esdhc_detect_irq, IRQF_DISABLED,
  1645. + host->slot_descr, host);
  1646. + if (ret) {
  1647. + printk(KERN_INFO "%s: request irq fail %x\n", __func__, ret);
  1648. + goto untasklet1;
  1649. + }
  1650. +
  1651. + mmiowb();
  1652. +
  1653. + ret = mmc_add_host(mmc);
  1654. + if (ret) {
  1655. + printk(KERN_INFO "%s: mmc_add_host fail %x\n", __func__, ret);
  1656. + goto unaddhost;
  1657. + }
  1658. +
  1659. + printk(KERN_INFO "%s: ESDHC at 0x%08lx irq %d %s\n", mmc_hostname(mmc),
  1660. + host->addr, host->irq,
  1661. + (host->flags & ESDHC_USE_DMA) ? "DMA" : "PIO");
  1662. +
  1663. +#ifdef ESDHC_DMA_KMALLOC
  1664. + host->dma_tx_buf = kmalloc(ESDHC_DMA_SIZE, GFP_DMA);
  1665. + host->dma_tx_dmahandle = virt_to_phys(host->dma_tx_buf);
  1666. +#else
  1667. + host->dma_tx_buf = dma_alloc_coherent(NULL, ESDHC_DMA_SIZE,
  1668. + &host->dma_tx_dmahandle, GFP_DMA|GFP_KERNEL);
  1669. +#endif
  1670. +
  1671. + if (((unsigned int)host->dma_tx_buf == 0) ||
  1672. + ((unsigned int)host->dma_tx_dmahandle == 0))
  1673. + printk(KERN_ERR "%s DMA alloc error\n", __func__);
  1674. +
  1675. + return 0;
  1676. +
  1677. +unaddhost:
  1678. + free_irq(card_detect_extern_irq, host);
  1679. +untasklet1:
  1680. + free_irq(host->irq, host);
  1681. +untasklet:
  1682. + tasklet_kill(&host->card_tasklet);
  1683. + tasklet_kill(&host->finish_tasklet);
  1684. +unmap:
  1685. + iounmap(host->ioaddr);
  1686. +release:
  1687. + release_mem_region(host->addr, host->size);
  1688. +free:
  1689. + mmc_free_host(mmc);
  1690. +
  1691. + return ret;
  1692. +}
  1693. +
  1694. +static void esdhc_remove_slot(struct platform_device *pdev, int slot)
  1695. +{
  1696. + struct esdhc_chip *chip;
  1697. + struct mmc_host *mmc;
  1698. + struct esdhc_host *host;
  1699. +
  1700. + chip = platform_get_drvdata(pdev);
  1701. + host = chip->hosts[slot];
  1702. + mmc = host->mmc;
  1703. +
  1704. + chip->hosts[slot] = NULL;
  1705. +
  1706. + mmc_remove_host(mmc);
  1707. +
  1708. + esdhc_reset(host, ESDHC_RESET_ALL);
  1709. +
  1710. + free_irq(card_detect_extern_irq, host);
  1711. +
  1712. + free_irq(host->irq, host);
  1713. +
  1714. + del_timer_sync(&host->timer);
  1715. +
  1716. + tasklet_kill(&host->card_tasklet);
  1717. + tasklet_kill(&host->finish_tasklet);
  1718. +
  1719. + iounmap(host->ioaddr);
  1720. +
  1721. + release_mem_region(host->addr, host->size);
  1722. +
  1723. + mmc_free_host(mmc);
  1724. + DBG("%s: Exit....\n", __func__);
  1725. +}
  1726. +
  1727. +static int __init esdhc_probe(struct platform_device *pdev)
  1728. +{
  1729. + int ret, i;
  1730. + u8 slots;
  1731. + struct esdhc_chip *chip;
  1732. +
  1733. + BUG_ON(pdev == NULL);
  1734. +
  1735. + /* Slew Rate */
  1736. + MCF_GPIO_SRCR_SDHC = 3;
  1737. + MCF_GPIO_SRCR_IRQ0 = 3;
  1738. +
  1739. + /* Port Configuration */
  1740. + MCF_GPIO_PAR_ESDHCH = 0xFF; /* DAT[3:0] */
  1741. + MCF_GPIO_PAR_ESDHCL = 0x0F; /* CMD, CLK */
  1742. +
  1743. + MCF_ESDHC_VSR = 2; /* disabled adma and set 3.0V */
  1744. +
  1745. + MCF_INTC2_ICR31 = 2; /* SDHC irqstat */
  1746. +#if defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ1)
  1747. + /*this is irq1 hardware work round*/
  1748. + MCF_GPIO_PAR_IRQ0H |= 0x3;
  1749. +
  1750. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA1_BOTH;
  1751. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE1;
  1752. +
  1753. + MCF_INTC0_ICR1 = 7; /* IRQ1 */
  1754. + DBG("MCF_INTC0_ICR1 %x MCF_EPORT_EPPAR %x "
  1755. + "MCF_EPORT_EPFR %x MCF_EPORT_EPIER %x "
  1756. + "MCF_INTC0_IMRL %x MCF_INTC0_INTFRCL %x "
  1757. + "MCF_INTC0_IPRL %x\n",
  1758. + MCF_INTC0_ICR1, MCF_EPORT_EPPAR, MCF_EPORT_EPFR,
  1759. + MCF_EPORT_EPIER, MCF_INTC0_IMRL, MCF_INTC0_INTFRCL,
  1760. + MCF_INTC0_IPRL);
  1761. +#elif defined(CONFIG_ESDHC_DETECT_USE_EXTERN_IRQ7)
  1762. + MCF_GPIO_PAR_IRQ0H |= MCF_GPIO_PAR_IRQH_IRQ7;
  1763. +
  1764. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
  1765. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
  1766. +
  1767. + MCF_INTC0_ICR7 = 2; /* IRQ7 */
  1768. + DBG("MCF_INTC0_ICR7 %x MCF_EPORT_EPPAR %x\n",
  1769. + MCF_INTC0_ICR7, MCF_EPORT_EPPAR);
  1770. +#else
  1771. + MCF_GPIO_PAR_IRQ0H |= MCF_GPIO_PAR_IRQH_IRQ7;
  1772. +
  1773. + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
  1774. + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
  1775. +
  1776. + MCF_INTC0_ICR7 = 2; /* IRQ7 */
  1777. + DBG("MCF_INTC0_ICR1 %x MCF_EPORT_EPPAR %x\n",
  1778. + MCF_INTC0_ICR7, MCF_EPORT_EPPAR);
  1779. +#endif
  1780. +
  1781. + slots = ESDHC_SLOTS_NUMBER;
  1782. + DBG("found %d slot(s)\n", slots);
  1783. + if (slots == 0) {
  1784. + printk(KERN_INFO "%s: slot err %d\n", __func__, slots);
  1785. + return -ENODEV;
  1786. + }
  1787. +
  1788. + chip = kmalloc(sizeof(struct esdhc_chip) +
  1789. + sizeof(struct esdhc_host *) * slots, GFP_KERNEL);
  1790. + if (!chip) {
  1791. + ret = -ENOMEM;
  1792. + printk(KERN_ERR "%s: kmalloc fail %x\n", __func__,
  1793. + (unsigned int)chip);
  1794. + goto err;
  1795. + }
  1796. +
  1797. + memset(chip, 0,
  1798. + sizeof(struct esdhc_chip) +
  1799. + sizeof(struct esdhc_host *) * slots);
  1800. +
  1801. + chip->pdev = pdev;
  1802. + chip->quirks = ESDHC_QUIRK_NO_CARD_NO_RESET;
  1803. +
  1804. + if (debug_quirks)
  1805. + chip->quirks = debug_quirks;
  1806. +
  1807. + chip->num_slots = slots;
  1808. + platform_set_drvdata(pdev, chip);
  1809. +
  1810. + for (i = 0; i < slots; i++) {
  1811. + ret = esdhc_probe_slot(pdev, i);
  1812. + if (ret) {
  1813. + for (i--; i >= 0; i--)
  1814. + esdhc_remove_slot(pdev, i);
  1815. + goto free;
  1816. + }
  1817. + }
  1818. +
  1819. + return 0;
  1820. +
  1821. +free:
  1822. + platform_set_drvdata(pdev, NULL);
  1823. + kfree(chip);
  1824. +
  1825. +err:
  1826. + return ret;
  1827. +}
  1828. +
  1829. +static int esdhc_remove(struct platform_device *pdev)
  1830. +{
  1831. + int i;
  1832. + struct esdhc_chip *chip;
  1833. +
  1834. + chip = platform_get_drvdata(pdev);
  1835. +
  1836. + if (chip) {
  1837. + for (i = 0; i < chip->num_slots; i++)
  1838. + esdhc_remove_slot(pdev, i);
  1839. +
  1840. + platform_set_drvdata(pdev, NULL);
  1841. +
  1842. + kfree(chip);
  1843. + }
  1844. +
  1845. + return 0;
  1846. +}
  1847. +
  1848. +/*-------------------------------------------------------------------------*/
  1849. +static struct platform_driver esdhc_driver = {
  1850. + .probe = esdhc_probe,
  1851. + .remove = esdhc_remove,
  1852. + .suspend = esdhc_suspend,
  1853. + .resume = esdhc_resume,
  1854. + .driver = {
  1855. + .name = DRIVER_NAME,
  1856. + .owner = THIS_MODULE,
  1857. + },
  1858. +};
  1859. +
  1860. +/*****************************************************************************\
  1861. + * *
  1862. + * Driver init/exit *
  1863. + * *
  1864. +\*****************************************************************************/
  1865. +
  1866. +static int __init esdhc_drv_init(void)
  1867. +{
  1868. + printk(KERN_INFO DRIVER_NAME
  1869. + ": Freescale Enhanced Secure Digital Host"
  1870. + " Controller driver\n");
  1871. +
  1872. + return platform_driver_register(&esdhc_driver);
  1873. +}
  1874. +
  1875. +static void __exit esdhc_drv_exit(void)
  1876. +{
  1877. + printk(KERN_INFO DRIVER_NAME
  1878. + ": Freescale Enhanced Secure Digital Host"
  1879. + " Controller driver exit\n");
  1880. + platform_driver_unregister(&esdhc_driver);
  1881. +}
  1882. +
  1883. +module_init(esdhc_drv_init);
  1884. +module_exit(esdhc_drv_exit);
  1885. +
  1886. +module_param(debug_nodma, uint, 0444);
  1887. +module_param(debug_forcedma, uint, 0444);
  1888. +module_param(debug_quirks, uint, 0444);
  1889. +
  1890. +MODULE_AUTHOR("Chenghu Wu<[email protected]>");
  1891. +MODULE_DESCRIPTION("Enhanced Secure Digital Host Controller driver");
  1892. +MODULE_LICENSE("GPL");
  1893. +
  1894. +MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers.");
  1895. +MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers.");
  1896. +MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
  1897. --- /dev/null
  1898. +++ b/drivers/mmc/host/esdhc.h
  1899. @@ -0,0 +1,310 @@
  1900. +/*
  1901. + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
  1902. + * Author: Chenghu Wu <[email protected]>
  1903. + * Xiaobo Xie <[email protected]>
  1904. + *
  1905. + * Based on mpc837x/driver/mmc/host/esdhc.c done by Xiaobo Xie
  1906. + * Ported to Coldfire platform by Chenghu Wu
  1907. + *
  1908. + * This program is free software; you can redistribute it and/or modify
  1909. + * it under the terms of the GNU General Public License as published by
  1910. + * the Free Software Foundation; either version 2 of the License, or (at
  1911. + * your option) any later version.
  1912. + */
  1913. +#ifndef ESDHC_H
  1914. +#define ESDHC_H
  1915. +
  1916. +#define MMC_ERR_NONE 0
  1917. +#define MMC_ERR_TIMEOUT 1
  1918. +#define MMC_ERR_BADCRC 2
  1919. +#define MMC_ERR_FIFO 3
  1920. +#define MMC_ERR_FAILED 4
  1921. +#define MMC_ERR_INVALID 5
  1922. +
  1923. +#define MCF_CLOCK_PLL_DR (*(volatile unsigned long *)(0xFC0C0004))
  1924. +#define MCF_ESDHC_HOSTCAPBLT (*(volatile unsigned long *)(0xFC0CC040))
  1925. +#define MCF_ESDHC_ADMAESR (*(volatile unsigned long *)(0xFC0CC054))
  1926. +#define MCF_ESDHC_ADMASAR (*(volatile unsigned long *)(0xFC0CC058))
  1927. +#define MCF_ESDHC_VSR (*(volatile unsigned long *)(0xFC0CC0C0))
  1928. +#define MCF_ESDHC_HOSTVER (*(volatile unsigned long *)(0xFC0CC0FC))
  1929. +/*
  1930. + * Controller registers (Big Endian)
  1931. + */
  1932. +
  1933. +#define MCF_GPIO_PAR_SDHC_DATA3 0x20
  1934. +#define MCF_GPIO_PAR_SDHC_DATA2 0x10
  1935. +#define MCF_GPIO_PAR_SDHC_DATA1 0x08
  1936. +#define MCF_GPIO_PAR_SDHC_DATA0 0x04
  1937. +#define MCF_GPIO_PAR_SDHC_CMD 0x02
  1938. +#define MCF_GPIO_PAR_SDHC_CLK 0x01
  1939. +
  1940. +
  1941. +#define MCF_GPIO_SRCR_SDHC_LOWEST 0x00
  1942. +#define MCF_GPIO_SRCR_SDHC_LOWE 0x01
  1943. +#define MCF_GPIO_SRCR_SDHC_HIGH 0x02
  1944. +#define MCF_GPIO_SRCR_SDHC_HIGHEST 0x03
  1945. +
  1946. +
  1947. +#define MCF_GPIO_PCRL_SDHC_DATA3 0x80
  1948. +#define MCF_GPIO_PCRL_SDHC_DATA2 0x40
  1949. +#define MCF_GPIO_PCRL_SDHC_DATA1 0x20
  1950. +#define MCF_GPIO_PCRL_SDHC_DATA0 0x10
  1951. +#define MCF_GPIO_PCRL_SDHC_CMD 0x08
  1952. +#define MCF_GPIO_PCRL_SDHC_CLK 0x04
  1953. +
  1954. +#define MCF_INT_SDHC 63
  1955. +/* DMA System Address Register */
  1956. +#define ESDHC_DMA_ADDRESS 0x00
  1957. +
  1958. +/* Block Attributes Register */
  1959. +#define ESDHC_BLOCK_ATTR 0x04
  1960. +#define ESDHC_BLOCK_SIZE_MASK 0x00000fff
  1961. +#define ESDHC_BLCOK_CNT_MASK 0xffff0000
  1962. +#define ESDHC_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
  1963. +
  1964. +/* Command Argument */
  1965. +#define ESDHC_ARGUMENT 0x08
  1966. +
  1967. +/* Transfer Type Register */
  1968. +#define ESDHC_COMMAND 0x0C
  1969. +
  1970. +#define ESDHC_TRNS_DMA 0x00000001
  1971. +#define ESDHC_TRNS_BLK_CNT_EN 0x00000002
  1972. +#define ESDHC_TRNS_ACMD12 0x00000004
  1973. +#define ESDHC_TRNS_READ 0x00000010
  1974. +#define ESDHC_TRNS_MULTI 0x00000020
  1975. +
  1976. +#define ESDHC_CMD_RESP_MASK 0x00030000
  1977. +#define ESDHC_CMD_CRC_EN 0x00080000
  1978. +#define ESDHC_CMD_INDEX_EN 0x00100000
  1979. +#define ESDHC_CMD_DATA 0x00200000
  1980. +#define ESDHC_CMD_TYPE_MASK 0x00c00000
  1981. +#define ESDHC_CMD_INDEX 0x3f000000
  1982. +
  1983. +#define ESDHC_CMD_RESP_NONE 0x00000000
  1984. +#define ESDHC_CMD_RESP_LONG 0x00010000
  1985. +#define ESDHC_CMD_RESP_SHORT 0x00020000
  1986. +#define ESDHC_CMD_RESP_SHORT_BUSY 0x00030000
  1987. +
  1988. +#define ESDHC_MAKE_CMD(c, f) (((c & 0xff) << 24) | (f & 0xfb0037))
  1989. +
  1990. +/* Response Register */
  1991. +#define ESDHC_RESPONSE 0x10
  1992. +
  1993. +/* Buffer Data Port Register */
  1994. +#define ESDHC_BUFFER 0x20
  1995. +
  1996. +/* Present State Register */
  1997. +#define ESDHC_PRESENT_STATE 0x24
  1998. +#define ESDHC_CMD_INHIBIT 0x00000001
  1999. +#define ESDHC_DATA_INHIBIT 0x00000002
  2000. +#define ESDHC_DOING_WRITE 0x00000100
  2001. +#define ESDHC_DOING_READ 0x00000200
  2002. +#define ESDHC_SPACE_AVAILABLE 0x00000400
  2003. +#define ESDHC_DATA_AVAILABLE 0x00000800
  2004. +#define ESDHC_CARD_PRESENT 0x00010000
  2005. +#define ESDHC_WRITE_PROTECT 0x00080000
  2006. +
  2007. +/* Protocol control Register */
  2008. +#define ESDHC_PROTOCOL_CONTROL 0x28
  2009. +
  2010. +#define ESDHC_CTRL_BUS_MASK 0x00000006
  2011. +#define ESDHC_CTRL_4BITBUS 0x00000002
  2012. +#define ESDHC_CTRL_D3_DETEC 0x00000008
  2013. +#define ESDHC_CTRL_DTCT_EN 0x00000080
  2014. +#define ESDHC_CTRL_DTCT_STATUS 0x00000040
  2015. +#define ESDHC_CTRL_WU_CRM 0x04000000
  2016. +#define ESDHC_CTRL_WU_CINS 0x02000000
  2017. +#define ESDHC_CTRL_WU_CINT 0x01000000
  2018. +
  2019. +/* System Control Register */
  2020. +#define ESDHC_SYSTEM_CONTROL 0x2C
  2021. +
  2022. +#define ESDHC_CLOCK_MASK 0x0000fff0
  2023. +#define ESDHC_CLOCK_DEFAULT 0x00008000
  2024. +#define ESDHC_PREDIV_SHIFT 8
  2025. +#define ESDHC_DIVIDER_SHIFT 4
  2026. +#define ESDHC_CLOCK_CARD_EN 0x00000004
  2027. +#define ESDHC_CLOCK_INT_STABLE 0x00000002
  2028. +#define ESDHC_CLOCK_INT_EN 0x00000001
  2029. +
  2030. +#define ESDHC_TIMEOUT_MASK 0x000f0000
  2031. +#define ESDHC_TIMEOUT_SHIFT 16
  2032. +
  2033. +#define ESDHC_RESET_SHIFT 24
  2034. +#define ESDHC_RESET_ALL 0x01
  2035. +#define ESDHC_RESET_CMD 0x02
  2036. +#define ESDHC_RESET_DATA 0x04
  2037. +#define ESDHC_INIT_CARD 0x08
  2038. +
  2039. +/* Interrupt Register */
  2040. +#define ESDHC_INT_STATUS 0x30
  2041. +#define ESDHC_INT_ENABLE 0x34
  2042. +#define ESDHC_SIGNAL_ENABLE 0x38
  2043. +
  2044. +#define ESDHC_INT_RESPONSE 0x00000001
  2045. +#define ESDHC_INT_DATA_END 0x00000002
  2046. +#define ESDHC_INT_DMA_END 0x00000008
  2047. +#define ESDHC_INT_SPACE_AVAIL 0x00000010
  2048. +#define ESDHC_INT_DATA_AVAIL 0x00000020
  2049. +#define ESDHC_INT_CARD_INSERT 0x00000040
  2050. +#define ESDHC_INT_CARD_REMOVE 0x00000080
  2051. +#define ESDHC_INT_CARD_INT 0x00000100
  2052. +
  2053. +#define ESDHC_INT_TIMEOUT 0x00010000
  2054. +#define ESDHC_INT_CRC 0x00020000
  2055. +#define ESDHC_INT_END_BIT 0x00040000
  2056. +#define ESDHC_INT_INDEX 0x00080000
  2057. +#define ESDHC_INT_DATA_TIMEOUT 0x00100000
  2058. +#define ESDHC_INT_DATA_CRC 0x00200000
  2059. +#define ESDHC_INT_DATA_END_BIT 0x00400000
  2060. +#define ESDHC_INT_ACMD12ERR 0x01000000
  2061. +#define ESDHC_INT_DMAERR 0x10000000
  2062. +
  2063. +#define ESDHC_INT_NORMAL_MASK 0x00007FFF
  2064. +#define ESDHC_INT_ERROR_MASK 0xFFFF8000
  2065. +
  2066. +#define ESDHC_INT_CMD_MASK (ESDHC_INT_RESPONSE | ESDHC_INT_TIMEOUT | \
  2067. + ESDHC_INT_CRC | ESDHC_INT_END_BIT | ESDHC_INT_INDEX)
  2068. +#define ESDHC_INT_DATA_MASK (ESDHC_INT_DATA_END | ESDHC_INT_DMA_END | \
  2069. + ESDHC_INT_DATA_AVAIL | ESDHC_INT_SPACE_AVAIL | \
  2070. + ESDHC_INT_DATA_TIMEOUT | ESDHC_INT_DATA_CRC | \
  2071. + ESDHC_INT_DATA_END_BIT)
  2072. +
  2073. +#define ESDHC_INT_INSERT_MASK (ESDHC_INT_DATA_END_BIT | ESDHC_INT_DATA_CRC | \
  2074. + ESDHC_INT_DATA_TIMEOUT | ESDHC_INT_INDEX | \
  2075. + ESDHC_INT_END_BIT | ESDHC_INT_CRC | ESDHC_INT_TIMEOUT | \
  2076. + ESDHC_INT_DATA_AVAIL | ESDHC_INT_SPACE_AVAIL | \
  2077. + ESDHC_INT_DMA_END | ESDHC_INT_DATA_END | \
  2078. + ESDHC_INT_RESPONSE | ESDHC_INT_CARD_REMOVE)
  2079. +
  2080. +#define ESDHC_INT_REMOVE_MASK (ESDHC_INT_DATA_END_BIT | ESDHC_INT_DATA_CRC | \
  2081. + ESDHC_INT_DATA_TIMEOUT | ESDHC_INT_INDEX | \
  2082. + ESDHC_INT_END_BIT | ESDHC_INT_CRC | ESDHC_INT_TIMEOUT | \
  2083. + ESDHC_INT_DATA_AVAIL | ESDHC_INT_SPACE_AVAIL | \
  2084. + ESDHC_INT_DMA_END | ESDHC_INT_DATA_END | \
  2085. + ESDHC_INT_RESPONSE | ESDHC_INT_CARD_INSERT)
  2086. +
  2087. +/* Auto CMD12 Error Status Register */
  2088. +#define ESDHC_ACMD12_ERR 0x3C
  2089. +
  2090. +/* 3E-3F reserved */
  2091. +/* Host Controller Capabilities */
  2092. +#define ESDHC_CAPABILITIES 0x40
  2093. +
  2094. +#define ESDHC_MAX_BLOCK_MASK 0x00070000
  2095. +#define ESDHC_MAX_BLOCK_SHIFT 16
  2096. +#define ESDHC_CAN_DO_HISPD 0x00200000
  2097. +#define ESDHC_CAN_DO_DMA 0x00400000
  2098. +#define ESDHC_CAN_DO_SUSPEND 0x00800000
  2099. +#define ESDHC_CAN_VDD_330 0x01000000
  2100. +#define ESDHC_CAN_VDD_300 0x02000000
  2101. +#define ESDHC_CAN_VDD_180 0x04000000
  2102. +
  2103. +/* Watermark Level Register */
  2104. +#define ESDHC_WML 0x44
  2105. +#define ESDHC_WML_MASK 0xff
  2106. +#define ESDHC_WML_READ_SHIFT 0
  2107. +#define ESDHC_WML_WRITE_SHIFT 16
  2108. +
  2109. +/* 45-4F reserved for more caps and max curren*/
  2110. +
  2111. +/* Force Event Register */
  2112. +#define ESDHC_FORCE_EVENT 0x50
  2113. +
  2114. +/* 54-FB reserved */
  2115. +
  2116. +/* Host Controller Version Register */
  2117. +#define ESDHC_HOST_VERSION 0xFC
  2118. +
  2119. +#define ESDHC_VENDOR_VER_MASK 0xFF00
  2120. +#define ESDHC_VENDOR_VER_SHIFT 8
  2121. +#define ESDHC_SPEC_VER_MASK 0x00FF
  2122. +#define ESDHC_SPEC_VER_SHIFT 0
  2123. +
  2124. +#define ESDHC_DMA_SYSCTL 0x40C
  2125. +#define ESDHC_DMA_SNOOP 0x00000040
  2126. +
  2127. +#define ESDHC_SLOTS_NUMBER 1
  2128. +
  2129. +/* The SCCR[SDHCCM] Register */
  2130. +#define MPC837X_SCCR_OFFS 0xA08
  2131. +#define MPC837X_SDHCCM_MASK 0x0c000000
  2132. +#define MPC837X_SDHCCM_SHIFT 26
  2133. +
  2134. +#define esdhc_readl(addr) \
  2135. + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
  2136. +
  2137. +#define esdhc_writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
  2138. +
  2139. +static inline u32 fsl_readl(unsigned __iomem *addr)
  2140. +{
  2141. + u32 val;
  2142. + /*val = inl(addr);*/
  2143. + val = esdhc_readl(addr);
  2144. + return val;
  2145. +}
  2146. +
  2147. +static inline void fsl_writel(unsigned __iomem *addr, u32 val)
  2148. +{
  2149. + /*outl(val, addr);*/
  2150. + esdhc_writel(val, addr);
  2151. +}
  2152. +
  2153. +#define setbits32(_addr, _v) outl((_addr), inl(_addr) | (_v))
  2154. +#define clrbits32(_addr, _v) outl((_addr), inl(_addr) & ~(_v))
  2155. +
  2156. +struct esdhc_chip;
  2157. +
  2158. +struct esdhc_host {
  2159. + struct esdhc_chip *chip;
  2160. + struct mmc_host *mmc; /* MMC structure */
  2161. +
  2162. + spinlock_t lock; /* Mutex */
  2163. +
  2164. + int flags; /* Host attributes */
  2165. +#define ESDHC_USE_DMA (1<<0)
  2166. +
  2167. + unsigned int max_clk; /* Max possible freq (MHz) */
  2168. + unsigned int timeout_clk; /* Timeout freq (KHz) */
  2169. +
  2170. + unsigned int clock; /* Current clock (MHz) */
  2171. + unsigned short power; /* Current voltage */
  2172. + unsigned short bus_width; /* current bus width */
  2173. +
  2174. + struct mmc_request *mrq; /* Current request */
  2175. + struct mmc_command *cmd; /* Current command */
  2176. + struct mmc_data *data; /* Current data request */
  2177. +
  2178. + struct scatterlist *cur_sg; /* We're working on this */
  2179. + int num_sg; /* Entries left */
  2180. + int offset; /* Offset into current sg */
  2181. + int remain; /* Bytes left in current */
  2182. +
  2183. + char slot_descr[20]; /* Name for reservations */
  2184. +
  2185. + int card_insert;
  2186. +
  2187. + int irq; /* Device IRQ */
  2188. + unsigned long addr; /* Bus address */
  2189. + unsigned int size; /* IO size */
  2190. + void __iomem *ioaddr; /* Mapped address */
  2191. +
  2192. + struct tasklet_struct card_tasklet; /* Tasklet structures */
  2193. + struct tasklet_struct finish_tasklet;
  2194. +
  2195. + struct timer_list timer; /* Timer for timeouts */
  2196. + void *dma_tx_buf;
  2197. + dma_addr_t dma_tx_dmahandle;
  2198. +};
  2199. +
  2200. +struct esdhc_chip {
  2201. + struct platform_device *pdev;
  2202. +
  2203. + unsigned long quirks;
  2204. +
  2205. + int num_slots; /* Slots on controller */
  2206. + struct esdhc_host *hosts[0]; /* Pointers to hosts */
  2207. +};
  2208. +
  2209. +#endif