summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/hw-sa1100.c
blob: 5acfab1e27a144ef7baca16ec5c6aa253d599e2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * arch/arm/kernel/hw-sa1100.c
 *
 * SA1100-dependent machine specifics
 *
 * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
 *
 * This will certainly contain more stuff with time... like power management,
 * special hardware autodetection, etc.
 *
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>

#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>

/*
 * SA1100 GPIO edge detection for IRQs:
 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
 * This must be called *before* the appropriate IRQ is registered.
 * Use this instead of directly setting GRER/GFER.
 */

int GPIO_IRQ_rising_edge;
int GPIO_IRQ_falling_edge;

void set_GPIO_IRQ_edge( int gpio_mask, int edge )
{
	if( edge & GPIO_FALLING_EDGE )
		GPIO_IRQ_falling_edge |= gpio_mask;
	else
		GPIO_IRQ_falling_edge &= ~gpio_mask;
	if( edge & GPIO_RISING_EDGE )
		GPIO_IRQ_rising_edge |= gpio_mask;
	else
		GPIO_IRQ_rising_edge &= ~gpio_mask;
}

EXPORT_SYMBOL(set_GPIO_IRQ_edge);


#ifdef CONFIG_SA1100_ASSABET

unsigned long BCR_value = BCR_DB1110;
unsigned long SCR_value = SCR_INIT;
EXPORT_SYMBOL(BCR_value);
EXPORT_SYMBOL(SCR_value);

/*
 * Read System Configuration "Register"
 * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
 * User's Guide", section 4.4.1)
 *
 * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S
 * to set up the serial port for decompression status messages. We 
 * repeat it here because the kernel may not be loaded as a zImage, and
 * also because it's a hassle to communicate the SCR value to the kernel
 * from the decompressor.
 */

void __init get_assabet_scr(void)
{
	unsigned long flags, scr, i;

	save_flags_cli(flags);
	GPDR |= 0x3fc;			/* Configure GPIO 9:2 as outputs */
	GPSR = 0x3fc;			/* Write 0xFF to GPIO 9:2 */
	GPDR &= ~(0x3fc);		/* Configure GPIO 9:2 as inputs */
	for(i = 100; i--; scr = GPLR);	/* Read GPIO 9:2 */
	GPDR |= 0x3fc;			/*  restore correct pin direction */
	restore_flags(flags);
	scr &= 0x3fc;			/* save as system configuration byte. */

	SCR_value = scr;
}

#endif  /* CONFIG_SA1100_ASSABET */

/*
 * Bitsy has extended, write-only memory-mapped GPIO's
 */
#if defined(CONFIG_SA1100_BITSY)
static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
void clr_bitsy_egpio(unsigned long x) 
{
  bitsy_egpio &= ~x;
  *(volatile int *)0xdc000000 = bitsy_egpio;
}
void set_bitsy_egpio(unsigned long x) 
{
  bitsy_egpio |= x;
  *(volatile int *)0xdc000000 = bitsy_egpio;
}
EXPORT_SYMBOL(clr_bitsy_egpio);
EXPORT_SYMBOL(set_bitsy_egpio);
#endif

#ifdef CONFIG_SA1111

void __init sa1111_init(void){
  unsigned long id=SKID;

  if((id & SKID_ID_MASK) == SKID_SA1111_ID)
    printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
	   "silicon revision %x, metal revision %x\n",
	   (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
  else {
    printk(KERN_ERR "Could not detect SA-1111!\n");
    return;
  }

  /* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
   * (SA-1110 Developer's Manual, section 9.1.2.1)
   */
  GAFR |= GPIO_GPIO27;
  GPDR |= GPIO_GPIO27;
  TUCR = TUCR_3_6864MHz;

  /* Now, set up the PLL and RCLK in the SA-1111: */
  SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
  udelay(100);
  SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;

  /* SA-1111 Register Access Bus should now be available. Clocks for
   * any other SA-1111 functional blocks must be enabled separately
   * using the SKPCR.
   */

  {
  /*
   * SA1111 DMA bus master setup 
   */
	int cas;

	/* SA1111 side */
	switch ( (MDCNFG>>12) & 0x03 ) {
	case 0x02:
		cas = 0; break;
	case 0x03:
		cas = 1; break;
	default:
		cas = 1; break;
	}
	SMCR = 1		/* 1: memory is SDRAM */
		| ( 1 << 1 )	/* 1:MBGNT is enable */
		| ( ((MDCNFG >> 4) & 0x07) << 2 )	/* row address lines */
		| ( cas << 5 );	/* CAS latency */

	/* SA1110 side */
	GPDR |= 1<<21;
	GPDR &= ~(1<<22);
	GAFR |= ( (1<<21) | (1<<22) );

	TUCR |= (1<<10);
  }
}

#endif


static int __init hw_sa1100_init(void)
{
	if( machine_is_assabet() ){
		if(machine_has_neponset()){
#ifdef CONFIG_ASSABET_NEPONSET
			LEDS = WHOAMI;
			sa1111_init();
#else
			printk( "Warning: Neponset detected but full support "
				"hasn't been configured in the kernel\n" );
#endif
		}
	} else if (machine_is_xp860()) {
		sa1111_init();
	}
	return 0;
}

module_init(hw_sa1100_init);