From: YAEGASHI T. <yae...@ma...> - 2000-09-27 23:04:24
|
Here are the latest HP600 updates. These will be available at Patch Manager of SourceForge. Introduced new machine vectors(hp620, hp680, hp690) and now we could support all of them more easily. -- YAEGASHI Takeshi <yae...@ma...> Index: kernel/arch/sh/config.in diff -u kernel/arch/sh/config.in:1.1.1.9 kernel/arch/sh/config.in:1.11.2.2 --- kernel/arch/sh/config.in:1.1.1.9 Tue Sep 26 22:56:34 2000 +++ kernel/arch/sh/config.in Wed Sep 27 16:21:55 2000 @@ -28,9 +28,16 @@ "Generic CONFIG_SH_GENERIC \ SolutionEngine CONFIG_SH_SOLUTION_ENGINE \ Overdrive CONFIG_SH_OVERDRIVE \ - HP600 CONFIG_SH_HP600 \ + HP620 CONFIG_SH_HP620 \ + HP680 CONFIG_SH_HP680 \ + HP690 CONFIG_SH_HP690 \ CqREEK CONFIG_SH_CQREEK \ BareCPU CONFIG_SH_UNKNOWN" Generic + +if [ "$CONFIG_SH_HP620" = "y" -o "$CONFIG_SH_HP680" = "y" -o \ + "$CONFIG_SH_HP690" = "y" ]; then + define_bool CONFIG_SH_HP600 y +fi choice 'Processor type' \ "SH7707 CONFIG_CPU_SUBTYPE_SH7707 \ Index: kernel/arch/sh/kernel/io_hd64461.c diff -u kernel/arch/sh/kernel/io_hd64461.c:1.1.1.4 kernel/arch/sh/kernel/io_hd64461.c:1.8 --- kernel/arch/sh/kernel/io_hd64461.c:1.1.1.4 Tue Aug 1 23:25:31 2000 +++ kernel/arch/sh/kernel/io_hd64461.c Mon Sep 4 07:25:30 2000 @@ -27,6 +27,12 @@ detail of CF's memory mapped addressing. */ if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port; if (port == 0x3f6) return 0xb50001fe; + if (port == 0x3f7) return 0xb50001ff; + + /* ide1 */ + if (0x170<=port && port<=0x177) return 0xba0001f0 + port - 0x170; + if (port == 0x376) return 0xba0003f6; + if (port == 0x377) return 0xba0003f7; #endif /* ??? */ Index: kernel/arch/sh/kernel/mach_hp600.c diff -u kernel/arch/sh/kernel/mach_hp600.c:1.1.1.2 kernel/arch/sh/kernel/mach_hp600.c:1.4 --- kernel/arch/sh/kernel/mach_hp600.c:1.1.1.2 Tue Aug 1 23:25:32 2000 +++ kernel/arch/sh/kernel/mach_hp600.c Mon Sep 4 07:25:31 2000 @@ -22,8 +22,8 @@ * The Machine Vector */ -struct sh_machine_vector mv_hp600 __initmv = { - mv_name: "HP600", +struct sh_machine_vector mv_hp620 __initmv = { + mv_name: "hp620", mv_nr_irqs: 80, /* HD64461_IRQBASE+16, see hd64461.h */ @@ -58,6 +58,91 @@ mv_irq_demux: hd64461_irq_demux, mv_hw_hp600: 1, + mv_hw_hp620: 1, mv_hw_hd64461: 1, }; -ALIAS_MV(hp600) +ALIAS_MV(hp620) + + +struct sh_machine_vector mv_hp680 __initmv = { + mv_name: "hp680", + + mv_nr_irqs: 80, /* HD64461_IRQBASE+16, see hd64461.h */ + + mv_inb: hd64461_inb, + mv_inw: hd64461_inw, + mv_inl: hd64461_inl, + mv_outb: hd64461_outb, + mv_outw: hd64461_outw, + mv_outl: hd64461_outl, + + mv_inb_p: hd64461_inb_p, + mv_inw_p: hd64461_inw, + mv_inl_p: hd64461_inl, + mv_outb_p: hd64461_outb_p, + mv_outw_p: hd64461_outw, + mv_outl_p: hd64461_outl, + + mv_insb: hd64461_insb, + mv_insw: hd64461_insw, + mv_insl: hd64461_insl, + mv_outsb: hd64461_outsb, + mv_outsw: hd64461_outsw, + mv_outsl: hd64461_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_irq_demux: hd64461_irq_demux, + + mv_hw_hp600: 1, + mv_hw_hp680: 1, + mv_hw_hd64461: 1, +}; +ALIAS_MV(hp680) + + +struct sh_machine_vector mv_hp690 __initmv = { + mv_name: "hp690", + + mv_nr_irqs: 80, /* HD64461_IRQBASE+16, see hd64461.h */ + + mv_inb: hd64461_inb, + mv_inw: hd64461_inw, + mv_inl: hd64461_inl, + mv_outb: hd64461_outb, + mv_outw: hd64461_outw, + mv_outl: hd64461_outl, + + mv_inb_p: hd64461_inb_p, + mv_inw_p: hd64461_inw, + mv_inl_p: hd64461_inl, + mv_outb_p: hd64461_outb_p, + mv_outw_p: hd64461_outw, + mv_outl_p: hd64461_outl, + + mv_insb: hd64461_insb, + mv_insw: hd64461_insw, + mv_insl: hd64461_insl, + mv_outsb: hd64461_outsb, + mv_outsw: hd64461_outsw, + mv_outsl: hd64461_outsl, + + mv_readb: generic_readb, + mv_readw: generic_readw, + mv_readl: generic_readl, + mv_writeb: generic_writeb, + mv_writew: generic_writew, + mv_writel: generic_writel, + + mv_irq_demux: hd64461_irq_demux, + + mv_hw_hp600: 1, + mv_hw_hp690: 1, + mv_hw_hd64461: 1, +}; +ALIAS_MV(hp690) Index: kernel/arch/sh/kernel/setup.c diff -u kernel/arch/sh/kernel/setup.c:1.1.1.7 kernel/arch/sh/kernel/setup.c:1.3 --- kernel/arch/sh/kernel/setup.c:1.1.1.7 Mon Aug 7 02:11:20 2000 +++ kernel/arch/sh/kernel/setup.c Fri Sep 1 22:10:25 2000 @@ -49,6 +49,7 @@ */ struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 0, 0, }; +struct screen_info screen_info; #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ @@ -269,6 +270,7 @@ int mv_mmio_enable = 0; unsigned long bootmap_size; unsigned long start_pfn, max_pfn, max_low_pfn; + extern struct sh_machine_vector mv_unknown; #ifdef CONFIG_SH_EARLY_PRINTK sh_console_init(); @@ -298,7 +300,6 @@ #ifdef CONFIG_SH_GENERIC if (mv == NULL) { - extern struct sh_machine_vector mv_unknown; mv = &mv_unknown; if (*mv_name != '\0') { printk("Warning: Unsupported machine %s, using unknown\n", @@ -344,6 +345,9 @@ sh_mv.mv_writeb = generic_writeb; sh_mv.mv_writew = generic_writew; sh_mv.mv_writel = generic_writel; + sh_mv.mv_ioremap = generic_ioremap; + sh_mv.mv_ioremap_nocache = generic_ioremap_nocache; + sh_mv.mv_iounmap = generic_iounmap; } #endif Index: kernel/arch/sh/kernel/setup_hd64461.c diff -u kernel/arch/sh/kernel/setup_hd64461.c:1.1.1.4 kernel/arch/sh/kernel/setup_hd64461.c:1.6 --- kernel/arch/sh/kernel/setup_hd64461.c:1.1.1.4 Tue Aug 1 23:25:31 2000 +++ kernel/arch/sh/kernel/setup_hd64461.c Thu Sep 28 07:22:57 2000 @@ -120,11 +120,17 @@ printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE, HD64461_IRQBASE+15); +#if 0 #ifdef CONFIG_CPU_SUBTYPE_SH7709 /* IRQ line for HD64461 should be set level trigger mode("10"). */ /* And this should be done earlier than the kernel starts. */ - ctrl_outw(0x0200, INTC_ICR1); /* when connected to IRQ4. */ +#define HD64461_IRQ_SHIFT ((CONFIG_HD64461_IRQ-IRQ0_IRQ)*2) + ctrl_outw(((ctrl_inw(INTC_ICR1) + & (~(0x3<<HD64461_IRQ_SHIFT))) + | (0x2<<HD64461_IRQ_SHIFT)), INTC_ICR1); /* when connected to IRQx. */ #endif +#endif + outw(0x2240, INTC_ICR1); outw(0xffff, HD64461_NIMR); for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { @@ -135,7 +141,7 @@ #ifdef CONFIG_HD64461_ENABLER printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); - outb(0x04, HD64461_PCC1CSCIER); + outb(0x4c, HD64461_PCC1CSCIER); outb(0x00, HD64461_PCC1CSCR); #endif Index: kernel/arch/sh/kernel/time.c diff -u kernel/arch/sh/kernel/time.c:1.1.1.5 kernel/arch/sh/kernel/time.c:1.8.2.2 --- kernel/arch/sh/kernel/time.c:1.1.1.5 Tue Sep 26 22:56:34 2000 +++ kernel/arch/sh/kernel/time.c Wed Sep 27 16:21:57 2000 @@ -416,12 +416,18 @@ tmp = (frqcr & 0x2000) >> 11; tmp |= frqcr & 0x0003; pfc = pfc_table[tmp]; - if (MACH_HP600) { + if (MACH_HP620) { + master_clock = cpu_clock/4; + bus_clock = master_clock; + } + else if (MACH_HP680 || MACH_HP690) { master_clock = cpu_clock/6; - } else { + bus_clock = master_clock; + } + else { master_clock = cpu_clock; + bus_clock = master_clock/pfc; } - bus_clock = master_clock/pfc; } #elif defined(__SH4__) { @@ -447,6 +453,9 @@ current_cpu_data.master_clock = master_clock; current_cpu_data.bus_clock = bus_clock; current_cpu_data.module_clock = module_clock; + + /* Stop TMU0 */ + ctrl_outb(0, TMU_TSTR); /* Start TMU0 */ ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); Index: kernel/drivers/char/hp600_keyb.c diff -u kernel/drivers/char/hp600_keyb.c:1.1.1.5 kernel/drivers/char/hp600_keyb.c:1.6 --- kernel/drivers/char/hp600_keyb.c:1.1.1.5 Tue Sep 26 22:55:41 2000 +++ kernel/drivers/char/hp600_keyb.c Tue Sep 26 05:29:04 2000 @@ -1,13 +1,17 @@ /* - * $Id$ + * $Id$ * Copyright (C) 2000 YAEGASHI Takeshi - * HP600 keyboard scan routine and translate table + * HP600 keyboard scan routine and translation table + * Copyright (C) 2000 Niibe Yutaka + * HP620 keyboard translation table */ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> -#include <linux/delay.h> + +#include <asm/machvec.h> +#include <asm/delay.h> #include <asm/io.h> #include "scan_keyb.h" @@ -18,54 +22,104 @@ #define PGDR 0xa400012c #define PHDR 0xa400012e -static const unsigned char hp690_japanese_table[]={ - 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, 0x70, 0x3a, - 0x3f, 0x3e, 0x40, 0x41, 0x42, 0x3d, 0x3c, 0x3b, +static const unsigned char hp620_japanese_table[] = { + 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x00, 0x00, 0x00, 0x2c, 0x00, 0x1c, 0x28, 0x35, - 0x31, 0x30, 0x32, 0x33, 0x34, 0x2f, 0x2e, 0x2d, + 0x18, 0x19, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x50, - 0x7b, 0x38, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + 0x26, 0x1a, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf9, 0x73, 0x53, 0x39, 0x00, 0x1d, + 0x27, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x2a, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x2b, 0x1b, 0x27, - 0x23, 0x22, 0x24, 0x25, 0x26, 0x21, 0x20, 0x1f, + 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x34, - 0x00, 0x00, 0x00, 0x0f, 0x00, 0x36, 0x7d, 0x48, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x28, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2d, 0x2e, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x1a, 0x19, - 0x15, 0x14, 0x16, 0x17, 0x18, 0x13, 0x12, 0x11, + 0x48, 0x4d, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x38, 0x00, 0x39, 0x00, 0x29, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x0c, 0x0b, - 0x07, 0x06, 0x08, 0x09, 0x0a, 0x05, 0x04, 0x03, + 0x4b, 0x50, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + +static const unsigned char hp680_japanese_table[] = { + 0x3a, 0x70, 0x29, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3b, 0x3c, 0x3d, 0x42, 0x41, 0x40, 0x3e, 0x3f, + + 0x35, 0x28, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x2d, 0x2e, 0x2f, 0x34, 0x33, 0x32, 0x30, 0x31, + + 0x50, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x38, 0x7b, + + 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x39, 0x53, 0x73, 0xf9, 0x00, 0x00, + + 0x27, 0x1b, 0x2b, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1f, 0x20, 0x21, 0x26, 0x25, 0x24, 0x22, 0x23, + + 0x48, 0x7d, 0x36, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -static const unsigned char hp690_switch[]= { - 0xfd, 0xff, - 0xdf, 0xff, - 0x7f, 0xff, - 0xff, 0xfe, - 0xff, 0xfd, - 0xff, 0xf7, - 0xff, 0xbf, - 0xff, 0x7f, + 0x19, 0x1a, 0x0e, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x11, 0x12, 0x13, 0x18, 0x17, 0x16, 0x14, 0x15, + + 0x0b, 0x0c, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x05, 0x0a, 0x09, 0x08, 0x06, 0x07, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; + +static int hp620_japanese_scan_kbd(unsigned char *s) +{ + int i; + unsigned char matrix_switch[] = { + 0xfd, 0xff, 0xdf, 0xff, + 0x7f, 0xff, 0xff, 0xfe, + 0xff, 0xfd, 0xff, 0xf7, + 0xff, 0xbf, 0xff, 0x7f, + }, *t=matrix_switch; + + for(i=0; i<8; i++) { + ctrl_outb(*t++, PDDR); + ctrl_outb(*t++, PEDR); + *s++=ctrl_inb(PCDR); + *s++=ctrl_inb(PFDR); + } -static void hp690_japanese_scan_kbd(unsigned char *s) + ctrl_outb(0xff, PDDR); + ctrl_outb(0xff, PEDR); + + *s++=ctrl_inb(PGDR); + *s++=ctrl_inb(PHDR); + + return 0; +} + + +static int hp680_japanese_scan_kbd(unsigned char *s) { int i; - unsigned const char *t=hp690_switch; + unsigned char matrix_switch[] = { + 0xfd, 0xff, 0xdf, 0xff, + 0x7f, 0xff, 0xff, 0xfe, + 0xff, 0xfd, 0xff, 0xf7, + 0xff, 0xbf, 0xff, 0x7f, + }, *t=matrix_switch; - for(i=0; i<9; i++) { + for(i=0; i<8; i++) { ctrl_outb(*t++, PDDR); ctrl_outb(*t++, PEDR); *s++=ctrl_inb(PCDR); @@ -77,14 +131,22 @@ *s++=ctrl_inb(PGDR); *s++=ctrl_inb(PHDR); + + return 0; } void __init hp600_kbd_init_hw(void) { scan_kbd_init(); - register_scan_keyboard(hp690_japanese_scan_kbd, - hp690_japanese_table, 18); + + if (MACH_HP620) + register_scan_keyboard(hp620_japanese_scan_kbd, + hp620_japanese_table, 18); + else if (MACH_HP680 || MACH_HP690) + register_scan_keyboard(hp680_japanese_scan_kbd, + hp680_japanese_table, 18); + printk(KERN_INFO "HP600 matrix scan keyboard registered\n"); } Index: kernel/drivers/char/scan_keyb.c diff -u kernel/drivers/char/scan_keyb.c:1.1.1.4 kernel/drivers/char/scan_keyb.c:1.8 --- kernel/drivers/char/scan_keyb.c:1.1.1.4 Sun Sep 3 01:01:41 2000 +++ kernel/drivers/char/scan_keyb.c Tue Sep 26 03:09:18 2000 @@ -18,33 +18,40 @@ #include <linux/miscdevice.h> #include <linux/malloc.h> #include <linux/kbd_kern.h> +#include <linux/timer.h> +#define SCANHZ (HZ/20) + struct scan_keyboard { struct scan_keyboard *next; - void (*scan)(unsigned char *buffer); + int (*scan)(unsigned char *buffer); const unsigned char *table; unsigned char *s0, *s1; int length; }; - + +static int scan_jiffies=0; static struct scan_keyboard *keyboards=NULL; -static struct tq_struct task_scan_kbd; +struct timer_list scan_timer; static void check_kbd(const unsigned char *table, unsigned char *new, unsigned char *old, int length) { int need_tasklet_schedule=0; - unsigned char xor, bit; + unsigned int xor, bit; while(length-->0) { if((xor=*new^*old)==0) { table+=8; } else { - for(bit=0x80; bit!=0; bit>>=1) { + for(bit=0x01; bit<0x100; bit<<=1) { if(xor&bit) { handle_scancode(*table, !(*new&bit)); need_tasklet_schedule=1; +#if 0 + printk("0x%x %s\n", *table, (*new&bit)?"released":"pressed"); +#endif } table++; } @@ -57,26 +64,39 @@ } -static void scan_kbd(void *dummy) +static void scan_kbd(unsigned long dummy) { struct scan_keyboard *kbd; + scan_jiffies++; + for(kbd=keyboards; kbd!=NULL; kbd=kbd->next) { - if(jiffies&1) { - kbd->scan(kbd->s0); - check_kbd(kbd->table, kbd->s0, kbd->s1, kbd->length); + if(scan_jiffies&1) { + if(!kbd->scan(kbd->s0)) + check_kbd(kbd->table, + kbd->s0, kbd->s1, kbd->length); + else + memcpy(kbd->s0, kbd->s1, kbd->length); } else { - kbd->scan(kbd->s1); - check_kbd(kbd->table, kbd->s1, kbd->s0, kbd->length); + if(!kbd->scan(kbd->s1)) + check_kbd(kbd->table, + kbd->s1, kbd->s0, kbd->length); + else + memcpy(kbd->s1, kbd->s0, kbd->length); } } - queue_task(&task_scan_kbd, &tq_timer); + + init_timer(&scan_timer); + scan_timer.expires = jiffies + SCANHZ; + scan_timer.data = 0; + scan_timer.function = scan_kbd; + add_timer(&scan_timer); } -int register_scan_keyboard(void (*scan)(unsigned char *buffer), +int register_scan_keyboard(int (*scan)(unsigned char *buffer), const unsigned char *table, int length) { @@ -98,8 +118,8 @@ if (kbd->s1 == NULL) goto error_free_s0; - kbd->scan(kbd->s0); - kbd->scan(kbd->s1); + memset(kbd->s0, -1, kbd->length); + memset(kbd->s1, -1, kbd->length); kbd->next=keyboards; keyboards=kbd; @@ -119,11 +139,11 @@ void __init scan_kbd_init(void) { + init_timer(&scan_timer); + scan_timer.expires = jiffies + SCANHZ; + scan_timer.data = 0; + scan_timer.function = scan_kbd; + add_timer(&scan_timer); - task_scan_kbd.next=NULL; - task_scan_kbd.sync=0; - task_scan_kbd.routine=scan_kbd; - task_scan_kbd.data=NULL; - queue_task(&task_scan_kbd, &tq_timer); printk(KERN_INFO "Generic scan keyboard driver initialized\n"); } Index: kernel/drivers/char/scan_keyb.h diff -u kernel/drivers/char/scan_keyb.h:1.1.1.3 kernel/drivers/char/scan_keyb.h:1.2 --- kernel/drivers/char/scan_keyb.h:1.1.1.3 Fri Jul 7 11:39:53 2000 +++ kernel/drivers/char/scan_keyb.h Thu Sep 14 10:49:52 2000 @@ -6,7 +6,7 @@ * Generic scan keyboard driver */ -int register_scan_keyboard(void (*scan)(unsigned char *buffer), +int register_scan_keyboard(int (*scan)(unsigned char *buffer), const unsigned char *table, int length); Index: kernel/drivers/video/hitfb.c diff -u kernel/drivers/video/hitfb.c:1.1.1.5 kernel/drivers/video/hitfb.c:1.5 --- kernel/drivers/video/hitfb.c:1.1.1.5 Thu Aug 10 01:15:02 2000 +++ kernel/drivers/video/hitfb.c Tue Sep 26 04:50:38 2000 @@ -22,9 +22,11 @@ #include <linux/nubus.h> #include <linux/init.h> +#include <asm/machvec.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/io.h> +#include <asm/hd64461.h> #include <linux/fb.h> @@ -32,20 +34,6 @@ #include <video/fbcon-cfb8.h> #include <video/fbcon-cfb16.h> -#include <asm/hd64461.h> - -#define CONFIG_SH_LCD_VIDEOBASE CONFIG_HD64461_IOBASE+0x2000000 - -/* These are for HP Jornada 680/690. - It is desired that they are configurable... */ -#define CONFIG_SH_LCD_VIDEOSIZE 1024*1024 -#define CONFIG_SH_LCD_HORZ 640 -#define CONFIG_SH_LCD_VERT 240 -#define CONFIG_SH_LCD_DEFAULTBPP 16 - -struct hitfb_info { - struct fb_info_gen gen; -}; struct hitfb_par { @@ -53,55 +41,79 @@ int bpp; }; -static struct hitfb_info fb_info; -static struct hitfb_par current_par; -static int current_par_valid = 0; -static struct display disp; -static union { +struct hitfb_info { + struct fb_info_gen gen; + struct display disp; + struct hitfb_par current_par; + struct fb_var_screeninfo default_var; + int current_par_valid; + unsigned long hit_videobase, hit_videosize; + union { #ifdef FBCON_HAS_CFB16 - u16 cfb16[16]; + u16 cfb16[16]; #endif -} fbcon_cmap; - -unsigned long hit_videobase, hit_videosize; -static struct fb_var_screeninfo default_var; + } fbcon_cmap; +} fb_info = { + {}, + {}, + {}, + {}, + 0, 0, 0, + {}, +}; -int hitfb_init(void); -static void hitfb_set_par(struct hitfb_par *par, const struct fb_info *info); -static void hitfb_encode_var(struct fb_var_screeninfo *var, - struct hitfb_par *par, - const struct fb_info *info); +static void hitfb_set_par(const void *fb_par, struct fb_info_gen *info); +static int hitfb_encode_var(struct fb_var_screeninfo *var, const void *fb_par, + struct fb_info_gen *info); static void hitfb_detect(void) { struct hitfb_par par; + unsigned short lcdclor, ldr3, ldvntr; + + fb_info.hit_videobase = CONFIG_HD64461_IOBASE + 0x02000000; + fb_info.hit_videosize = (MACH_HP680 || MACH_HP690) ? 1024*1024 : 512*1024; - hit_videobase = CONFIG_SH_LCD_VIDEOBASE; - hit_videosize = CONFIG_SH_LCD_VIDEOSIZE; + lcdclor = inw(HD64461_LCDCLOR); + ldvntr = inw(HD64461_LDVNTR); + ldr3 = inw(HD64461_LDR3); + + switch(ldr3&15) { + default: + case 4: + par.bpp = 8; + par.x = lcdclor; + break; + case 8: + par.bpp = 16; + par.x = lcdclor/2; + break; + } - par.x = CONFIG_SH_LCD_HORZ; - par.y = CONFIG_SH_LCD_VERT; - par.bpp = CONFIG_SH_LCD_DEFAULTBPP; + par.y = ldvntr+1; hitfb_set_par(&par, NULL); - hitfb_encode_var(&default_var, &par, NULL); + hitfb_encode_var(&fb_info.default_var, &par, NULL); } -static int hitfb_encode_fix(struct fb_fix_screeninfo *fix, - struct hitfb_par *par, - const struct fb_info *info) + +static int hitfb_encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par, + struct fb_info_gen *info) { + const struct hitfb_par *par = fb_par; + memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, "Hitachi HD64461"); - fix->smem_start = hit_videobase; - fix->smem_len = hit_videosize; + fix->smem_start = fb_info.hit_videobase; + fix->smem_len = fb_info.hit_videosize; fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; - fix->visual = FB_VISUAL_TRUECOLOR; + fix->visual = (par->bpp == 8) ? + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; fix->xpanstep = 0; fix->ypanstep = 0; fix->ywrapstep = 0; @@ -120,10 +132,11 @@ } -static int hitfb_decode_var(struct fb_var_screeninfo *var, - struct hitfb_par *par, - const struct fb_info *info) +static int hitfb_decode_var(const struct fb_var_screeninfo *var, void *fb_par, + struct fb_info_gen *info) { + struct hitfb_par *par = fb_par; + par->x = var->xres; par->y = var->yres; par->bpp = var->bits_per_pixel; @@ -131,10 +144,11 @@ } -static void hitfb_encode_var(struct fb_var_screeninfo *var, - struct hitfb_par *par, - const struct fb_info *info) +static int hitfb_encode_var(struct fb_var_screeninfo *var, const void *fb_par, + struct fb_info_gen *info) { + const struct hitfb_par *par = fb_par; + memset(var, 0, sizeof(*var)); var->xres = par->x; @@ -191,25 +205,28 @@ var->green.msb_right = 0; var->blue.msb_right = 0; var->transp.msb_right = 0; + + return 0; } -static void hitfb_get_par(struct hitfb_par *par, const struct fb_info *info) +static void hitfb_get_par(void *par, struct fb_info_gen *info) { - *par = current_par; + *(struct hitfb_par *)par = fb_info.current_par; } -static void hitfb_set_par(struct hitfb_par *par, const struct fb_info *info) +static void hitfb_set_par(const void *fb_par, struct fb_info_gen *info) { - /* Set the hardware according to 'par'. */ - current_par = *par; - current_par_valid = 1; + const struct hitfb_par *par = fb_par; + fb_info.current_par = *par; + fb_info.current_par_valid = 1; } -static int hitfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp, struct fb_info *info) +static int hitfb_getcolreg(unsigned regno, unsigned *red, unsigned *green, + unsigned *blue, unsigned *transp, + struct fb_info *info) { if (regno > 255) return 1; @@ -224,8 +241,9 @@ } -static int hitfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) +static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) { if (regno > 255) return 1; @@ -236,10 +254,10 @@ outw(blue>>10, HD64461_CPTWDR); if(regno<16) { - switch(current_par.bpp) { + switch(fb_info.current_par.bpp) { #ifdef FBCON_HAS_CFB16 case 16: - fbcon_cmap.cfb16[regno] = + fb_info.fbcon_cmap.cfb16[regno] = ((red & 0xf800) ) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); @@ -250,17 +268,33 @@ return 0; } + -static int hitfb_blank(int blank_mode, const struct fb_info *info) +static int hitfb_pan_display(const struct fb_var_screeninfo *var, + struct fb_info_gen *info) { + if (!fb_info.current_par_valid) + return -EINVAL; + return 0; } -static void hitfb_set_disp(const void *par, struct display *disp, - struct fb_info_gen *info) +static int hitfb_blank(int blank_mode, struct fb_info_gen *info) { - disp->screen_base = (void *)hit_videobase; + if (!fb_info.current_par_valid) + return 1; + + return 0; +} + + +static void hitfb_set_disp(const void *fb_par, struct display *disp, + struct fb_info_gen *info) +{ + const struct hitfb_par *par = fb_par; + + disp->screen_base = (void *)fb_info.hit_videobase; switch(((struct hitfb_par *)par)->bpp) { #ifdef FBCON_HAS_CFB8 case 8: @@ -270,7 +304,7 @@ #ifdef FBCON_HAS_CFB16 case 16: disp->dispsw = &fbcon_cfb16; - disp->dispsw_data = fbcon_cmap.cfb16; + disp->dispsw_data = fb_info.fbcon_cmap.cfb16; break; #endif default: @@ -288,18 +322,20 @@ hitfb_set_par, hitfb_getcolreg, hitfb_setcolreg, - NULL, + hitfb_pan_display, hitfb_blank, hitfb_set_disp }; + static struct fb_ops hitfb_ops = { - owner: THIS_MODULE, - fb_get_fix: fbgen_get_fix, - fb_get_var: fbgen_get_var, - fb_set_var: fbgen_set_var, - fb_get_cmap: fbgen_get_cmap, - fb_set_cmap: fbgen_set_cmap, + owner: THIS_MODULE, + fb_get_fix: fbgen_get_fix, + fb_get_var: fbgen_get_var, + fb_set_var: fbgen_set_var, + fb_get_cmap: fbgen_get_cmap, + fb_set_cmap: fbgen_set_cmap, + fb_pan_display: fbgen_pan_display, }; @@ -309,7 +345,7 @@ fb_info.gen.info.node = -1; fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT; fb_info.gen.info.fbops = &hitfb_ops; - fb_info.gen.info.disp = &disp; + fb_info.gen.info.disp = &fb_info.disp; fb_info.gen.info.changevar = NULL; fb_info.gen.info.switch_con = &fbgen_switch; fb_info.gen.info.updatevar = &fbgen_update_var; @@ -318,9 +354,9 @@ fb_info.gen.fbhw = &hitfb_switch; fb_info.gen.fbhw->detect(); - fbgen_get_var(&disp.var, -1, &fb_info.gen.info); - disp.var.activate = FB_ACTIVATE_NOW; - fbgen_do_set_var(&disp.var, 1, &fb_info.gen); + fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info); + fb_info.disp.var.activate = FB_ACTIVATE_NOW; + fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen); fbgen_set_disp(-1, &fb_info.gen); fbgen_install_cmap(0, &fb_info.gen); @@ -347,6 +383,13 @@ void cleanup_module(void) { - hitfb_cleanup(void); + hitfb_cleanup(void); } #endif + + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ Index: kernel/include/asm-sh/hd64461.h diff -u kernel/include/asm-sh/hd64461.h:1.1.1.4 kernel/include/asm-sh/hd64461.h:1.4 --- kernel/include/asm-sh/hd64461.h:1.1.1.4 Tue Aug 1 23:23:17 2000 +++ kernel/include/asm-sh/hd64461.h Mon Sep 4 07:25:33 2000 @@ -11,11 +11,23 @@ #define HD64461_SYSCR 0x10002 #define HD64461_SCPUCR 0x10004 -#define HD64461_CPTWAR 0x11030 -#define HD64461_CPTWDR 0x11032 -#define HD64461_CPTRAR 0x11034 -#define HD64461_CPTRDR 0x11036 +#define HD64461_LCDCBAR 0x11000 +#define HD64461_LCDCLOR 0x11002 +#define HD64461_LCDCCRR 0x11004 +#define HD64461_LDR1 0x11010 +#define HD64461_LDR2 0x11012 +#define HD64461_LDHNCR 0x11014 +#define HD64461_LDHNSR 0x11016 +#define HD64461_LDVNTR 0x11018 +#define HD64461_LDVNDR 0x1101a +#define HD64461_LDVSPR 0x1101c +#define HD64461_LDR3 0x1101e +#define HD64461_CPTWAR 0x11030 +#define HD64461_CPTWDR 0x11032 +#define HD64461_CPTRAR 0x11034 +#define HD64461_CPTRDR 0x11036 + #define HD64461_PCC0ISR 0x12000 #define HD64461_PCC0GCR 0x12002 #define HD64461_PCC0CSCR 0x12004 @@ -29,6 +41,23 @@ #define HD64461_P0OCR 0x1202a #define HD64461_P1OCR 0x1202c #define HD64461_PGCR 0x1202e + +#define HD64461_GPACR 0x14000 +#define HD64461_GPBCR 0x14002 +#define HD64461_GPCCR 0x14004 +#define HD64461_GPDCR 0x14006 +#define HD64461_GPADR 0x14010 +#define HD64461_GPBDR 0x14012 +#define HD64461_GPCDR 0x14014 +#define HD64461_GPDDR 0x14016 +#define HD64461_GPAICR 0x14020 +#define HD64461_GPBICR 0x14022 +#define HD64461_GPCICR 0x14024 +#define HD64461_GPDICR 0x14026 +#define HD64461_GPAISR 0x14040 +#define HD64461_GPBISR 0x14042 +#define HD64461_GPCISR 0x14044 +#define HD64461_GPDISR 0x14046 #define HD64461_NIRR 0x15000 #define HD64461_NIMR 0x15002 Index: kernel/include/asm-sh/ide.h diff -u kernel/include/asm-sh/ide.h:1.1.1.4 kernel/include/asm-sh/ide.h:1.6 --- kernel/include/asm-sh/ide.h:1.1.1.4 Sun Sep 3 01:01:18 2000 +++ kernel/include/asm-sh/ide.h Mon Sep 4 07:25:33 2000 @@ -28,7 +28,7 @@ { switch (base) { case 0x01f0: return 77; - case 0x0170: return 77; + case 0x0170: return 78; default: return 0; } Index: kernel/include/asm-sh/io_hd64461.h diff -u kernel/include/asm-sh/io_hd64461.h:1.1.1.2 kernel/include/asm-sh/io_hd64461.h:1.3 --- kernel/include/asm-sh/io_hd64461.h:1.1.1.2 Tue Sep 26 22:55:16 2000 +++ kernel/include/asm-sh/io_hd64461.h Tue Sep 26 23:06:46 2000 @@ -14,23 +14,23 @@ #include <asm/io_generic.h> -extern unsigned long hd64461_inb(unsigned int port); -extern unsigned long hd64461_inw(unsigned int port); -extern unsigned long hd64461_inl(unsigned int port); +unsigned long hd64461_inb(unsigned int port); +unsigned long hd64461_inw(unsigned int port); +unsigned long hd64461_inl(unsigned int port); -extern void hd64461_outb(unsigned long value, unsigned int port); -extern void hd64461_outw(unsigned long value, unsigned int port); -extern void hd64461_outl(unsigned long value, unsigned int port); +void hd64461_outb(unsigned long value, unsigned int port); +void hd64461_outw(unsigned long value, unsigned int port); +void hd64461_outl(unsigned long value, unsigned int port); -extern unsigned long hd64461_inb_p(unsigned int port); -extern void hd64461_outb_p(unsigned long value, unsigned int port); +unsigned long hd64461_inb_p(unsigned int port); +void hd64461_outb_p(unsigned long value, unsigned int port); -extern void hd64461_insb(unsigned int port, void *addr, unsigned long count); -extern void hd64461_insw(unsigned int port, void *addr, unsigned long count); -extern void hd64461_insl(unsigned int port, void *addr, unsigned long count); -extern void hd64461_outsb(unsigned int port, const void *addr, unsigned long count); -extern void hd64461_outsw(unsigned int port, const void *addr, unsigned long count); -extern void hd64461_outsl(unsigned int port, const void *addr, unsigned long count); +void hd64461_insb(unsigned int port, void *addr, unsigned long count); +void hd64461_insw(unsigned int port, void *addr, unsigned long count); +void hd64461_insl(unsigned int port, void *addr, unsigned long count); +void hd64461_outsb(unsigned int port, const void *addr, unsigned long count); +void hd64461_outsw(unsigned int port, const void *addr, unsigned long count); +void hd64461_outsl(unsigned int port, const void *addr, unsigned long count); #ifdef __WANT_IO_DEF Index: kernel/include/asm-sh/machvec.h diff -u kernel/include/asm-sh/machvec.h:1.1.1.2 kernel/include/asm-sh/machvec.h:1.4.2.2 --- kernel/include/asm-sh/machvec.h:1.1.1.2 Tue Aug 1 23:23:17 2000 +++ kernel/include/asm-sh/machvec.h Sun Sep 17 14:58:36 2000 @@ -65,6 +65,9 @@ unsigned int mv_hw_se : 1; unsigned int mv_hw_hp600 : 1; + unsigned int mv_hw_hp620 : 1; + unsigned int mv_hw_hp680 : 1; + unsigned int mv_hw_hp690 : 1; unsigned int mv_hw_hd64461 : 1; }; @@ -74,6 +77,9 @@ #ifdef CONFIG_SH_GENERIC #define MACH_SE (sh_mv.mv_hw_se) #define MACH_HP600 (sh_mv.mv_hw_hp600) +#define MACH_HP620 (sh_mv.mv_hw_hp620) +#define MACH_HP680 (sh_mv.mv_hw_hp680) +#define MACH_HP690 (sh_mv.mv_hw_hp690) #define MACH_HD64461 (sh_mv.mv_hw_hd64461) #else # ifdef CONFIG_SH_SOLUTION_ENGINE @@ -85,6 +91,21 @@ # define MACH_HP600 1 # else # define MACH_HP600 0 +# endif +# ifdef CONFIG_SH_HP620 +# define MACH_HP620 1 +# else +# define MACH_HP620 0 +# endif +# ifdef CONFIG_SH_HP680 +# define MACH_HP680 1 +# else +# define MACH_HP680 0 +# endif +# ifdef CONFIG_SH_HP690 +# define MACH_HP690 1 +# else +# define MACH_HP690 0 # endif # ifdef CONFIG_HD64461 # define MACH_HD64461 1 |