-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mark A. Greer
authored and
Paul Mackerras
committed
May 12, 2007
1 parent
1aa3edb
commit ec04638
Showing
5 changed files
with
175 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 0f81b11d2a14adaa9b2c944f104e13d72fedc769 | ||
refs/heads/master: e12deb840ceed7051ab4799ae71b675a83c58c7c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* | ||
* MPSC/UART driver for the Marvell mv64360, mv64460, ... | ||
* | ||
* Author: Mark A. Greer <mgreer@mvista.com> | ||
* | ||
* 2007 (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. | ||
*/ | ||
|
||
#include <stdarg.h> | ||
#include <stddef.h> | ||
#include "types.h" | ||
#include "string.h" | ||
#include "stdio.h" | ||
#include "io.h" | ||
#include "ops.h" | ||
|
||
extern void udelay(long delay); | ||
|
||
#define MPSC_CHR_1 0x000c | ||
|
||
#define MPSC_CHR_2 0x0010 | ||
#define MPSC_CHR_2_TA (1<<7) | ||
#define MPSC_CHR_2_TCS (1<<9) | ||
#define MPSC_CHR_2_RA (1<<23) | ||
#define MPSC_CHR_2_CRD (1<<25) | ||
#define MPSC_CHR_2_EH (1<<31) | ||
|
||
#define MPSC_CHR_4 0x0018 | ||
#define MPSC_CHR_4_Z (1<<29) | ||
|
||
#define MPSC_CHR_5 0x001c | ||
#define MPSC_CHR_5_CTL1_INTR (1<<12) | ||
#define MPSC_CHR_5_CTL1_VALID (1<<15) | ||
|
||
#define MPSC_CHR_10 0x0030 | ||
|
||
#define MPSC_INTR_CAUSE 0x0000 | ||
#define MPSC_INTR_CAUSE_RCC (1<<6) | ||
#define MPSC_INTR_MASK 0x0080 | ||
|
||
#define SDMA_SDCM 0x0008 | ||
#define SDMA_SDCM_AR (1<<15) | ||
#define SDMA_SDCM_AT (1<<31) | ||
|
||
static volatile char *mpsc_base; | ||
static volatile char *mpscintr_base; | ||
static u32 chr1, chr2; | ||
|
||
static int mpsc_open(void) | ||
{ | ||
chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000; | ||
chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA | ||
| MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD | ||
| MPSC_CHR_2_EH); | ||
out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z); | ||
out_le32((u32 *)(mpsc_base + MPSC_CHR_5), | ||
MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID); | ||
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH); | ||
return 0; | ||
} | ||
|
||
static void mpsc_putc(unsigned char c) | ||
{ | ||
while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS); | ||
|
||
out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c); | ||
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS); | ||
} | ||
|
||
static unsigned char mpsc_getc(void) | ||
{ | ||
u32 cause = 0; | ||
unsigned char c; | ||
|
||
while (!(cause & MPSC_INTR_CAUSE_RCC)) | ||
cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE)); | ||
|
||
c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2)); | ||
out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c); | ||
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), | ||
cause & ~MPSC_INTR_CAUSE_RCC); | ||
|
||
return c; | ||
} | ||
|
||
static u8 mpsc_tstc(void) | ||
{ | ||
return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE)) | ||
& MPSC_INTR_CAUSE_RCC) != 0); | ||
} | ||
|
||
static void mpsc_stop_dma(volatile char *sdma_base) | ||
{ | ||
out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA); | ||
out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT); | ||
|
||
while ((in_le32((u32 *)(sdma_base + SDMA_SDCM)) | ||
& (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0) | ||
udelay(100); | ||
} | ||
|
||
static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop) | ||
{ | ||
void *v; | ||
int n; | ||
|
||
n = getprop(devp, prop, &v, sizeof(v)); | ||
if (n != sizeof(v)) | ||
goto err_out; | ||
|
||
devp = find_node_by_linuxphandle((u32)v); | ||
if (devp == NULL) | ||
goto err_out; | ||
|
||
n = getprop(devp, "virtual-reg", &v, sizeof(v)); | ||
if (n == sizeof(v)) | ||
return v; | ||
|
||
err_out: | ||
return NULL; | ||
} | ||
|
||
int mpsc_console_init(void *devp, struct serial_console_data *scdp) | ||
{ | ||
void *v; | ||
int n, reg_set; | ||
volatile char *sdma_base; | ||
|
||
n = getprop(devp, "virtual-reg", &v, sizeof(v)); | ||
if (n != sizeof(v)) | ||
goto err_out; | ||
mpsc_base = v; | ||
|
||
sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma"); | ||
if (sdma_base == NULL) | ||
goto err_out; | ||
|
||
mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr"); | ||
if (mpscintr_base == NULL) | ||
goto err_out; | ||
|
||
n = getprop(devp, "block-index", &v, sizeof(v)); | ||
if (n != sizeof(v)) | ||
goto err_out; | ||
reg_set = (int)v; | ||
|
||
mpscintr_base += (reg_set == 0) ? 0x4 : 0xc; | ||
|
||
/* Make sure the mpsc ctlrs are shutdown */ | ||
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0); | ||
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0); | ||
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0); | ||
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0); | ||
|
||
mpsc_stop_dma(sdma_base); | ||
|
||
scdp->open = mpsc_open; | ||
scdp->putc = mpsc_putc; | ||
scdp->getc = mpsc_getc; | ||
scdp->tstc = mpsc_tstc; | ||
scdp->close = NULL; | ||
|
||
return 0; | ||
|
||
err_out: | ||
return -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters