cmd_pcmcia.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622
  1. /*
  2. * (C) Copyright 2000-2002
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. ********************************************************************
  24. *
  25. * Lots of code copied from:
  26. *
  27. * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
  28. * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
  29. *
  30. * "The ExCA standard specifies that socket controllers should provide
  31. * two IO and five memory windows per socket, which can be independently
  32. * configured and positioned in the host address space and mapped to
  33. * arbitrary segments of card address space. " - David A Hinds. 1999
  34. *
  35. * This controller does _not_ meet the ExCA standard.
  36. *
  37. * m8xx pcmcia controller brief info:
  38. * + 8 windows (attrib, mem, i/o)
  39. * + up to two slots (SLOT_A and SLOT_B)
  40. * + inputpins, outputpins, event and mask registers.
  41. * - no offset register. sigh.
  42. *
  43. * Because of the lacking offset register we must map the whole card.
  44. * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
  45. * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
  46. * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
  47. * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
  48. * They are maximum 64KByte each...
  49. */
  50. /* #define DEBUG 1 */
  51. /*
  52. * PCMCIA support
  53. */
  54. #include <common.h>
  55. #include <command.h>
  56. #include <config.h>
  57. #include <pcmcia.h>
  58. #if defined(CONFIG_8xx)
  59. #include <mpc8xx.h>
  60. #endif
  61. #if defined(CONFIG_LWMON)
  62. #include <i2c.h>
  63. #endif
  64. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
  65. ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
  66. int pcmcia_on (void);
  67. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  68. static int pcmcia_off (void);
  69. #endif
  70. #ifdef CONFIG_I82365
  71. extern int i82365_init (void);
  72. extern void i82365_exit (void);
  73. #else /* ! CONFIG_I82365 */
  74. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  75. static int hardware_disable(int slot);
  76. #endif
  77. static int hardware_enable (int slot);
  78. static int voltage_set(int slot, int vcc, int vpp);
  79. #ifndef CONFIG_I82365
  80. static u_int m8xx_get_graycode(u_int size);
  81. #endif /* CONFIG_I82365 */
  82. #if 0
  83. static u_int m8xx_get_speed(u_int ns, u_int is_io);
  84. #endif
  85. /* -------------------------------------------------------------------- */
  86. /* look up table for pgcrx registers */
  87. static u_int *pcmcia_pgcrx[2] = {
  88. &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
  89. &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
  90. };
  91. #define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
  92. #endif /* CONFIG_I82365 */
  93. #ifdef CONFIG_IDE_8xx_PCCARD
  94. static void print_funcid (int func);
  95. static void print_fixed (volatile uchar *p);
  96. static int identify (volatile uchar *p);
  97. static int check_ide_device (int slot);
  98. #endif /* CONFIG_IDE_8xx_PCCARD */
  99. const char *indent = "\t ";
  100. /* -------------------------------------------------------------------- */
  101. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  102. int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  103. {
  104. int rcode = 0;
  105. if (argc != 2) {
  106. printf ("Usage: pinit {on | off}\n");
  107. return 1;
  108. }
  109. if (strcmp(argv[1],"on") == 0) {
  110. rcode = pcmcia_on ();
  111. } else if (strcmp(argv[1],"off") == 0) {
  112. rcode = pcmcia_off ();
  113. } else {
  114. printf ("Usage: pinit {on | off}\n");
  115. return 1;
  116. }
  117. return rcode;
  118. }
  119. #endif /* CFG_CMD_PCMCIA */
  120. /* -------------------------------------------------------------------- */
  121. #ifdef CONFIG_I82365
  122. int pcmcia_on (void)
  123. {
  124. u_int rc;
  125. debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
  126. rc = i82365_init();
  127. if (rc == 0)
  128. {
  129. rc = check_ide_device(0);
  130. }
  131. return (rc);
  132. }
  133. #else
  134. #ifdef CONFIG_HMI10
  135. # define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
  136. #endif
  137. #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
  138. # define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
  139. #else
  140. # define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
  141. #endif
  142. int pcmcia_on (void)
  143. {
  144. int i;
  145. u_long reg, base;
  146. pcmcia_win_t *win;
  147. u_int slotbit;
  148. u_int rc, slot;
  149. debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
  150. /* intialize the fixed memory windows */
  151. win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
  152. base = CFG_PCMCIA_MEM_ADDR;
  153. if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
  154. printf ("Cannot set window size to 0x%08x\n",
  155. CFG_PCMCIA_MEM_SIZE);
  156. return (1);
  157. }
  158. slotbit = PCMCIA_SLOT_x;
  159. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  160. win->br = base;
  161. #if (PCMCIA_SOCKETS_NO == 2)
  162. if (i == 4) /* Another slot starting from win 4 */
  163. slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
  164. #endif
  165. switch (i) {
  166. #ifdef CONFIG_IDE_8xx_PCCARD
  167. case 4:
  168. #ifdef CONFIG_HMI10
  169. { /* map FRAM area */
  170. win->or = ( PCMCIA_BSIZE_256K
  171. | PCMCIA_PPS_8
  172. | PCMCIA_PRS_ATTR
  173. | slotbit
  174. | PCMCIA_PV
  175. | HMI10_FRAM_TIMING );
  176. break;
  177. }
  178. #endif
  179. case 0: { /* map attribute memory */
  180. win->or = ( PCMCIA_BSIZE_64M
  181. | PCMCIA_PPS_8
  182. | PCMCIA_PRS_ATTR
  183. | slotbit
  184. | PCMCIA_PV
  185. | CFG_PCMCIA_TIMING );
  186. break;
  187. }
  188. case 5:
  189. case 1: { /* map I/O window for data reg */
  190. win->or = ( PCMCIA_BSIZE_1K
  191. | PCMCIA_PPS_16
  192. | PCMCIA_PRS_IO
  193. | slotbit
  194. | PCMCIA_PV
  195. | CFG_PCMCIA_TIMING );
  196. break;
  197. }
  198. case 6:
  199. case 2: { /* map I/O window for cmd/ctrl reg block */
  200. win->or = ( PCMCIA_BSIZE_1K
  201. | PCMCIA_PPS_8
  202. | PCMCIA_PRS_IO
  203. | slotbit
  204. | PCMCIA_PV
  205. | CFG_PCMCIA_TIMING );
  206. break;
  207. }
  208. #endif /* CONFIG_IDE_8xx_PCCARD */
  209. #ifdef CONFIG_HMI10
  210. case 3: { /* map I/O window for 4xUART data/ctrl */
  211. win->br += 0x40000;
  212. win->or = ( PCMCIA_BSIZE_256K
  213. | PCMCIA_PPS_8
  214. | PCMCIA_PRS_IO
  215. | slotbit
  216. | PCMCIA_PV
  217. | CFG_PCMCIA_TIMING );
  218. break;
  219. }
  220. #endif /* CONFIG_HMI10 */
  221. default: /* set to not valid */
  222. win->or = 0;
  223. break;
  224. }
  225. debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
  226. i, win->br, win->or);
  227. base += CFG_PCMCIA_MEM_SIZE;
  228. ++win;
  229. }
  230. for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
  231. /* turn off voltage */
  232. if ((rc = voltage_set(slot, 0, 0)))
  233. continue;
  234. /* Enable external hardware */
  235. if ((rc = hardware_enable(slot)))
  236. continue;
  237. #ifdef CONFIG_IDE_8xx_PCCARD
  238. if ((rc = check_ide_device(i)))
  239. continue;
  240. #endif
  241. }
  242. return (rc);
  243. }
  244. #endif /* CONFIG_I82365 */
  245. /* -------------------------------------------------------------------- */
  246. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  247. #ifdef CONFIG_I82365
  248. static int pcmcia_off (void)
  249. {
  250. printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
  251. i82365_exit();
  252. return 0;
  253. }
  254. #else
  255. static int pcmcia_off (void)
  256. {
  257. int i;
  258. pcmcia_win_t *win;
  259. printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
  260. /* clear interrupt state, and disable interrupts */
  261. ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
  262. ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
  263. /* turn off interrupt and disable CxOE */
  264. PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
  265. /* turn off memory windows */
  266. win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
  267. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  268. /* disable memory window */
  269. win->or = 0;
  270. ++win;
  271. }
  272. /* turn off voltage */
  273. voltage_set(_slot_, 0, 0);
  274. /* disable external hardware */
  275. printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
  276. hardware_disable(_slot_);
  277. return 0;
  278. }
  279. #endif /* CONFIG_I82365 */
  280. #endif /* CFG_CMD_PCMCIA */
  281. /* -------------------------------------------------------------------- */
  282. #ifdef CONFIG_IDE_8xx_PCCARD
  283. #define MAX_TUPEL_SZ 512
  284. #define MAX_FEATURES 4
  285. int ide_devices_found;
  286. static int check_ide_device (int slot)
  287. {
  288. volatile uchar *ident = NULL;
  289. volatile uchar *feature_p[MAX_FEATURES];
  290. volatile uchar *p, *start, *addr;
  291. int n_features = 0;
  292. uchar func_id = ~0;
  293. uchar code, len;
  294. ushort config_base = 0;
  295. int found = 0;
  296. int i;
  297. addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
  298. CFG_PCMCIA_MEM_SIZE * (slot * 4));
  299. debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
  300. start = p = (volatile uchar *) addr;
  301. while ((p - start) < MAX_TUPEL_SZ) {
  302. code = *p; p += 2;
  303. if (code == 0xFF) { /* End of chain */
  304. break;
  305. }
  306. len = *p; p += 2;
  307. #if defined(DEBUG) && (DEBUG > 1)
  308. { volatile uchar *q = p;
  309. printf ("\nTuple code %02x length %d\n\tData:",
  310. code, len);
  311. for (i = 0; i < len; ++i) {
  312. printf (" %02x", *q);
  313. q+= 2;
  314. }
  315. }
  316. #endif /* DEBUG */
  317. switch (code) {
  318. case CISTPL_VERS_1:
  319. ident = p + 4;
  320. break;
  321. case CISTPL_FUNCID:
  322. /* Fix for broken SanDisk which may have 0x80 bit set */
  323. func_id = *p & 0x7F;
  324. break;
  325. case CISTPL_FUNCE:
  326. if (n_features < MAX_FEATURES)
  327. feature_p[n_features++] = p;
  328. break;
  329. case CISTPL_CONFIG:
  330. config_base = (*(p+6) << 8) + (*(p+4));
  331. debug ("\n## Config_base = %04x ###\n", config_base);
  332. default:
  333. break;
  334. }
  335. p += 2 * len;
  336. }
  337. found = identify (ident);
  338. if (func_id != ((uchar)~0)) {
  339. print_funcid (func_id);
  340. if (func_id == CISTPL_FUNCID_FIXED)
  341. found = 1;
  342. else
  343. return (1); /* no disk drive */
  344. }
  345. for (i=0; i<n_features; ++i) {
  346. print_fixed (feature_p[i]);
  347. }
  348. if (!found) {
  349. printf ("unknown card type\n");
  350. return (1);
  351. }
  352. ide_devices_found |= (1 << slot);
  353. /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
  354. *((uchar *)(addr + config_base)) = 1;
  355. return (0);
  356. }
  357. #endif /* CONFIG_IDE_8xx_PCCARD */
  358. /* -------------------------------------------------------------------- */
  359. /* -------------------------------------------------------------------- */
  360. /* board specific stuff: */
  361. /* voltage_set(), hardware_enable() and hardware_disable() */
  362. /* -------------------------------------------------------------------- */
  363. /* -------------------------------------------------------------------- */
  364. /* RPX Boards from Embedded Planet */
  365. /* -------------------------------------------------------------------- */
  366. #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  367. /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
  368. * SYPCR is write once only, therefore must the slowest memory be faster
  369. * than the bus monitor or we will get a machine check due to the bus timeout.
  370. */
  371. #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
  372. #undef PCMCIA_BMT_LIMIT
  373. #define PCMCIA_BMT_LIMIT (6*8)
  374. static int voltage_set(int slot, int vcc, int vpp)
  375. {
  376. u_long reg = 0;
  377. switch(vcc) {
  378. case 0: break;
  379. case 33: reg |= BCSR1_PCVCTL4; break;
  380. case 50: reg |= BCSR1_PCVCTL5; break;
  381. default: return 1;
  382. }
  383. switch(vpp) {
  384. case 0: break;
  385. case 33:
  386. case 50:
  387. if(vcc == vpp)
  388. reg |= BCSR1_PCVCTL6;
  389. else
  390. return 1;
  391. break;
  392. case 120:
  393. reg |= BCSR1_PCVCTL7;
  394. default: return 1;
  395. }
  396. if(vcc == 120)
  397. return 1;
  398. /* first, turn off all power */
  399. *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
  400. | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
  401. /* enable new powersettings */
  402. *((uint *)RPX_CSR_ADDR) |= reg;
  403. return 0;
  404. }
  405. #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
  406. static int hardware_enable (int slot)
  407. {
  408. return 0; /* No hardware to enable */
  409. }
  410. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  411. static int hardware_disable(int slot)
  412. {
  413. return 0; /* No hardware to disable */
  414. }
  415. #endif /* CFG_CMD_PCMCIA */
  416. #endif /* CONFIG_RPXCLASSIC */
  417. /* -------------------------------------------------------------------- */
  418. /* (F)ADS Boards from Motorola */
  419. /* -------------------------------------------------------------------- */
  420. #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
  421. #ifdef CONFIG_ADS
  422. #define PCMCIA_BOARD_MSG "ADS"
  423. #define PCMCIA_GLITCHY_CD /* My ADS board needs this */
  424. #else
  425. #define PCMCIA_BOARD_MSG "FADS"
  426. #endif
  427. static int voltage_set(int slot, int vcc, int vpp)
  428. {
  429. u_long reg = 0;
  430. switch(vpp) {
  431. case 0: reg = 0; break;
  432. case 50: reg = 1; break;
  433. case 120: reg = 2; break;
  434. default: return 1;
  435. }
  436. switch(vcc) {
  437. case 0: reg = 0; break;
  438. #ifdef CONFIG_ADS
  439. case 50: reg = BCSR1_PCCVCCON; break;
  440. #endif
  441. #ifdef CONFIG_FADS
  442. case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
  443. case 50: reg = BCSR1_PCCVCC1; break;
  444. #endif
  445. default: return 1;
  446. }
  447. /* first, turn off all power */
  448. #ifdef CONFIG_ADS
  449. *((uint *)BCSR1) |= BCSR1_PCCVCCON;
  450. #endif
  451. #ifdef CONFIG_FADS
  452. *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
  453. #endif
  454. *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
  455. /* enable new powersettings */
  456. #ifdef CONFIG_ADS
  457. *((uint *)BCSR1) &= ~reg;
  458. #endif
  459. #ifdef CONFIG_FADS
  460. *((uint *)BCSR1) |= reg;
  461. #endif
  462. *((uint *)BCSR1) |= reg << 20;
  463. return 0;
  464. }
  465. #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
  466. static int hardware_enable(int slot)
  467. {
  468. *((uint *)BCSR1) &= ~BCSR1_PCCEN;
  469. return 0;
  470. }
  471. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  472. static int hardware_disable(int slot)
  473. {
  474. *((uint *)BCSR1) &= ~BCSR1_PCCEN;
  475. return 0;
  476. }
  477. #endif /* CFG_CMD_PCMCIA */
  478. #endif /* (F)ADS */
  479. /* -------------------------------------------------------------------- */
  480. /* TQM8xxL Boards by TQ Components */
  481. /* SC8xx Boards by SinoVee Microsystems */
  482. /* -------------------------------------------------------------------- */
  483. #if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
  484. #if defined(CONFIG_TQM8xxL)
  485. #define PCMCIA_BOARD_MSG "TQM8xxL"
  486. #endif
  487. #if defined(CONFIG_SVM_SC8xx)
  488. #define PCMCIA_BOARD_MSG "SC8xx"
  489. #endif
  490. static int hardware_enable(int slot)
  491. {
  492. volatile immap_t *immap;
  493. volatile cpm8xx_t *cp;
  494. volatile pcmconf8xx_t *pcmp;
  495. volatile sysconf8xx_t *sysp;
  496. uint reg, mask;
  497. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  498. udelay(10000);
  499. immap = (immap_t *)CFG_IMMR;
  500. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  501. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  502. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  503. /*
  504. * Configure SIUMCR to enable PCMCIA port B
  505. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  506. */
  507. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  508. /* clear interrupt state, and disable interrupts */
  509. pcmp->pcmc_pscr = PCMCIA_MASK(slot);
  510. pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
  511. /*
  512. * Disable interrupts, DMA, and PCMCIA buffers
  513. * (isolate the interface) and assert RESET signal
  514. */
  515. debug ("Disable PCMCIA buffers and assert RESET\n");
  516. reg = 0;
  517. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  518. #ifndef NSCU_OE_INV
  519. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  520. #endif
  521. PCMCIA_PGCRX(slot) = reg;
  522. udelay(500);
  523. #ifndef CONFIG_HMI10
  524. #ifndef CONFIG_NSCU
  525. /*
  526. * Configure Port C pins for
  527. * 5 Volts Enable and 3 Volts enable
  528. */
  529. immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
  530. immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
  531. /* remove all power */
  532. immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
  533. #endif
  534. #else /* CONFIG_HMI10 */
  535. /*
  536. * Configure Port B pins for
  537. * 5 Volts Enable and 3 Volts enable
  538. */
  539. immap->im_cpm.cp_pbpar &= ~(0x00000300);
  540. /* remove all power */
  541. immap->im_cpm.cp_pbdat |= 0x00000300;
  542. #endif /* CONFIG_HMI10 */
  543. /*
  544. * Make sure there is a card in the slot, then configure the interface.
  545. */
  546. udelay(10000);
  547. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  548. __LINE__,__FUNCTION__,
  549. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  550. #ifndef CONFIG_HMI10
  551. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  552. #else
  553. if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
  554. #endif /* CONFIG_HMI10 */
  555. printf (" No Card found\n");
  556. return (1);
  557. }
  558. /*
  559. * Power On.
  560. */
  561. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  562. reg = pcmp->pcmc_pipr;
  563. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  564. reg,
  565. (reg&PCMCIA_VS1(slot))?"n":"ff",
  566. (reg&PCMCIA_VS2(slot))?"n":"ff");
  567. #ifndef CONFIG_NSCU
  568. if ((reg & mask) == mask) {
  569. #ifndef CONFIG_HMI10
  570. immap->im_ioport.iop_pcdat |= 0x0004;
  571. #else
  572. immap->im_cpm.cp_pbdat &= ~(0x0000100);
  573. #endif /* CONFIG_HMI10 */
  574. puts (" 5.0V card found: ");
  575. } else {
  576. #ifndef CONFIG_HMI10
  577. immap->im_ioport.iop_pcdat |= 0x0002;
  578. #else
  579. immap->im_cpm.cp_pbdat &= ~(0x0000200);
  580. #endif /* CONFIG_HMI10 */
  581. puts (" 3.3V card found: ");
  582. }
  583. #ifndef CONFIG_HMI10
  584. immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
  585. #else
  586. immap->im_cpm.cp_pbdir |= 0x00000300;
  587. #endif /* CONFIG_HMI10 */
  588. #else
  589. if ((reg & mask) == mask) {
  590. puts (" 5.0V card found: ");
  591. } else {
  592. puts (" 3.3V card found: ");
  593. }
  594. #endif
  595. #if 0
  596. /* VCC switch error flag, PCMCIA slot INPACK_ pin */
  597. cp->cp_pbdir &= ~(0x0020 | 0x0010);
  598. cp->cp_pbpar &= ~(0x0020 | 0x0010);
  599. udelay(500000);
  600. #endif
  601. udelay(1000);
  602. debug ("Enable PCMCIA buffers and stop RESET\n");
  603. reg = PCMCIA_PGCRX(slot);
  604. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  605. #ifndef NSCU_OE_INV
  606. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  607. #else
  608. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  609. #endif
  610. PCMCIA_PGCRX(slot) = reg;
  611. udelay(250000); /* some cards need >150 ms to come up :-( */
  612. debug ("# hardware_enable done\n");
  613. return (0);
  614. }
  615. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  616. static int hardware_disable(int slot)
  617. {
  618. volatile immap_t *immap;
  619. volatile pcmconf8xx_t *pcmp;
  620. u_long reg;
  621. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  622. immap = (immap_t *)CFG_IMMR;
  623. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  624. #ifndef CONFIG_HMI10
  625. #ifndef CONFIG_NSCU
  626. /* remove all power */
  627. immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
  628. #endif
  629. #else /* CONFIG_HMI10 */
  630. immap->im_cpm.cp_pbdat |= 0x00000300;
  631. #endif /* CONFIG_HMI10 */
  632. debug ("Disable PCMCIA buffers and assert RESET\n");
  633. reg = 0;
  634. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  635. #ifndef NSCU_OE_INV
  636. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  637. #endif
  638. PCMCIA_PGCRX(slot) = reg;
  639. udelay(10000);
  640. return (0);
  641. }
  642. #endif /* CFG_CMD_PCMCIA */
  643. #ifdef CONFIG_NSCU
  644. static int voltage_set(int slot, int vcc, int vpp)
  645. {
  646. return 0;
  647. }
  648. #else
  649. static int voltage_set(int slot, int vcc, int vpp)
  650. {
  651. volatile immap_t *immap;
  652. volatile pcmconf8xx_t *pcmp;
  653. u_long reg;
  654. debug ("voltage_set: "
  655. PCMCIA_BOARD_MSG
  656. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  657. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  658. immap = (immap_t *)CFG_IMMR;
  659. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  660. /*
  661. * Disable PCMCIA buffers (isolate the interface)
  662. * and assert RESET signal
  663. */
  664. debug ("Disable PCMCIA buffers and assert RESET\n");
  665. reg = PCMCIA_PGCRX(slot);
  666. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  667. #ifndef NSCU_OE_INV
  668. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  669. #else
  670. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  671. #endif
  672. PCMCIA_PGCRX(slot) = reg;
  673. udelay(500);
  674. #ifndef CONFIG_HMI10
  675. /*
  676. * Configure Port C pins for
  677. * 5 Volts Enable and 3 Volts enable,
  678. * Turn off all power
  679. */
  680. debug ("PCMCIA power OFF\n");
  681. immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
  682. immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
  683. immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
  684. reg = 0;
  685. switch(vcc) {
  686. case 0: break;
  687. case 33: reg |= 0x0002; break;
  688. case 50: reg |= 0x0004; break;
  689. default: goto done;
  690. }
  691. #else /* CONFIG_HMI10 */
  692. /*
  693. * Configure Port B pins for
  694. * 5 Volts Enable and 3 Volts enable,
  695. * Turn off all power
  696. */
  697. debug ("PCMCIA power OFF\n");
  698. immap->im_cpm.cp_pbpar &= ~(0x00000300);
  699. /* remove all power */
  700. immap->im_cpm.cp_pbdat |= 0x00000300;
  701. reg = 0;
  702. switch(vcc) {
  703. case 0: break;
  704. case 33: reg |= 0x00000200; break;
  705. case 50: reg |= 0x00000100; break;
  706. default: goto done;
  707. }
  708. #endif /* CONFIG_HMI10 */
  709. /* Checking supported voltages */
  710. debug ("PIPR: 0x%x --> %s\n",
  711. pcmp->pcmc_pipr,
  712. (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
  713. #ifndef CONFIG_HMI10
  714. immap->im_ioport.iop_pcdat |= reg;
  715. immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
  716. #else
  717. immap->im_cpm.cp_pbdat &= !reg;
  718. immap->im_cpm.cp_pbdir |= 0x00000300;
  719. #endif /* CONFIG_HMI10 */
  720. if (reg) {
  721. #ifndef CONFIG_HMI10
  722. debug ("PCMCIA powered at %sV\n",
  723. (reg&0x0004) ? "5.0" : "3.3");
  724. #else
  725. debug ("PCMCIA powered at %sV\n",
  726. (reg&0x00000200) ? "5.0" : "3.3");
  727. #endif /* CONFIG_HMI10 */
  728. } else {
  729. debug ("PCMCIA powered down\n");
  730. }
  731. done:
  732. debug ("Enable PCMCIA buffers and stop RESET\n");
  733. reg = PCMCIA_PGCRX(slot);
  734. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  735. #ifndef NSCU_OE_INV
  736. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  737. #else
  738. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  739. #endif
  740. PCMCIA_PGCRX(slot) = reg;
  741. udelay(500);
  742. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  743. slot+'A');
  744. return (0);
  745. }
  746. #endif
  747. #endif /* TQM8xxL */
  748. /* -------------------------------------------------------------------- */
  749. /* LWMON Board */
  750. /* -------------------------------------------------------------------- */
  751. #if defined(CONFIG_LWMON)
  752. #define PCMCIA_BOARD_MSG "LWMON"
  753. /* #define's for MAX1604 Power Switch */
  754. #define MAX1604_OP_SUS 0x80
  755. #define MAX1604_VCCBON 0x40
  756. #define MAX1604_VCC_35 0x20
  757. #define MAX1604_VCCBHIZ 0x10
  758. #define MAX1604_VPPBON 0x08
  759. #define MAX1604_VPPBPBPGM 0x04
  760. #define MAX1604_VPPBHIZ 0x02
  761. /* reserved 0x01 */
  762. static int hardware_enable(int slot)
  763. {
  764. volatile immap_t *immap;
  765. volatile cpm8xx_t *cp;
  766. volatile pcmconf8xx_t *pcmp;
  767. volatile sysconf8xx_t *sysp;
  768. uint reg, mask;
  769. uchar val;
  770. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  771. /* Switch on PCMCIA port in PIC register 0x60 */
  772. reg = pic_read (0x60);
  773. debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
  774. reg &= ~0x10;
  775. /* reg |= 0x08; Vpp not needed */
  776. pic_write (0x60, reg);
  777. #ifdef DEBUG
  778. reg = pic_read (0x60);
  779. printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
  780. #endif
  781. udelay(10000);
  782. immap = (immap_t *)CFG_IMMR;
  783. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  784. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  785. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  786. /*
  787. * Configure SIUMCR to enable PCMCIA port B
  788. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  789. */
  790. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  791. /* clear interrupt state, and disable interrupts */
  792. pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
  793. pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
  794. /*
  795. * Disable interrupts, DMA, and PCMCIA buffers
  796. * (isolate the interface) and assert RESET signal
  797. */
  798. debug ("Disable PCMCIA buffers and assert RESET\n");
  799. reg = 0;
  800. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  801. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  802. PCMCIA_PGCRX(_slot_) = reg;
  803. udelay(500);
  804. /*
  805. * Make sure there is a card in the slot, then configure the interface.
  806. */
  807. udelay(10000);
  808. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  809. __LINE__,__FUNCTION__,
  810. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  811. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  812. printf (" No Card found\n");
  813. return (1);
  814. }
  815. /*
  816. * Power On.
  817. */
  818. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  819. reg = pcmp->pcmc_pipr;
  820. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  821. reg,
  822. (reg&PCMCIA_VS1(slot))?"n":"ff",
  823. (reg&PCMCIA_VS2(slot))?"n":"ff");
  824. if ((reg & mask) == mask) {
  825. val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
  826. puts (" 5.0V card found: ");
  827. } else {
  828. val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
  829. puts (" 3.3V card found: ");
  830. }
  831. /* switch VCC on */
  832. val |= MAX1604_OP_SUS | MAX1604_VCCBON;
  833. i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
  834. i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
  835. udelay(500000);
  836. debug ("Enable PCMCIA buffers and stop RESET\n");
  837. reg = PCMCIA_PGCRX(_slot_);
  838. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  839. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  840. PCMCIA_PGCRX(_slot_) = reg;
  841. udelay(250000); /* some cards need >150 ms to come up :-( */
  842. debug ("# hardware_enable done\n");
  843. return (0);
  844. }
  845. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  846. static int hardware_disable(int slot)
  847. {
  848. volatile immap_t *immap;
  849. volatile pcmconf8xx_t *pcmp;
  850. u_long reg;
  851. uchar val;
  852. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  853. immap = (immap_t *)CFG_IMMR;
  854. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  855. /* remove all power, put output in high impedance state */
  856. val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
  857. i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
  858. i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
  859. /* Configure PCMCIA General Control Register */
  860. debug ("Disable PCMCIA buffers and assert RESET\n");
  861. reg = 0;
  862. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  863. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  864. PCMCIA_PGCRX(_slot_) = reg;
  865. /* Switch off PCMCIA port in PIC register 0x60 */
  866. reg = pic_read (0x60);
  867. debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
  868. reg |= 0x10;
  869. reg &= ~0x08;
  870. pic_write (0x60, reg);
  871. #ifdef DEBUG
  872. reg = pic_read (0x60);
  873. printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
  874. #endif
  875. udelay(10000);
  876. return (0);
  877. }
  878. #endif /* CFG_CMD_PCMCIA */
  879. static int voltage_set(int slot, int vcc, int vpp)
  880. {
  881. volatile immap_t *immap;
  882. volatile pcmconf8xx_t *pcmp;
  883. u_long reg;
  884. uchar val;
  885. debug ("voltage_set: "
  886. PCMCIA_BOARD_MSG
  887. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  888. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  889. immap = (immap_t *)CFG_IMMR;
  890. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  891. /*
  892. * Disable PCMCIA buffers (isolate the interface)
  893. * and assert RESET signal
  894. */
  895. debug ("Disable PCMCIA buffers and assert RESET\n");
  896. reg = PCMCIA_PGCRX(_slot_);
  897. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  898. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  899. PCMCIA_PGCRX(_slot_) = reg;
  900. udelay(500);
  901. /*
  902. * Turn off all power (switch to high impedance)
  903. */
  904. debug ("PCMCIA power OFF\n");
  905. val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
  906. i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
  907. i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
  908. val = 0;
  909. switch(vcc) {
  910. case 0: break;
  911. case 33: val = MAX1604_VCC_35; break;
  912. case 50: break;
  913. default: goto done;
  914. }
  915. /* Checking supported voltages */
  916. debug ("PIPR: 0x%x --> %s\n",
  917. pcmp->pcmc_pipr,
  918. (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
  919. i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
  920. if (val) {
  921. debug ("PCMCIA powered at %sV\n",
  922. (val & MAX1604_VCC_35) ? "3.3" : "5.0");
  923. } else {
  924. debug ("PCMCIA powered down\n");
  925. }
  926. done:
  927. debug ("Enable PCMCIA buffers and stop RESET\n");
  928. reg = PCMCIA_PGCRX(_slot_);
  929. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  930. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  931. PCMCIA_PGCRX(_slot_) = reg;
  932. udelay(500);
  933. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  934. slot+'A');
  935. return (0);
  936. }
  937. #endif /* LWMON */
  938. /* -------------------------------------------------------------------- */
  939. /* GTH board by Corelatus AB */
  940. /* -------------------------------------------------------------------- */
  941. #if defined(CONFIG_GTH)
  942. #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
  943. static int voltage_set (int slot, int vcc, int vpp)
  944. { /* Do nothing */
  945. return 0;
  946. }
  947. static int hardware_enable (int slot)
  948. {
  949. volatile immap_t *immap;
  950. volatile cpm8xx_t *cp;
  951. volatile pcmconf8xx_t *pcmp;
  952. volatile sysconf8xx_t *sysp;
  953. uint reg, mask;
  954. debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
  955. immap = (immap_t *) CFG_IMMR;
  956. sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
  957. pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
  958. cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
  959. /* clear interrupt state, and disable interrupts */
  960. pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
  961. pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
  962. /*
  963. * Disable interrupts, DMA, and PCMCIA buffers
  964. * (isolate the interface) and assert RESET signal
  965. */
  966. debug ("Disable PCMCIA buffers and assert RESET\n");
  967. reg = 0;
  968. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  969. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  970. PCMCIA_PGCRX (_slot_) = reg;
  971. udelay (500);
  972. /*
  973. * Make sure there is a card in the slot,
  974. * then configure the interface.
  975. */
  976. udelay (10000);
  977. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  978. __LINE__, __FUNCTION__,
  979. &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
  980. if (pcmp->pcmc_pipr & 0x98000000) {
  981. printf (" No Card found\n");
  982. return (1);
  983. }
  984. mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
  985. reg = pcmp->pcmc_pipr;
  986. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  987. reg,
  988. (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
  989. (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
  990. debug ("Enable PCMCIA buffers and stop RESET\n");
  991. reg = PCMCIA_PGCRX (_slot_);
  992. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  993. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  994. PCMCIA_PGCRX (_slot_) = reg;
  995. udelay (250000); /* some cards need >150 ms to come up :-( */
  996. debug ("# hardware_enable done\n");
  997. return 0;
  998. }
  999. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1000. static int hardware_disable(int slot)
  1001. {
  1002. return 0; /* No hardware to disable */
  1003. }
  1004. #endif /* CFG_CMD_PCMCIA */
  1005. #endif /* CONFIG_GTH */
  1006. /* -------------------------------------------------------------------- */
  1007. /* ICU862 Boards by Cambridge Broadband Ltd. */
  1008. /* -------------------------------------------------------------------- */
  1009. #if defined(CONFIG_ICU862)
  1010. #define PCMCIA_BOARD_MSG "ICU862"
  1011. static void cfg_port_B (void);
  1012. static int hardware_enable(int slot)
  1013. {
  1014. volatile immap_t *immap;
  1015. volatile cpm8xx_t *cp;
  1016. volatile pcmconf8xx_t *pcmp;
  1017. volatile sysconf8xx_t *sysp;
  1018. uint reg, pipr, mask;
  1019. int i;
  1020. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1021. udelay(10000);
  1022. immap = (immap_t *)CFG_IMMR;
  1023. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  1024. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1025. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1026. /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
  1027. cfg_port_B ();
  1028. /*
  1029. * Configure SIUMCR to enable PCMCIA port B
  1030. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  1031. */
  1032. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  1033. /* clear interrupt state, and disable interrupts */
  1034. pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
  1035. pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
  1036. /*
  1037. * Disable interrupts, DMA, and PCMCIA buffers
  1038. * (isolate the interface) and assert RESET signal
  1039. */
  1040. debug ("Disable PCMCIA buffers and assert RESET\n");
  1041. reg = 0;
  1042. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1043. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1044. PCMCIA_PGCRX(_slot_) = reg;
  1045. udelay(500);
  1046. /*
  1047. * Make sure there is a card in the slot, then configure the interface.
  1048. */
  1049. udelay(10000);
  1050. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  1051. __LINE__,__FUNCTION__,
  1052. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  1053. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  1054. printf (" No Card found\n");
  1055. return (1);
  1056. }
  1057. /*
  1058. * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
  1059. */
  1060. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  1061. pipr = pcmp->pcmc_pipr;
  1062. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  1063. pipr,
  1064. (reg&PCMCIA_VS1(slot))?"n":"ff",
  1065. (reg&PCMCIA_VS2(slot))?"n":"ff");
  1066. reg = cp->cp_pbdat;
  1067. if ((pipr & mask) == mask) {
  1068. reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
  1069. TPS2205_VCC3); /* 3V off */
  1070. reg &= ~(TPS2205_VCC5); /* 5V on */
  1071. puts (" 5.0V card found: ");
  1072. } else {
  1073. reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
  1074. TPS2205_VCC5); /* 5V off */
  1075. reg &= ~(TPS2205_VCC3); /* 3V on */
  1076. puts (" 3.3V card found: ");
  1077. }
  1078. debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
  1079. reg,
  1080. (reg & TPS2205_VCC3) ? "off" : "on",
  1081. (reg & TPS2205_VCC5) ? "off" : "on",
  1082. (reg & TPS2205_VPP_PGM) ? "off" : "on",
  1083. (reg & TPS2205_VPP_VCC) ? "off" : "on" );
  1084. cp->cp_pbdat = reg;
  1085. /* Wait 500 ms; use this to check for over-current */
  1086. for (i=0; i<5000; ++i) {
  1087. if ((cp->cp_pbdat & TPS2205_OC) == 0) {
  1088. printf (" *** Overcurrent - Safety shutdown ***\n");
  1089. cp->cp_pbdat &= ~(TPS2205_SHDN);
  1090. return (1);
  1091. }
  1092. udelay (100);
  1093. }
  1094. debug ("Enable PCMCIA buffers and stop RESET\n");
  1095. reg = PCMCIA_PGCRX(_slot_);
  1096. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1097. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1098. PCMCIA_PGCRX(_slot_) = reg;
  1099. udelay(250000); /* some cards need >150 ms to come up :-( */
  1100. debug ("# hardware_enable done\n");
  1101. return (0);
  1102. }
  1103. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1104. static int hardware_disable(int slot)
  1105. {
  1106. volatile immap_t *immap;
  1107. volatile cpm8xx_t *cp;
  1108. volatile pcmconf8xx_t *pcmp;
  1109. u_long reg;
  1110. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1111. immap = (immap_t *)CFG_IMMR;
  1112. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1113. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1114. /* Shut down */
  1115. cp->cp_pbdat &= ~(TPS2205_SHDN);
  1116. /* Configure PCMCIA General Control Register */
  1117. debug ("Disable PCMCIA buffers and assert RESET\n");
  1118. reg = 0;
  1119. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1120. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1121. PCMCIA_PGCRX(_slot_) = reg;
  1122. udelay(10000);
  1123. return (0);
  1124. }
  1125. #endif /* CFG_CMD_PCMCIA */
  1126. static int voltage_set(int slot, int vcc, int vpp)
  1127. {
  1128. volatile immap_t *immap;
  1129. volatile cpm8xx_t *cp;
  1130. volatile pcmconf8xx_t *pcmp;
  1131. u_long reg;
  1132. debug ("voltage_set: "
  1133. PCMCIA_BOARD_MSG
  1134. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  1135. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  1136. immap = (immap_t *)CFG_IMMR;
  1137. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1138. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1139. /*
  1140. * Disable PCMCIA buffers (isolate the interface)
  1141. * and assert RESET signal
  1142. */
  1143. debug ("Disable PCMCIA buffers and assert RESET\n");
  1144. reg = PCMCIA_PGCRX(_slot_);
  1145. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1146. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1147. PCMCIA_PGCRX(_slot_) = reg;
  1148. udelay(500);
  1149. /*
  1150. * Configure Port C pins for
  1151. * 5 Volts Enable and 3 Volts enable,
  1152. * Turn all power pins to Hi-Z
  1153. */
  1154. debug ("PCMCIA power OFF\n");
  1155. cfg_port_B (); /* Enables switch, but all in Hi-Z */
  1156. reg = cp->cp_pbdat;
  1157. switch(vcc) {
  1158. case 0: break; /* Switch off */
  1159. case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
  1160. case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
  1161. default: goto done;
  1162. }
  1163. /* Checking supported voltages */
  1164. debug ("PIPR: 0x%x --> %s\n",
  1165. pcmp->pcmc_pipr,
  1166. (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
  1167. cp->cp_pbdat = reg;
  1168. #ifdef DEBUG
  1169. {
  1170. char *s;
  1171. if ((reg & TPS2205_VCC3) == 0) {
  1172. s = "at 3.3V";
  1173. } else if ((reg & TPS2205_VCC5) == 0) {
  1174. s = "at 5.0V";
  1175. } else {
  1176. s = "down";
  1177. }
  1178. printf ("PCMCIA powered %s\n", s);
  1179. }
  1180. #endif
  1181. done:
  1182. debug ("Enable PCMCIA buffers and stop RESET\n");
  1183. reg = PCMCIA_PGCRX(_slot_);
  1184. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1185. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1186. PCMCIA_PGCRX(_slot_) = reg;
  1187. udelay(500);
  1188. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  1189. slot+'A');
  1190. return (0);
  1191. }
  1192. static void cfg_port_B (void)
  1193. {
  1194. volatile immap_t *immap;
  1195. volatile cpm8xx_t *cp;
  1196. uint reg;
  1197. immap = (immap_t *)CFG_IMMR;
  1198. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1199. /*
  1200. * Configure Port B for TPS2205 PC-Card Power-Interface Switch
  1201. *
  1202. * Switch off all voltages, assert shutdown
  1203. */
  1204. reg = cp->cp_pbdat;
  1205. reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
  1206. TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
  1207. TPS2205_SHDN); /* enable switch */
  1208. cp->cp_pbdat = reg;
  1209. cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
  1210. reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
  1211. cp->cp_pbdir = reg | TPS2205_OUTPUTS;
  1212. debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
  1213. cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
  1214. }
  1215. #endif /* ICU862 */
  1216. /* -------------------------------------------------------------------- */
  1217. /* C2MON Boards by TTTech Computertechnik AG */
  1218. /* -------------------------------------------------------------------- */
  1219. #if defined(CONFIG_C2MON)
  1220. #define PCMCIA_BOARD_MSG "C2MON"
  1221. static void cfg_ports (void);
  1222. static int hardware_enable(int slot)
  1223. {
  1224. volatile immap_t *immap;
  1225. volatile cpm8xx_t *cp;
  1226. volatile pcmconf8xx_t *pcmp;
  1227. volatile sysconf8xx_t *sysp;
  1228. uint reg, pipr, mask;
  1229. ushort sreg;
  1230. int i;
  1231. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1232. udelay(10000);
  1233. immap = (immap_t *)CFG_IMMR;
  1234. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  1235. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1236. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1237. /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
  1238. cfg_ports ();
  1239. /*
  1240. * Configure SIUMCR to enable PCMCIA port B
  1241. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  1242. */
  1243. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  1244. /* clear interrupt state, and disable interrupts */
  1245. pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
  1246. pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
  1247. /*
  1248. * Disable interrupts, DMA, and PCMCIA buffers
  1249. * (isolate the interface) and assert RESET signal
  1250. */
  1251. debug ("Disable PCMCIA buffers and assert RESET\n");
  1252. reg = 0;
  1253. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1254. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1255. PCMCIA_PGCRX(_slot_) = reg;
  1256. udelay(500);
  1257. /*
  1258. * Make sure there is a card in the slot, then configure the interface.
  1259. */
  1260. udelay(10000);
  1261. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  1262. __LINE__,__FUNCTION__,
  1263. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  1264. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  1265. printf (" No Card found\n");
  1266. return (1);
  1267. }
  1268. /*
  1269. * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
  1270. */
  1271. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  1272. pipr = pcmp->pcmc_pipr;
  1273. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  1274. pipr,
  1275. (reg&PCMCIA_VS1(slot))?"n":"ff",
  1276. (reg&PCMCIA_VS2(slot))?"n":"ff");
  1277. sreg = immap->im_ioport.iop_pcdat;
  1278. if ((pipr & mask) == mask) {
  1279. sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
  1280. TPS2211_VCCD1); /* 5V on */
  1281. sreg &= ~(TPS2211_VCCD0); /* 3V off */
  1282. puts (" 5.0V card found: ");
  1283. } else {
  1284. sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
  1285. TPS2211_VCCD0); /* 3V on */
  1286. sreg &= ~(TPS2211_VCCD1); /* 5V off */
  1287. puts (" 3.3V card found: ");
  1288. }
  1289. debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
  1290. sreg,
  1291. ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
  1292. (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
  1293. );
  1294. immap->im_ioport.iop_pcdat = sreg;
  1295. /* Wait 500 ms; use this to check for over-current */
  1296. for (i=0; i<5000; ++i) {
  1297. if ((cp->cp_pbdat & TPS2211_OC) == 0) {
  1298. printf (" *** Overcurrent - Safety shutdown ***\n");
  1299. immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
  1300. return (1);
  1301. }
  1302. udelay (100);
  1303. }
  1304. debug ("Enable PCMCIA buffers and stop RESET\n");
  1305. reg = PCMCIA_PGCRX(_slot_);
  1306. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1307. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1308. PCMCIA_PGCRX(_slot_) = reg;
  1309. udelay(250000); /* some cards need >150 ms to come up :-( */
  1310. debug ("# hardware_enable done\n");
  1311. return (0);
  1312. }
  1313. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1314. static int hardware_disable(int slot)
  1315. {
  1316. volatile immap_t *immap;
  1317. volatile cpm8xx_t *cp;
  1318. volatile pcmconf8xx_t *pcmp;
  1319. u_long reg;
  1320. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1321. immap = (immap_t *)CFG_IMMR;
  1322. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1323. /* Configure PCMCIA General Control Register */
  1324. debug ("Disable PCMCIA buffers and assert RESET\n");
  1325. reg = 0;
  1326. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1327. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1328. PCMCIA_PGCRX(_slot_) = reg;
  1329. /* ALl voltages off / Hi-Z */
  1330. immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
  1331. TPS2211_VCCD0 | TPS2211_VCCD1 );
  1332. udelay(10000);
  1333. return (0);
  1334. }
  1335. #endif /* CFG_CMD_PCMCIA */
  1336. static int voltage_set(int slot, int vcc, int vpp)
  1337. {
  1338. volatile immap_t *immap;
  1339. volatile cpm8xx_t *cp;
  1340. volatile pcmconf8xx_t *pcmp;
  1341. u_long reg;
  1342. ushort sreg;
  1343. debug ("voltage_set: "
  1344. PCMCIA_BOARD_MSG
  1345. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  1346. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  1347. immap = (immap_t *)CFG_IMMR;
  1348. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1349. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1350. /*
  1351. * Disable PCMCIA buffers (isolate the interface)
  1352. * and assert RESET signal
  1353. */
  1354. debug ("Disable PCMCIA buffers and assert RESET\n");
  1355. reg = PCMCIA_PGCRX(_slot_);
  1356. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1357. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1358. PCMCIA_PGCRX(_slot_) = reg;
  1359. udelay(500);
  1360. /*
  1361. * Configure Port C pins for
  1362. * 5 Volts Enable and 3 Volts enable,
  1363. * Turn all power pins to Hi-Z
  1364. */
  1365. debug ("PCMCIA power OFF\n");
  1366. cfg_ports (); /* Enables switch, but all in Hi-Z */
  1367. sreg = immap->im_ioport.iop_pcdat;
  1368. sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
  1369. switch(vcc) {
  1370. case 0: break; /* Switch off */
  1371. case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
  1372. sreg &= ~TPS2211_VCCD1;
  1373. break;
  1374. case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
  1375. sreg |= TPS2211_VCCD1;
  1376. break;
  1377. default: goto done;
  1378. }
  1379. /* Checking supported voltages */
  1380. debug ("PIPR: 0x%x --> %s\n",
  1381. pcmp->pcmc_pipr,
  1382. (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
  1383. immap->im_ioport.iop_pcdat = sreg;
  1384. #ifdef DEBUG
  1385. {
  1386. char *s;
  1387. if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
  1388. s = "at 3.3V";
  1389. } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
  1390. s = "at 5.0V";
  1391. } else {
  1392. s = "down";
  1393. }
  1394. printf ("PCMCIA powered %s\n", s);
  1395. }
  1396. #endif
  1397. done:
  1398. debug ("Enable PCMCIA buffers and stop RESET\n");
  1399. reg = PCMCIA_PGCRX(_slot_);
  1400. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1401. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1402. PCMCIA_PGCRX(_slot_) = reg;
  1403. udelay(500);
  1404. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  1405. slot+'A');
  1406. return (0);
  1407. }
  1408. static void cfg_ports (void)
  1409. {
  1410. volatile immap_t *immap;
  1411. volatile cpm8xx_t *cp;
  1412. ushort sreg;
  1413. immap = (immap_t *)CFG_IMMR;
  1414. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1415. /*
  1416. * Configure Port C for TPS2211 PC-Card Power-Interface Switch
  1417. *
  1418. * Switch off all voltages, assert shutdown
  1419. */
  1420. sreg = immap->im_ioport.iop_pcdat;
  1421. sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
  1422. sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
  1423. immap->im_ioport.iop_pcdat = sreg;
  1424. immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
  1425. immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
  1426. debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
  1427. immap->im_ioport.iop_pcpar,
  1428. immap->im_ioport.iop_pcdir,
  1429. immap->im_ioport.iop_pcdat);
  1430. /*
  1431. * Configure Port B for TPS2211 PC-Card Power-Interface Switch
  1432. *
  1433. * Over-Current Input only
  1434. */
  1435. cp->cp_pbpar &= ~(TPS2211_INPUTS);
  1436. cp->cp_pbdir &= ~(TPS2211_INPUTS);
  1437. debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
  1438. cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
  1439. }
  1440. #endif /* C2MON */
  1441. /* -------------------------------------------------------------------- */
  1442. /* MBX board from Morotola */
  1443. /* -------------------------------------------------------------------- */
  1444. #if defined( CONFIG_MBX )
  1445. #include <../board/mbx8xx/csr.h>
  1446. /* A lot of this has been taken from the RPX code in this file it works from me.
  1447. I have added the voltage selection for the MBX board. */
  1448. /* MBX voltage bit in control register #2 */
  1449. #define CR2_VPP12 ((uchar)0x10)
  1450. #define CR2_VPPVDD ((uchar)0x20)
  1451. #define CR2_VDD5 ((uchar)0x40)
  1452. #define CR2_VDD3 ((uchar)0x80)
  1453. #define PCMCIA_BOARD_MSG "MBX860"
  1454. static int voltage_set (int slot, int vcc, int vpp)
  1455. {
  1456. uchar reg = 0;
  1457. debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  1458. 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
  1459. switch (vcc) {
  1460. case 0:
  1461. break;
  1462. case 33:
  1463. reg |= CR2_VDD3;
  1464. break;
  1465. case 50:
  1466. reg |= CR2_VDD5;
  1467. break;
  1468. default:
  1469. return 1;
  1470. }
  1471. switch (vpp) {
  1472. case 0:
  1473. break;
  1474. case 33:
  1475. case 50:
  1476. if (vcc == vpp) {
  1477. reg |= CR2_VPPVDD;
  1478. } else {
  1479. return 1;
  1480. }
  1481. break;
  1482. case 120:
  1483. reg |= CR2_VPP12;
  1484. break;
  1485. default:
  1486. return 1;
  1487. }
  1488. /* first, turn off all power */
  1489. MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
  1490. /* enable new powersettings */
  1491. MBX_CSR2 |= reg;
  1492. debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
  1493. return (0);
  1494. }
  1495. static int hardware_enable (int slot)
  1496. {
  1497. volatile immap_t *immap;
  1498. volatile cpm8xx_t *cp;
  1499. volatile pcmconf8xx_t *pcmp;
  1500. volatile sysconf8xx_t *sysp;
  1501. uint reg, mask;
  1502. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
  1503. 'A' + slot);
  1504. udelay (10000);
  1505. immap = (immap_t *) CFG_IMMR;
  1506. sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
  1507. pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
  1508. cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
  1509. /* clear interrupt state, and disable interrupts */
  1510. pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
  1511. pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
  1512. /*
  1513. * Disable interrupts, DMA, and PCMCIA buffers
  1514. * (isolate the interface) and assert RESET signal
  1515. */
  1516. debug ("Disable PCMCIA buffers and assert RESET\n");
  1517. reg = 0;
  1518. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1519. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1520. PCMCIA_PGCRX (_slot_) = reg;
  1521. udelay (500);
  1522. /* remove all power */
  1523. voltage_set (slot, 0, 0);
  1524. /*
  1525. * Make sure there is a card in the slot, then configure the interface.
  1526. */
  1527. udelay(10000);
  1528. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  1529. __LINE__,__FUNCTION__,
  1530. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  1531. #ifndef CONFIG_HMI10
  1532. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  1533. #else
  1534. if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
  1535. #endif /* CONFIG_HMI10 */
  1536. printf (" No Card found\n");
  1537. return (1);
  1538. }
  1539. /*
  1540. * Power On.
  1541. */
  1542. mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
  1543. reg = pcmp->pcmc_pipr;
  1544. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
  1545. (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
  1546. (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
  1547. if ((reg & mask) == mask) {
  1548. voltage_set (_slot_, 50, 0);
  1549. printf (" 5.0V card found: ");
  1550. } else {
  1551. voltage_set (_slot_, 33, 0);
  1552. printf (" 3.3V card found: ");
  1553. }
  1554. debug ("Enable PCMCIA buffers and stop RESET\n");
  1555. reg = PCMCIA_PGCRX (_slot_);
  1556. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1557. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1558. PCMCIA_PGCRX (_slot_) = reg;
  1559. udelay (250000); /* some cards need >150 ms to come up :-( */
  1560. debug ("# hardware_enable done\n");
  1561. return (0);
  1562. }
  1563. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1564. static int hardware_disable (int slot)
  1565. {
  1566. return 0; /* No hardware to disable */
  1567. }
  1568. #endif /* CFG_CMD_PCMCIA */
  1569. #endif /* CONFIG_MBX */
  1570. /* -------------------------------------------------------------------- */
  1571. /* R360MPI Board */
  1572. /* -------------------------------------------------------------------- */
  1573. #if defined(CONFIG_R360MPI)
  1574. #define PCMCIA_BOARD_MSG "R360MPI"
  1575. static int hardware_enable(int slot)
  1576. {
  1577. volatile immap_t *immap;
  1578. volatile cpm8xx_t *cp;
  1579. volatile pcmconf8xx_t *pcmp;
  1580. volatile sysconf8xx_t *sysp;
  1581. uint reg, mask;
  1582. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1583. udelay(10000);
  1584. immap = (immap_t *)CFG_IMMR;
  1585. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  1586. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1587. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1588. /*
  1589. * Configure SIUMCR to enable PCMCIA port B
  1590. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  1591. */
  1592. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  1593. /* clear interrupt state, and disable interrupts */
  1594. pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
  1595. pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
  1596. /*
  1597. * Disable interrupts, DMA, and PCMCIA buffers
  1598. * (isolate the interface) and assert RESET signal
  1599. */
  1600. debug ("Disable PCMCIA buffers and assert RESET\n");
  1601. reg = 0;
  1602. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1603. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1604. PCMCIA_PGCRX(_slot_) = reg;
  1605. udelay(500);
  1606. /*
  1607. * Configure Ports A, B & C pins for
  1608. * 5 Volts Enable and 3 Volts enable
  1609. */
  1610. immap->im_ioport.iop_pcpar &= ~(0x0400);
  1611. immap->im_ioport.iop_pcso &= ~(0x0400);/*
  1612. immap->im_ioport.iop_pcdir |= 0x0400;*/
  1613. immap->im_ioport.iop_papar &= ~(0x0200);/*
  1614. immap->im_ioport.iop_padir |= 0x0200;*/
  1615. #if 0
  1616. immap->im_ioport.iop_pbpar &= ~(0xC000);
  1617. immap->im_ioport.iop_pbdir &= ~(0xC000);
  1618. #endif
  1619. /* remove all power */
  1620. immap->im_ioport.iop_pcdat |= 0x0400;
  1621. immap->im_ioport.iop_padat |= 0x0200;
  1622. /*
  1623. * Make sure there is a card in the slot, then configure the interface.
  1624. */
  1625. udelay(10000);
  1626. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  1627. __LINE__,__FUNCTION__,
  1628. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  1629. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  1630. printf (" No Card found\n");
  1631. return (1);
  1632. }
  1633. /*
  1634. * Power On.
  1635. */
  1636. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  1637. reg = pcmp->pcmc_pipr;
  1638. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  1639. reg,
  1640. (reg&PCMCIA_VS1(slot))?"n":"ff",
  1641. (reg&PCMCIA_VS2(slot))?"n":"ff");
  1642. if ((reg & mask) == mask) {
  1643. immap->im_ioport.iop_pcdat &= ~(0x4000);
  1644. puts (" 5.0V card found: ");
  1645. } else {
  1646. immap->im_ioport.iop_padat &= ~(0x0002);
  1647. puts (" 3.3V card found: ");
  1648. }
  1649. immap->im_ioport.iop_pcdir |= 0x0400;
  1650. immap->im_ioport.iop_padir |= 0x0200;
  1651. #if 0
  1652. /* VCC switch error flag, PCMCIA slot INPACK_ pin */
  1653. cp->cp_pbdir &= ~(0x0020 | 0x0010);
  1654. cp->cp_pbpar &= ~(0x0020 | 0x0010);
  1655. udelay(500000);
  1656. #endif
  1657. debug ("Enable PCMCIA buffers and stop RESET\n");
  1658. reg = PCMCIA_PGCRX(_slot_);
  1659. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1660. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1661. PCMCIA_PGCRX(_slot_) = reg;
  1662. udelay(250000); /* some cards need >150 ms to come up :-( */
  1663. debug ("# hardware_enable done\n");
  1664. return (0);
  1665. }
  1666. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1667. static int hardware_disable(int slot)
  1668. {
  1669. volatile immap_t *immap;
  1670. volatile pcmconf8xx_t *pcmp;
  1671. u_long reg;
  1672. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1673. immap = (immap_t *)CFG_IMMR;
  1674. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1675. /* remove all power */
  1676. immap->im_ioport.iop_pcdat |= 0x0400;
  1677. immap->im_ioport.iop_padat |= 0x0200;
  1678. /* Configure PCMCIA General Control Register */
  1679. debug ("Disable PCMCIA buffers and assert RESET\n");
  1680. reg = 0;
  1681. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1682. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1683. PCMCIA_PGCRX(_slot_) = reg;
  1684. udelay(10000);
  1685. return (0);
  1686. }
  1687. #endif /* CFG_CMD_PCMCIA */
  1688. static int voltage_set(int slot, int vcc, int vpp)
  1689. {
  1690. volatile immap_t *immap;
  1691. volatile pcmconf8xx_t *pcmp;
  1692. u_long reg;
  1693. debug ("voltage_set: "
  1694. PCMCIA_BOARD_MSG
  1695. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  1696. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  1697. immap = (immap_t *)CFG_IMMR;
  1698. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1699. /*
  1700. * Disable PCMCIA buffers (isolate the interface)
  1701. * and assert RESET signal
  1702. */
  1703. debug ("Disable PCMCIA buffers and assert RESET\n");
  1704. reg = PCMCIA_PGCRX(_slot_);
  1705. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1706. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1707. PCMCIA_PGCRX(_slot_) = reg;
  1708. udelay(500);
  1709. /*
  1710. * Configure Ports A & C pins for
  1711. * 5 Volts Enable and 3 Volts enable,
  1712. * Turn off all power
  1713. */
  1714. debug ("PCMCIA power OFF\n");
  1715. immap->im_ioport.iop_pcpar &= ~(0x0400);
  1716. immap->im_ioport.iop_pcso &= ~(0x0400);/*
  1717. immap->im_ioport.iop_pcdir |= 0x0400;*/
  1718. immap->im_ioport.iop_papar &= ~(0x0200);/*
  1719. immap->im_ioport.iop_padir |= 0x0200;*/
  1720. immap->im_ioport.iop_pcdat |= 0x0400;
  1721. immap->im_ioport.iop_padat |= 0x0200;
  1722. reg = 0;
  1723. switch(vcc) {
  1724. case 0: break;
  1725. case 33: reg |= 0x0200; break;
  1726. case 50: reg |= 0x0400; break;
  1727. default: goto done;
  1728. }
  1729. /* Checking supported voltages */
  1730. debug ("PIPR: 0x%x --> %s\n",
  1731. pcmp->pcmc_pipr,
  1732. (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
  1733. if (reg & 0x0200)
  1734. immap->im_ioport.iop_pcdat &= !reg;
  1735. if (reg & 0x0400)
  1736. immap->im_ioport.iop_padat &= !reg;
  1737. immap->im_ioport.iop_pcdir |= 0x0200;
  1738. immap->im_ioport.iop_padir |= 0x0400;
  1739. if (reg) {
  1740. debug ("PCMCIA powered at %sV\n",
  1741. (reg&0x0400) ? "5.0" : "3.3");
  1742. } else {
  1743. debug ("PCMCIA powered down\n");
  1744. }
  1745. done:
  1746. debug ("Enable PCMCIA buffers and stop RESET\n");
  1747. reg = PCMCIA_PGCRX(_slot_);
  1748. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1749. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1750. PCMCIA_PGCRX(_slot_) = reg;
  1751. udelay(500);
  1752. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  1753. slot+'A');
  1754. return (0);
  1755. }
  1756. #endif /* R360MPI */
  1757. /* -------------------------------------------------------------------- */
  1758. /* KUP4K Board */
  1759. /* -------------------------------------------------------------------- */
  1760. #if defined(CONFIG_KUP4K)
  1761. #define PCMCIA_BOARD_MSG "KUP4K"
  1762. #define KUP4K_PCMCIA_B_3V3 (0x00020000)
  1763. static int hardware_enable(int slot)
  1764. {
  1765. volatile immap_t *immap;
  1766. volatile cpm8xx_t *cp;
  1767. volatile pcmconf8xx_t *pcmp;
  1768. volatile sysconf8xx_t *sysp;
  1769. uint reg, mask;
  1770. debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1771. udelay(10000);
  1772. immap = (immap_t *)CFG_IMMR;
  1773. sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
  1774. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1775. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1776. /*
  1777. * Configure SIUMCR to enable PCMCIA port B
  1778. * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  1779. */
  1780. sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
  1781. /* clear interrupt state, and disable interrupts */
  1782. pcmp->pcmc_pscr = PCMCIA_MASK(slot);
  1783. pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
  1784. /*
  1785. * Disable interrupts, DMA, and PCMCIA buffers
  1786. * (isolate the interface) and assert RESET signal
  1787. */
  1788. debug ("Disable PCMCIA buffers and assert RESET\n");
  1789. reg = 0;
  1790. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1791. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1792. PCMCIA_PGCRX(slot) = reg;
  1793. udelay(2500);
  1794. /*
  1795. * Configure Port B pins for
  1796. * 3 Volts enable
  1797. */
  1798. if (slot) { /* Slot A is built-in */
  1799. cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
  1800. cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
  1801. /* remove all power */
  1802. cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
  1803. }
  1804. /*
  1805. * Make sure there is a card in the slot, then configure the interface.
  1806. */
  1807. udelay(10000);
  1808. debug ("[%d] %s: PIPR(%p)=0x%x\n",
  1809. __LINE__,__FUNCTION__,
  1810. &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  1811. if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  1812. printf (" No Card found\n");
  1813. return (1);
  1814. }
  1815. /*
  1816. * Power On.
  1817. */
  1818. printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
  1819. mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  1820. reg = pcmp->pcmc_pipr;
  1821. debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  1822. reg,
  1823. (reg&PCMCIA_VS1(slot))?"n":"ff",
  1824. (reg&PCMCIA_VS2(slot))?"n":"ff");
  1825. if ((reg & mask) == mask) {
  1826. puts (" 5.0V card found: NOT SUPPORTED !!!\n");
  1827. } else {
  1828. if(slot)
  1829. cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
  1830. puts (" 3.3V card found: ");
  1831. }
  1832. #if 0
  1833. /* VCC switch error flag, PCMCIA slot INPACK_ pin */
  1834. cp->cp_pbdir &= ~(0x0020 | 0x0010);
  1835. cp->cp_pbpar &= ~(0x0020 | 0x0010);
  1836. udelay(500000);
  1837. #endif
  1838. debug ("Enable PCMCIA buffers and stop RESET\n");
  1839. reg = PCMCIA_PGCRX(slot);
  1840. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1841. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1842. PCMCIA_PGCRX(slot) = reg;
  1843. udelay(250000); /* some cards need >150 ms to come up :-( */
  1844. debug ("# hardware_enable done\n");
  1845. return (0);
  1846. }
  1847. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  1848. static int hardware_disable(int slot)
  1849. {
  1850. volatile immap_t *immap;
  1851. volatile cpm8xx_t *cp;
  1852. volatile pcmconf8xx_t *pcmp;
  1853. u_long reg;
  1854. debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  1855. immap = (immap_t *)CFG_IMMR;
  1856. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1857. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1858. /* remove all power */
  1859. if (slot)
  1860. cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
  1861. /* Configure PCMCIA General Control Register */
  1862. debug ("Disable PCMCIA buffers and assert RESET\n");
  1863. reg = 0;
  1864. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1865. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1866. PCMCIA_PGCRX(slot) = reg;
  1867. udelay(10000);
  1868. return (0);
  1869. }
  1870. #endif /* CFG_CMD_PCMCIA */
  1871. static int voltage_set(int slot, int vcc, int vpp)
  1872. {
  1873. volatile immap_t *immap;
  1874. volatile cpm8xx_t *cp;
  1875. volatile pcmconf8xx_t *pcmp;
  1876. u_long reg;
  1877. debug ("voltage_set: " \
  1878. PCMCIA_BOARD_MSG \
  1879. " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
  1880. 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
  1881. if (!slot) /* Slot A is not configurable */
  1882. return 0;
  1883. immap = (immap_t *)CFG_IMMR;
  1884. pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
  1885. cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
  1886. /*
  1887. * Disable PCMCIA buffers (isolate the interface)
  1888. * and assert RESET signal
  1889. */
  1890. debug ("Disable PCMCIA buffers and assert RESET\n");
  1891. reg = PCMCIA_PGCRX(slot);
  1892. reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
  1893. reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
  1894. PCMCIA_PGCRX(slot) = reg;
  1895. udelay(500);
  1896. debug ("PCMCIA power OFF\n");
  1897. /*
  1898. * Configure Port B pins for
  1899. * 3 Volts enable
  1900. */
  1901. cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
  1902. cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
  1903. /* remove all power */
  1904. cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
  1905. switch(vcc) {
  1906. case 0: break;
  1907. case 33:
  1908. cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
  1909. debug ("PCMCIA powered at 3.3V\n");
  1910. break;
  1911. case 50:
  1912. debug ("PCMCIA: 5Volt vcc not supported\n");
  1913. break;
  1914. default:
  1915. puts("PCMCIA: vcc not supported");
  1916. break;
  1917. }
  1918. udelay(10000);
  1919. /* Checking supported voltages */
  1920. debug ("PIPR: 0x%x --> %s\n",
  1921. pcmp->pcmc_pipr,
  1922. (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
  1923. ? "only 5 V --> NOT SUPPORTED"
  1924. : "can do 3.3V");
  1925. debug ("Enable PCMCIA buffers and stop RESET\n");
  1926. reg = PCMCIA_PGCRX(slot);
  1927. reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
  1928. reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
  1929. PCMCIA_PGCRX(slot) = reg;
  1930. udelay(500);
  1931. debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
  1932. slot+'A');
  1933. return (0);
  1934. }
  1935. #endif /* KUP4K */
  1936. /* -------------------------------------------------------------------- */
  1937. /* End of Board Specific Stuff */
  1938. /* -------------------------------------------------------------------- */
  1939. /* -------------------------------------------------------------------- */
  1940. /* MPC8xx Specific Stuff - should go to MPC8xx directory */
  1941. /* -------------------------------------------------------------------- */
  1942. /*
  1943. * Search this table to see if the windowsize is
  1944. * supported...
  1945. */
  1946. #define M8XX_SIZES_NO 32
  1947. static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
  1948. { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
  1949. 0x00000080, 0x00000040, 0x00000010, 0x00000020,
  1950. 0x00008000, 0x00004000, 0x00001000, 0x00002000,
  1951. 0x00000100, 0x00000200, 0x00000800, 0x00000400,
  1952. 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  1953. 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
  1954. 0x00010000, 0x00020000, 0x00080000, 0x00040000,
  1955. 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
  1956. /* -------------------------------------------------------------------- */
  1957. #ifndef CONFIG_I82365
  1958. static u_int m8xx_get_graycode(u_int size)
  1959. {
  1960. u_int k;
  1961. for (k = 0; k < M8XX_SIZES_NO; k++) {
  1962. if(m8xx_size_to_gray[k] == size)
  1963. break;
  1964. }
  1965. if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
  1966. k = -1;
  1967. return k;
  1968. }
  1969. #endif /* CONFIG_I82365 */
  1970. /* -------------------------------------------------------------------- */
  1971. #if 0
  1972. static u_int m8xx_get_speed(u_int ns, u_int is_io)
  1973. {
  1974. u_int reg, clocks, psst, psl, psht;
  1975. if(!ns) {
  1976. /*
  1977. * We get called with IO maps setup to 0ns
  1978. * if not specified by the user.
  1979. * They should be 255ns.
  1980. */
  1981. if(is_io)
  1982. ns = 255;
  1983. else
  1984. ns = 100; /* fast memory if 0 */
  1985. }
  1986. /*
  1987. * In PSST, PSL, PSHT fields we tell the controller
  1988. * timing parameters in CLKOUT clock cycles.
  1989. * CLKOUT is the same as GCLK2_50.
  1990. */
  1991. /* how we want to adjust the timing - in percent */
  1992. #define ADJ 180 /* 80 % longer accesstime - to be sure */
  1993. clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
  1994. clocks = (clocks * ADJ) / (100*1000);
  1995. if(clocks >= PCMCIA_BMT_LIMIT) {
  1996. DEBUG(0, "Max access time limit reached\n");
  1997. clocks = PCMCIA_BMT_LIMIT-1;
  1998. }
  1999. psst = clocks / 7; /* setup time */
  2000. psht = clocks / 7; /* hold time */
  2001. psl = (clocks * 5) / 7; /* strobe length */
  2002. psst += clocks - (psst + psht + psl);
  2003. reg = psst << 12;
  2004. reg |= psl << 7;
  2005. reg |= psht << 16;
  2006. return reg;
  2007. }
  2008. #endif
  2009. /* -------------------------------------------------------------------- */
  2010. #ifdef CONFIG_IDE_8xx_PCCARD
  2011. static void print_funcid (int func)
  2012. {
  2013. puts (indent);
  2014. switch (func) {
  2015. case CISTPL_FUNCID_MULTI:
  2016. puts (" Multi-Function");
  2017. break;
  2018. case CISTPL_FUNCID_MEMORY:
  2019. puts (" Memory");
  2020. break;
  2021. case CISTPL_FUNCID_SERIAL:
  2022. puts (" Serial Port");
  2023. break;
  2024. case CISTPL_FUNCID_PARALLEL:
  2025. puts (" Parallel Port");
  2026. break;
  2027. case CISTPL_FUNCID_FIXED:
  2028. puts (" Fixed Disk");
  2029. break;
  2030. case CISTPL_FUNCID_VIDEO:
  2031. puts (" Video Adapter");
  2032. break;
  2033. case CISTPL_FUNCID_NETWORK:
  2034. puts (" Network Adapter");
  2035. break;
  2036. case CISTPL_FUNCID_AIMS:
  2037. puts (" AIMS Card");
  2038. break;
  2039. case CISTPL_FUNCID_SCSI:
  2040. puts (" SCSI Adapter");
  2041. break;
  2042. default:
  2043. puts (" Unknown");
  2044. break;
  2045. }
  2046. puts (" Card\n");
  2047. }
  2048. #endif /* CONFIG_IDE_8xx_PCCARD */
  2049. /* -------------------------------------------------------------------- */
  2050. #ifdef CONFIG_IDE_8xx_PCCARD
  2051. static void print_fixed (volatile uchar *p)
  2052. {
  2053. if (p == NULL)
  2054. return;
  2055. puts(indent);
  2056. switch (*p) {
  2057. case CISTPL_FUNCE_IDE_IFACE:
  2058. { uchar iface = *(p+2);
  2059. puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
  2060. puts (" interface ");
  2061. break;
  2062. }
  2063. case CISTPL_FUNCE_IDE_MASTER:
  2064. case CISTPL_FUNCE_IDE_SLAVE:
  2065. { uchar f1 = *(p+2);
  2066. uchar f2 = *(p+4);
  2067. puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
  2068. if (f1 & CISTPL_IDE_UNIQUE)
  2069. puts (" [unique]");
  2070. puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
  2071. if (f2 & CISTPL_IDE_HAS_SLEEP)
  2072. puts (" [sleep]");
  2073. if (f2 & CISTPL_IDE_HAS_STANDBY)
  2074. puts (" [standby]");
  2075. if (f2 & CISTPL_IDE_HAS_IDLE)
  2076. puts (" [idle]");
  2077. if (f2 & CISTPL_IDE_LOW_POWER)
  2078. puts (" [low power]");
  2079. if (f2 & CISTPL_IDE_REG_INHIBIT)
  2080. puts (" [reg inhibit]");
  2081. if (f2 & CISTPL_IDE_HAS_INDEX)
  2082. puts (" [index]");
  2083. if (f2 & CISTPL_IDE_IOIS16)
  2084. puts (" [IOis16]");
  2085. break;
  2086. }
  2087. }
  2088. putc ('\n');
  2089. }
  2090. #endif /* CONFIG_IDE_8xx_PCCARD */
  2091. /* -------------------------------------------------------------------- */
  2092. #ifdef CONFIG_IDE_8xx_PCCARD
  2093. #define MAX_IDENT_CHARS 64
  2094. #define MAX_IDENT_FIELDS 4
  2095. static uchar *known_cards[] = {
  2096. "ARGOSY PnPIDE D5",
  2097. NULL
  2098. };
  2099. static int identify (volatile uchar *p)
  2100. {
  2101. uchar id_str[MAX_IDENT_CHARS];
  2102. uchar data;
  2103. uchar *t;
  2104. uchar **card;
  2105. int i, done;
  2106. if (p == NULL)
  2107. return (0); /* Don't know */
  2108. t = id_str;
  2109. done =0;
  2110. for (i=0; i<=4 && !done; ++i, p+=2) {
  2111. while ((data = *p) != '\0') {
  2112. if (data == 0xFF) {
  2113. done = 1;
  2114. break;
  2115. }
  2116. *t++ = data;
  2117. if (t == &id_str[MAX_IDENT_CHARS-1]) {
  2118. done = 1;
  2119. break;
  2120. }
  2121. p += 2;
  2122. }
  2123. if (!done)
  2124. *t++ = ' ';
  2125. }
  2126. *t = '\0';
  2127. while (--t > id_str) {
  2128. if (*t == ' ')
  2129. *t = '\0';
  2130. else
  2131. break;
  2132. }
  2133. puts (id_str);
  2134. putc ('\n');
  2135. for (card=known_cards; *card; ++card) {
  2136. debug ("## Compare against \"%s\"\n", *card);
  2137. if (strcmp(*card, id_str) == 0) { /* found! */
  2138. debug ("## CARD FOUND ##\n");
  2139. return (1);
  2140. }
  2141. }
  2142. return (0); /* don't know */
  2143. }
  2144. #endif /* CONFIG_IDE_8xx_PCCARD */
  2145. /* -------------------------------------------------------------------- */
  2146. #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
  2147. /**************************************************/
  2148. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  2149. U_BOOT_CMD(
  2150. pinit, 2, 1, do_pinit,
  2151. "pinit - PCMCIA sub-system\n",
  2152. "on - power on PCMCIA socket\n"
  2153. "pinit off - power off PCMCIA socket\n"
  2154. );
  2155. #endif