OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [sysdev/] [mv64x60_udbg.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * udbg serial input/output routines for the Marvell MV64x60 (Discovery).
3
 *
4
 * Author: Dale Farnsworth <dale@farnsworth.org>
5
 *
6
 * 2007 (c) MontaVista Software, Inc.  This file is licensed under
7
 * the terms of the GNU General Public License version 2.  This program
8
 * is licensed "as is" without any warranty of any kind, whether express
9
 * or implied.
10
 */
11
 
12
#include <asm/io.h>
13
#include <asm/prom.h>
14
#include <asm/udbg.h>
15
 
16
#include <sysdev/mv64x60.h>
17
 
18
#define MPSC_0_CR1_OFFSET       0x000c
19
 
20
#define MPSC_0_CR2_OFFSET       0x0010
21
#define MPSC_CHR_2_TCS          (1 << 9)
22
 
23
#define MPSC_0_CHR_10_OFFSET    0x0030
24
 
25
#define MPSC_INTR_CAUSE_OFF_0   0x0004
26
#define MPSC_INTR_CAUSE_OFF_1   0x000c
27
#define MPSC_INTR_CAUSE_RCC     (1<<6)
28
 
29
static void __iomem *mpsc_base;
30
static void __iomem *mpsc_intr_cause;
31
 
32
static void mv64x60_udbg_putc(char c)
33
{
34
        if (c == '\n')
35
                mv64x60_udbg_putc('\r');
36
 
37
        while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS)
38
                ;
39
        out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c);
40
        out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS);
41
}
42
 
43
static int mv64x60_udbg_testc(void)
44
{
45
        return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0;
46
}
47
 
48
static int mv64x60_udbg_getc(void)
49
{
50
        int cause = 0;
51
        int c;
52
 
53
        while (!mv64x60_udbg_testc())
54
                ;
55
 
56
        c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2);
57
        out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c);
58
        out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC);
59
        return c;
60
}
61
 
62
static int mv64x60_udbg_getc_poll(void)
63
{
64
        if (!mv64x60_udbg_testc())
65
                return -1;
66
 
67
        return mv64x60_udbg_getc();
68
}
69
 
70
static void mv64x60_udbg_init(void)
71
{
72
        struct device_node *np, *mpscintr, *stdout = NULL;
73
        const char *path;
74
        const phandle *ph;
75
        struct resource r[2];
76
        const int *block_index;
77
        int intr_cause_offset;
78
        int err;
79
 
80
        path = of_get_property(of_chosen, "linux,stdout-path", NULL);
81
        if (!path)
82
                return;
83
 
84
        stdout = of_find_node_by_path(path);
85
        if (!stdout)
86
                return;
87
 
88
        for (np = NULL;
89
             (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); )
90
                if (np == stdout)
91
                        break;
92
 
93
        of_node_put(stdout);
94
        if (!np)
95
                return;
96
 
97
        block_index = of_get_property(np, "block-index", NULL);
98
        if (!block_index)
99
                goto error;
100
 
101
        switch (*block_index) {
102
        case 0:
103
                intr_cause_offset = MPSC_INTR_CAUSE_OFF_0;
104
                break;
105
        case 1:
106
                intr_cause_offset = MPSC_INTR_CAUSE_OFF_1;
107
                break;
108
        default:
109
                goto error;
110
        }
111
 
112
        err = of_address_to_resource(np, 0, &r[0]);
113
        if (err)
114
                goto error;
115
 
116
        ph = of_get_property(np, "mpscintr", NULL);
117
        mpscintr = of_find_node_by_phandle(*ph);
118
        if (!mpscintr)
119
                goto error;
120
 
121
        err = of_address_to_resource(mpscintr, 0, &r[1]);
122
        of_node_put(mpscintr);
123
        if (err)
124
                goto error;
125
 
126
        of_node_put(np);
127
 
128
        mpsc_base = ioremap(r[0].start, r[0].end - r[0].start + 1);
129
        if (!mpsc_base)
130
                return;
131
 
132
        mpsc_intr_cause = ioremap(r[1].start, r[1].end - r[1].start + 1);
133
        if (!mpsc_intr_cause) {
134
                iounmap(mpsc_base);
135
                return;
136
        }
137
        mpsc_intr_cause += intr_cause_offset;
138
 
139
        udbg_putc = mv64x60_udbg_putc;
140
        udbg_getc = mv64x60_udbg_getc;
141
        udbg_getc_poll = mv64x60_udbg_getc_poll;
142
 
143
        return;
144
 
145
error:
146
        of_node_put(np);
147
}
148
 
149
void mv64x60_init_early(void)
150
{
151
        mv64x60_udbg_init();
152
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.