mpsc.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. /*
  2. * (C) Copyright 2001
  3. * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
  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. * changes for Marvell DB64460 eval board 2003 by Ingo Assmus <ingo.assmus@keymile.com>
  25. *
  26. ************************************************************************/
  27. /*
  28. * mpsc.c - driver for console over the MPSC.
  29. */
  30. #include <common.h>
  31. #include <config.h>
  32. #include <asm/cache.h>
  33. #include <malloc.h>
  34. #include "mpsc.h"
  35. #include "mv_regs.h"
  36. #include "../../Marvell/include/memory.h"
  37. DECLARE_GLOBAL_DATA_PTR;
  38. /* Define this if you wish to use the MPSC as a register based UART.
  39. * This will force the serial port to not use the SDMA engine at all.
  40. */
  41. #undef CONFIG_MPSC_DEBUG_PORT
  42. int (*mpsc_putchar) (char ch) = mpsc_putchar_early;
  43. char (*mpsc_getchar) (void) = mpsc_getchar_debug;
  44. int (*mpsc_test_char) (void) = mpsc_test_char_debug;
  45. static volatile unsigned int *rx_desc_base = NULL;
  46. static unsigned int rx_desc_index = 0;
  47. static volatile unsigned int *tx_desc_base = NULL;
  48. static unsigned int tx_desc_index = 0;
  49. /* local function declarations */
  50. static int galmpsc_connect (int channel, int connect);
  51. static int galmpsc_route_rx_clock (int channel, int brg);
  52. static int galmpsc_route_tx_clock (int channel, int brg);
  53. static int galmpsc_write_config_regs (int mpsc, int mode);
  54. static int galmpsc_config_channel_regs (int mpsc);
  55. static int galmpsc_set_char_length (int mpsc, int value);
  56. static int galmpsc_set_stop_bit_length (int mpsc, int value);
  57. static int galmpsc_set_parity (int mpsc, int value);
  58. static int galmpsc_enter_hunt (int mpsc);
  59. static int galmpsc_set_brkcnt (int mpsc, int value);
  60. static int galmpsc_set_tcschar (int mpsc, int value);
  61. static int galmpsc_set_snoop (int mpsc, int value);
  62. static int galmpsc_shutdown (int mpsc);
  63. static int galsdma_set_RFT (int channel);
  64. static int galsdma_set_SFM (int channel);
  65. static int galsdma_set_rxle (int channel);
  66. static int galsdma_set_txle (int channel);
  67. static int galsdma_set_burstsize (int channel, unsigned int value);
  68. static int galsdma_set_RC (int channel, unsigned int value);
  69. static int galbrg_set_CDV (int channel, int value);
  70. static int galbrg_enable (int channel);
  71. static int galbrg_disable (int channel);
  72. static int galbrg_set_clksrc (int channel, int value);
  73. static int galbrg_set_CUV (int channel, int value);
  74. static void galsdma_enable_rx (void);
  75. static int galsdma_set_mem_space (unsigned int memSpace,
  76. unsigned int memSpaceTarget,
  77. unsigned int memSpaceAttr,
  78. unsigned int baseAddress,
  79. unsigned int size);
  80. #define SOFTWARE_CACHE_MANAGEMENT
  81. #ifdef SOFTWARE_CACHE_MANAGEMENT
  82. #define FLUSH_DCACHE(a,b) if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}
  83. #define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));}
  84. #define INVALIDATE_DCACHE(a,b) if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));}
  85. #else
  86. #define FLUSH_DCACHE(a,b)
  87. #define FLUSH_AND_INVALIDATE_DCACHE(a,b)
  88. #define INVALIDATE_DCACHE(a,b)
  89. #endif
  90. #ifdef CONFIG_MPSC_DEBUG_PORT
  91. static void mpsc_debug_init (void)
  92. {
  93. volatile unsigned int temp;
  94. /* Clear the CFR (CHR4) */
  95. /* Write random 'Z' bit (bit 29) of CHR4 to enable debug uart *UNDOCUMENTED FEATURE* */
  96. temp = GTREGREAD (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP));
  97. temp &= 0xffffff00;
  98. temp |= BIT29;
  99. GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP),
  100. temp);
  101. /* Set the Valid bit 'V' (bit 12) and int generation bit 'INT' (bit 15) */
  102. temp = GTREGREAD (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP));
  103. temp |= (BIT12 | BIT15);
  104. GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP),
  105. temp);
  106. /* Set int mask */
  107. temp = GTREGREAD (GALMPSC_0_INT_MASK);
  108. temp |= BIT6;
  109. GT_REG_WRITE (GALMPSC_0_INT_MASK, temp);
  110. }
  111. #endif
  112. char mpsc_getchar_debug (void)
  113. {
  114. volatile int temp;
  115. volatile unsigned int cause;
  116. cause = GTREGREAD (GALMPSC_0_INT_CAUSE);
  117. while ((cause & BIT6) == 0) {
  118. cause = GTREGREAD (GALMPSC_0_INT_CAUSE);
  119. }
  120. temp = GTREGREAD (GALMPSC_CHANNELREG_10 +
  121. (CHANNEL * GALMPSC_REG_GAP));
  122. /* By writing 1's to the set bits, the register is cleared */
  123. GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (CHANNEL * GALMPSC_REG_GAP),
  124. temp);
  125. GT_REG_WRITE (GALMPSC_0_INT_CAUSE, cause & ~BIT6);
  126. return (temp >> 16) & 0xff;
  127. }
  128. /* special function for running out of flash. doesn't modify any
  129. * global variables [josh] */
  130. int mpsc_putchar_early (char ch)
  131. {
  132. int mpsc = CHANNEL;
  133. int temp =
  134. GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
  135. galmpsc_set_tcschar (mpsc, ch);
  136. GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP),
  137. temp | 0x200);
  138. #define MAGIC_FACTOR (10*1000000)
  139. udelay (MAGIC_FACTOR / gd->baudrate);
  140. return 0;
  141. }
  142. /* This is used after relocation, see serial.c and mpsc_init2 */
  143. static int mpsc_putchar_sdma (char ch)
  144. {
  145. volatile unsigned int *p;
  146. unsigned int temp;
  147. /* align the descriptor */
  148. p = tx_desc_base;
  149. memset ((void *) p, 0, 8 * sizeof (unsigned int));
  150. /* fill one 64 bit buffer */
  151. /* word swap, pad with 0 */
  152. p[4] = 0; /* x */
  153. p[5] = (unsigned int) ch; /* x */
  154. /* CHANGED completely according to GT64260A dox - NTL */
  155. p[0] = 0x00010001; /* 0 */
  156. p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* 4 */
  157. p[2] = 0; /* 8 */
  158. p[3] = (unsigned int) &p[4]; /* c */
  159. #if 0
  160. p[9] = DESC_FIRST | DESC_LAST;
  161. p[10] = (unsigned int) &p[0];
  162. p[11] = (unsigned int) &p[12];
  163. #endif
  164. FLUSH_DCACHE (&p[0], &p[8]);
  165. GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
  166. (unsigned int) &p[0]);
  167. GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
  168. (unsigned int) &p[0]);
  169. temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF));
  170. temp |= (TX_DEMAND | TX_STOP);
  171. GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp);
  172. INVALIDATE_DCACHE (&p[1], &p[2]);
  173. while (p[1] & DESC_OWNER_BIT) {
  174. udelay (100);
  175. INVALIDATE_DCACHE (&p[1], &p[2]);
  176. }
  177. return 0;
  178. }
  179. char mpsc_getchar_sdma (void)
  180. {
  181. static unsigned int done = 0;
  182. volatile char ch;
  183. unsigned int len = 0, idx = 0, temp;
  184. volatile unsigned int *p;
  185. do {
  186. p = &rx_desc_base[rx_desc_index * 8];
  187. INVALIDATE_DCACHE (&p[0], &p[1]);
  188. /* Wait for character */
  189. while (p[1] & DESC_OWNER_BIT) {
  190. udelay (100);
  191. INVALIDATE_DCACHE (&p[0], &p[1]);
  192. }
  193. /* Handle error case */
  194. if (p[1] & (1 << 15)) {
  195. printf ("oops, error: %08x\n", p[1]);
  196. temp = GTREGREAD (GALMPSC_CHANNELREG_2 +
  197. (CHANNEL * GALMPSC_REG_GAP));
  198. temp |= (1 << 23);
  199. GT_REG_WRITE (GALMPSC_CHANNELREG_2 +
  200. (CHANNEL * GALMPSC_REG_GAP), temp);
  201. /* Can't poll on abort bit, so we just wait. */
  202. udelay (100);
  203. galsdma_enable_rx ();
  204. }
  205. /* Number of bytes left in this descriptor */
  206. len = p[0] & 0xffff;
  207. if (len) {
  208. /* Where to look */
  209. idx = 5;
  210. if (done > 3)
  211. idx = 4;
  212. if (done > 7)
  213. idx = 7;
  214. if (done > 11)
  215. idx = 6;
  216. INVALIDATE_DCACHE (&p[idx], &p[idx + 1]);
  217. ch = p[idx] & 0xff;
  218. done++;
  219. }
  220. if (done < len) {
  221. /* this descriptor has more bytes still
  222. * shift down the char we just read, and leave the
  223. * buffer in place for the next time around
  224. */
  225. p[idx] = p[idx] >> 8;
  226. FLUSH_DCACHE (&p[idx], &p[idx + 1]);
  227. }
  228. if (done == len) {
  229. /* nothing left in this descriptor.
  230. * go to next one
  231. */
  232. p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST;
  233. p[0] = 0x00100000;
  234. FLUSH_DCACHE (&p[0], &p[1]);
  235. /* Next descriptor */
  236. rx_desc_index = (rx_desc_index + 1) % RX_DESC;
  237. done = 0;
  238. }
  239. } while (len == 0); /* galileo bug.. len might be zero */
  240. return ch;
  241. }
  242. int mpsc_test_char_debug (void)
  243. {
  244. if ((GTREGREAD (GALMPSC_0_INT_CAUSE) & BIT6) == 0)
  245. return 0;
  246. else {
  247. return 1;
  248. }
  249. }
  250. int mpsc_test_char_sdma (void)
  251. {
  252. volatile unsigned int *p = &rx_desc_base[rx_desc_index * 8];
  253. INVALIDATE_DCACHE (&p[1], &p[2]);
  254. if (p[1] & DESC_OWNER_BIT)
  255. return 0;
  256. else
  257. return 1;
  258. }
  259. int mpsc_init (int baud)
  260. {
  261. /* BRG CONFIG */
  262. galbrg_set_baudrate (CHANNEL, baud);
  263. galbrg_set_clksrc (CHANNEL, 8); /* set source=Tclk */
  264. galbrg_set_CUV (CHANNEL, 0); /* set up CountUpValue */
  265. galbrg_enable (CHANNEL); /* Enable BRG */
  266. /* Set up clock routing */
  267. galmpsc_connect (CHANNEL, GALMPSC_CONNECT); /* connect it */
  268. galmpsc_route_rx_clock (CHANNEL, CHANNEL); /* chosse BRG0 for Rx */
  269. galmpsc_route_tx_clock (CHANNEL, CHANNEL); /* chose BRG0 for Tx */
  270. /* reset MPSC state */
  271. galmpsc_shutdown (CHANNEL);
  272. /* SDMA CONFIG */
  273. galsdma_set_burstsize (CHANNEL, L1_CACHE_BYTES / 8); /* in 64 bit words (8 bytes) */
  274. galsdma_set_txle (CHANNEL);
  275. galsdma_set_rxle (CHANNEL);
  276. galsdma_set_RC (CHANNEL, 0xf);
  277. galsdma_set_SFM (CHANNEL);
  278. galsdma_set_RFT (CHANNEL);
  279. /* MPSC CONFIG */
  280. galmpsc_write_config_regs (CHANNEL, GALMPSC_UART);
  281. galmpsc_config_channel_regs (CHANNEL);
  282. galmpsc_set_char_length (CHANNEL, GALMPSC_CHAR_LENGTH_8); /* 8 */
  283. galmpsc_set_parity (CHANNEL, GALMPSC_PARITY_NONE); /* N */
  284. galmpsc_set_stop_bit_length (CHANNEL, GALMPSC_STOP_BITS_1); /* 1 */
  285. #ifdef CONFIG_MPSC_DEBUG_PORT
  286. mpsc_debug_init ();
  287. #endif
  288. /* COMM_MPSC CONFIG */
  289. #ifdef SOFTWARE_CACHE_MANAGEMENT
  290. galmpsc_set_snoop (CHANNEL, 0); /* disable snoop */
  291. #else
  292. galmpsc_set_snoop (CHANNEL, 1); /* enable snoop */
  293. #endif
  294. return 0;
  295. }
  296. void mpsc_sdma_init (void)
  297. {
  298. /* Setup SDMA channel0 SDMA_CONFIG_REG*/
  299. GT_REG_WRITE (SDMA_CONFIG_REG (0), 0x000020ff);
  300. /* Enable MPSC-Window0 for DRAM Bank 0 */
  301. if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT,
  302. MV64460_SDMA_DRAM_CS_0_TARGET,
  303. 0,
  304. memoryGetBankBaseAddress(0),
  305. memoryGetBankSize(0)) != true)
  306. printf ("%s: SDMA_Window0 memory setup failed !!! \n",
  307. __FUNCTION__);
  308. /* Enable MPSC-Window1 for DRAM Bank 1 */
  309. if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_1_BIT,
  310. MV64460_SDMA_DRAM_CS_1_TARGET,
  311. 0,
  312. memoryGetBankBaseAddress(1),
  313. memoryGetBankSize(1)) != true)
  314. printf ("%s: SDMA_Window1 memory setup failed !!! \n",
  315. __FUNCTION__);
  316. /* Disable MPSC-Window2 */
  317. if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_2_BIT,
  318. MV64460_SDMA_DRAM_CS_2_TARGET,
  319. 0,
  320. memoryGetBankBaseAddress(2),
  321. memoryGetBankSize(2)) != true)
  322. printf ("%s: SDMA_Window2 memory setup failed !!! \n",
  323. __FUNCTION__);
  324. /* Disable MPSC-Window3 */
  325. if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_3_BIT,
  326. MV64460_SDMA_DRAM_CS_3_TARGET,
  327. 0,
  328. memoryGetBankBaseAddress(3),
  329. memoryGetBankSize(3)) != true)
  330. printf ("%s: SDMA_Window3 memory setup failed !!! \n",
  331. __FUNCTION__);
  332. /* Setup MPSC0 access mode Window0 full access */
  333. GT_SET_REG_BITS (MPSC0_ACCESS_PROTECTION_REG,
  334. (MV64460_SDMA_WIN_ACCESS_FULL <<
  335. (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2)));
  336. /* Setup MPSC1 access mode Window1 full access */
  337. GT_SET_REG_BITS (MPSC1_ACCESS_PROTECTION_REG,
  338. (MV64460_SDMA_WIN_ACCESS_FULL <<
  339. (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2)));
  340. /* Setup MPSC internal address space base address */
  341. GT_REG_WRITE (CUNIT_INTERNAL_SPACE_BASE_ADDR_REG, CONFIG_SYS_GT_REGS);
  342. /* no high address remap*/
  343. GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG0, 0x00);
  344. GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG1, 0x00);
  345. /* clear interrupt cause register for MPSC (fault register)*/
  346. GT_REG_WRITE (CUNIT_INTERRUPT_CAUSE_REG, 0x00);
  347. }
  348. void mpsc_init2 (void)
  349. {
  350. int i;
  351. #ifndef CONFIG_MPSC_DEBUG_PORT
  352. mpsc_putchar = mpsc_putchar_sdma;
  353. mpsc_getchar = mpsc_getchar_sdma;
  354. mpsc_test_char = mpsc_test_char_sdma;
  355. #endif
  356. /* RX descriptors */
  357. rx_desc_base = (unsigned int *) malloc (((RX_DESC + 1) * 8) *
  358. sizeof (unsigned int));
  359. /* align descriptors */
  360. rx_desc_base = (unsigned int *)
  361. (((unsigned int) rx_desc_base + 32) & 0xFFFFFFF0);
  362. rx_desc_index = 0;
  363. memset ((void *) rx_desc_base, 0,
  364. (RX_DESC * 8) * sizeof (unsigned int));
  365. for (i = 0; i < RX_DESC; i++) {
  366. rx_desc_base[i * 8 + 3] = (unsigned int) &rx_desc_base[i * 8 + 4]; /* Buffer */
  367. rx_desc_base[i * 8 + 2] = (unsigned int) &rx_desc_base[(i + 1) * 8]; /* Next descriptor */
  368. rx_desc_base[i * 8 + 1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* Command & control */
  369. rx_desc_base[i * 8] = 0x00100000;
  370. }
  371. rx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &rx_desc_base[0];
  372. FLUSH_DCACHE (&rx_desc_base[0], &rx_desc_base[RX_DESC * 8]);
  373. GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
  374. (unsigned int) &rx_desc_base[0]);
  375. /* TX descriptors */
  376. tx_desc_base = (unsigned int *) malloc (((TX_DESC + 1) * 8) *
  377. sizeof (unsigned int));
  378. /* align descriptors */
  379. tx_desc_base = (unsigned int *)
  380. (((unsigned int) tx_desc_base + 32) & 0xFFFFFFF0);
  381. tx_desc_index = -1;
  382. memset ((void *) tx_desc_base, 0,
  383. (TX_DESC * 8) * sizeof (unsigned int));
  384. for (i = 0; i < TX_DESC; i++) {
  385. tx_desc_base[i * 8 + 5] = (unsigned int) 0x23232323;
  386. tx_desc_base[i * 8 + 4] = (unsigned int) 0x23232323;
  387. tx_desc_base[i * 8 + 3] =
  388. (unsigned int) &tx_desc_base[i * 8 + 4];
  389. tx_desc_base[i * 8 + 2] =
  390. (unsigned int) &tx_desc_base[(i + 1) * 8];
  391. tx_desc_base[i * 8 + 1] =
  392. DESC_OWNER_BIT | DESC_FIRST | DESC_LAST;
  393. /* set sbytecnt and shadow byte cnt to 1 */
  394. tx_desc_base[i * 8] = 0x00010001;
  395. }
  396. tx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &tx_desc_base[0];
  397. FLUSH_DCACHE (&tx_desc_base[0], &tx_desc_base[TX_DESC * 8]);
  398. udelay (100);
  399. galsdma_enable_rx ();
  400. return;
  401. }
  402. int galbrg_set_baudrate (int channel, int rate)
  403. {
  404. int clock;
  405. galbrg_disable (channel); /*ok */
  406. #ifdef ZUMA_NTL
  407. /* from tclk */
  408. clock = (CONFIG_SYS_TCLK / (16 * rate)) - 1;
  409. #else
  410. clock = (CONFIG_SYS_TCLK / (16 * rate)) - 1;
  411. #endif
  412. galbrg_set_CDV (channel, clock); /* set timer Reg. for BRG */
  413. galbrg_enable (channel);
  414. gd->baudrate = rate;
  415. return 0;
  416. }
  417. /* ------------------------------------------------------------------ */
  418. /* Below are all the private functions that no one else needs */
  419. static int galbrg_set_CDV (int channel, int value)
  420. {
  421. unsigned int temp;
  422. temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
  423. temp &= 0xFFFF0000;
  424. temp |= (value & 0x0000FFFF);
  425. GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
  426. return 0;
  427. }
  428. static int galbrg_enable (int channel)
  429. {
  430. unsigned int temp;
  431. temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
  432. temp |= 0x00010000;
  433. GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
  434. return 0;
  435. }
  436. static int galbrg_disable (int channel)
  437. {
  438. unsigned int temp;
  439. temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
  440. temp &= 0xFFFEFFFF;
  441. GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
  442. return 0;
  443. }
  444. static int galbrg_set_clksrc (int channel, int value)
  445. {
  446. unsigned int temp;
  447. temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
  448. temp &= 0xFFC3FFFF; /* Bit 18 - 21 (MV 64260 18-22) */
  449. temp |= (value << 18);
  450. GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
  451. return 0;
  452. }
  453. static int galbrg_set_CUV (int channel, int value)
  454. {
  455. /* set CountUpValue */
  456. GT_REG_WRITE (GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value);
  457. return 0;
  458. }
  459. #if 0
  460. static int galbrg_reset (int channel)
  461. {
  462. unsigned int temp;
  463. temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
  464. temp |= 0x20000;
  465. GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
  466. return 0;
  467. }
  468. #endif
  469. static int galsdma_set_RFT (int channel)
  470. {
  471. unsigned int temp;
  472. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  473. temp |= 0x00000001;
  474. GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
  475. temp);
  476. return 0;
  477. }
  478. static int galsdma_set_SFM (int channel)
  479. {
  480. unsigned int temp;
  481. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  482. temp |= 0x00000002;
  483. GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
  484. temp);
  485. return 0;
  486. }
  487. static int galsdma_set_rxle (int channel)
  488. {
  489. unsigned int temp;
  490. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  491. temp |= 0x00000040;
  492. GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
  493. temp);
  494. return 0;
  495. }
  496. static int galsdma_set_txle (int channel)
  497. {
  498. unsigned int temp;
  499. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  500. temp |= 0x00000080;
  501. GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
  502. temp);
  503. return 0;
  504. }
  505. static int galsdma_set_RC (int channel, unsigned int value)
  506. {
  507. unsigned int temp;
  508. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  509. temp &= ~0x0000003c;
  510. temp |= (value << 2);
  511. GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
  512. temp);
  513. return 0;
  514. }
  515. static int galsdma_set_burstsize (int channel, unsigned int value)
  516. {
  517. unsigned int temp;
  518. temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
  519. temp &= 0xFFFFCFFF;
  520. switch (value) {
  521. case 8:
  522. GT_REG_WRITE (GALSDMA_0_CONF_REG +
  523. (channel * GALSDMA_REG_DIFF),
  524. (temp | (0x3 << 12)));
  525. break;
  526. case 4:
  527. GT_REG_WRITE (GALSDMA_0_CONF_REG +
  528. (channel * GALSDMA_REG_DIFF),
  529. (temp | (0x2 << 12)));
  530. break;
  531. case 2:
  532. GT_REG_WRITE (GALSDMA_0_CONF_REG +
  533. (channel * GALSDMA_REG_DIFF),
  534. (temp | (0x1 << 12)));
  535. break;
  536. case 1:
  537. GT_REG_WRITE (GALSDMA_0_CONF_REG +
  538. (channel * GALSDMA_REG_DIFF),
  539. (temp | (0x0 << 12)));
  540. break;
  541. default:
  542. return -1;
  543. break;
  544. }
  545. return 0;
  546. }
  547. static int galmpsc_connect (int channel, int connect)
  548. {
  549. unsigned int temp;
  550. temp = GTREGREAD (GALMPSC_ROUTING_REGISTER);
  551. if ((channel == 0) && connect)
  552. temp &= ~0x00000007;
  553. else if ((channel == 1) && connect)
  554. temp &= ~(0x00000007 << 6);
  555. else if ((channel == 0) && !connect)
  556. temp |= 0x00000007;
  557. else
  558. temp |= (0x00000007 << 6);
  559. /* Just in case... */
  560. temp &= 0x3fffffff;
  561. GT_REG_WRITE (GALMPSC_ROUTING_REGISTER, temp);
  562. return 0;
  563. }
  564. static int galmpsc_route_rx_clock (int channel, int brg)
  565. {
  566. unsigned int temp;
  567. temp = GTREGREAD (GALMPSC_RxC_ROUTE);
  568. if (channel == 0) {
  569. temp &= ~0x0000000F;
  570. temp |= brg;
  571. } else {
  572. temp &= ~0x00000F00;
  573. temp |= (brg << 8);
  574. }
  575. GT_REG_WRITE (GALMPSC_RxC_ROUTE, temp);
  576. return 0;
  577. }
  578. static int galmpsc_route_tx_clock (int channel, int brg)
  579. {
  580. unsigned int temp;
  581. temp = GTREGREAD (GALMPSC_TxC_ROUTE);
  582. if (channel == 0) {
  583. temp &= ~0x0000000F;
  584. temp |= brg;
  585. } else {
  586. temp &= ~0x00000F00;
  587. temp |= (brg << 8);
  588. }
  589. GT_REG_WRITE (GALMPSC_TxC_ROUTE, temp);
  590. return 0;
  591. }
  592. static int galmpsc_write_config_regs (int mpsc, int mode)
  593. {
  594. if (mode == GALMPSC_UART) {
  595. /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */
  596. GT_REG_WRITE (GALMPSC_MCONF_LOW + (mpsc * GALMPSC_REG_GAP),
  597. 0x000004c4);
  598. /* Main config reg High (32x Rx/Tx clock mode, width=8bits */
  599. GT_REG_WRITE (GALMPSC_MCONF_HIGH + (mpsc * GALMPSC_REG_GAP),
  600. 0x024003f8);
  601. /* 22 2222 1111 */
  602. /* 54 3210 9876 */
  603. /* 0000 0010 0000 0000 */
  604. /* 1 */
  605. /* 098 7654 3210 */
  606. /* 0000 0011 1111 1000 */
  607. } else
  608. return -1;
  609. return 0;
  610. }
  611. static int galmpsc_config_channel_regs (int mpsc)
  612. {
  613. GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), 0);
  614. GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), 0);
  615. GT_REG_WRITE (GALMPSC_CHANNELREG_3 + (mpsc * GALMPSC_REG_GAP), 1);
  616. GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (mpsc * GALMPSC_REG_GAP), 0);
  617. GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (mpsc * GALMPSC_REG_GAP), 0);
  618. GT_REG_WRITE (GALMPSC_CHANNELREG_6 + (mpsc * GALMPSC_REG_GAP), 0);
  619. GT_REG_WRITE (GALMPSC_CHANNELREG_7 + (mpsc * GALMPSC_REG_GAP), 0);
  620. GT_REG_WRITE (GALMPSC_CHANNELREG_8 + (mpsc * GALMPSC_REG_GAP), 0);
  621. GT_REG_WRITE (GALMPSC_CHANNELREG_9 + (mpsc * GALMPSC_REG_GAP), 0);
  622. GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (mpsc * GALMPSC_REG_GAP), 0);
  623. galmpsc_set_brkcnt (mpsc, 0x3);
  624. galmpsc_set_tcschar (mpsc, 0xab);
  625. return 0;
  626. }
  627. static int galmpsc_set_brkcnt (int mpsc, int value)
  628. {
  629. unsigned int temp;
  630. temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP));
  631. temp &= 0x0000FFFF;
  632. temp |= (value << 16);
  633. GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp);
  634. return 0;
  635. }
  636. static int galmpsc_set_tcschar (int mpsc, int value)
  637. {
  638. unsigned int temp;
  639. temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP));
  640. temp &= 0xFFFF0000;
  641. temp |= value;
  642. GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp);
  643. return 0;
  644. }
  645. static int galmpsc_set_char_length (int mpsc, int value)
  646. {
  647. unsigned int temp;
  648. temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP));
  649. temp &= 0xFFFFCFFF;
  650. temp |= (value << 12);
  651. GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp);
  652. return 0;
  653. }
  654. static int galmpsc_set_stop_bit_length (int mpsc, int value)
  655. {
  656. unsigned int temp;
  657. temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP));
  658. temp &= 0xFFFFBFFF;
  659. temp |= (value << 14);
  660. GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp);
  661. return 0;
  662. }
  663. static int galmpsc_set_parity (int mpsc, int value)
  664. {
  665. unsigned int temp;
  666. temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
  667. if (value != -1) {
  668. temp &= 0xFFF3FFF3;
  669. temp |= ((value << 18) | (value << 2));
  670. temp |= ((value << 17) | (value << 1));
  671. } else {
  672. temp &= 0xFFF1FFF1;
  673. }
  674. GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
  675. return 0;
  676. }
  677. static int galmpsc_enter_hunt (int mpsc)
  678. {
  679. int temp;
  680. temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
  681. temp |= 0x80000000;
  682. GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
  683. while (GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)) &
  684. MPSC_ENTER_HUNT) {
  685. udelay (1);
  686. }
  687. return 0;
  688. }
  689. static int galmpsc_shutdown (int mpsc)
  690. {
  691. unsigned int temp;
  692. /* cause RX abort (clears RX) */
  693. temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
  694. temp |= MPSC_RX_ABORT | MPSC_TX_ABORT;
  695. temp &= ~MPSC_ENTER_HUNT;
  696. GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
  697. GT_REG_WRITE (GALSDMA_0_COM_REG, 0);
  698. GT_REG_WRITE (GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT);
  699. /* shut down the MPSC */
  700. GT_REG_WRITE (GALMPSC_MCONF_LOW, 0);
  701. GT_REG_WRITE (GALMPSC_MCONF_HIGH, 0);
  702. GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), 0);
  703. udelay (100);
  704. /* shut down the sdma engines. */
  705. /* reset config to default */
  706. GT_REG_WRITE (GALSDMA_0_CONF_REG, 0x000000fc);
  707. udelay (100);
  708. /* clear the SDMA current and first TX and RX pointers */
  709. GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR, 0);
  710. GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR, 0);
  711. GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR, 0);
  712. udelay (100);
  713. return 0;
  714. }
  715. static void galsdma_enable_rx (void)
  716. {
  717. int temp;
  718. /* Enable RX processing */
  719. temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF));
  720. temp |= RX_ENABLE;
  721. GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp);
  722. galmpsc_enter_hunt (CHANNEL);
  723. }
  724. static int galmpsc_set_snoop (int mpsc, int value)
  725. {
  726. int reg =
  727. mpsc ? MPSC_1_ADDRESS_CONTROL_LOW :
  728. MPSC_0_ADDRESS_CONTROL_LOW;
  729. int temp = GTREGREAD (reg);
  730. if (value)
  731. temp |= (1 << 6) | (1 << 14) | (1 << 22) | (1 << 30);
  732. else
  733. temp &= ~((1 << 6) | (1 << 14) | (1 << 22) | (1 << 30));
  734. GT_REG_WRITE (reg, temp);
  735. return 0;
  736. }
  737. /*******************************************************************************
  738. * galsdma_set_mem_space - Set MV64460 IDMA memory decoding map.
  739. *
  740. * DESCRIPTION:
  741. * the MV64460 SDMA has its own address decoding map that is de-coupled
  742. * from the CPU interface address decoding windows. The SDMA channels
  743. * share four address windows. Each region can be individually configured
  744. * by this function by associating it to a target interface and setting
  745. * base and size values.
  746. *
  747. * NOTE!!!
  748. * The size must be in 64Kbyte granularity.
  749. * The base address must be aligned to the size.
  750. * The size must be a series of 1s followed by a series of zeros
  751. *
  752. * OUTPUT:
  753. * None.
  754. *
  755. * RETURN:
  756. * True for success, false otherwise.
  757. *
  758. *******************************************************************************/
  759. static int galsdma_set_mem_space (unsigned int memSpace,
  760. unsigned int memSpaceTarget,
  761. unsigned int memSpaceAttr,
  762. unsigned int baseAddress, unsigned int size)
  763. {
  764. unsigned int temp;
  765. if (size == 0) {
  766. GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG,
  767. 1 << memSpace);
  768. return true;
  769. }
  770. /* The base address must be aligned to the size. */
  771. if (baseAddress % size != 0) {
  772. return false;
  773. }
  774. if (size < 0x10000) {
  775. return false;
  776. }
  777. /* Align size and base to 64K */
  778. baseAddress &= 0xffff0000;
  779. size &= 0xffff0000;
  780. temp = size >> 16;
  781. /* Checking that the size is a sequence of '1' followed by a
  782. sequence of '0' starting from LSB to MSB. */
  783. while ((temp > 0) && (temp & 0x1)) {
  784. temp = temp >> 1;
  785. }
  786. if (temp != 0) {
  787. GT_REG_WRITE (MV64460_CUNIT_BASE_ADDR_REG0 + memSpace * 8,
  788. (baseAddress | memSpaceTarget | memSpaceAttr));
  789. GT_REG_WRITE ((MV64460_CUNIT_SIZE0 + memSpace * 8),
  790. (size - 1) & 0xffff0000);
  791. GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG,
  792. 1 << memSpace);
  793. } else {
  794. /* An invalid size was specified */
  795. return false;
  796. }
  797. return true;
  798. }