|
|
|
Harald Roeck
|
Is it possible do get the new gumstix ethernet module working inside
oklinux? Running linux native we used the smc911x driver. I tried to port the gumstix smc911x driver to oklinux and got it to compile and boot (see attached patch file). however, the driver is not getting any interrupts. I noticed the following warning when oklinux boots: No IRQF_TRIGGER set_type function for IRQ 66 (iguana) The eth0 interrupt is registered at IRQ 66, see: / # cat /proc/interrupts 22: 178 iguana FFUART 25: 0 iguana DMA 27: 757 iguana ost1 52: 0 iguana cell 66: 0 iguana eth0 fyi: I'm running OKL4 3.0 on a gumstix verdex with the netwifimicrosd daughter board. thanks, -Harald [fix-smc911.patch] diff --git a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c --- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c +++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c @@ -27,32 +27,13 @@ * History: * 04/16/05 Dustin McIntire Initial version */ + static const char version[] = "smc911x.c: v1.0 04-16-2005 by Dustin McIntire <[hidden email]>\n"; -/* Debugging options */ -#define ENABLE_SMC_DEBUG_RX 0 -#define ENABLE_SMC_DEBUG_TX 0 -#define ENABLE_SMC_DEBUG_DMA 0 -#define ENABLE_SMC_DEBUG_PKTS 0 -#define ENABLE_SMC_DEBUG_MISC 0 -#define ENABLE_SMC_DEBUG_FUNC 0 - -#define SMC_DEBUG_RX ((ENABLE_SMC_DEBUG_RX ? 1 : 0) << 0) -#define SMC_DEBUG_TX ((ENABLE_SMC_DEBUG_TX ? 1 : 0) << 1) -#define SMC_DEBUG_DMA ((ENABLE_SMC_DEBUG_DMA ? 1 : 0) << 2) -#define SMC_DEBUG_PKTS ((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3) -#define SMC_DEBUG_MISC ((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4) -#define SMC_DEBUG_FUNC ((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5) - #ifndef SMC_DEBUG -#define SMC_DEBUG ( SMC_DEBUG_RX | \ - SMC_DEBUG_TX | \ - SMC_DEBUG_DMA | \ - SMC_DEBUG_PKTS | \ - SMC_DEBUG_MISC | \ - SMC_DEBUG_FUNC \ - ) +#define SMC_DEBUG 0 +#define SMC_DEBUG_PKTS 0 #endif #include <linux/init.h> @@ -76,6 +57,7 @@ #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/irq.h> #include <asm/io.h> #include "smc911x.h" @@ -295,14 +277,14 @@ SMC_SET_AFC_CFG(lp->afc_cfg); - /* Set to LED outputs */ - SMC_SET_GPIO_CFG(0x70070000); + /* Set to LED outputs and configure EEPROM pins as GP outputs */ + SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20); /* - * Deassert IRQ for 1*10us for edge type interrupts + * Deassert IRQ for 22*10us for edge type interrupts * and drive IRQ pin push-pull */ - SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); + SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); /* clear anything saved */ if (lp->pending_tx_skb != NULL) { @@ -405,7 +387,7 @@ if (fifo_count <= 4) { /* Manually dump the packet data */ while (fifo_count--) - SMC_GET_RX_FIFO(); + (void)SMC_GET_RX_FIFO(); } else { /* Fast forward through the bad packet */ SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_); @@ -891,6 +873,7 @@ unsigned long ioaddr = dev->base_addr; unsigned int bmcr; + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); /* Enter Link Disable state */ SMC_GET_PHY_BMCR(phy, bmcr); bmcr |= BMCR_PDOWN; @@ -916,6 +899,7 @@ if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { /* duplex state has changed */ + DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name); SMC_GET_PHY_BMCR(phyaddr, bmcr); SMC_GET_MAC_CR(cr); if (lp->mii.full_duplex) { @@ -951,6 +935,7 @@ int my_phy_caps; /* My PHY capabilities */ int my_ad_caps; /* My Advertised capabilities */ int status; + int bmcr; unsigned long flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); @@ -1024,9 +1009,12 @@ DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps); DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps); + DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status); /* Restart auto-negotiation process in order to advertise my caps */ - SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); + SMC_GET_PHY_BMCR(phyaddr, bmcr); + bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; + SMC_SET_PHY_BMCR(phyaddr, bmcr); smc911x_phy_check_media(dev, 1); @@ -1856,6 +1844,48 @@ return probe_irq_off(cookie); } +static inline unsigned int is_gumstix_oui(u8 *addr) +{ + return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9); +} + +/** + * gen_serial_ether_addr - Generate software assigned Ethernet address + * based on the system_serial number + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Generate an Ethernet address (MAC) that is not multicast + * and has the local assigned bit set, keyed on the system_serial + */ +static inline void gen_serial_ether_addr(u8 *addr) +{ +#ifdef CONFIG_CELL + addr [0] = 0x00; + addr [1] = 0x15; + addr [2] = 0xC9; + addr [3] = 0x83; + addr [4] = 0x82; + addr [5] = 0x81; +#else + static u8 ether_serial_digit = 0; + addr [0] = system_serial_high >> 8; + addr [1] = system_serial_high; + addr [2] = system_serial_low >> 24; + addr [3] = system_serial_low >> 16; + addr [4] = system_serial_low >> 8; + addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */ + (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */ + ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */ +#endif + + if(!is_gumstix_oui(addr)) + { + addr [0] &= 0xfe; /* clear multicast bit */ + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ + } +} + + /* * Function: smc911x_probe(unsigned long ioaddr) * @@ -2082,15 +2112,13 @@ #endif printk("\n"); if (!is_valid_ether_addr(dev->dev_addr)) { - printk("%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", dev->name); - } else { - /* Print the Ethernet address */ - printk("%s: Ethernet addr: ", dev->name); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[5]); + gen_serial_ether_addr(dev->dev_addr); } + /* Print the Ethernet address */ + printk("%s: Ethernet addr: ", dev->name); + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[5]); if (lp->phy_type == 0) { PRINTK("%s: No PHY found\n", dev->name); @@ -2265,8 +2293,15 @@ }, }; +#ifdef CONFIG_ARCH_GUMSTIX +extern void gumstix_smc911x_load(void); +#endif + static int __init smc911x_init(void) { +#ifdef CONFIG_ARCH_GUMSTIX + gumstix_smc911x_load(); +#endif return platform_driver_register(&smc911x_driver); } diff --git a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h --- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h +++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h @@ -33,7 +33,9 @@ * Use the DMA feature on PXA chips */ #ifdef CONFIG_ARCH_PXA +#if !defined( CONFIG_SMC911X_GUMSTIX ) && !defined( CONFIG_SMC911X_GUMSTIX_MODULE ) #define SMC_USE_PXA_DMA 1 +#endif #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING @@ -52,13 +54,13 @@ #if SMC_USE_16BIT #define SMC_inb(a, r) readb((a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16)) +#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16)) #define SMC_outb(v, a, r) writeb(v, (a) + (r)) #define SMC_outw(v, a, r) writew(v, (a) + (r)) #define SMC_outl(v, a, r) \ do{ \ - writel(v & 0xFFFF, (a) + (r)); \ - writel(v >> 16, (a) + (r) + 2); \ + writel((v) & 0xFFFF, (a) + (r)); \ + writel((v) >> 16, (a) + (r) + 2); \ } while (0) #define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2) #define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2) diff --git a/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell b/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell --- a/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell +++ b/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell @@ -475,10 +475,12 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set -CONFIG_SMC91X_GUMSTIX=y -CONFIG_SMC91X=y +CONFIG_SMC91X_GUMSTIX=n +CONFIG_SMC91X=n # CONFIG_DM9000 is not set -# CONFIG_SMC911X is not set +CONFIG_SMC911X=y +CONFIG_SMC911X_GUMSTIX=y + # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set diff --git a/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c new file mode 100644 --- /dev/null +++ b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c @@ -0,0 +1,209 @@ +/* + * Gumstix SMC911x chip intialization driver + * + * Author: Craig Hughes + * Created: December 9, 2004 + * Copyright: (C) 2004 Craig Hughes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/mii.h> + +#include <asm/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/delay.h> + +#include <asm/arch/gumstix.h> + +#define SMC_DEBUG 9 +#include <asm/io.h> +#include "smc911x.h" + +static struct resource gumstix_smc911x0_resources[] = { + [0] = { + .name = "smc911x-regs", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + 0x000fffff, +#endif + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = GUMSTIX_ETH0_IRQ, + .end = GUMSTIX_ETH0_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-dma", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_DMA, + .end = PXA_CS1_DMA + 0x000fffff, +#endif + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource gumstix_smc911x1_resources[] = { + [0] = { + .name = "smc911x-regs", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 0x000fffff, +#endif + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = GUMSTIX_ETH1_IRQ, + .end = GUMSTIX_ETH1_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-dma", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_DMA, + .end = PXA_CS1_DMA + 0x000fffff, +#endif + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device gumstix_smc911x0_device = { + .name = "smc911x", + .id = 0, + .num_resources = ARRAY_SIZE(gumstix_smc911x0_resources), + .resource = gumstix_smc911x0_resources, +}; + +static struct platform_device gumstix_smc911x1_device = { + .name = "smc911x", + .id = 1, + .num_resources = ARRAY_SIZE(gumstix_smc911x1_resources), + .resource = gumstix_smc911x1_resources, +}; + +static struct platform_device *smc911x_devices[] = { + &gumstix_smc911x0_device, + &gumstix_smc911x1_device, +}; + +/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines + * that it would otherwise use. We have no choice but to probe by doing: + * Set nCS2 to CS2 mode + * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset) + * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device + */ +int __init gumstix_smc911x_init(void) +{ + unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices); + void *ioaddr; + printk("%s\n", __FUNCTION__); +#if defined(CONFIG_CELL) + gumstix_smc911x0_resources[0].start += PXA_CS1_PHYS; + printk("start: %lx\n", gumstix_smc911x0_resources[0].start); + gumstix_smc911x0_resources[0].end += PXA_CS1_PHYS; + gumstix_smc911x1_resources[0].start += PXA_CS2_PHYS; + gumstix_smc911x1_resources[0].end += PXA_CS2_PHYS; + + gumstix_smc911x0_resources[2].start += PXA_CS1_DMA; + gumstix_smc911x0_resources[2].end += PXA_CS1_DMA; + gumstix_smc911x1_resources[2].start += PXA_CS2_DMA; + gumstix_smc911x1_resources[2].end += PXA_CS2_DMA; +#endif + + printk("%s %d\n", __FILE__, __LINE__); + + /* Set up nPWE */ + pxa_gpio_mode(GPIO49_nPWE_MD); + + pxa_gpio_mode(GPIO78_nCS_2_MD); + // If either if statement fails, then we'll drop out and turn_off_eth1, + // if both succeed, then we'll skip that and just proceed with 2 cards + printk("%s %d\n", __FILE__, __LINE__); +#if 0 /* do not check for second network interface */ + if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe")) + { + printk("%s %d\n", __FILE__, __LINE__); + ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); + printk("%s %d ioaddr 0x%p\n", __FILE__, __LINE__, ioaddr); + val = SMC_GET_PN(); + printk("%s %d\n", __FILE__, __LINE__); + iounmap(ioaddr); + printk("%s %d\n", __FILE__, __LINE__); + release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); + printk("%s %d\n", __FILE__, __LINE__); + if (CHIP_9115 == val || + CHIP_9116 == val || + CHIP_9117 == val || + CHIP_9118 == val ) { + goto proceed; + } + printk("%s %d\n", __FILE__, __LINE__); + } +#endif + + printk("%s %d\n", __FILE__, __LINE__); +turn_off_eth1: + // This is apparently not an SMC911x + // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode + num_devices--; + smc911x_devices[1] = NULL; + pxa_gpio_mode(78 | GPIO_IN); + + printk("%s %d\n", __FILE__, __LINE__); +proceed: + pxa_gpio_mode(GPIO15_nCS_1_MD); + + if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD); + pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD); + + if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); + GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); + msleep(500); // Hold RESET for at least 200õ + + if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); + GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); + msleep(50); + + printk("%s %d\n", __FILE__, __LINE__); + return platform_add_devices(smc911x_devices, num_devices); +} + +void __exit gumstix_smc911x_exit(void) +{ + if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device); + platform_device_unregister(&gumstix_smc911x0_device); +} + +void gumstix_smc911x_load(void) {} +EXPORT_SYMBOL(gumstix_smc911x_load); + +module_init(gumstix_smc911x_init); +module_exit(gumstix_smc911x_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Craig Hughes <[hidden email]>"); +MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver"); +MODULE_VERSION("1:0.1"); _______________________________________________ Developer mailing list [hidden email] https://lists.okl4.org/mailman/listinfo/developer |
||||||||||||||||
|
Harald Roeck
|
got the ethernet driver in wombat working. attached are two patch
files. a patch for OKL4 to get the additional registers of the PXA27x cpus (i.e. gumstix verdex board). the second patch adds pxa27x support and the smc911x driver to wombat. regards, -Harald On Wed, Apr 15, 2009 at 3:22 PM, Harald Roeck <[hidden email]> wrote: > Is it possible do get the new gumstix ethernet module working inside > oklinux? Running linux native we used the smc911x driver. I tried to > port the gumstix smc911x driver to oklinux and got it to compile and > boot (see attached patch file). however, the driver is not getting any > interrupts. I noticed the following warning when oklinux boots: > > No IRQF_TRIGGER set_type function for IRQ 66 (iguana) > > The eth0 interrupt is registered at IRQ 66, see: > / # cat /proc/interrupts > 22: 178 iguana FFUART > 25: 0 iguana DMA > 27: 757 iguana ost1 > 52: 0 iguana cell > 66: 0 iguana eth0 > > fyi: I'm running OKL4 3.0 on a gumstix verdex with the netwifimicrosd > daughter board. > > thanks, > -Harald > [wombat_pxa270_smc911x.patch] diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/Kconfig --- a/linux/kernel-2.6.24-v2/arch/l4/Kconfig Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/Kconfig Wed Apr 22 20:24:29 2009 +0200 @@ -328,15 +328,12 @@ bool "Generic PXA27x platform" select PXA27x config ARCH_GUMSTIX -bool "Support for Gumstix platform" - depends on PXA + bool "Gumstix Platform" select ARCH_PXA - select PXA25x - help - Support for Gumstix + config IBOX -bool "Support for IBOX platform" + bool "Support for IBOX platform" depends on PXA select ARCH_PXA select PXA27x @@ -350,6 +347,35 @@ bool "Support for PLEB2 platform" select PXA25x help Support for PLEB 2 + +endchoice + +choice + depends on ARCH_GUMSTIX + prompt "Gumstix Platform Version" + default ARCH_GUMSTIX_F + +config ARCH_GUMSTIX_F + bool "Gumstix-F" + select PXA25x + help + The updated Gumstix basix and connex boards with 60-pin connector, and + waysmall systems using these boards, including ws-200ax and ws-400ax. + +config ARCH_GUMSTIX_ORIG + bool "Support for Gumstix platform" + depends on PXA + select ARCH_PXA + select PXA25x + help + Support for Gumstix + +config ARCH_GUMSTIX_VERDEX + bool "Support for Gumstix verdex platform" + depends on PXA + select PXA27x + help + Support for Gumstix verdex endchoice @@ -548,4 +574,5 @@ config EARLY_PRINTK help Write kernel log output directly to L4 KDB. +#source "drivers/gpio/Kconfig" endmenu diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c --- a/linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c Wed Apr 22 20:24:29 2009 +0200 @@ -10,6 +10,7 @@ #include <linux/init.h> #include <linux/utsname.h> #include <linux/console.h> +#include <linux/module.h> #include <asm/page.h> #include <asm/tlbflush.h> #include <asm/setup.h> @@ -123,6 +124,7 @@ void okl4_env_lookup_address(const char for (i = 0; i < segs->num_segments; i++) { if (segs->segments[i].segment == *seg) { *addr = segs->segments[i].virt_addr; + printk("found address %p for %s\n", addr, name); break; } } @@ -250,10 +252,12 @@ setup_arch (char **command_line) #if defined(CONFIG_ARCH_GUMSTIX) { extern unsigned long GPIO_BASE, DMAC_BASE; + extern unsigned long PXA_CS0_PHYS; extern unsigned long PXA_CS1_PHYS, PXA_CS1_DMA; extern unsigned long PXA_CS2_PHYS, PXA_CS2_DMA; okl4_env_lookup_address("MAIN_GPIO_MEM0", &GPIO_BASE); okl4_env_lookup_address("MAIN_DMA_MEM0", &DMAC_BASE); + okl4_env_lookup_address("MAIN_CS_MEM0", &PXA_CS0_PHYS); okl4_env_lookup_address("MAIN_CS_MEM1", &PXA_CS1_PHYS); okl4_env_lookup_address("MAIN_CS_MEM2", &PXA_CS2_PHYS); @@ -273,10 +277,18 @@ unsigned long KMI0_BASE; unsigned long KMI0_BASE; unsigned long KMI1_BASE; unsigned long GPIO_BASE; +EXPORT_SYMBOL(GPIO_BASE); unsigned long DMAC_BASE; +EXPORT_SYMBOL(DMAC_BASE); unsigned long VERSATILE_SYS_BASE; +unsigned long PXA_CS0_PHYS; +EXPORT_SYMBOL(PXA_CS0_PHYS); unsigned long PXA_CS1_PHYS; +EXPORT_SYMBOL(PXA_CS1_PHYS); unsigned long PXA_CS2_PHYS; +EXPORT_SYMBOL(PXA_CS2_PHYS); unsigned long PXA_CS1_DMA; +EXPORT_SYMBOL(PXA_CS1_DMA); unsigned long PXA_CS2_DMA; +EXPORT_SYMBOL(PXA_CS2_DMA); #endif diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c --- a/linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c Wed Apr 22 20:24:29 2009 +0200 @@ -1,8 +1,10 @@ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/highmem.h> +#include <linux/delay.h> #include <asm/uaccess.h> +#include <asm/io.h> #include <l4/ipc.h> #include "assert.h" @@ -47,14 +49,56 @@ EXPORT_SYMBOL(memsection_register_server EXPORT_SYMBOL(memsection_register_server); #endif + /* io */ +#ifndef __raw_readsb +EXPORT_SYMBOL(__raw_readsb); +#endif +#ifndef __raw_readsw +EXPORT_SYMBOL(__raw_readsw); +#endif +#ifndef __raw_readsl +EXPORT_SYMBOL(__raw_readsl); +#endif +#ifndef __raw_writesb +EXPORT_SYMBOL(__raw_writesb); +#endif +#ifndef __raw_writesw +EXPORT_SYMBOL(__raw_writesw); +#endif +#ifndef __raw_writesl +EXPORT_SYMBOL(__raw_writesl); +#endif + #ifdef CONFIG_AEABI /* * Needed for modules */ extern void *__aeabi_idivmod; +EXPORT_SYMBOL(__aeabi_idivmod); -EXPORT_SYMBOL(__aeabi_idivmod); +extern void *__aeabi_uidivmod; +EXPORT_SYMBOL(__aeabi_uidivmod); + +extern void __aeabi_idiv(void); +EXPORT_SYMBOL(__aeabi_idiv); + +extern void __aeabi_uidiv(void); +EXPORT_SYMBOL(__aeabi_uidiv); #endif + +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__const_udelay); + + /* bitops */ +EXPORT_SYMBOL(_set_bit_le); +EXPORT_SYMBOL(_test_and_set_bit_le); +EXPORT_SYMBOL(_clear_bit_le); +EXPORT_SYMBOL(_test_and_clear_bit_le); +EXPORT_SYMBOL(_change_bit_le); +EXPORT_SYMBOL(_find_first_zero_bit_le); +EXPORT_SYMBOL(_find_next_zero_bit_le); +EXPORT_SYMBOL(_find_first_bit_le); +EXPORT_SYMBOL(_find_next_bit_le); /* * Because we don't use OKL4 libc we need to do this to force diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/lib/Makefile --- a/linux/kernel-2.6.24-v2/arch/l4/lib/Makefile Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/lib/Makefile Wed Apr 22 20:24:29 2009 +0200 @@ -1,3 +1,3 @@ obj-y := assert.o -obj-y := assert.o +obj-y := assert.o io-readsb.o obj-y += oklibs/ obj-$(CONFIG_NET) += checksum.o diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/lib/io-readsb.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux/kernel-2.6.24-v2/arch/l4/lib/io-readsb.S Wed Apr 22 20:24:29 2009 +0200 @@ -0,0 +1,122 @@ +/* + * linux/arch/arm/lib/io-readsb.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include INC_SYSTEM(assembler.h) + +.Linsb_align: rsb ip, ip, #4 + cmp ip, r2 + movgt ip, r2 + cmp ip, #2 + ldrb r3, [r0] + strb r3, [r1], #1 + ldrgeb r3, [r0] + strgeb r3, [r1], #1 + ldrgtb r3, [r0] + strgtb r3, [r1], #1 + subs r2, r2, ip + bne .Linsb_aligned + +ENTRY(__raw_readsb) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + ands ip, r1, #3 + bne .Linsb_align + +.Linsb_aligned: stmfd sp!, {r4 - r6, lr} + + subs r2, r2, #16 + bmi .Linsb_no_16 + +.Linsb_16_lp: ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + mov r3, r3, put_byte_0 + ldrb r6, [r0] + orr r3, r3, r4, put_byte_1 + ldrb r4, [r0] + orr r3, r3, r5, put_byte_2 + ldrb r5, [r0] + orr r3, r3, r6, put_byte_3 + ldrb r6, [r0] + mov r4, r4, put_byte_0 + ldrb ip, [r0] + orr r4, r4, r5, put_byte_1 + ldrb r5, [r0] + orr r4, r4, r6, put_byte_2 + ldrb r6, [r0] + orr r4, r4, ip, put_byte_3 + ldrb ip, [r0] + mov r5, r5, put_byte_0 + ldrb lr, [r0] + orr r5, r5, r6, put_byte_1 + ldrb r6, [r0] + orr r5, r5, ip, put_byte_2 + ldrb ip, [r0] + orr r5, r5, lr, put_byte_3 + ldrb lr, [r0] + mov r6, r6, put_byte_0 + orr r6, r6, ip, put_byte_1 + ldrb ip, [r0] + orr r6, r6, lr, put_byte_2 + orr r6, r6, ip, put_byte_3 + stmia r1!, {r3 - r6} + + subs r2, r2, #16 + bpl .Linsb_16_lp + + tst r2, #15 + ldmeqfd sp!, {r4 - r6, pc} + +.Linsb_no_16: tst r2, #8 + beq .Linsb_no_8 + + ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + mov r3, r3, put_byte_0 + ldrb r6, [r0] + orr r3, r3, r4, put_byte_1 + ldrb r4, [r0] + orr r3, r3, r5, put_byte_2 + ldrb r5, [r0] + orr r3, r3, r6, put_byte_3 + ldrb r6, [r0] + mov r4, r4, put_byte_0 + ldrb ip, [r0] + orr r4, r4, r5, put_byte_1 + orr r4, r4, r6, put_byte_2 + orr r4, r4, ip, put_byte_3 + stmia r1!, {r3, r4} + +.Linsb_no_8: tst r2, #4 + beq .Linsb_no_4 + + ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + ldrb r6, [r0] + mov r3, r3, put_byte_0 + orr r3, r3, r4, put_byte_1 + orr r3, r3, r5, put_byte_2 + orr r3, r3, r6, put_byte_3 + str r3, [r1], #4 + +.Linsb_no_4: ands r2, r2, #3 + ldmeqfd sp!, {r4 - r6, pc} + + cmp r2, #2 + ldrb r3, [r0] + strb r3, [r1], #1 + ldrgeb r3, [r0] + strgeb r3, [r1], #1 + ldrgtb r3, [r0] + strgtb r3, [r1] + + ldmfd sp!, {r4 - r6, pc} diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c --- a/linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c Wed Apr 22 20:24:29 2009 +0200 @@ -119,6 +119,7 @@ return (void __iomem *) (offset + phys_a return (void __iomem *) (offset + (char __iomem *)addr); } +EXPORT_SYMBOL(__ioremap); /* * As per ioremap, but ensures that it is uncached. @@ -217,4 +218,5 @@ void iounmap(volatile void __iomem *addr #endif /*CONFIG_CELL*/ return; } +EXPORT_SYMBOL(iounmap); diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c --- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c Wed Apr 22 20:24:29 2009 +0200 @@ -1,6 +1,7 @@ #include <l4.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -45,6 +46,7 @@ void _memcpy_fromio(void *to, unsigned l from++; } } +EXPORT_SYMBOL(_memcpy_fromio); /* * Copy data from "real" memory space to IO memory space. @@ -60,6 +62,7 @@ void _memcpy_toio(unsigned long to, cons to++; } } +EXPORT_SYMBOL(_memcpy_toio); /* * "memset" on IO memory space. diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile --- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile Wed Apr 22 20:24:29 2009 +0200 @@ -2,7 +2,7 @@ obj-$(CONFIG_IGUANA) += generic.o obj-$(CONFIG_IGUANA) += generic.o obj-$(CONFIG_CELL) += generic.o time.o clock.o dma.o -#obj-$(CONFIG_PXA27x) += pxa27x.o +obj-$(CONFIG_PXA27x) += pxa27x.o obj-$(CONFIG_PXA25x) += pxa25x.o #obj-$(CONFIG_IBOX) += ibox.o diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c --- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c Wed Apr 22 20:24:29 2009 +0200 @@ -11,26 +11,35 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - #include <linux/module.h> #include <linux/kernel.h> -#include <asm/arch/pxa-regs.h> #include <linux/init.h> -#include <linux/pm.h> +#include <linux/suspend.h> +#include <linux/platform_device.h> #include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/irqs.h> +#include <asm/arch/pxa-regs.h> +//#include <asm/arch/ohci.h> +//#include <asm/arch/pm.h> +#include <asm/arch/dma.h> #include "generic.h" +#include "devices.h" +#include "clock.h" /* Crystal clock: 13MHz */ #define BASE_CLK 13000000 + +#if 0 /*Disable stuff we don't need in OK Linux -cvs*/ /* * Get the clock frequency as reflected by CCSR and the turbo flag. * We assume these values have been applied via a fcs. * If info is not 0 we also display the current settings. */ -unsigned int get_clk_frequency_khz( int info) +unsigned int pxa27x_get_clk_frequency_khz(int info) { unsigned long ccsr, clkcfg; unsigned int l, L, m, M, n2, N, S; @@ -40,13 +49,8 @@ unsigned int get_clk_frequency_khz( int cccr_a = CCCR & (1 << 25); /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ - - /* We can't do this because we're at user level in Wombat. I'm just - going to fudge it for the moment -- DS*/ - // asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); - clkcfg = 0x09; - - t = clkcfg & (1 << 1); + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); + t = clkcfg & (1 << 0); ht = clkcfg & (1 << 2); b = clkcfg & (1 << 3); @@ -78,7 +82,7 @@ unsigned int get_clk_frequency_khz( int * Return the current mem clock frequency in units of 10kHz as * reflected by CCCR[A], B, and L */ -unsigned int get_memclk_frequency_10khz(void) +unsigned int pxa27x_get_memclk_frequency_10khz(void) { unsigned long ccsr, clkcfg; unsigned int l, L, m, M; @@ -88,8 +92,7 @@ unsigned int get_memclk_frequency_10khz( cccr_a = CCCR & (1 << 25); /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ - // asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); - clkcfg = 0x09; + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); b = clkcfg & (1 << 3); l = ccsr & 0x1f; @@ -104,7 +107,7 @@ unsigned int get_memclk_frequency_10khz( /* * Return the current LCD clock frequency in units of 10kHz as */ -unsigned int get_lcdclk_frequency_10khz(void) +static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) { unsigned long ccsr; unsigned int l, L, k, K; @@ -120,6 +123,345 @@ unsigned int get_lcdclk_frequency_10khz( return (K / 10000); } -EXPORT_SYMBOL(get_clk_frequency_khz); -EXPORT_SYMBOL(get_memclk_frequency_10khz); -EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) +{ + return pxa27x_get_lcdclk_frequency_10khz() * 10000; +} + +static const struct clkops clk_pxa27x_lcd_ops = { + .enable = clk_cken_enable, + .disable = clk_cken_disable, + .getrate = clk_pxa27x_lcd_getrate, +}; +#endif + +#if defined(CONFIG_CELL) + +static struct clk pxa27x_clks[] = { +// INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), +// INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), + + INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), +// INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), +// INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), + +// INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), +// INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), +// INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), +// INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), +// INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), + +// INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev), +// INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), +// INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), + + /* + INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL), + INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL), + INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), + INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), + INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), + INIT_CKEN("IMCLK", IM, 0, 0, NULL), + INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), + */ +}; + +#ifdef CONFIG_PM + +#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x +#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] + +#define RESTORE_GPLEVEL(n) do { \ + GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ + GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ +} while (0) + +/* + * List of global PXA peripheral registers to preserve. + * More ones like CP and general purpose register values are preserved + * with the stack pointer in sleep.S. + */ +enum { SLEEP_SAVE_START = 0, + + SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, + SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, + SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, + SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, + SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, + + SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, + SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, + SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, + SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, + + SLEEP_SAVE_PSTR, + + SLEEP_SAVE_ICMR, + SLEEP_SAVE_CKEN, + + SLEEP_SAVE_MDREFR, + SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, + SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, + + SLEEP_SAVE_SIZE +}; + +void pxa27x_cpu_pm_save(unsigned long *sleep_save) +{ + SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3); + SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3); + SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3); + SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3); + SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); + + SAVE(GAFR0_L); SAVE(GAFR0_U); + SAVE(GAFR1_L); SAVE(GAFR1_U); + SAVE(GAFR2_L); SAVE(GAFR2_U); + SAVE(GAFR3_L); SAVE(GAFR3_U); + + SAVE(MDREFR); + SAVE(PWER); SAVE(PCFR); SAVE(PRER); + SAVE(PFER); SAVE(PKWR); + + SAVE(ICMR); ICMR = 0; + SAVE(CKEN); + SAVE(PSTR); + + /* Clear GPIO transition detect bits */ + GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; +} + +void pxa27x_cpu_pm_restore(unsigned long *sleep_save) +{ + /* ensure not to come back here if it wasn't intended */ + PSPR = 0; + + /* restore registers */ + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); + RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); + RESTORE(GAFR0_L); RESTORE(GAFR0_U); + RESTORE(GAFR1_L); RESTORE(GAFR1_U); + RESTORE(GAFR2_L); RESTORE(GAFR2_U); + RESTORE(GAFR3_L); RESTORE(GAFR3_U); + RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); + RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); + RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); + + RESTORE(MDREFR); + RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); + RESTORE(PFER); RESTORE(PKWR); + + PSSR = PSSR_RDH | PSSR_PH; + + RESTORE(CKEN); + + ICLR = 0; + ICCR = 1; + RESTORE(ICMR); + RESTORE(PSTR); +} + +void pxa27x_cpu_pm_enter(suspend_state_t state) +{ + extern void pxa_cpu_standby(void); + + if (state == PM_SUSPEND_STANDBY) + CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | + (1 << CKEN_LCD) | (1 << CKEN_PWM0); + else + CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); + + /* ensure voltage-change sequencer not initiated, which hangs */ + PCFR &= ~PCFR_FVC; + + /* Clear edge-detect status register. */ + PEDR = 0xDF12FE1B; + + switch (state) { + case PM_SUSPEND_STANDBY: + pxa_cpu_standby(); + break; + case PM_SUSPEND_MEM: + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); + pxa27x_cpu_suspend(PWRMODE_SLEEP); + break; + } +} + +static int pxa27x_cpu_pm_valid(suspend_state_t state) +{ + return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; +} + +static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { + .save_size = SLEEP_SAVE_SIZE, + .save = pxa27x_cpu_pm_save, + .restore = pxa27x_cpu_pm_restore, + .valid = pxa27x_cpu_pm_valid, + .enter = pxa27x_cpu_pm_enter, +}; + +static void __init pxa27x_init_pm(void) +{ + pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; +} +#endif + +#if 0 +/* PXA27x: Various gpios can issue wakeup events. This logic only + * handles the simple cases, not the WEMUX2 and WEMUX3 options + */ +#define PXA27x_GPIO_NOWAKE_MASK \ + ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) +#define WAKEMASK(gpio) \ + (((gpio) <= 15) \ + ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ + : ((gpio == 35) ? (1 << 24) : 0)) + +static int pxa27x_set_wake(unsigned int irq, unsigned int on) +{ + int gpio = IRQ_TO_GPIO(irq); + uint32_t mask; + + if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) { + if (WAKEMASK(gpio) == 0) + return -EINVAL; + + mask = WAKEMASK(gpio); + + if (on) { + if (GRER(gpio) | GPIO_bit(gpio)) + PRER |= mask; + else + PRER &= ~mask; + + if (GFER(gpio) | GPIO_bit(gpio)) + PFER |= mask; + else + PFER &= ~mask; + } + goto set_pwer; + } + + switch (irq) { + case IRQ_RTCAlrm: + mask = PWER_RTC; + break; + case IRQ_USB: + mask = 1u << 26; + break; + default: + return -EINVAL; + } + +set_pwer: + if (on) + PWER |= mask; + else + PWER &=~mask; + + return 0; +} +#endif + +void __init pxa27x_init_irq(void) +{ +// pxa_init_irq_low(); +// pxa_init_irq_high(); +// pxa_init_irq_gpio(128); +// pxa_init_irq_set_wake(pxa27x_set_wake); +} + +/* + * device registration specific to PXA27x. + */ + +#if 0 +static u64 pxa27x_dmamask = 0xffffffffUL; + +static struct resource pxa27x_ohci_resources[] = { + [0] = { + .start = 0x4C000000, + .end = 0x4C00ff6f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBH1, + .end = IRQ_USBH1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_ohci = { + .name = "pxa27x-ohci", + .id = -1, + .dev = { + .dma_mask = &pxa27x_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa27x_ohci_resources), + .resource = pxa27x_ohci_resources, +}; + +void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) +{ + pxa27x_device_ohci.dev.platform_data = info; +} + +static struct resource i2c_power_resources[] = { + { + .start = 0x40f00180, + .end = 0x40f001a3, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PWRI2C, + .end = IRQ_PWRI2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_i2c_power = { + .name = "pxa2xx-i2c", + .id = 1, + .resource = i2c_power_resources, + .num_resources = ARRAY_SIZE(i2c_power_resources), +}; +#endif + +static struct platform_device *devices[] __initdata = { +// &pxa_device_mci, +// &pxa_device_udc, +// &pxa_device_fb, + &pxa_device_ffuart, +// &pxa_device_btuart, +// &pxa_device_stuart, +// &pxa_device_i2c, +// &pxa_device_i2s, +// &pxa_device_ficp, +// &pxa_device_rtc, +// &pxa27x_device_i2c_power, +// &pxa27x_device_ohci, +}; + +static int __init pxa27x_init(void) +{ + int ret = 0; + if (cpu_is_pxa27x()) { + clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); + + if ((ret = pxa_init_dma(32))) + return ret; +#ifdef CONFIG_PM + pxa27x_init_pm(); +#endif + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + } + return ret; +} + +subsys_initcall(pxa27x_init); +#endif diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c Wed Apr 22 20:24:29 2009 +0200 @@ -0,0 +1,209 @@ +/* + * Gumstix SMC911x chip intialization driver + * + * Author: Craig Hughes + * Created: December 9, 2004 + * Copyright: (C) 2004 Craig Hughes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/mii.h> + +#include <asm/hardware.h> +#include <asm/arch/pxa-regs.h> +#include <asm/delay.h> + +#include <asm/arch/gumstix.h> + +#define SMC_DEBUG 9 +#include <asm/io.h> +#include "smc911x.h" + +static struct resource gumstix_smc911x0_resources[] = { + [0] = { + .name = "smc911x-regs", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_PHYS, + .end = PXA_CS1_PHYS + 0x000fffff, +#endif + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = GUMSTIX_ETH0_IRQ, + .end = GUMSTIX_ETH0_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-dma", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_DMA, + .end = PXA_CS1_DMA + 0x000fffff, +#endif + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource gumstix_smc911x1_resources[] = { + [0] = { + .name = "smc911x-regs", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS2_PHYS, + .end = PXA_CS2_PHYS + 0x000fffff, +#endif + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = GUMSTIX_ETH1_IRQ, + .end = GUMSTIX_ETH1_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-dma", +#if defined(CONFIG_CELL) + .start = 0x00000000, + .end = 0x000fffff, +#else + .start = PXA_CS1_DMA, + .end = PXA_CS1_DMA + 0x000fffff, +#endif + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device gumstix_smc911x0_device = { + .name = "smc911x", + .id = 0, + .num_resources = ARRAY_SIZE(gumstix_smc911x0_resources), + .resource = gumstix_smc911x0_resources, +}; + +static struct platform_device gumstix_smc911x1_device = { + .name = "smc911x", + .id = 1, + .num_resources = ARRAY_SIZE(gumstix_smc911x1_resources), + .resource = gumstix_smc911x1_resources, +}; + +static struct platform_device *smc911x_devices[] = { + &gumstix_smc911x0_device, + &gumstix_smc911x1_device, +}; + +/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines + * that it would otherwise use. We have no choice but to probe by doing: + * Set nCS2 to CS2 mode + * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset) + * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device + */ +int __init gumstix_smc911x_init(void) +{ + unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices); + void *ioaddr; + printk("%s\n", __FUNCTION__); +#if defined(CONFIG_CELL) + gumstix_smc911x0_resources[0].start += PXA_CS1_PHYS; + printk("start: %lx\n", gumstix_smc911x0_resources[0].start); + gumstix_smc911x0_resources[0].end += PXA_CS1_PHYS; + gumstix_smc911x1_resources[0].start += PXA_CS2_PHYS; + gumstix_smc911x1_resources[0].end += PXA_CS2_PHYS; + + gumstix_smc911x0_resources[2].start += PXA_CS1_DMA; + gumstix_smc911x0_resources[2].end += PXA_CS1_DMA; + gumstix_smc911x1_resources[2].start += PXA_CS2_DMA; + gumstix_smc911x1_resources[2].end += PXA_CS2_DMA; +#endif + + printk("%s %d\n", __FILE__, __LINE__); + + /* Set up nPWE */ + pxa_gpio_mode(GPIO49_nPWE_MD); + + pxa_gpio_mode(GPIO78_nCS_2_MD); + // If either if statement fails, then we'll drop out and turn_off_eth1, + // if both succeed, then we'll skip that and just proceed with 2 cards + printk("%s %d\n", __FILE__, __LINE__); +#if 0 /* do not check for second network interface */ + if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe")) + { + printk("%s %d\n", __FILE__, __LINE__); + ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); + printk("%s %d ioaddr 0x%p\n", __FILE__, __LINE__, ioaddr); + val = SMC_GET_PN(); + printk("%s %d\n", __FILE__, __LINE__); + iounmap(ioaddr); + printk("%s %d\n", __FILE__, __LINE__); + release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); + printk("%s %d\n", __FILE__, __LINE__); + if (CHIP_9115 == val || + CHIP_9116 == val || + CHIP_9117 == val || + CHIP_9118 == val ) { + goto proceed; + } + printk("%s %d\n", __FILE__, __LINE__); + } +#endif + + printk("%s %d\n", __FILE__, __LINE__); +turn_off_eth1: + // This is apparently not an SMC911x + // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode + num_devices--; + smc911x_devices[1] = NULL; + pxa_gpio_mode(78 | GPIO_IN); + + printk("%s %d\n", __FILE__, __LINE__); +proceed: + pxa_gpio_mode(GPIO15_nCS_1_MD); + + if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD); + pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD); + + if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); + GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); + msleep(500); // Hold RESET for at least 200õ + + if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); + GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); + msleep(50); + + printk("%s %d\n", __FILE__, __LINE__); + return platform_add_devices(smc911x_devices, num_devices); +} + +void __exit gumstix_smc911x_exit(void) +{ + if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device); + platform_device_unregister(&gumstix_smc911x0_device); +} + +void gumstix_smc911x_load(void) {} +EXPORT_SYMBOL(gumstix_smc911x_load); + +module_init(gumstix_smc911x_init); +module_exit(gumstix_smc911x_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Craig Hughes <[hidden email]>"); +MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver"); +MODULE_VERSION("1:0.1"); diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/smc911x.c --- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c Wed Apr 22 20:24:29 2009 +0200 @@ -27,32 +27,13 @@ * History: * 04/16/05 Dustin McIntire Initial version */ + static const char version[] = "smc911x.c: v1.0 04-16-2005 by Dustin McIntire <[hidden email]>\n"; -/* Debugging options */ -#define ENABLE_SMC_DEBUG_RX 0 -#define ENABLE_SMC_DEBUG_TX 0 -#define ENABLE_SMC_DEBUG_DMA 0 -#define ENABLE_SMC_DEBUG_PKTS 0 -#define ENABLE_SMC_DEBUG_MISC 0 -#define ENABLE_SMC_DEBUG_FUNC 0 - -#define SMC_DEBUG_RX ((ENABLE_SMC_DEBUG_RX ? 1 : 0) << 0) -#define SMC_DEBUG_TX ((ENABLE_SMC_DEBUG_TX ? 1 : 0) << 1) -#define SMC_DEBUG_DMA ((ENABLE_SMC_DEBUG_DMA ? 1 : 0) << 2) -#define SMC_DEBUG_PKTS ((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3) -#define SMC_DEBUG_MISC ((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4) -#define SMC_DEBUG_FUNC ((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5) - #ifndef SMC_DEBUG -#define SMC_DEBUG ( SMC_DEBUG_RX | \ - SMC_DEBUG_TX | \ - SMC_DEBUG_DMA | \ - SMC_DEBUG_PKTS | \ - SMC_DEBUG_MISC | \ - SMC_DEBUG_FUNC \ - ) +#define SMC_DEBUG 0 +#define SMC_DEBUG_PKTS 0 #endif #include <linux/init.h> @@ -76,6 +57,7 @@ static const char version[] = #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/irq.h> #include <asm/io.h> #include "smc911x.h" @@ -295,14 +277,14 @@ static void smc911x_reset(struct net_dev SMC_SET_AFC_CFG(lp->afc_cfg); - /* Set to LED outputs */ - SMC_SET_GPIO_CFG(0x70070000); + /* Set to LED outputs and configure EEPROM pins as GP outputs */ + SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20); /* - * Deassert IRQ for 1*10us for edge type interrupts + * Deassert IRQ for 22*10us for edge type interrupts * and drive IRQ pin push-pull */ - SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); + SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); /* clear anything saved */ if (lp->pending_tx_skb != NULL) { @@ -405,7 +387,7 @@ static inline void smc911x_drop_pkt(stru if (fifo_count <= 4) { /* Manually dump the packet data */ while (fifo_count--) - SMC_GET_RX_FIFO(); + (void)SMC_GET_RX_FIFO(); } else { /* Fast forward through the bad packet */ SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_); @@ -891,6 +873,7 @@ static void smc911x_phy_powerdown(struct unsigned long ioaddr = dev->base_addr; unsigned int bmcr; + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); /* Enter Link Disable state */ SMC_GET_PHY_BMCR(phy, bmcr); bmcr |= BMCR_PDOWN; @@ -916,6 +899,7 @@ static void smc911x_phy_check_media(stru if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { /* duplex state has changed */ + DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name); SMC_GET_PHY_BMCR(phyaddr, bmcr); SMC_GET_MAC_CR(cr); if (lp->mii.full_duplex) { @@ -951,6 +935,7 @@ static void smc911x_phy_configure(struct int my_phy_caps; /* My PHY capabilities */ int my_ad_caps; /* My Advertised capabilities */ int status; + int bmcr; unsigned long flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); @@ -1024,9 +1009,12 @@ static void smc911x_phy_configure(struct DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps); DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps); + DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status); /* Restart auto-negotiation process in order to advertise my caps */ - SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); + SMC_GET_PHY_BMCR(phyaddr, bmcr); + bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; + SMC_SET_PHY_BMCR(phyaddr, bmcr); smc911x_phy_check_media(dev, 1); @@ -1856,6 +1844,48 @@ static int __init smc911x_findirq(unsign return probe_irq_off(cookie); } +static inline unsigned int is_gumstix_oui(u8 *addr) +{ + return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9); +} + +/** + * gen_serial_ether_addr - Generate software assigned Ethernet address + * based on the system_serial number + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Generate an Ethernet address (MAC) that is not multicast + * and has the local assigned bit set, keyed on the system_serial + */ +static inline void gen_serial_ether_addr(u8 *addr) +{ +#ifdef CONFIG_CELL + addr [0] = 0x00; + addr [1] = 0x15; + addr [2] = 0xC9; + addr [3] = 0x83; + addr [4] = 0x82; + addr [5] = 0x81; +#else + static u8 ether_serial_digit = 0; + addr [0] = system_serial_high >> 8; + addr [1] = system_serial_high; + addr [2] = system_serial_low >> 24; + addr [3] = system_serial_low >> 16; + addr [4] = system_serial_low >> 8; + addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */ + (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */ + ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */ +#endif + + if(!is_gumstix_oui(addr)) + { + addr [0] &= 0xfe; /* clear multicast bit */ + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ + } +} + + /* * Function: smc911x_probe(unsigned long ioaddr) * @@ -2082,15 +2112,13 @@ static int __init smc911x_probe(struct n #endif printk("\n"); if (!is_valid_ether_addr(dev->dev_addr)) { - printk("%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", dev->name); - } else { - /* Print the Ethernet address */ - printk("%s: Ethernet addr: ", dev->name); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[5]); + gen_serial_ether_addr(dev->dev_addr); } + /* Print the Ethernet address */ + printk("%s: Ethernet addr: ", dev->name); + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[5]); if (lp->phy_type == 0) { PRINTK("%s: No PHY found\n", dev->name); @@ -2265,8 +2293,15 @@ static struct platform_driver smc911x_dr }, }; +#ifdef CONFIG_ARCH_GUMSTIX +extern void gumstix_smc911x_load(void); +#endif + static int __init smc911x_init(void) { +#ifdef CONFIG_ARCH_GUMSTIX + gumstix_smc911x_load(); +#endif return platform_driver_register(&smc911x_driver); } diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/smc911x.h --- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h Wed Apr 22 20:24:29 2009 +0200 @@ -33,7 +33,9 @@ * Use the DMA feature on PXA chips */ #ifdef CONFIG_ARCH_PXA +#if !defined( CONFIG_SMC911X_GUMSTIX ) && !defined( CONFIG_SMC911X_GUMSTIX_MODULE ) #define SMC_USE_PXA_DMA 1 +#endif #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING @@ -52,13 +54,13 @@ #if SMC_USE_16BIT #define SMC_inb(a, r) readb((a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16)) +#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16)) #define SMC_outb(v, a, r) writeb(v, (a) + (r)) #define SMC_outw(v, a, r) writew(v, (a) + (r)) #define SMC_outl(v, a, r) \ do{ \ - writel(v & 0xFFFF, (a) + (r)); \ - writel(v >> 16, (a) + (r) + 2); \ + writel((v) & 0xFFFF, (a) + (r)); \ + writel((v) >> 16, (a) + (r) + 2); \ } while (0) #define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2) #define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2) diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h --- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h Wed Apr 22 20:24:29 2009 +0200 @@ -43,8 +43,9 @@ #ifdef CONFIG_PXA27x #define __cpu_is_pxa27x(id) \ ({ \ - unsigned int _id = (id) >> 4 & 0xfff; \ - _id == 0x411; \ + /*unsigned int _id = (id) >> 4 & 0xfff; */ \ + /*_id == 0x411; */ \ + 0 == 0; \ }) #else #define __cpu_is_pxa27x(id) (0) diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h --- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h Wed Apr 22 20:24:29 2009 +0200 @@ -73,8 +73,12 @@ #define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */ #endif -#if defined(CONFIG_CELL) && defined(CONFIG_PXA25x) +#if defined(CONFIG_CELL) +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) #define PXA_GPIO_IRQ_BASE (32 - 2) +#else +#error cpu not supported +#endif #else #define PXA_GPIO_IRQ_BASE (64) #endif diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h --- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h Wed Apr 08 15:37:40 2009 +0200 +++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h Wed Apr 22 20:24:29 2009 +0200 @@ -26,6 +26,8 @@ extern unsigned long DMAC_BASE; extern unsigned long PXA_CS1_PHYS, PXA_CS1_DMA; extern unsigned long PXA_CS2_PHYS, PXA_CS2_DMA; +extern unsigned long PXA_CS3_PHYS, PXA_CS3_DMA; +extern unsigned long PXA_CS4_PHYS, PXA_CS4_DMA; #else @@ -1213,14 +1215,14 @@ extern unsigned long PXA_CS2_PHYS, PXA_C #define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ #define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ -#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) -#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) -#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3) -#define _GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3) -#define _GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3) -#define _GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3) -#define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) -#define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) +#define _GPLR(x) __REG2_GPIO(0x40E00000, ((x) & 0x60) >> 3) +#define _GPDR(x) __REG2_GPIO(0x40E0000C, ((x) & 0x60) >> 3) +#define _GPSR(x) __REG2_GPIO(0x40E00018, ((x) & 0x60) >> 3) +#define _GPCR(x) __REG2_GPIO(0x40E00024, ((x) & 0x60) >> 3) +#define _GRER(x) __REG2_GPIO(0x40E00030, ((x) & 0x60) >> 3) +#define _GFER(x) __REG2_GPIO(0x40E0003C, ((x) & 0x60) >> 3) +#define _GEDR(x) __REG2_GPIO(0x40E00048, ((x) & 0x60) >> 3) +#define _GAFR(x) __REG2_GPIO(0x40E00054, ((x) & 0x70) >> 2) #define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3)) #define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3)) @@ -1342,6 +1344,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C #define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ #define GPIO78_nCS_2 78 /* chip select 2 */ #define GPIO79_nCS_3 79 /* chip select 3 */ +#define GPIO79_pSKTSEL 79 /* Socket Select for Card Space (PXA27x) */ #define GPIO80_nCS_4 80 /* chip select 4 */ #define GPIO81_NSCLK 81 /* NSSP clock */ #define GPIO82_NSFRM 82 /* NSSP Frame */ @@ -1351,6 +1354,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C #define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ #define GPIO104_pSKTSEL 104 /* PCMCIA Socket Select (PXA27x) */ +#define GPIO105_nPCE_2 105 /* Card Enable for Card Space (PXA27x) */ #define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ #define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ #define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ @@ -1496,6 +1500,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) +#define GPIO105_nPCE_2_MD (105 | GPIO_ALT_FN_1_OUT) #define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) [okl4_pxa270_platform.patch] diff -r 4e814c1899b6 platform/pxa/pistachio/include/intctrl.h --- a/platform/pxa/pistachio/include/intctrl.h Wed Apr 08 15:37:40 2009 +0200 +++ b/platform/pxa/pistachio/include/intctrl.h Wed Apr 22 20:22:40 2009 +0200 @@ -102,9 +102,15 @@ #define PXA_GRER0 (*(volatile word_t *)(PXA_GPIO + 0x30)) /* GPIO rising edge 0 */ #define PXA_GRER1 (*(volatile word_t *)(PXA_GPIO + 0x34)) /* GPIO rising edge 1 */ #define PXA_GRER2 (*(volatile word_t *)(PXA_GPIO + 0x38)) /* GPIO rising edge 2 */ +#if defined(CONFIG_SUBPLAT_PXA270) +#define PXA_GRER3 (*(volatile word_t *)(PXA_GPIO + 0x130)) /* GPIO rising edge 3 */ +#endif #define PXA_GFER0 (*(volatile word_t *)(PXA_GPIO + 0x3C)) /* GPIO falling edge 0 */ #define PXA_GFER1 (*(volatile word_t *)(PXA_GPIO + 0x40)) /* GPIO falling edge 1 */ #define PXA_GFER2 (*(volatile word_t *)(PXA_GPIO + 0x44)) /* GPIO falling edge 2 */ +#if defined(CONFIG_SUBPLAT_PXA270) +#define PXA_GFER3 (*(volatile word_t *)(PXA_GPIO + 0x13C)) /* GPIO falling edge 3 */ +#endif #endif /*__PLATFORM__PXA__INTCTRL_H__ */ diff -r 4e814c1899b6 platform/pxa/pistachio/include/interrupt.h --- a/platform/pxa/pistachio/include/interrupt.h Wed Apr 08 15:37:40 2009 +0200 +++ b/platform/pxa/pistachio/include/interrupt.h Wed Apr 22 20:22:40 2009 +0200 @@ -70,7 +70,12 @@ #define PMN0_IRQ_ENABLE (1UL << 4) #define PRIMARY_IRQS 32 +#if defined(CONFIG_SUBPLAT_PXA255) #define GPIO_IRQS (85 - 2) /* The first two IRQs have level one interrupts */ +#elif defined(CONFIG_SUBPLAT_PXA270) +#define GPIO_IRQS (121 - 2) /* The first two IRQs have level one interrupts; + PXA270 bounds 119; PXA271 and PXA272 bounds all 121 */ +#endif #define GPIO_IRQ 10 #define IRQS (PRIMARY_IRQS + GPIO_IRQS) diff -r 4e814c1899b6 platform/pxa/pistachio/include/timer.h --- a/platform/pxa/pistachio/include/timer.h Wed Apr 08 15:37:40 2009 +0200 +++ b/platform/pxa/pistachio/include/timer.h Wed Apr 22 20:22:40 2009 +0200 @@ -80,7 +80,7 @@ static const int TIMER_TICK_LENGTH = 500 #error Invalid sub-architecture #endif -#if defined(CONFIG_PXA270) +#if defined(CONFIG_SUBPLAT_PXA270) /* CLKCFG Modes */ #define CLKCFG_B (1<<3) /* Fast Bus Mode */ #define CLKCFG_HT (1<<2) /* Half Turbo */ diff -r 4e814c1899b6 platform/pxa/pistachio/src/interrupt.c --- a/platform/pxa/pistachio/src/interrupt.c Wed Apr 08 15:37:40 2009 +0200 +++ b/platform/pxa/pistachio/src/interrupt.c Wed Apr 22 20:22:40 2009 +0200 @@ -78,7 +78,7 @@ addr_t xscale_int_va; addr_t xscale_int_va; addr_t xscale_gpio_va; -#if !defined(CONFIG_SUBPLAT_PXA255) +#if !defined(CONFIG_SUBPLAT_PXA255) && !defined(CONFIG_SUBPLAT_PXA270) #error "Unsupported subplatform." #endif @@ -107,13 +107,28 @@ soc_unmask_irq(word_t irq) /* XXX This is a GPIO IRQ and we should unmask GPIO set */ XSCALE_INT_ICMR |= (1 << GPIO_IRQ); + /* XXX unmask falling edge detect too. + * smc911x on gumstix uses falling edge interrupts */ if (idx == 0) { PXA_GRER0 = (1UL << gpio); + PXA_GFER0 = (1UL << gpio); } else if (idx == 1) { PXA_GRER1 = (1UL << gpio); - } else { + PXA_GFER1 = (1UL << gpio); + } else +#if defined(CONFIG_SUBPLAT_PXA270) + if (idx == 2) +#endif + { PXA_GRER2 = (1UL << gpio); + PXA_GFER2 = (1UL << gpio); } +#if defined(CONFIG_SUBPLAT_PXA270) + else { + PXA_GRER3 = (1UL << gpio); + PXA_GFER3 = (1UL << gpio); + } +#endif } } @@ -147,6 +162,15 @@ pxa_gpio_irq(void) return 64 + irq - 2; } + +#if defined(CONFIG_SUBPLAT_PXA270) + mask = PXA_GEDR3; + if (mask) { + irq = msb(mask); + PXA_GEDR3 = (1UL << irq); + return 96 + irq - 2; + } +#endif return -1; } diff -r 4e814c1899b6 platform/pxa/tools/machines.py --- a/platform/pxa/tools/machines.py Wed Apr 08 15:37:40 2009 +0200 +++ b/platform/pxa/tools/machines.py Wed Apr 22 20:22:40 2009 +0200 @@ -77,7 +77,8 @@ class gumstix(pxa): cs_driver = "pxa250_cs" uart = "FFUART" serial_driver = "uart_8250" - subplatform = "pxa255" +# subplatform = "pxa255" + subplatform = "pxa270" drivers = [timer_driver] + pxa.drivers device_core = "gumstix" @@ -91,10 +92,12 @@ class gumstix(pxa): interrupt_rtc = [31] memory_irq_controller = [Region(0x40d00000, 0x40d01000, "all", "uncached")] memory_gpio = [Region(0x40e00000, 0x40e01000, "all", "uncached")] - interrupt_gpio = [8,9] + range(32,32+(85-2)) + interrupt_gpio = [8,9] + range(32,32+(121 - 2)) memory_cs = [Region(0x00000000, 0x04000000, "all", "uncached"), Region(0x04000000, 0x08000000, "all", "uncached"), - Region(0x08000000, 0x0c000000, "all", "uncached")] + Region(0x08000000, 0x0c000000, "all", "uncached"), + Region(0x0c000000, 0x10000000, "all", "uncached"), + Region(0x10000000, 0x14000000, "all", "uncached")] pmu_irq = [12] v2_drivers = [ ("test_device", "vtest", [], [1,3]), _______________________________________________ Developer mailing list [hidden email] https://lists.okl4.org/mailman/listinfo/developer |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |