X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fboot%2Fsimple%2Fmv64x60_tty.c;h=de260eafdd31d7272cac9b8f9b28f93ff52156a9;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=b1cb21a16ff22da0e03e2574d6de9b8931158594;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c index b1cb21a16..de260eafd 100644 --- a/arch/ppc/boot/simple/mv64x60_tty.c +++ b/arch/ppc/boot/simple/mv64x60_tty.c @@ -1,17 +1,15 @@ /* * arch/ppc/boot/simple/mv64x60_tty.c - * + * * Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60. * Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA). * * Author: Mark A. Greer * - * Copyright 2001 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 2001 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. */ /* This code assumes that the data cache has been disabled (L1, L2, L3). */ @@ -21,7 +19,7 @@ #include #include #include -#include "../../../../drivers/serial/mpsc/mpsc_defs.h" +#include extern void udelay(long); static void stop_dma(int chan); @@ -34,7 +32,7 @@ mv64x60_in_le32(volatile unsigned *addr) unsigned ret; __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) : - "r" (addr), "m" (*addr)); + "r" (addr), "m" (*addr)); return ret; } @@ -42,16 +40,16 @@ inline void mv64x60_out_le32(volatile unsigned *addr, int val) { __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) : - "r" (val), "r" (addr)); + "r" (val), "r" (addr)); } #define MV64x60_REG_READ(offs) \ (mv64x60_in_le32((volatile uint *)(mv64x60_base + (offs)))) #define MV64x60_REG_WRITE(offs, d) \ - (mv64x60_out_le32((volatile uint *)(mv64x60_base + (offs)), (int)(d))) + (mv64x60_out_le32((volatile uint *)(mv64x60_base + (offs)), (int)(d))) -typedef struct { +struct sdma_regs { u32 sdc; u32 sdcm; u32 rx_desc; @@ -60,36 +58,38 @@ typedef struct { u32 tx_desc; u32 sctdp; u32 sftdp; -} sdma_regs_t; +}; -static sdma_regs_t sdma_regs[2]; +static struct sdma_regs sdma_regs[2]; #define SDMA_REGS_INIT(s, reg_base) { \ - (s)->sdc = (reg_base) + SDMA_SDC; \ - (s)->sdcm = (reg_base) + SDMA_SDCM; \ - (s)->rx_desc = (reg_base) + SDMA_RX_DESC; \ + (s)->sdc = (reg_base) + SDMA_SDC; \ + (s)->sdcm = (reg_base) + SDMA_SDCM; \ + (s)->rx_desc = (reg_base) + SDMA_RX_DESC; \ (s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR; \ - (s)->scrdp = (reg_base) + SDMA_SCRDP; \ - (s)->tx_desc = (reg_base) + SDMA_TX_DESC; \ - (s)->sctdp = (reg_base) + SDMA_SCTDP; \ - (s)->sftdp = (reg_base) + SDMA_SFTDP; \ + (s)->scrdp = (reg_base) + SDMA_SCRDP; \ + (s)->tx_desc = (reg_base) + SDMA_TX_DESC; \ + (s)->sctdp = (reg_base) + SDMA_SCTDP; \ + (s)->sftdp = (reg_base) + SDMA_SFTDP; \ } -typedef struct { - volatile u16 bufsize; - volatile u16 bytecnt; - volatile u32 cmd_stat; - volatile u32 next_desc_ptr; - volatile u32 buffer; -} mv64x60_rx_desc_t; - -typedef struct { - volatile u16 bytecnt; - volatile u16 shadow; - volatile u32 cmd_stat; - volatile u32 next_desc_ptr; - volatile u32 buffer; -} mv64x60_tx_desc_t; +static u32 mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET }; + +struct mv64x60_rx_desc { + u16 bufsize; + u16 bytecnt; + u32 cmd_stat; + u32 next_desc_ptr; + u32 buffer; +}; + +struct mv64x60_tx_desc { + u16 bytecnt; + u16 shadow; + u32 cmd_stat; + u32 next_desc_ptr; + u32 buffer; +}; #define MAX_RESET_WAIT 10000 #define MAX_TX_WAIT 10000 @@ -97,11 +97,11 @@ typedef struct { #define RX_NUM_DESC 2 #define TX_NUM_DESC 2 -#define RX_BUF_SIZE 16 -#define TX_BUF_SIZE 16 +#define RX_BUF_SIZE 32 +#define TX_BUF_SIZE 32 -static mv64x60_rx_desc_t rd[2][RX_NUM_DESC] __attribute__ ((aligned(32))); -static mv64x60_tx_desc_t td[2][TX_NUM_DESC] __attribute__ ((aligned(32))); +static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32))); +static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32))); static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32))); static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32))); @@ -115,34 +115,50 @@ static char chan_initialized[2] = { 0, 0 }; #define RX_INIT_RDP(rdp) { \ (rdp)->bufsize = 2; \ (rdp)->bytecnt = 0; \ - (rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | \ - SDMA_DESC_CMDSTAT_F | \ - SDMA_DESC_CMDSTAT_O; \ + (rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | \ + SDMA_DESC_CMDSTAT_O; \ } +#ifdef CONFIG_MV64360 +static u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { + { MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE }, + { MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE }, + { MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE }, + { MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE } +}; + +static u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = { + { MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE }, + { MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE }, + { MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE }, + { MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE } +}; + +static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 }; +#endif + unsigned long serial_init(int chan, void *ignored) { - u32 mpsc_base, mpsc_routing_base, sdma_base, brg_bcr, cdv; + u32 mpsc_routing_base, sdma_base, brg_bcr, cdv; int i; extern long mv64x60_console_baud; extern long mv64x60_mpsc_clk_src; extern long mv64x60_mpsc_clk_freq; - chan = (chan == 1); /* default to chan 0 if anything but 1 */ + chan = (chan == 1); /* default to chan 0 if anything but 1 */ - if (chan_initialized[chan]) return chan; + if (chan_initialized[chan]) + return chan; chan_initialized[chan] = 1; if (chan == 0) { - mpsc_base = MV64x60_MPSC_0_OFFSET; sdma_base = MV64x60_SDMA_0_OFFSET; brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR; SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET); } else { - mpsc_base = MV64x60_MPSC_1_OFFSET; sdma_base = MV64x60_SDMA_1_OFFSET; brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR; SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET); @@ -170,48 +186,79 @@ serial_init(int chan, void *ignored) td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0]; /* Set MPSC Routing */ - MV64x60_REG_WRITE(mpsc_routing_base + MPSC_MRR, 0x3ffffe38); + MV64x60_REG_WRITE(mpsc_routing_base + MPSC_MRR, 0x3ffffe38); + +#ifdef CONFIG_GT64260 + MV64x60_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); +#else /* Must be MV64360 or MV64460 */ + { + u32 enables, prot_bits, v; + + /* Set up comm unit to memory mapping windows */ + /* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */ + + enables = MV64x60_REG_READ(MV64360_CPU_BAR_ENABLE) & 0xf; + prot_bits = 0; -/* XXXX Not for 64360 XXXX*/ - MV64x60_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); + for (i=0; i= TX_NUM_DESC) cur_td[com_port] = 0; + if (++cur_td[com_port] >= TX_NUM_DESC) + cur_td[com_port] = 0; *(unchar *)(tdp->buffer ^ 7) = c; tdp->bytecnt = 1; @@ -279,7 +332,7 @@ serial_putc(unsigned long com_port, unsigned char c) unsigned char serial_getc(unsigned long com_port) { - mv64x60_rx_desc_t *rdp; + struct mv64x60_rx_desc *rdp; unchar c = '\0'; rdp = &rd[com_port][cur_rd[com_port]]; @@ -287,7 +340,8 @@ serial_getc(unsigned long com_port) if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) { c = *(unchar *)(rdp->buffer ^ 7); RX_INIT_RDP(rdp); - if (++cur_rd[com_port] >= RX_NUM_DESC) cur_rd[com_port] = 0; + if (++cur_rd[com_port] >= RX_NUM_DESC) + cur_rd[com_port] = 0; } return c; @@ -296,7 +350,7 @@ serial_getc(unsigned long com_port) int serial_tstc(unsigned long com_port) { - mv64x60_rx_desc_t *rdp; + struct mv64x60_rx_desc *rdp; int loop_count = 0; int rc = 0; @@ -304,15 +358,14 @@ serial_tstc(unsigned long com_port) /* Go thru rcv desc's until empty looking for one with data (no error)*/ while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) && - (loop_count++ < RX_NUM_DESC)) { + (loop_count++ < RX_NUM_DESC)) { /* If there was an error, reinit the desc & continue */ if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) { RX_INIT_RDP(rdp); - if (++cur_rd[com_port] >= RX_NUM_DESC) { + if (++cur_rd[com_port] >= RX_NUM_DESC) cur_rd[com_port] = 0; - } - rdp = (mv64x60_rx_desc_t *)rdp->next_desc_ptr; + rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr; } else { rc = 1;