Skip to content

Commit

Permalink
[ARM] 5319/1: AT91: support AT91CAP9 revC CPUs
Browse files Browse the repository at this point in the history
The AT91CAP9 revC CPU has a few differences over the previous,
revB CPU which was distributed in small quantities only (revA was
an internal Atmel product only).

This patch adds the detection routines to recognize the different
AT91CAP9 revisions (based on the PMC subsystem version number), and
uses them to:
	- activate a workaround for the external interrupts levels
	  (on revB CPUs)
	- set the UDPHS_BYPASS bit (on revB CPUs)
	- set AT91_GPBR register address to the correct offset
	  (0xfffffd50 on revB, 0xfffffd60 on revC)

For debugging usage, the CPU revision can be found in /proc/cpuinfo
on the 'Revision' line.

This patch is extracted from Andrew Victor's -at91 patch (2.6.27-at91.patch)
where it has been tested for the last 6 months.

Signed-off-by: Stelian Pop <[email protected]>
Signed-off-by: Andrew Victor <[email protected]>
Signed-off-by: Russell King <[email protected]>
  • Loading branch information
stelian42 authored and Russell King committed Dec 1, 2008
1 parent ffc63b7 commit 7be90a6
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 8 deletions.
8 changes: 8 additions & 0 deletions arch/arm/mach-at91/at91cap9.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <asm/mach/arch.h>
#include <asm/mach/map.h>

#include <mach/cpu.h>
#include <mach/at91cap9.h>
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
Expand Down Expand Up @@ -317,6 +319,12 @@ void __init at91cap9_initialize(unsigned long main_clock)

/* Register GPIO subsystem */
at91_gpio_init(at91cap9_gpio, 4);

/* Remember the silicon revision */
if (cpu_is_at91cap9_revB())
system_rev = 0xB;
else if (cpu_is_at91cap9_revC())
system_rev = 0xC;
}

/* --------------------------------------------------------------------
Expand Down
17 changes: 15 additions & 2 deletions arch/arm/mach-at91/at91cap9_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>

#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
Expand All @@ -21,6 +22,7 @@
#include <video/atmel_lcdc.h>

#include <mach/board.h>
#include <mach/cpu.h>
#include <mach/gpio.h>
#include <mach/at91cap9.h>
#include <mach/at91cap9_matrix.h>
Expand Down Expand Up @@ -69,6 +71,9 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
if (!data)
return;

if (cpu_is_at91cap9_revB())
set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);

/* Enable VBus control for UHP ports */
for (i = 0; i < data->ports; i++) {
if (data->vbus_pin[i])
Expand Down Expand Up @@ -151,8 +156,13 @@ static struct platform_device at91_usba_udc_device = {

void __init at91_add_device_usba(struct usba_platform_data *data)
{
at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
AT91_MATRIX_UDPHS_BYPASS_LOCK);
if (cpu_is_at91cap9_revB()) {
set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
AT91_MATRIX_UDPHS_BYPASS_LOCK);
}
else
at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);

/*
* Invalid pins are 0 on AT91, but the usba driver is shared
Expand Down Expand Up @@ -850,6 +860,9 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
if (!data)
return;

if (cpu_is_at91cap9_revB())
set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);

at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
Expand Down
5 changes: 0 additions & 5 deletions arch/arm/mach-at91/board-cap9adk.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@
#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/irq.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>

#include <mach/board.h>
#include <mach/gpio.h>
Expand Down Expand Up @@ -376,10 +374,8 @@ static void __init cap9adk_board_init(void)
/* Serial */
at91_add_device_serial();
/* USB Host */
set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
at91_add_device_usbh(&cap9adk_usbh_data);
/* USB HS */
set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
at91_add_device_usba(&cap9adk_usba_udc_data);
/* SPI */
at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
Expand All @@ -396,7 +392,6 @@ static void __init cap9adk_board_init(void)
/* I2C */
at91_add_device_i2c(NULL, 0);
/* LCD Controller */
set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
at91_add_device_lcdc(&cap9adk_lcdc_data);
/* AC97 */
at91_add_device_ac97(&cap9adk_ac97_data);
Expand Down
7 changes: 7 additions & 0 deletions arch/arm/mach-at91/include/mach/at91_pmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define AT91_PMC_PCK (1 << 0) /* Processor Clock */
#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */
#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [AT91CAP9 revC only] */
#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */
#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */
#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */
Expand Down Expand Up @@ -102,10 +103,16 @@
#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */
#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */
#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */
#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */

#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */
#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */

#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */

#endif
4 changes: 3 additions & 1 deletion arch/arm/mach-at91/include/mach/at91cap9.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@
#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
#define AT91_GPBR (cpu_is_at91cap9_revB() ? \
(0xfffffd50 - AT91_BASE_SYS) : \
(0xfffffd60 - AT91_BASE_SYS))

#define AT91_USART0 AT91CAP9_BASE_US0
#define AT91_USART1 AT91CAP9_BASE_US1
Expand Down
15 changes: 15 additions & 0 deletions arch/arm/mach-at91/include/mach/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ static inline unsigned long at91_arch_identify(void)
return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH);
}

#ifdef CONFIG_ARCH_AT91CAP9
#include <mach/at91_pmc.h>

#define ARCH_REVISION_CAP9_B 0x399
#define ARCH_REVISION_CAP9_C 0x601

static inline unsigned long at91cap9_rev_identify(void)
{
return (at91_sys_read(AT91_PMC_VER));
}
#endif

#ifdef CONFIG_ARCH_AT91RM9200
#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200)
Expand Down Expand Up @@ -90,8 +101,12 @@ static inline unsigned long at91_arch_identify(void)

#ifdef CONFIG_ARCH_AT91CAP9
#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C)
#else
#define cpu_is_at91cap9() (0)
#define cpu_is_at91cap9_revB() (0)
#define cpu_is_at91cap9_revC() (0)
#endif

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/rtc/rtc-at91sam9.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <mach/board.h>
#include <mach/at91_rtt.h>
#include <mach/cpu.h>


/*
Expand Down

0 comments on commit 7be90a6

Please sign in to comment.