Commit c520e749 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] mips: SGI IP32 updates

SGI IP32 aka O2 Updates:

 o Handle all possibly memory configurations
 o Fix PS/2 handling
 o Sysfs magic for IP32's GBE frame buffer driver.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ffe90e0f
......@@ -496,6 +496,11 @@ config REPLICATE_EXHANDLERS
config SGI_IP32
bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
depends on MIPS64 && EXPERIMENTAL
select ARC
select ARC32
select BOOT_ELF32
select OWN_DMA
select DMA_IP32
select DMA_NONCOHERENT
select HW_HAS_PCI
select R5000_CPU_SCACHE
......
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.10-rc2
# Sun Nov 21 14:12:00 2004
# Linux kernel version: 2.6.11-rc2
# Wed Jan 26 02:49:04 2005
#
CONFIG_MIPS=y
CONFIG_MIPS64=y
......@@ -78,14 +78,16 @@ CONFIG_SGI_IP32=y
# CONFIG_SIBYTE_SB1xxx_SOC is not set
# CONFIG_SNI_RM200_PCI is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_IP32=y
CONFIG_OWN_DMA=y
CONFIG_DMA_NONCOHERENT=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_ARC32=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_ARC32=y
# CONFIG_FB is not set
CONFIG_ARC_MEMORY=y
CONFIG_ARC_PROMLIB=y
......@@ -130,6 +132,20 @@ CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PC-card bridges
#
#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
#
......@@ -151,6 +167,7 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
# Memory Technology Devices (MTD)
......@@ -174,11 +191,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
......@@ -191,6 +210,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_ATA_OVER_ETH=y
#
# ATA/ATAPI/MFM/RLL support
......@@ -225,6 +245,7 @@ CONFIG_SCSI_LOGGING=y
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
......@@ -258,14 +279,12 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLOGIC_1280_1040 is not set
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
# CONFIG_SCSI_QLA6322 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
......@@ -465,6 +484,7 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_MACEPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=y
#
......@@ -519,7 +539,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
......@@ -550,12 +569,14 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
# CONFIG_FB is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
......@@ -569,11 +590,25 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# File systems
#
......@@ -677,6 +712,11 @@ CONFIG_SGI_PARTITION=y
#
# CONFIG_NLS is not set
#
# Profiling support
#
# CONFIG_PROFILING is not set
#
# Kernel hacking
#
......@@ -696,6 +736,10 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#
#
# Library routines
#
......
......@@ -4,6 +4,6 @@
#
obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
crime.o
crime.o ip32-memory.o
EXTRA_AFLAGS := $(CFLAGS)
......@@ -4,6 +4,7 @@
* for more details.
*
* Copyright (C) 2001, 2003 Keith M Wesolowski
* Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
*/
#include <linux/types.h>
#include <linux/init.h>
......@@ -24,7 +25,8 @@ void __init crime_init(void)
{
unsigned int id, rev;
const int field = 2 * sizeof(unsigned long);
set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
......
......@@ -117,7 +117,7 @@ static void inline flush_mace_bus(void)
* IRQ spinlock - Ralf says not to disable CPU interrupts,
* and I think he knows better.
*/
static spinlock_t ip32_irq_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(ip32_irq_lock);
/* Some initial interrupts to set up */
extern irqreturn_t crime_memerr_intr (int irq, void *dev_id,
......
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2003 Keith M Wesolowski
* Copyright (C) 2005 Ilya A. Volynets (Total Knowledge)
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/ip32/crime.h>
#include <asm/bootinfo.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
extern void crime_init(void);
void __init prom_meminit (void)
{
u64 base, size;
int bank;
crime_init();
for (bank=0; bank < CRIME_MAXBANKS; bank++) {
u64 bankctl = crime->bank_ctrl[bank];
base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25;
if (bank != 0 && base == 0)
continue;
size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32;
size <<= 20;
if (base + size > (256 << 20))
base += CRIME_HI_MEM_BASE;
printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
bank, base, size);
add_memory_region (base, size, BOOT_MEM_RAM);
}
}
unsigned long __init prom_free_prom_memory (void)
{
return 0;
}
......@@ -189,11 +189,13 @@ static __init int ip32_reboot_setup(void)
_machine_restart = ip32_machine_restart;
_machine_halt = ip32_machine_halt;
_machine_power_off = ip32_machine_power_off;
request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
init_timer(&blink_timer);
blink_timer.function = blink_timeout;
notifier_chain_register(&panic_notifier_list, &panic_block);
request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
return 0;
}
......
......@@ -6,7 +6,7 @@
* for more details.
*
* Copyright (C) 2000 Harald Koerfgen
* Copyright (C) 2002, 03 Ilya A. Volynets
* Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
*/
#include <linux/config.h>
#include <linux/console.h>
......@@ -94,10 +94,6 @@ void __init ip32_timer_setup(struct irqaction *irq)
static int __init ip32_setup(void)
{
set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
crime_init();
board_be_init = ip32_be_init;
rtc_get_time = mc146818_get_cmos_time;
......
......@@ -62,8 +62,8 @@ static int maceps2_write(struct serio *dev, unsigned char val)
unsigned int timeout = MACE_PS2_TIMEOUT;
do {
if (mace_read(port->status) & PS2_STATUS_TX_EMPTY) {
mace_write(val, port->tx);
if (port->status & PS2_STATUS_TX_EMPTY) {
port->tx = val;
return 0;
}
udelay(50);
......@@ -72,14 +72,15 @@ static int maceps2_write(struct serio *dev, unsigned char val)
return -1;
}
static irqreturn_t maceps2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
struct serio *dev = dev_id;
struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
unsigned int byte;
unsigned long byte;
if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
byte = mace_read(port->rx);
if (port->status & PS2_STATUS_RX_FULL) {
byte = port->rx;
serio_interrupt(dev, byte & 0xff, 0, regs);
}
......@@ -96,13 +97,13 @@ static int maceps2_open(struct serio *dev)
}
/* Reset port */
mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
data->port->control);
data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
udelay(100);
/* Enable interrupts */
mace_write(PS2_CONTROL_RX_CLOCK_ENABLE | PS2_CONTROL_TX_ENABLE |
PS2_CONTROL_RX_INT_ENABLE, data->port->control);
data->port->control = PS2_CONTROL_RX_CLOCK_ENABLE |
PS2_CONTROL_TX_ENABLE |
PS2_CONTROL_RX_INT_ENABLE;
return 0;
}
......@@ -111,8 +112,7 @@ static void maceps2_close(struct serio *dev)
{
struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
data->port->control);
data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
udelay(100);
free_irq(data->irq, dev);
}
......
......@@ -85,7 +85,6 @@ static struct {
static int gbe_revision;
static struct fb_info fb_info;
static int ypan, ywrap;
static uint32_t pseudo_palette[256];
......@@ -190,8 +189,6 @@ struct fb_var_screeninfo *default_var = &default_var_CRT;
static int flat_panel_enabled = 0;
static struct gbefb_par par_current;
static void gbe_reset(void)
{
/* Turn on dotclock PLL */
......@@ -1044,6 +1041,36 @@ static struct fb_ops gbefb_ops = {
.fb_cursor = soft_cursor,
};
/*
* sysfs
*/
static ssize_t gbefb_show_memsize(struct device *dev, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
}
static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
static ssize_t gbefb_show_rev(struct device *device, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
}
static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
static void __devexit gbefb_remove_sysfs(struct device *dev)
{
device_remove_file(dev, &dev_attr_size);
device_remove_file(dev, &dev_attr_revision);
}
static void gbefb_create_sysfs(struct device *dev)
{
device_create_file(dev, &dev_attr_size);
device_create_file(dev, &dev_attr_revision);
}
/*
* Initialization
*/
......@@ -1079,13 +1106,21 @@ int __init gbefb_setup(char *options)
return 0;
}
int __init gbefb_init(void)
static int __init gbefb_probe(struct device *dev)
{
int i, ret = 0;
struct fb_info *info;
struct gbefb_par *par;
struct platform_device *p_dev = to_platform_device(dev);
#ifndef MODULE
char *options = NULL;
#endif
info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
if (!info)
return -ENOMEM;
#ifndef MODULE
if (fb_get_options("gbefb", &options))
return -ENODEV;
gbefb_setup(options);
......@@ -1093,7 +1128,8 @@ int __init gbefb_init(void)
if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
return -EBUSY;
ret = -EBUSY;
goto out_release_framebuffer;
}
gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
......@@ -1113,7 +1149,6 @@ int __init gbefb_init(void)
goto out_unmap;
}
if (gbe_mem_phys) {
/* memory was allocated at boot time */
gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
......@@ -1140,32 +1175,35 @@ int __init gbefb_init(void)
for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
fb_info.fbops = &gbefb_ops;
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_DEFAULT;
fb_info.screen_base = gbe_mem;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
info->fbops = &gbefb_ops;
info->pseudo_palette = pseudo_palette;
info->flags = FBINFO_DEFAULT;
info->screen_base = gbe_mem;
fb_alloc_cmap(&info->cmap, 256, 0);
/* reset GBE */
gbe_reset();
par = info->par;
/* turn on default video mode */
if (fb_find_mode(&par_current.var, &fb_info, mode_option, NULL, 0,
if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
default_mode, 8) == 0)
par_current.var = *default_var;
fb_info.var = par_current.var;
gbefb_check_var(&par_current.var, &fb_info);
gbefb_encode_fix(&fb_info.fix, &fb_info.var);
fb_info.par = &par_current;
par->var = *default_var;
info->var = par->var;
gbefb_check_var(&par->var, info);
gbefb_encode_fix(&info->fix, &info->var);
if (register_framebuffer(&fb_info) < 0) {
ret = -ENXIO;
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
ret = -ENXIO;
goto out_gbe_unmap;
}
dev_set_drvdata(&p_dev->dev, info);
gbefb_create_sysfs(dev);
printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
fb_info.node, fb_info.fix.id, gbe_revision, (unsigned) GBE_BASE,
info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
gbe_mem_size >> 10);
return 0;
......@@ -1182,12 +1220,18 @@ int __init gbefb_init(void)
iounmap(gbe);
out_release_mem_region:
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
out_release_framebuffer:
framebuffer_release(info);
return ret;
}
void __exit gbefb_exit(void)
static int __devexit gbefb_remove(struct device* dev)
{
unregister_framebuffer(&fb_info);
struct platform_device *p_dev = to_platform_device(dev);
struct fb_info *info = dev_get_drvdata(&p_dev->dev);
unregister_framebuffer(info);
gbe_turn_off();
if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
......@@ -1197,12 +1241,40 @@ void __exit gbefb_exit(void)
(void *)gbe_tiles.cpu, gbe_tiles.dma);
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
iounmap(gbe);
gbefb_remove_sysfs(dev);
framebuffer_release(info);
return 0;
}
module_init(gbefb_init);
static struct device_driver gbefb_driver = {
.name = "gbefb",
.bus = &platform_bus_type,
.probe = gbefb_probe,
.remove = __devexit_p(gbefb_remove),
};
static struct platform_device gbefb_device = {
.name = "gbefb",
};
#ifdef MODULE
int __init gbefb_init(void)
{
int ret = driver_register(&gbefb_driver);
if (!ret) {
ret = platform_device_register(&gbefb_device);
if (ret)
driver_unregister(&gbefb_driver);
}
return ret;
}
void __exit gbefb_exit(void)
{
driver_unregister(&gbefb_driver);
}
module_init(gbefb_init);
module_exit(gbefb_exit);
#endif
MODULE_LICENSE("GPL");
......@@ -156,4 +156,6 @@ struct sgi_crime {
extern struct sgi_crime *crime;
#define CRIME_HI_MEM_BASE 0x40000000 /* this is where whole 1G of RAM is mapped */
#endif /* __ASM_CRIME_H__ */
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2005 Ilya A. Volynets-Evenbakh
* Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
*/
#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
#include <linux/config.h>
/*
* R5000 has an interesting "restriction": ll(d)/sc(d)
* instructions to XKPHYS region simply do uncached bus
* requests. This breaks all the atomic bitops functions.
* so, for 64bit IP32 kernel we just don't use ll/sc.
* This does not affect luserland.
*/
#if defined(CONFIG_CPU_R5000) && defined(CONFIG_MIPS64)
#define cpu_has_llsc 0
#else
#define cpu_has_llsc 1
#endif
/* Settings which are common for all ip32 CPUs */
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
#define cpu_has_mips16 0
#define cpu_has_vce 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_mcheck 0
#define cpu_has_ejtag 0
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 0
#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
......@@ -15,7 +15,6 @@
#include <asm/ip32/mace.h>
#define RTC_PORT(x) (0x70 + (x))
#define RTC_IRQ MACEISA_RTC_IRQ
static unsigned char CMOS_READ(unsigned long addr)
{
......
......@@ -3,20 +3,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
* Copyright (C) 1994 - 1999, 2000, 03, 04, 05 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2000, 2002 Maciej W. Rozycki
* Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_MACH_IP32_SPACES_H
#define _ASM_MACH_IP32_SPACES_H
#include <linux/config.h>
/*
* This handles the memory map.
*/
#define PAGE_OFFSET 0xffffffff80000000
/*
* Memory above this physical address will be considered highmem.
* Fixme: 59 bits is a fictive number and makes assumptions about processors
......@@ -26,11 +19,7 @@
#define HIGHMEM_START (1UL << 59UL)
#endif
#ifdef CONFIG_DMA_NONCOHERENT
#define CAC_BASE 0x9800000000000000
#else
#define CAC_BASE 0xa800000000000000
#endif
#define IO_BASE 0x9000000000000000
#define UNCAC_BASE 0x9000000000000000
#define MAP_BASE 0xc000000000000000
......@@ -39,4 +28,9 @@
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
/*
* This handles the memory map.
*/
#define PAGE_OFFSET CAC_BASE
#endif /* __ASM_MACH_IP32_SPACES_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment