aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ddb5xxx/common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/ddb5xxx/common')
-rw-r--r--arch/mips/ddb5xxx/common/Makefile5
-rw-r--r--arch/mips/ddb5xxx/common/nile4.c130
-rw-r--r--arch/mips/ddb5xxx/common/prom.c142
-rw-r--r--arch/mips/ddb5xxx/common/rtc_ds1386.c164
4 files changed, 441 insertions, 0 deletions
diff --git a/arch/mips/ddb5xxx/common/Makefile b/arch/mips/ddb5xxx/common/Makefile
new file mode 100644
index 000000000000..bc44e3032711
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the common code of NEC DDB-Vrc5xxx board
3#
4
5obj-y += nile4.o prom.o rtc_ds1386.o
diff --git a/arch/mips/ddb5xxx/common/nile4.c b/arch/mips/ddb5xxx/common/nile4.c
new file mode 100644
index 000000000000..7ec7d903ba97
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/nile4.c
@@ -0,0 +1,130 @@
1/*
2 *
3 * Copyright 2001 MontaVista Software Inc.
4 * Author: jsun@mvista.com or jsun@junsun.net
5 *
6 * arch/mips/ddb5xxx/common/nile4.c
7 * misc low-level routines for vrc-5xxx controllers.
8 *
9 * derived from original code by Geert Uytterhoeven <geert@sonycom.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/types.h>
17#include <linux/kernel.h>
18
19#include <asm/ddb5xxx/ddb5xxx.h>
20
21u32
22ddb_calc_pdar(u32 phys, u32 size, int width,
23 int on_memory_bus, int pci_visible)
24{
25 u32 maskbits;
26 u32 widthbits;
27
28 switch (size) {
29#if 0 /* We don't support 4 GB yet */
30 case 0x100000000: /* 4 GB */
31 maskbits = 4;
32 break;
33#endif
34 case 0x80000000: /* 2 GB */
35 maskbits = 5;
36 break;
37 case 0x40000000: /* 1 GB */
38 maskbits = 6;
39 break;
40 case 0x20000000: /* 512 MB */
41 maskbits = 7;
42 break;
43 case 0x10000000: /* 256 MB */
44 maskbits = 8;
45 break;
46 case 0x08000000: /* 128 MB */
47 maskbits = 9;
48 break;
49 case 0x04000000: /* 64 MB */
50 maskbits = 10;
51 break;
52 case 0x02000000: /* 32 MB */
53 maskbits = 11;
54 break;
55 case 0x01000000: /* 16 MB */
56 maskbits = 12;
57 break;
58 case 0x00800000: /* 8 MB */
59 maskbits = 13;
60 break;
61 case 0x00400000: /* 4 MB */
62 maskbits = 14;
63 break;
64 case 0x00200000: /* 2 MB */
65 maskbits = 15;
66 break;
67 case 0: /* OFF */
68 maskbits = 0;
69 break;
70 default:
71 panic("nile4_set_pdar: unsupported size %p", (void *) size);
72 }
73 switch (width) {
74 case 8:
75 widthbits = 0;
76 break;
77 case 16:
78 widthbits = 1;
79 break;
80 case 32:
81 widthbits = 2;
82 break;
83 case 64:
84 widthbits = 3;
85 break;
86 default:
87 panic("nile4_set_pdar: unsupported width %d", width);
88 }
89
90 return maskbits | (on_memory_bus ? 0x10 : 0) |
91 (pci_visible ? 0x20 : 0) | (widthbits << 6) |
92 (phys & 0xffe00000);
93}
94
95void
96ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width,
97 int on_memory_bus, int pci_visible)
98{
99 u32 temp= ddb_calc_pdar(phys, size, width, on_memory_bus, pci_visible);
100 ddb_out32(pdar, temp);
101 ddb_out32(pdar + 4, 0);
102
103 /*
104 * When programming a PDAR, the register should be read immediately
105 * after writing it. This ensures that address decoders are properly
106 * configured.
107 * [jsun] is this really necessary?
108 */
109 ddb_in32(pdar);
110 ddb_in32(pdar + 4);
111}
112
113/*
114 * routines that mess with PCIINITx registers
115 */
116
117void ddb_set_pmr(u32 pmr, u32 type, u32 addr, u32 options)
118{
119 switch (type) {
120 case DDB_PCICMD_IACK: /* PCI Interrupt Acknowledge */
121 case DDB_PCICMD_IO: /* PCI I/O Space */
122 case DDB_PCICMD_MEM: /* PCI Memory Space */
123 case DDB_PCICMD_CFG: /* PCI Configuration Space */
124 break;
125 default:
126 panic("nile4_set_pmr: invalid type %d", type);
127 }
128 ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options );
129 ddb_out32(pmr + 4, 0);
130}
diff --git a/arch/mips/ddb5xxx/common/prom.c b/arch/mips/ddb5xxx/common/prom.c
new file mode 100644
index 000000000000..b8d1f7489f3b
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/prom.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10#include <linux/config.h>
11#include <linux/init.h>
12#include <linux/mm.h>
13#include <linux/sched.h>
14#include <linux/bootmem.h>
15
16#include <asm/addrspace.h>
17#include <asm/bootinfo.h>
18#include <asm/ddb5xxx/ddb5xxx.h>
19#include <asm/debug.h>
20
21const char *get_system_type(void)
22{
23 switch (mips_machtype) {
24 case MACH_NEC_DDB5074: return "NEC DDB Vrc-5074";
25 case MACH_NEC_DDB5476: return "NEC DDB Vrc-5476";
26 case MACH_NEC_DDB5477: return "NEC DDB Vrc-5477";
27 case MACH_NEC_ROCKHOPPER: return "NEC Rockhopper";
28 case MACH_NEC_ROCKHOPPERII: return "NEC RockhopperII";
29 default: return "Unknown NEC board";
30 }
31}
32
33#if defined(CONFIG_DDB5477)
34void ddb5477_runtime_detection(void);
35#endif
36
37/* [jsun@junsun.net] PMON passes arguments in C main() style */
38void __init prom_init(void)
39{
40 int argc = fw_arg0;
41 char **arg = (char**) fw_arg1;
42 int i;
43
44 /* if user passes kernel args, ignore the default one */
45 if (argc > 1)
46 arcs_cmdline[0] = '\0';
47
48 /* arg[0] is "g", the rest is boot parameters */
49 for (i = 1; i < argc; i++) {
50 if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
51 >= sizeof(arcs_cmdline))
52 break;
53 strcat(arcs_cmdline, arg[i]);
54 strcat(arcs_cmdline, " ");
55 }
56
57 mips_machgroup = MACH_GROUP_NEC_DDB;
58
59#if defined(CONFIG_DDB5074)
60 mips_machtype = MACH_NEC_DDB5074;
61 add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
62#elif defined(CONFIG_DDB5476)
63 mips_machtype = MACH_NEC_DDB5476;
64 add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
65#elif defined(CONFIG_DDB5477)
66 ddb5477_runtime_detection();
67 add_memory_region(0, board_ram_size, BOOT_MEM_RAM);
68#endif
69}
70
71unsigned long __init prom_free_prom_memory(void)
72{
73 return 0;
74}
75
76#if defined(CONFIG_DDB5477)
77
78#define DEFAULT_LCS1_BASE 0x19000000
79#define TESTVAL1 'K'
80#define TESTVAL2 'S'
81
82int board_ram_size;
83void ddb5477_runtime_detection(void)
84{
85 volatile char *test_offset;
86 char saved_test_byte;
87
88 /* Determine if this is a DDB5477 board, or a BSB-VR0300
89 base board. We can tell by checking for the location of
90 the NVRAM. It lives at the beginning of LCS1 on the DDB5477,
91 and the beginning of LCS1 on the BSB-VR0300 is flash memory.
92 The first 2K of the NVRAM are reserved, so don't we'll poke
93 around just after that.
94 */
95
96 /* We can only use the PCI bus to distinquish between
97 the Rockhopper and RockhopperII backplanes and this must
98 wait until ddb5477_board_init() in setup.c after the 5477
99 is initialized. So, until then handle
100 both Rockhopper and RockhopperII backplanes as Rockhopper 1
101 */
102
103 test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800);
104 saved_test_byte = *test_offset;
105
106 *test_offset = TESTVAL1;
107 if (*test_offset != TESTVAL1) {
108 /* We couldn't set our test value, so it must not be NVRAM,
109 so it's a BSB_VR0300 */
110 mips_machtype = MACH_NEC_ROCKHOPPER;
111 } else {
112 /* We may have gotten lucky, and the TESTVAL1 was already
113 stored at the test location, so we must check a second
114 test value */
115 *test_offset = TESTVAL2;
116 if (*test_offset != TESTVAL2) {
117 /* OK, we couldn't set this value either, so it must
118 definately be a BSB_VR0300 */
119 mips_machtype = MACH_NEC_ROCKHOPPER;
120 } else {
121 /* We could change the value twice, so it must be
122 NVRAM, so it's a DDB_VRC5477 */
123 mips_machtype = MACH_NEC_DDB5477;
124 }
125 }
126 /* Restore the original byte */
127 *test_offset = saved_test_byte;
128
129 /* before we know a better way, we will trust PMON for getting
130 * RAM size
131 */
132 board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf));
133
134 db_run(printk("DDB run-time detection : %s, %d MB RAM\n",
135 mips_machtype == MACH_NEC_DDB5477 ?
136 "DDB5477" : "Rockhopper",
137 board_ram_size >> 20));
138
139 /* we can't handle ram size > 128 MB */
140 db_assert(board_ram_size <= (128 << 20));
141}
142#endif
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
new file mode 100644
index 000000000000..f5b11508ff2f
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -0,0 +1,164 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * arch/mips/ddb5xxx/common/rtc_ds1386.c
6 * low-level RTC hookups for s for Dallas 1396 chip.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14
15/*
16 * This file exports a function, rtc_ds1386_init(), which expects an
17 * uncached base address as the argument. It will set the two function
18 * pointers expected by the MIPS generic timer code.
19 */
20
21#include <linux/types.h>
22#include <linux/time.h>
23#include <linux/bcd.h>
24
25#include <asm/time.h>
26#include <asm/addrspace.h>
27
28#include <asm/mc146818rtc.h>
29#include <asm/debug.h>
30
31#define EPOCH 2000
32
33#define READ_RTC(x) *(volatile unsigned char*)(rtc_base+x)
34#define WRITE_RTC(x, y) *(volatile unsigned char*)(rtc_base+x) = y
35
36static unsigned long rtc_base;
37
38static unsigned long
39rtc_ds1386_get_time(void)
40{
41 u8 byte;
42 u8 temp;
43 unsigned int year, month, day, hour, minute, second;
44
45 /* let us freeze external registers */
46 byte = READ_RTC(0xB);
47 byte &= 0x3f;
48 WRITE_RTC(0xB, byte);
49
50 /* read time data */
51 year = BCD2BIN(READ_RTC(0xA)) + EPOCH;
52 month = BCD2BIN(READ_RTC(0x9) & 0x1f);
53 day = BCD2BIN(READ_RTC(0x8));
54 minute = BCD2BIN(READ_RTC(0x2));
55 second = BCD2BIN(READ_RTC(0x1));
56
57 /* hour is special - deal with it later */
58 temp = READ_RTC(0x4);
59
60 /* enable time transfer */
61 byte |= 0x80;
62 WRITE_RTC(0xB, byte);
63
64 /* calc hour */
65 if (temp & 0x40) {
66 /* 12 hour format */
67 hour = BCD2BIN(temp & 0x1f);
68 if (temp & 0x20) hour += 12; /* PM */
69 } else {
70 /* 24 hour format */
71 hour = BCD2BIN(temp & 0x3f);
72 }
73
74 return mktime(year, month, day, hour, minute, second);
75}
76
77static int
78rtc_ds1386_set_time(unsigned long t)
79{
80 struct rtc_time tm;
81 u8 byte;
82 u8 temp;
83 u8 year, month, day, hour, minute, second;
84
85 /* let us freeze external registers */
86 byte = READ_RTC(0xB);
87 byte &= 0x3f;
88 WRITE_RTC(0xB, byte);
89
90 /* convert */
91 to_tm(t, &tm);
92
93
94 /* check each field one by one */
95 year = BIN2BCD(tm.tm_year - EPOCH);
96 if (year != READ_RTC(0xA)) {
97 WRITE_RTC(0xA, year);
98 }
99
100 temp = READ_RTC(0x9);
101 month = BIN2BCD(tm.tm_mon+1); /* tm_mon starts from 0 to 11 */
102 if (month != (temp & 0x1f)) {
103 WRITE_RTC( 0x9,
104 (month & 0x1f) | (temp & ~0x1f) );
105 }
106
107 day = BIN2BCD(tm.tm_mday);
108 if (day != READ_RTC(0x8)) {
109 WRITE_RTC(0x8, day);
110 }
111
112 temp = READ_RTC(0x4);
113 if (temp & 0x40) {
114 /* 12 hour format */
115 hour = 0x40;
116 if (tm.tm_hour > 12) {
117 hour |= 0x20 | (BIN2BCD(hour-12) & 0x1f);
118 } else {
119 hour |= BIN2BCD(tm.tm_hour);
120 }
121 } else {
122 /* 24 hour format */
123 hour = BIN2BCD(tm.tm_hour) & 0x3f;
124 }
125 if (hour != temp) WRITE_RTC(0x4, hour);
126
127 minute = BIN2BCD(tm.tm_min);
128 if (minute != READ_RTC(0x2)) {
129 WRITE_RTC(0x2, minute);
130 }
131
132 second = BIN2BCD(tm.tm_sec);
133 if (second != READ_RTC(0x1)) {
134 WRITE_RTC(0x1, second);
135 }
136
137 return 0;
138}
139
140void
141rtc_ds1386_init(unsigned long base)
142{
143 unsigned char byte;
144
145 /* remember the base */
146 rtc_base = base;
147 db_assert((rtc_base & 0xe0000000) == KSEG1);
148
149 /* turn on RTC if it is not on */
150 byte = READ_RTC(0x9);
151 if (byte & 0x80) {
152 byte &= 0x7f;
153 WRITE_RTC(0x9, byte);
154 }
155
156 /* enable time transfer */
157 byte = READ_RTC(0xB);
158 byte |= 0x80;
159 WRITE_RTC(0xB, byte);
160
161 /* set the function pointers */
162 rtc_get_time = rtc_ds1386_get_time;
163 rtc_set_time = rtc_ds1386_set_time;
164}