1 /*
2  * linux/arch/arm/mach-sa1100/system3.c
3  *
4  * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
5  *
6  * $Id: system3.c,v 1.1.6.1 2001/12/04 17:28:06 seletz Exp $
7  *
8  * This file contains all PT Sytsem 3 tweaks. Based on original work from
9  * Nicolas Pitre's assabet fixes
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  * $Log: system3.c,v $
16  * Revision 1.1.6.1  2001/12/04 17:28:06  seletz
17  * - merged from previous branch
18  *
19  * Revision 1.1.4.3  2001/12/04 15:16:31  seletz
20  * - merged from linux_2_4_13_ac5_rmk2
21  *
22  * Revision 1.1.4.2  2001/11/19 17:18:57  seletz
23  * - more code cleanups
24  *
25  * Revision 1.1.4.1  2001/11/16 13:52:05  seletz
26  * - PT Digital Board Support Code
27  *
28  * Revision 1.1.2.2  2001/11/05 16:46:18  seletz
29  * - cleanups
30  *
31  * Revision 1.1.2.1  2001/10/15 16:00:43  seletz
32  * - first revision working with new board
33  *
34  *
35  */
36 
37 #include <linux/config.h>
38 #include <linux/init.h>
39 #include <linux/kernel.h>
40 #include <linux/sched.h>
41 #include <linux/tty.h>
42 #include <linux/module.h>
43 #include <linux/errno.h>
44 #include <linux/cpufreq.h>
45 #include <linux/list.h>
46 #include <linux/timer.h>
47 
48 #include <asm/hardware.h>
49 #include <asm/setup.h>
50 #include <asm/page.h>
51 #include <asm/pgtable.h>
52 #include <asm/irq.h>
53 
54 #include <asm/mach/arch.h>
55 #include <asm/mach/map.h>
56 #include <asm/mach/irq.h>
57 #include <asm/mach/serial_sa1100.h>
58 
59 #include <asm/arch/irq.h>
60 
61 #include <linux/serial_core.h>
62 
63 #include "generic.h"
64 #include "sa1111.h"
65 
66 #define DEBUG 1
67 
68 #ifdef DEBUG
69 #	define DPRINTK( x, args... )	printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args  );
70 #else
71 #	define DPRINTK( x, args... )	/* nix */
72 #endif
73 
74 /**********************************************************************
75  *  prototypes
76  */
77 
78 /* init funcs */
79 static void __init fixup_system3(struct machine_desc *desc,
80 		struct param_struct *params, char **cmdline, struct meminfo *mi);
81 static void __init get_system3_scr(void);
82 static int __init system3_init(void);
83 static void __init system3_init_irq(void);
84 static void __init system3_map_io(void);
85 
86 static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
87 static int system3_get_mctrl(struct uart_port *port);
88 static void system3_set_mctrl(struct uart_port *port, u_int mctrl);
89 static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
90 static int sdram_notifier(struct notifier_block *nb, unsigned long event, void *data);
91 
92 extern void convert_to_tag_list(struct param_struct *params, int mem_init);
93 
94 
95 /**********************************************************************
96  *  global data
97  */
98 
99 /**********************************************************************
100  *  static data
101  */
102 
103 static struct map_desc system3_io_desc[] __initdata = {
104  /* virtual     physical    length      domain     r  w  c  b */
105   { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
106   { 0xf3000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
107   { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
108   LAST_DESC
109 };
110 
111 static struct sa1100_port_fns system3_port_fns __initdata = {
112 	.set_mctrl	= system3_set_mctrl,
113 	.get_mctrl	= system3_get_mctrl,
114 	.pm		= system3_uart_pm,
115 };
116 
117 static struct irqaction system3_irq = {
118 	.name		= "PT Digital Board SA1111 IRQ",
119 	.handler	= system3_IRQ_demux,
120 	.flags		= SA_INTERRUPT
121 };
122 
123 static struct notifier_block system3_clkchg_block = {
124 	.notifier_call	= sdram_notifier,
125 };
126 
127 /**********************************************************************
128  *  Static functions
129  */
130 
system3_map_io(void)131 static void __init system3_map_io(void)
132 {
133 	DPRINTK( "%s\n", "START" );
134 	sa1100_map_io();
135 	iotable_init(system3_io_desc);
136 
137 	sa1100_register_uart_fns(&system3_port_fns);
138 	sa1100_register_uart(0, 1);	/* com port */
139 	sa1100_register_uart(1, 2);
140 	sa1100_register_uart(2, 3);	/* radio module */
141 
142 	Ser1SDCR0 |= SDCR0_SUS;
143 }
144 
145 
146 /*********************************************************************
147  * Install IRQ handler
148  */
system3_IRQ_demux(int irq,void * dev_id,struct pt_regs * regs)149 static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
150 {
151 	u_char irr;
152 
153 	for(;;){
154 		//irr = PTCPLD_REG_IRQSR & (PT_IRQ_LAN | PT_IRQ_USAR | PT_IRQ_SA1111);
155 		irr = PT_IRQSR & (PT_IRQ_LAN | PT_IRQ_SA1111);
156 
157 		irr ^= (PT_IRQ_LAN);
158 		if (!irr) break;
159 
160 		if( irr & PT_IRQ_LAN )
161 			do_IRQ(IRQ_SYSTEM3_SMC9196, regs);
162 
163 #if 0
164 		/* Highspeed Serial Bus not yet used */
165 		if( irr & PT_IRQ_USAR )
166 			do_IRQ(PT_USAR_IRQ, regs);
167 #endif
168 
169 		if( irr & PT_IRQ_SA1111 )
170 			sa1111_IRQ_demux(irq, dev_id, regs);
171 	}
172 }
173 
174 
system3_init_irq(void)175 static void __init system3_init_irq(void)
176 {
177 	int irq;
178 
179 	DPRINTK( "%s\n", "START" );
180 
181 	/* SA1111 IRQ not routed to a GPIO. */
182 	sa1111_init_irq(-1);
183 
184 	/* setup extra IRQs */
185 	irq = IRQ_SYSTEM3_SMC9196;
186 	irq_desc[irq].valid	= 1;
187 	irq_desc[irq].probe_ok	= 1;
188 
189 #if 0
190 	/* Highspeed Serial Bus not yet used */
191 	irq = PT_USAR_IRQ;
192 	irq_desc[irq].valid	= 1;
193 	irq_desc[irq].probe_ok	= 1;
194 #endif
195 
196 	/* IRQ by CPLD */
197 	set_GPIO_IRQ_edge( GPIO_GPIO(25), GPIO_RISING_EDGE );
198 	setup_arm_irq( IRQ_GPIO25, &system3_irq );
199 }
200 
201 /**********************************************************************
202  * On system 3 limit cpu frequency to 206 Mhz
203  */
sdram_notifier(struct notifier_block * nb,unsigned long event,void * data)204 static int sdram_notifier(struct notifier_block *nb, unsigned long event,
205 		void *data)
206 {
207 	switch (event) {
208 		case CPUFREQ_MINMAX:
209 			cpufreq_updateminmax(data, 147500, 206000);
210 			break;
211 
212 	}
213 	return 0;
214 }
215 
216 /**
217  *	fixup_system3 - fixup function for system 3 board
218  *	@desc:		machine description
219  *	@param:		kernel params
220  *	@cmdline:	kernel cmdline
221  *	@mi:		memory info struct
222  *
223  */
fixup_system3(struct machine_desc * desc,struct param_struct * params,char ** cmdline,struct meminfo * mi)224 static void __init fixup_system3(struct machine_desc *desc,
225 		struct param_struct *params, char **cmdline, struct meminfo *mi)
226 {
227 	DPRINTK( "%s\n", "START" );
228 
229 	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
230 	setup_ramdisk( 1, 0, 0, 8192 );
231 	setup_initrd( 0xc0800000, 8*1024*1024 );
232 }
233 
234 
235 /**
236  *	system3_uart_pm - powermgmt callback function for system 3 UART
237  *	@port: uart port structure
238  *	@state: pm state
239  *	@oldstate: old pm state
240  *
241  */
system3_uart_pm(struct uart_port * port,u_int state,u_int oldstate)242 static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
243 {
244 	/* TODO: switch on/off uart in powersave mode */
245 }
246 
247 /*
248  * Note! this can be called from IRQ context.
249  * FIXME: Handle PT Digital Board CTRL regs irq-safe.
250  *
251  * NB: system3 uses COM_RTS and COM_DTR for both UART1 (com port)
252  * and UART3 (radio module).  We only handle them for UART1 here.
253  */
system3_set_mctrl(struct uart_port * port,u_int mctrl)254 static void system3_set_mctrl(struct uart_port *port, u_int mctrl)
255 {
256 	if (port->mapbase == _Ser1UTCR0) {
257 		u_int set = 0, clear = 0;
258 
259 		if (mctrl & TIOCM_RTS)
260 			set |= PT_CTRL2_RS1_RTS;
261 		else
262 			clear |= PT_CTRL2_RS1_RTS;
263 
264 		if (mctrl & TIOCM_DTR)
265 			set |= PT_CTRL2_RS1_DTR;
266 		else
267 			clear |= PT_CTRL2_RS1_DTR;
268 
269 		PTCTRL2_clear(clear);
270 		PTCTRL2_set(set);
271 	}
272 }
273 
system3_get_mctrl(struct uart_port * port)274 static int system3_get_mctrl(struct uart_port *port)
275 {
276 	u_int ret = 0;
277 	u_int irqsr = PT_IRQSR;
278 
279 	/* need 2 reads to read current value */
280 	irqsr = PT_IRQSR;
281 
282 	/* TODO: check IRQ source register for modem/com
283 	 status lines and set them correctly. */
284 
285 	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
286 
287 	return ret;
288 }
289 
system3_init(void)290 static int __init system3_init(void)
291 {
292 	int ret = 0;
293 	DPRINTK( "%s\n", "START" );
294 
295 	if ( !machine_is_pt_system3() ) {
296 		ret = -EINVAL;
297 		goto DONE;
298 	}
299 
300 	/* init control register */
301 	PT_CTRL0 = PT_CTRL0_INIT;
302 	PT_CTRL1 = 0x02;
303 	PT_CTRL2 = 0x00;
304 	DPRINTK( "CTRL[0]=0x%02x\n", PT_CTRL0 );
305 	DPRINTK( "CTRL[1]=0x%02x\n", PT_CTRL1 );
306 	DPRINTK( "CTRL[2]=0x%02x\n", PT_CTRL2 );
307 
308 	/*
309 	 * Ensure that the memory bus request/grant signals are setup,
310 	 * and the grant is held in its inactive state.
311 	 */
312 	sa1110_mb_disable();
313 
314 	/*
315 	 * Probe for a SA1111.
316 	 */
317 	ret = sa1111_probe(PT_SA1111_BASE);
318 	if (ret < 0) {
319 		printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
320 		goto DONE;
321 	}
322 
323 	/*
324 	 * We found it.  Wake the chip up.
325 	 */
326 	sa1111_wake();
327 
328 	/*
329 	 * The SDRAM configuration of the SA1110 and the SA1111 must
330 	 * match.  This is very important to ensure that SA1111 accesses
331 	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
332 	 * MBGNT signal, so we must have called sa1110_mb_disable()
333 	 * beforehand.
334 	 */
335 	sa1111_configure_smc(1,
336 			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
337 			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
338 
339 	/*
340 	 * We only need to turn on DCLK whenever we want to use the
341 	 * DMA.  It can otherwise be held firmly in the off position.
342 	 */
343 	SKPCR |= SKPCR_DCLKEN;
344 
345 	/*
346 	 * Enable the SA1110 memory bus request and grant signals.
347 	 */
348 	sa1110_mb_enable();
349 
350 	system3_init_irq();
351 
352 #if defined( CONFIG_CPU_FREQ )
353 	ret = cpufreq_register_notifier(&system3_clkchg_block);
354 	if ( ret != 0 ) {
355 		printk( KERN_WARNING"PT Digital Board: could not register clock scale callback\n" );
356 		goto DONE;
357 	}
358 #endif
359 
360 	ret = 0;
361 DONE:
362 	DPRINTK( "ret=%d\n", ret );
363 	return ret;
364 }
365 
366 /**********************************************************************
367  *  Exported Functions
368  */
369 
370 /**********************************************************************
371  *  kernel magic macros
372  */
373 __initcall(system3_init);
374 
375 MACHINE_START(PT_SYSTEM3, "PT System 3")
376 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
377 	BOOT_PARAMS(0xc0000100)
378 	FIXUP(fixup_system3)
379 	MAPIO(system3_map_io)
380 	INITIRQ(sa1100_init_irq)
381 MACHINE_END
382