--- ../../kernel.org/linux-2.4.29-rc1/Makefile 2005-01-10 22:11:59.000000000 +0000 +++ dropin/Makefile 2005-01-10 22:34:46.000000000 +0000 @@ -5,7 +5,7 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) +ARCH := sh64 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g") CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -140,7 +140,8 @@ DRIVERS-y += drivers/char/char.o \ drivers/block/block.o \ drivers/misc/misc.o \ - drivers/net/net.o + drivers/net/net.o +# drivers/media/media.o DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o DRIVERS-$(CONFIG_DRM_NEW) += drivers/char/drm/drm.o DRIVERS-$(CONFIG_DRM_OLD) += drivers/char/drm-4.0/drm.o --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/Makefile 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -32,7 +32,8 @@ CFLAGS += $(cpu-y) ENTRY_POINT = --defsym phys_stext=_stext-0x$(CONFIG_CACHED_MEMORY_OFFSET) \ - -e phys_stext + --defsym phys_stext_shmedia=phys_stext+1 \ + -e phys_stext_shmedia OBJCOPY = $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment \ -R .stab -R .stabstr -S LD = $(CROSS_COMPILE)ld $(LDFLAGS) @@ -46,6 +47,7 @@ machine-$(CONFIG_SH_CAYMAN) := cayman machine-$(CONFIG_SH_SIMULATOR) := sim machine-$(CONFIG_SH_HARP) := harp +machine-$(CONFIG_SH_ROMRAM) := romram HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o MAKEROOTFS = --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/boot/compressed/head.S 2003-11-28 18:26:19.000000000 +0000 +++ dropin/arch/sh64/boot/compressed/head.S 2005-01-10 22:34:21.000000000 +0000 @@ -18,7 +18,6 @@ #include #include #include -#include /* * Fixed TLB entries to identity map the beginning of RAM --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/config.in 2004-11-29 23:17:58.000000000 +0000 +++ dropin/arch/sh64/config.in 2005-01-10 22:34:21.000000000 +0000 @@ -30,6 +30,7 @@ "Generic CONFIG_SH_GENERIC \ Simulator CONFIG_SH_SIMULATOR \ Cayman CONFIG_SH_CAYMAN \ + ROM/RAM CONFIG_SH_ROMRAM \ ST50-Harp CONFIG_SH_HARP" Simulator endmenu @@ -109,6 +110,11 @@ define_bool CONFIG_NET n fi +if [ "$CONFIG_SH_ROMRAM" = "y" ]; then + define_bool CONFIG_PCI n + define_bool CONFIG_NET n +fi + if [ "$CONFIG_SH_HARP" = "y" ]; then define_bool CONFIG_PCI n define_bool CONFIG_NET y @@ -175,6 +181,7 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else + define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -190,7 +197,7 @@ fi endmenu -# source drivers/ieee1394/Config.in +source drivers/ieee1394/Config.in if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment @@ -294,6 +301,8 @@ source drivers/usb/Config.in +source net/bluetooth/Config.in + mainmenu_option next_comment comment 'Kernel hacking' @@ -303,6 +312,8 @@ dep_bool "Debug: report TLB fill/purge activity through /proc/tlb" CONFIG_SH64_PROC_TLB $CONFIG_PROC_FS dep_bool "Debug: report ASIDS through /proc/asids" CONFIG_SH64_PROC_ASIDS $CONFIG_PROC_FS bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" CONFIG_SH64_SR_WATCH +bool "Enable debug outputs to on-board alphanumeric display" CONFIG_SH_ALPHANUMERIC +bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)" CONFIG_SH_NO_BSS_INIT int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/defconfig 2004-11-29 23:17:58.000000000 +0000 +++ dropin/arch/sh64/defconfig 2005-01-10 22:34:21.000000000 +0000 @@ -22,6 +22,7 @@ # CONFIG_SH_GENERIC is not set # CONFIG_SH_SIMULATOR is not set CONFIG_SH_CAYMAN=y +# CONFIG_SH_ROMRAM is not set # CONFIG_SH_HARP is not set # @@ -44,9 +45,8 @@ # # Memory options # -CONFIG_MEMORY_SIZE_IN_MB=64 +CONFIG_MEMORY_SIZE_IN_MB=128 CONFIG_CACHED_MEMORY_OFFSET=20000000 -CONFIG_UNCACHED_MEMORY_OFFSET=00000000 CONFIG_MEMORY_START=80000000 # @@ -84,6 +84,7 @@ # CONFIG_KCORE_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Block devices @@ -97,6 +98,7 @@ # CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -131,7 +133,6 @@ # # SCTP Configuration (EXPERIMENTAL) # -CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -171,6 +172,7 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -229,6 +231,7 @@ # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set +# CONFIG_FORCEDETH is not set # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139CP is not set @@ -292,6 +295,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -374,6 +378,11 @@ # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -444,6 +453,7 @@ # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -491,6 +501,9 @@ # CONFIG_SH64_PROC_TLB is not set # CONFIG_SH64_PROC_ASIDS is not set # CONFIG_SH64_SR_WATCH is not set +# CONFIG_SH_ALPHANUMERIC is not set +# CONFIG_SH_NO_BSS_INIT is not set +CONFIG_LOG_BUF_SHIFT=0 # # Library routines --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/Makefile 2004-02-18 13:36:30.000000000 +0000 +++ dropin/arch/sh64/kernel/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -21,6 +21,7 @@ ptrace.o setup.o time.o sys_sh64.o semaphore.o sh_ksyms.o obj-$(CONFIG_HEARTBEAT) += led.o +obj-$(CONFIG_SH_ALPHANUMERIC) += alphanum.o obj-$(CONFIG_PCI) += pci-dma.o pcibios.o ifeq ($(CONFIG_PCI),y) --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/alphanum.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/arch/sh64/kernel/alphanum.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * arch/sh64/kernel/alpanum.c + * + * Copyright (C) 2002 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine-independent functions for handling 8-digit alphanumeric display + * (e.g. Agilent HDSP-253x) + */ +#include +#include +#include + +void mach_alphanum(int pos, unsigned char val); +void mach_led(int pos, int val); + +void print_seg(char *file, int line) +{ + int i; + unsigned int nibble; + + for (i = 0; i < 5; i++) { + mach_alphanum(i, file[i]); + } + + for (i = 0; i < 3; i++) { + nibble = ((line >> (i * 4)) & 0xf); + mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); + } +} + +void print_seg_num(unsigned num) +{ + int i; + unsigned int nibble; + + for (i = 0; i < 8; i++) { + nibble = ((num >> (i * 4)) & 0xf); + + mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); + } +} + --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/entry.S 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/kernel/entry.S 2005-01-10 22:34:21.000000000 +0000 @@ -499,6 +499,7 @@ .space 256, 0 /* Power-on class handler, */ /* not required here */ not_a_tlb_miss: + synco /* TAKum03020 (but probably a good idea anyway.) */ /* Save original stack pointer into KCR1 */ putcon SP, KCR1 @@ -546,6 +547,7 @@ * (this may need to be extended...) */ reset_or_panic: + synco /* TAKum03020 (but probably a good idea anyway.) */ putcon SP, DCR /* First save r0-1 and tr0, as we need to use these */ _loada resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP @@ -605,6 +607,7 @@ .balign TEXT_SIZE debug_exception: + synco /* TAKum03020 (but probably a good idea anyway.) */ /* * Single step/software_break_point first level handler. * Called with MMU off, so the first thing we do is enable it @@ -684,6 +687,7 @@ LRESVEC_block_end: /* Marker. Unused. */ tlb_miss: + synco /* TAKum03020 (but probably a good idea anyway.) */ putcon SP, KCR1 _loada reg_save_area, SP /* SP is guaranteed 32-byte aligned. */ @@ -808,6 +812,7 @@ /* VBR + 0x600 */ interrupt: + synco /* TAKum03020 (but probably a good idea anyway.) */ /* Save original stack pointer into KCR1 */ putcon SP, KCR1 @@ -1971,6 +1976,21 @@ ptabs LINK, t0 blink t0, ZERO +/* + * extern void *current_text_addr(void); + * + * Inputs: + * none + * + * Ouputs: + * (r2) address of caller + */ + .global current_text_addr +current_text_addr: + ptabs r18, tr0 + addi.l r18, -4, r2 + blink tr0, r63 + /* * --- Signal Handling Section --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/head.S 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/kernel/head.S 2005-01-10 22:34:21.000000000 +0000 @@ -91,8 +91,8 @@ .long 0 /* RAMDISK_FLAGS */ .long 0x0200 /* ORIG_ROOT_DEV */ .long 1 /* LOADER_TYPE */ - .long 0x00360000 /* INITRD_START */ - .long 0x000a0000 /* INITRD_SIZE */ + .long 0x00800000 /* INITRD_START */ + .long 0x00800000 /* INITRD_SIZE */ .long 0 .text @@ -235,6 +235,18 @@ add.l r22, r63, r22 /* Sign extend */ putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ +#if 0 + /* XXX: Early Console */ + /* Map 0x0a030000 phys -> 0xfa030000 virt */ + addi r21, MMUDR_STEP, r21 + movi 0x0a03, r22 + shori 0x0148, r22 + putcfg r21, 1, r22 /* PTEL first */ + movi 0xfa03, r22 + shori 0x0003, r22 + putcfg r21, 0, r22 /* PTEH last */ +#endif + /* * Set cache behaviours. */ @@ -315,6 +327,10 @@ #endif or r21, ZERO, r31 /* Set FPU flag at last */ +#ifndef CONFIG_SH_NO_BSS_INIT +/* Don't clear BSS if running on slow platforms such as an RTL simulation, + remote memory via SHdebug link, etc. For these the memory can be guaranteed + to be all zero on boot anyway. */ /* * Clear bss */ @@ -325,6 +341,7 @@ st.q r22, 0, ZERO addi r22, 8, r22 bne r22, r23, t1 /* Both quad aligned, see vmlinux.lds.S */ +#endif _ptaru hopeless, t1 /* Say bye to head.S but be prepared to wrongly get back ... */ --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/led.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/kernel/led.c 2005-01-10 22:34:21.000000000 +0000 @@ -12,36 +12,8 @@ #include #include -void mach_alphanum(int pos, unsigned char val); void mach_led(int pos, int val); -void print_seg(char *file, int line) -{ - int i; - unsigned int nibble; - - for (i = 0; i < 5; i++) { - mach_alphanum(i, file[i]); - } - - for (i = 0; i < 3; i++) { - nibble = ((line >> (i * 4)) & 0xf); - mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); - } -} - -void print_seg_num(unsigned num) -{ - int i; - unsigned int nibble; - - for (i = 0; i < 8; i++) { - nibble = ((num >> (i * 4)) & 0xf); - - mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48)); - } -} - /* acts like an actual heart beat -- ie thump-thump-pause... */ void heartbeat(void) { --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/pci_sh5.c 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/kernel/pci_sh5.c 2005-01-10 22:34:21.000000000 +0000 @@ -26,9 +26,9 @@ #undef DEBUG #ifdef DEBUG -# define dprintk(x...) printk(KERN_DEBUG x) +# define dprintk(x...) printk(KERN_DEBUG x) #else -# define dprintk(x...) do { } while (0) +# define dprintk(x...) do { } while (0) #endif /* DEBUG */ static unsigned long pcicr_virt; @@ -343,7 +343,6 @@ int pin; } path[4]; int i=0; - int base; while (dev->bus->number > 0) { @@ -413,8 +412,8 @@ #endif /* DEBUG */ void __init - pcibios_fixup_pbus_ranges(struct pci_bus *bus, - struct pbus_set_ranges_data *ranges) +pcibios_fixup_pbus_ranges(struct pci_bus *bus, + struct pbus_set_ranges_data *ranges) { #ifdef DEBUG int i; --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/process.c 2003-11-28 18:26:19.000000000 +0000 +++ dropin/arch/sh64/kernel/process.c 2005-01-10 22:34:21.000000000 +0000 @@ -963,7 +963,7 @@ unsigned long asid, context; context = mm->context; asid = (context & 0xff); - len += sprintf(buf+len, "%5d : %02x\n", pid, asid); + len += sprintf(buf+len, "%5d : %02lx\n", pid, asid); } else { len += sprintf(buf+len, "%5d : (none)\n", pid); } --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/ptrace.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/kernel/ptrace.c 2005-01-10 22:34:21.000000000 +0000 @@ -121,9 +121,26 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child, *tsk = current; + extern void poke_real_address_q(unsigned long long addr, unsigned long long data); +#define WPC_DBRMODE 0x0d104008 + static int first_call = 1; int ret; lock_kernel(); + + if (first_call) { + /* Set WPC.DBRMODE to 0. This makes all debug events get + * delivered through RESVEC, i.e. into the handlers in entry.S. + * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE + * would normally be left set to 1, which makes debug events get + * delivered through DBRVEC, i.e. into the remote gdb's + * handlers. This prevents ptrace getting them, and confuses + * the remote gdb.) */ + printk("DBRMODE set to 0 to permit native debugging\n"); + poke_real_address_q(WPC_DBRMODE, 0); + first_call = 0; + } + ret = -EPERM; if (request == PTRACE_TRACEME) { /* are we already being traced? */ --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/setup.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/kernel/setup.c 2005-01-10 22:34:21.000000000 +0000 @@ -79,6 +79,8 @@ extern int sh64_cache_init(void); extern int sh64_tlb_init(void); +extern int blk_nohighio; + #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 @@ -99,9 +101,7 @@ unsigned long long memory_start = CONFIG_MEMORY_START; unsigned long long memory_end = CONFIG_MEMORY_START + (CONFIG_MEMORY_SIZE_IN_MB * 1024 * 1024); -struct sh_cpuinfo boot_cpu_data = { - .type = CPU_SH5_101, -}; +struct sh_cpuinfo boot_cpu_data; static inline void parse_mem_cmdline (char ** cmdline_p) { @@ -142,12 +142,41 @@ { } +static void __init sh64_cpu_type_detect(void) +{ + extern unsigned long long peek_real_address_q(unsigned long long addr); + unsigned long long cir; + /* Do peeks in real mode to avoid having to set up a mapping for the + WPC registers. On SH5-101 cut2, such a mapping would be exposed to + an address translation erratum which would make it hard to set up + correctly. */ + cir = peek_real_address_q(0x0d000008); + + if ((cir & 0xffff) == 0x5103) { + boot_cpu_data.type = CPU_SH5_103; + } else if (((cir >> 32) & 0xffff) == 0x51e2) { + /* CPU.VCR aliased at CIR address on SH5-101 */ + boot_cpu_data.type = CPU_SH5_101; + } else { + boot_cpu_data.type = CPU_SH_NONE; + } +} + + void __init setup_arch(char **cmdline_p) { unsigned long bootmap_size, i; unsigned long first_pfn, start_pfn, last_pfn, pages; /* + * Stops the scsi device using highio fixes problem with ieee1394 scsi + * device, since it stops sg being used for single-segment transfers + * (such transfers appear not to be handled properly by the serial bus + * part of the ieee1394 stack.) + */ + blk_nohighio = 1; + + /* * Setup TLB mappings */ sh64_tlb_init(); @@ -161,6 +190,8 @@ platform_setup(); platform_monitor(); + sh64_cpu_type_detect(); + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); #ifdef CONFIG_BLK_DEV_RAM --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/signal.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/kernel/signal.c 2005-01-10 22:34:21.000000000 +0000 @@ -31,6 +31,7 @@ #define REG_RET 9 #define REG_ARG1 2 #define REG_ARG2 3 +#define REG_ARG3 4 #define REG_SP 15 #define REG_PR 18 #define REF_REG_RET regs->regs[REG_RET] @@ -269,6 +270,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, long long *r2_p) { unsigned int err = 0; + unsigned long long current_sr, new_sr; +#define SR_MASK 0xffff8cfd #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) @@ -290,7 +293,16 @@ COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); - COPY(sr); COPY(pc); + + /* Prevent the signal handler manipulating SR in a way that can + crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be + modified */ + current_sr = regs->sr; + err |= __get_user(new_sr, &sc->sc_sr); + regs->sr &= SR_MASK; + regs->sr |= (new_sr & ~SR_MASK); + + COPY(pc); #undef COPY @@ -461,8 +473,7 @@ if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], - sizeof(frame->extramask)); - } + sizeof(frame->extramask)); } /* Give up earlier as i386, in case */ if (err) @@ -510,7 +521,19 @@ regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ + + /* FIXME: + The glibc profiling support for SH-5 needs to be passed a sigcontext + so it can retrieve the PC. At some point during 2003 the glibc + support was changed to receive the sigcontext through the 2nd + argument, but there are still versions of libc.so in use that use + the 3rd argument. Until libc.so is stabilised, pass the sigcontext + through both 2nd and 3rd arguments. + */ + regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; + regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; + regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; @@ -617,7 +640,8 @@ regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ - regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; + regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; + regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/time.c 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/kernel/time.c 2005-01-10 22:34:21.000000000 +0000 @@ -563,7 +563,7 @@ /* Configure deep standby on sleep */ ctrl_outl(0x03, STBCR); -#ifdef CONFIG_SH_CAYMAN +#ifdef CONFIG_SH_ALPHANUMERIC { extern void mach_alphanum(int position, unsigned char value); extern void mach_alphanum_brightness(int setting); --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/kernel/traps.c 2003-11-28 18:26:19.000000000 +0000 +++ dropin/arch/sh64/kernel/traps.c 2005-01-10 22:34:21.000000000 +0000 @@ -382,7 +382,9 @@ __u64 base_address, addr; int basereg; +#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) int do_as_user = user_mode(regs); +#endif basereg = (opcode >> 20) & 0x3f; base_address = regs->regs[basereg]; --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/lib/c-checksum.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/lib/c-checksum.c 2005-01-10 22:34:21.000000000 +0000 @@ -62,30 +62,6 @@ */ #define U16(x) ntohs(x) -static unsigned long do_moronic_csum(const unsigned char *a16p, int cnt) -{ - u32 sum; - int oddb; - - /* This algorithm is correct only for those values of cnt < 65536 */ - - oddb = odd(cnt); - cnt >>= 1; /* convert to a word count */ - sum = 0; /* do a straight two's complement sum */ - while (cnt--) - sum += U16(*a16p++); - if (oddb) /* pick up the odd byte */ - sum += U16(*a16p++) & (u16) 0xFF00; - /* add in the sum of the `carry' bits, making this one's complement */ - sum = (sum & (u32) 0xFFFF) + ((sum >> 16) & (u32) 0xFFFF); - if (sum & (u32) 0x10000) /* one last possible carry */ - sum = (sum + 1) & (u32) 0xFFFF; - if (sum == (u32) 0xFFFF) /* remove the -0 ambiguity */ - sum = (u32) 0; - return sum; - -} - #if 0 static inline unsigned long do_csum(const unsigned char *buff, int len) { --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/lib/copy_user_memcpy.S 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/lib/copy_user_memcpy.S 2005-01-10 22:34:21.000000000 +0000 @@ -46,6 +46,11 @@ */ +/* NOTE : Prefetches removed and allocos guarded by synco to avoid TAKum03020 + * erratum. The first two prefetches are nop-ed out to avoid upsetting the + * instruction counts used in the jump address calculation. + * */ + .section .text..SHmedia32,"ax" .little .balign 32 @@ -58,7 +63,7 @@ #define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1 #define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1 - ld.b r3,0,r63 + nop ! ld.b r3,0,r63 ! TAKum03020 pta/l Large,tr0 movi 25,r0 bgeu/u r4,r0,tr0 @@ -108,7 +113,7 @@ /* 2 or 3 byte memcpy */ ld.b r3,0,r0 - ld.b r2,0,r63 + nop ! ld.b r2,0,r63 ! TAKum03020 ld.b r3,1,r1 st.b r2,0,r0 pta/l L2_3,tr0 @@ -151,7 +156,7 @@ blink tr1,r63 Large: - ld.b r2, 0, r63 + ! ld.b r2, 0, r63 ! TAKum03020 pta/l Loop_ua, tr1 ori r3, -8, r7 sub r2, r7, r22 @@ -173,8 +178,9 @@ addi r6, -8, r21 Loop_line: - ldx.q r22, r36, r63 + ! ldx.q r22, r36, r63 ! TAKum03020 alloco r22, 32 + synco ! TAKum03020 addi r22, 32, r22 ldx.q r22, r19, r23 sthi.q r22, -25, r0 --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/lib/io.c 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/lib/io.c 2005-01-10 22:34:21.000000000 +0000 @@ -45,46 +45,46 @@ } } -unsigned long inb(unsigned long port) +unsigned char inb(unsigned long port) { - unsigned long r; + unsigned char r; r = ctrl_inb(io_addr(port)); dprintk("inb(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); return r; } -unsigned long inw(unsigned long port) +unsigned short inw(unsigned long port) { - unsigned long r; + unsigned short r; r = ctrl_inw(io_addr(port)); dprintk("inw(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); return r; } -unsigned long inl(unsigned long port) +unsigned int inl(unsigned long port) { - unsigned long r; + unsigned int r; r = ctrl_inl(io_addr(port)); dprintk("inl(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); return r; } -void outb(unsigned long value, unsigned long port) +void outb(unsigned char value, unsigned long port) { dprintk("outb(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); ctrl_outb(value, io_addr(port)); } -void outw(unsigned long value, unsigned long port) +void outw(unsigned short value, unsigned long port) { dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); ctrl_outw(value, io_addr(port)); } -void outl(unsigned long value, unsigned long port) +void outl(unsigned int value, unsigned long port) { dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); ctrl_outl(value, io_addr(port)); --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/lib/page_clear.S 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/lib/page_clear.S 2005-01-10 22:34:21.000000000 +0000 @@ -11,7 +11,9 @@ r2 : source effective address (start of page) Always clears 4096 bytes. - + + Note : alloco guarded by synco to avoid TAKum03020 erratum + */ .section .text..SHmedia32,"ax" @@ -29,6 +31,7 @@ add r2, r63, r6 1: alloco r6, 0 + synco ! TAKum03020 addi r6, 32, r6 bgt/l r7, r6, tr1 --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/lib/page_copy.S 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/lib/page_copy.S 2005-01-10 22:34:21.000000000 +0000 @@ -34,12 +34,17 @@ pta 3f, tr3 ptabs r18, tr0 +#if 0 + /* TAKum03020 */ ld.q r2, 0x00, r63 ld.q r2, 0x20, r63 ld.q r2, 0x40, r63 ld.q r2, 0x60, r63 +#endif alloco r3, 0x00 + synco ! TAKum03020 alloco r3, 0x20 + synco ! TAKum03020 movi 3968, r6 add r3, r6, r6 @@ -55,11 +60,15 @@ because they overlap with the time spent waiting for prefetches to complete. */ 1: +#if 0 + /* TAKum03020 */ bge/u r3, r6, tr2 ! skip prefetch for last 4 lines ldx.q r3, r22, r63 ! prefetch 4 lines hence +#endif 2: bge/u r3, r7, tr3 ! skip alloco for last 2 lines alloco r3, 0x40 ! alloc destination line 2 lines ahead + synco ! TAKum03020 3: ldx.q r3, r60, r36 ldx.q r3, r61, r37 --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/mach-romram/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ dropin/arch/sh64/mach-romram/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,14 @@ +# +# Makefile for the SH-5 ROM/RAM specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +O_TARGET := romram.o + +obj-y := setup.o + +include $(TOPDIR)/Rules.make + --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/mach-romram/setup.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/arch/sh64/mach-romram/setup.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,142 @@ +/* + * 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. + * + * arch/sh64/mach-romram/setup.c + * + * SH-5 ROM/RAM Platform Support + * + * This file handles the architecture-dependent parts of initialization + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * benedict.gaster@superh.com: 3rd May 2002 + * Added support for ramdisk, removing statically linked romfs at the same time. * + * + * lethal@linux-sh.org: 15th May 2003 + * Use the generic procfs cpuinfo interface, just return a valid board name. + * + * Sean.McGoogan@superh.com 17th Feb 2004 + * copied from arch/sh64/mach-harp/setup.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RES_COUNT(res) ((sizeof((res))/sizeof(struct resource))) + +/* + * Platform Dependent Interrupt Priorities. + */ + +/* Using defaults defined in irq.h */ +#define RES NO_PRIORITY /* Disabled */ +#define IR0 IRL0_PRIORITY /* IRLs */ +#define IR1 IRL1_PRIORITY +#define IR2 IRL2_PRIORITY +#define IR3 IRL3_PRIORITY +#define PCA INTA_PRIORITY /* PCI Ints */ +#define PCB INTB_PRIORITY +#define PCC INTC_PRIORITY +#define PCD INTD_PRIORITY +#define SER TOP_PRIORITY +#define ERR TOP_PRIORITY +#define PW0 TOP_PRIORITY +#define PW1 TOP_PRIORITY +#define PW2 TOP_PRIORITY +#define PW3 TOP_PRIORITY +#define DM0 NO_PRIORITY /* DMA Ints */ +#define DM1 NO_PRIORITY +#define DM2 NO_PRIORITY +#define DM3 NO_PRIORITY +#define DAE NO_PRIORITY +#define TU0 TIMER_PRIORITY /* TMU Ints */ +#define TU1 NO_PRIORITY +#define TU2 NO_PRIORITY +#define TI2 NO_PRIORITY +#define ATI NO_PRIORITY /* RTC Ints */ +#define PRI NO_PRIORITY +#define CUI RTC_PRIORITY +#define ERI SCIF_PRIORITY /* SCIF Ints */ +#define RXI SCIF_PRIORITY +#define BRI SCIF_PRIORITY +#define TXI SCIF_PRIORITY +#define ITI TOP_PRIORITY /* WDT Ints */ + +/* + * Platform dependent structures: maps and parms block. + */ +struct resource io_resources[] = { + /* To be updated with external devices */ +}; + +struct resource kram_resources[] = { + { "Kernel code", 0, 0 }, /* These must be last in the array */ + { "Kernel data", 0, 0 } /* These must be last in the array */ +}; + +struct resource xram_resources[] = { + /* To be updated with external devices */ +}; + +struct resource rom_resources[] = { + /* To be updated with external devices */ +}; + +struct sh64_platform platform_parms = { + .readonly_rootfs = 1, + .initial_root_dev = 0x0100, + .loader_type = 1, + .io_res_p = io_resources, + .io_res_count = RES_COUNT(io_resources), + .kram_res_p = kram_resources, + .kram_res_count = RES_COUNT(kram_resources), + .xram_res_p = xram_resources, + .xram_res_count = RES_COUNT(xram_resources), + .rom_res_p = rom_resources, + .rom_res_count = RES_COUNT(rom_resources), +}; + +int platform_int_priority[NR_INTC_IRQS] = { + IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ + RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ + PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ + TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ + RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ + RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ +}; + +void __init platform_setup(void) +{ + /* ROM/RAM platform leaves the decision to head.S, for now */ + platform_parms.fpu_flags = fpu_in_use; +} + +void __init platform_monitor(void) +{ + /* Nothing yet .. */ +} + +void __init platform_reserve(void) +{ + /* Nothing yet .. */ +} + +const char *get_system_type(void) +{ + return "ROM/RAM"; +} + --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/mm/cache.c 2004-11-29 23:17:21.000000000 +0000 +++ dropin/arch/sh64/mm/cache.c 2005-01-10 22:34:21.000000000 +0000 @@ -415,6 +415,7 @@ eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; for (eaddr=eaddr0; eaddrdcache.way_ofs) { asm __volatile__ ("alloco %0, 0" : : "r" (eaddr)); + asm __volatile__ ("synco"); /* TAKum03020 */ } eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/mm/fault.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/mm/fault.c 2005-01-10 22:34:21.000000000 +0000 @@ -127,8 +127,6 @@ struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; - unsigned long page; - unsigned long long lpage; unsigned long fixup; pte_t *pte; --- ../../kernel.org/linux-2.4.29-rc1/arch/sh64/mm/ioremap.c 2003-08-25 12:44:40.000000000 +0100 +++ dropin/arch/sh64/mm/ioremap.c 2005-01-10 22:34:21.000000000 +0000 @@ -290,7 +290,7 @@ psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; /* log at boot time ... */ - printk("mapioaddr: %6s [%2ld page%s] va 0x%08lx pa 0x%08x\n", + printk("mapioaddr: %6s [%2d page%s] va 0x%08lx pa 0x%08x\n", ((res->name != NULL) ? res->name : "???"), psz, psz == 1 ? " " : "s", va, pa); @@ -396,7 +396,7 @@ psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; - printk(KERN_DEBUG "unmapioaddr: %6s [%2ld page%s] freed\n", + printk(KERN_DEBUG "unmapioaddr: %6s [%2d page%s] freed\n", res->name, psz, psz == 1 ? " " : "s"); shmedia_free_io(res); --- ../../kernel.org/linux-2.4.29-rc1/drivers/char/Makefile 2004-11-29 23:17:22.000000000 +0000 +++ dropin/drivers/char/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -233,6 +233,13 @@ ifeq ($(CONFIG_INPUT),y) obj-y += joystick/js.o +else + # Some soundcard drivers, such as es1371, depend on joystick/gameport.o + # so we need to build it even if CONFIG_INPUT is not set. + ifeq ($(CONFIG_INPUT_GAMEPORT),y) + subdir-y += joystick + obj-y += joystick/js.o + endif endif obj-$(CONFIG_FETCHOP) += fetchop.o --- ../../kernel.org/linux-2.4.29-rc1/drivers/sound/es1371.c 2003-08-25 12:44:42.000000000 +0100 +++ dropin/drivers/sound/es1371.c 2005-01-10 22:34:21.000000000 +0000 @@ -509,6 +509,12 @@ return r; } +#if 0 + +/* Original code, never reaches OK state but always times out, + * at least on SH-5. This creates long delays during driver initialisation. + */ + static unsigned src_read(struct es1371_state *s, unsigned reg) { unsigned int temp,i,orig; @@ -530,17 +536,46 @@ if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){ /* wait for the right state */ for (i=0; iio + ES1371_REG_SRCONV); if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 )) break; } } + if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )) { + printk(PFX "sample rate converter read timeout, state=0x%08x\n", temp); + } + /* hide the state bits */ outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV); - return temp; - - + return temp; +} +#endif + +static unsigned src_read(struct es1371_state *s, unsigned reg) +{ + unsigned int temp,i,orig; + + /* wait for ready */ + orig = wait_src_ready(s); + + /* we can only access the SRC at certain times, make sure + we're allowed to before we read */ + + /* expose the SRC state bits */ + outl((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), + s->io + ES1371_REG_SRCONV); + + /* now, wait for busy and the correct time to read */ + temp = wait_src_ready(s); + + /* hide the state bits, is this necessary? */ + outl((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), + s->io + ES1371_REG_SRCONV); + + return temp; } static void src_write(struct es1371_state *s, unsigned reg, unsigned data) @@ -565,15 +600,21 @@ if (rate > 48000) rate = 48000; + if (rate < 4000) rate = 4000; + n = rate / 3000; + if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) n--; + truncm = (21 * n - 1) | 1; freq = ((48000UL << 15) / rate) * n; s->adcrate = (48000UL << 15) / (freq / n); + spin_lock_irqsave(&s->lock, flags); + if (rate >= 24000) { if (truncm > 239) truncm = 239; @@ -585,9 +626,11 @@ src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); } + src_write(s, SRCREG_ADC+SRCREG_INT_REGS, (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00)); + src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff); src_write(s, SRCREG_VOL_ADC, n << 8); src_write(s, SRCREG_VOL_ADC+1, n << 8); @@ -666,10 +709,21 @@ src_write(s, SRCREG_VOL_DAC1+1, 1 << 12); src_write(s, SRCREG_VOL_DAC2, 1 << 12); src_write(s, SRCREG_VOL_DAC2+1, 1 << 12); + + printk("src_init: src registers written\n"); + set_adc_rate(s, 22050); + + printk("src_init: adc rate set\n"); + set_dac1_rate(s, 22050); + + printk("src_init: dac1 rate set\n"); + set_dac2_rate(s, 22050); + printk("src_init: dac2 rate set\n"); + /* WARNING: * enabling the sample rate converter without properly programming * its parameters causes the chip to lock up (the SRC busy bit will @@ -677,7 +731,12 @@ * power cycle) */ wait_src_ready(s); + + printk("src_init: ready again\n"); + outl(0, s->io+ES1371_REG_SRCONV); + + printk("src_init: done\n"); } /* --------------------------------------------------------------------- */ @@ -764,6 +823,7 @@ wait_src_ready(s); outl(x, s->io+ES1371_REG_SRCONV); +#if 0 /* wait for WIP again */ for (t = 0; t < 0x1000; t++) if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) @@ -773,6 +833,15 @@ for (t = 0; t < POLL_COUNT; t++) if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY) break; +#endif + + /* wait for WIP to be false and RDY to be true */ + for (t = 0; t < POLL_COUNT; t++) { + x = inl(s->io+ES1371_REG_CODEC); + + if ((x & (CODEC_WIP | CODEC_RDY)) == CODEC_RDY) + break; + } spin_unlock_irqrestore(&s->lock, flags); return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/Config.in 2004-02-18 13:36:31.000000000 +0000 +++ dropin/drivers/video/Config.in 2005-01-10 22:34:21.000000000 +0000 @@ -12,6 +12,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_PCI" = "y" ]; then tristate ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA + tristate ' IMG Kyro support (EXPERIMENTAL)' CONFIG_FB_KYRO fi if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then tristate ' Cirrus Logic support (EXPERIMENTAL)' CONFIG_FB_CLGEN --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/Makefile 2004-02-18 13:36:31.000000000 +0000 +++ dropin/drivers/video/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -114,6 +114,11 @@ obj-y += riva/rivafb.o endif +subdir-$(CONFIG_FB_KYRO) += kyro +ifeq ($(CONFIG_FB_KYRO),y) +obj-y += kyro/kyro.o fbgen.o +endif + subdir-$(CONFIG_FB_SIS) += sis ifeq ($(CONFIG_FB_SIS),y) obj-y += sis/sisfb.o --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/fbmem.c 2005-01-10 22:12:04.000000000 +0000 +++ dropin/drivers/video/fbmem.c 2005-01-10 22:34:46.000000000 +0000 @@ -143,6 +143,8 @@ extern int pvr2fb_setup(char*); extern int sstfb_init(void); extern int sstfb_setup(char*); +extern int kyrofb_init(void); +extern int kyrofb_setup(char*); extern int it8181fb_init(void); extern int it8181fb_setup(char*); @@ -335,7 +337,6 @@ { "it8181fb", it8181fb_init, it8181fb_setup }, #endif - /* * Generic drivers that don't use resource management (yet) */ @@ -346,6 +347,10 @@ #ifdef CONFIG_FB_STI { "stifb", stifb_init, stifb_setup }, #endif +#ifdef CONFIG_FB_KYRO + { "kyrofb", kyrofb_init, kyrofb_setup }, +#endif + #ifdef CONFIG_GSP_RESOLVER /* Not a real frame buffer device... */ --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/Makefile 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,16 @@ +# +# Makefile for the Kyro framebuffer driver +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := kyro.o + +obj-y := vesa_timing.o STG4000Ramdac.o STG4000VTG.o STG4000OverlayDevice.o\ + STG4000InitDevice.o kyrofb.o +obj-m := $(O_TARGET) + +include $(TOPDIR)/Rules.make --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/STG4000InitDevice.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/STG4000InitDevice.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,328 @@ +/* + * linux/drivers/video/kyro/STG4000InitDevice.c + * + * Copyright (C) 2000 Imagination Technologies Ltd + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#include +#include +#include +#include + +#include "STG4000Reg.h" + +/* SDRAM fixed settings */ +#define SDRAM_CFG_0 0x49A1 +#define SDRAM_CFG_1 0xA732 +#define SDRAM_CFG_2 0x31 +#define SDRAM_ARB_CFG 0xA0 +#define SDRAM_REFRESH 0x20 + +/* Reset values */ +#define PMX2_SOFTRESET_DAC_RST 0x0001 +#define PMX2_SOFTRESET_C1_RST 0x0004 +#define PMX2_SOFTRESET_C2_RST 0x0008 +#define PMX2_SOFTRESET_3D_RST 0x0010 +#define PMX2_SOFTRESET_VIDIN_RST 0x0020 +#define PMX2_SOFTRESET_TLB_RST 0x0040 +#define PMX2_SOFTRESET_SD_RST 0x0080 +#define PMX2_SOFTRESET_VGA_RST 0x0100 +#define PMX2_SOFTRESET_ROM_RST 0x0200 /* reserved bit, do not reset */ +#define PMX2_SOFTRESET_TA_RST 0x0400 +#define PMX2_SOFTRESET_REG_RST 0x4000 +#define PMX2_SOFTRESET_ALL 0x7fff + +/* Core clock freq */ +#define CORE_PLL_FREQ 1000000 + +/* Reference Clock freq */ +#define REF_FREQ 14318 + +/* PCI Registers */ +static u16 CorePllControl = 0x70; + +#define PCI_CONFIG_SUBSYS_ID 0x2e + +/* Misc */ +#define CORE_PLL_MODE_REG_0_7 3 +#define CORE_PLL_MODE_REG_8_15 2 +#define CORE_PLL_MODE_CONFIG_REG 1 +#define DAC_PLL_CONFIG_REG 0 + +#define STG_MAX_VCO 500000 +#define STG_MIN_VCO 100000 + +/* PLL Clock */ +#define STG4K3_PLL_SCALER 8 /* scale numbers by 2^8 for fixed point calc */ +#define STG4K3_PLL_MIN_R 2 /* Minimum multiplier */ +#define STG4K3_PLL_MAX_R 33 /* Max */ +#define STG4K3_PLL_MIN_F 2 /* Minimum divisor */ +#define STG4K3_PLL_MAX_F 513 /* Max */ +#define STG4K3_PLL_MIN_OD 0 /* Min output divider (shift) */ +#define STG4K3_PLL_MAX_OD 2 /* Max */ +#define STG4K3_PLL_MIN_VCO_SC (100000000 >> STG4K3_PLL_SCALER) /* Min VCO rate */ +#define STG4K3_PLL_MAX_VCO_SC (500000000 >> STG4K3_PLL_SCALER) /* Max VCO rate */ +#define STG4K3_PLL_MINR_VCO_SC (100000000 >> STG4K3_PLL_SCALER) /* Min VCO rate (restricted) */ +#define STG4K3_PLL_MAXR_VCO_SC (500000000 >> STG4K3_PLL_SCALER) /* Max VCO rate (restricted) */ +#define STG4K3_PLL_MINR_VCO 100000000 /* Min VCO rate (restricted) */ +#define STG4K3_PLL_MAX_VCO 500000000 /* Max VCO rate */ +#define STG4K3_PLL_MAXR_VCO 500000000 /* Max VCO rate (restricted) */ + +#define OS_DELAY(X) \ +{ \ +volatile u32 i,count=0; \ + for(i=0;i> 4; + dwChipSpeedIdx = (dwSubSysID & 0x180) >> 7; + + if (dwMemTypeIdx > 4 || dwChipSpeedIdx > 2) + return 0; + + /* Program SD-RAM interface */ + STG_WRITE_REG(SDRAMArbiterConf, adwSDRAMArgCfg0[dwMemTypeIdx]); + if (dwRevID < 5) { + STG_WRITE_REG(SDRAMConf0, 0x49A1); + STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg1[dwMemTypeIdx]); + } else { + STG_WRITE_REG(SDRAMConf0, 0x4DF1); + STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg2[dwMemTypeIdx]); + } + + STG_WRITE_REG(SDRAMConf2, 0x31); + STG_WRITE_REG(SDRAMRefresh, adwSDRAMRsh[dwChipSpeedIdx]); + + return adwChipSpeed[dwChipSpeedIdx] * 10000; +} + +/*-----------------------------------------------------------------------*/ + +u32 ProgramClock(u32 refClock, + u32 coreClock, + u32 * FOut, u32 * ROut, u32 * POut) +{ + u32 R = 0, F = 0, OD = 0, ODIndex = 0; + u32 ulBestR = 0, ulBestF = 0, ulBestOD = 0; + u32 ulBestVCO = 0, ulBestClk = 0, ulBestScore = 0; + u32 ulScore, ulPhaseScore, ulVcoScore; + u32 ulTmp = 0, ulVCO; + u32 ulScaleClockReq, ulMinClock, ulMaxClock; + u32 ODValues[] = { 1, 2, 0 }; + + /* Translate clock in Hz */ + coreClock *= 100; /* in Hz */ + refClock *= 1000; /* in Hz */ + + /* Work out acceptable clock + * The method calculates ~ +- 0.4% (1/256) + */ + ulMinClock = coreClock - (coreClock >> 8); + ulMaxClock = coreClock + (coreClock >> 8); + + /* Scale clock required for use in calculations */ + ulScaleClockReq = coreClock >> STG4K3_PLL_SCALER; + + /* Iterate through post divider values */ + for (ODIndex = 0; ODIndex < 3; ODIndex++) { + OD = ODValues[ODIndex]; + R = STG4K3_PLL_MIN_R; + + /* loop for pre-divider from min to max */ + while (R <= STG4K3_PLL_MAX_R) { + /* estimate required feedback multiplier */ + ulTmp = R * (ulScaleClockReq << OD); + + /* F = ClkRequired * R * (2^OD) / Fref */ + F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER)); + + /* compensate for accuracy */ + if (F > STG4K3_PLL_MIN_F) + F--; + + + /* + * We should be close to our target frequency (if it's + * achievable with current OD & R) let's iterate + * through F for best fit + */ + while ((F >= STG4K3_PLL_MIN_F) && + (F <= STG4K3_PLL_MAX_F)) { + /* Calc VCO at full accuracy */ + ulVCO = refClock / R; + ulVCO = F * ulVCO; + + /* + * Check it's within restricted VCO range + * unless of course the desired frequency is + * above the restricted range, then test + * against VCO limit + */ + if ((ulVCO >= STG4K3_PLL_MINR_VCO) && + ((ulVCO <= STG4K3_PLL_MAXR_VCO) || + ((coreClock > STG4K3_PLL_MAXR_VCO) + && (ulVCO <= STG4K3_PLL_MAX_VCO)))) { + ulTmp = (ulVCO >> OD); /* Clock = VCO / (2^OD) */ + + /* Is this clock good enough? */ + if ((ulTmp >= ulMinClock) + && (ulTmp <= ulMaxClock)) { + ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10); + + ulVcoScore = ((ulVCO - STG4K3_PLL_MINR_VCO)) / ((STG4K3_PLL_MAXR_VCO - STG4K3_PLL_MINR_VCO) >> 10); + ulScore = ulPhaseScore + ulVcoScore; + + if (!ulBestScore) { + ulBestVCO = ulVCO; + ulBestOD = OD; + ulBestF = F; + ulBestR = R; + ulBestClk = ulTmp; + ulBestScore = + ulScore; + } + /* is this better, ( aim for highest Score) */ + /*-------------------------------------------------------------------------- + Here we want to use a scoring system which will take account of both the + value at the phase comparater and the VCO output + to do this we will use a cumulative score between the two + The way this ends up is that we choose the first value in the loop anyway + but we shall keep this code in case new restrictions come into play + --------------------------------------------------------------------------*/ + if ((ulScore >= ulBestScore) && (OD > 0)) { + ulBestVCO = ulVCO; + ulBestOD = OD; + ulBestF = F; + ulBestR = R; + ulBestClk = ulTmp; + ulBestScore = + ulScore; + } + } + } + F++; + } + R++; + } + } + + /* + did we find anything? + Then return RFOD + */ + if (ulBestScore) { + *ROut = ulBestR; + *FOut = ulBestF; + + if ((ulBestOD == 2) || (ulBestOD == 3)) { + *POut = 3; + } else + *POut = ulBestOD; + + } + + return (ulBestClk); +} + +int SetCoreClockPLL(volatile STG4000REG * pSTGReg, struct pci_dev *pDev) +{ + u32 F, R, P; + u16 core_pll = 0, sub; + u32 ulCoreClock; + u32 tmp; + u32 ulChipSpeed; + u8 rev; + + STG_WRITE_REG(IntMask, 0xFFFF); + + /* Disable Primary Core Thread0 */ + tmp = STG_READ_REG(Thread0Enable); + CLEAR_BIT(0); + STG_WRITE_REG(Thread0Enable, tmp); + + /* Disable Primary Core Thread1 */ + tmp = STG_READ_REG(Thread1Enable); + CLEAR_BIT(0); + STG_WRITE_REG(Thread1Enable, tmp); + + STG_WRITE_REG(SoftwareReset, + PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST); + STG_WRITE_REG(SoftwareReset, + PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST | + PMX2_SOFTRESET_ROM_RST); + + /* Need to play around to reset TA */ + STG_WRITE_REG(TAConfiguration, 0); + STG_WRITE_REG(SoftwareReset, + PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST); + STG_WRITE_REG(SoftwareReset, + PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST | + PMX2_SOFTRESET_ROM_RST); + + pci_read_config_word(pDev, PCI_CONFIG_SUBSYS_ID, &sub); + pci_read_config_byte(pDev, PCI_REVISION_ID, &rev); + + ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub, (u32)rev); + + if (ulChipSpeed == 0) + return -EINVAL; + + ulCoreClock = ProgramClock(REF_FREQ, CORE_PLL_FREQ, &F, &R, &P); + + core_pll |= ((P) | ((F - 2) << 2) | ((R - 2) << 11)); + + /* Set Core PLL Control to Core PLL Mode */ + + /* Send bits 0:7 of the Core PLL Mode register */ + tmp = ((CORE_PLL_MODE_REG_0_7 << 8) | (core_pll & 0x00FF)); + pci_write_config_word(pDev, CorePllControl, tmp); + /* Without some delay between the PCI config writes the clock does + not reliably set when the code is compiled -O3 + */ + OS_DELAY(1000000); + + tmp |= SET_BIT(14); + pci_write_config_word(pDev, CorePllControl, tmp); + OS_DELAY(1000000); + + /* Send bits 8:15 of the Core PLL Mode register */ + tmp = + ((CORE_PLL_MODE_REG_8_15 << 8) | ((core_pll & 0xFF00) >> 8)); + pci_write_config_word(pDev, CorePllControl, tmp); + OS_DELAY(1000000); + + tmp |= SET_BIT(14); + pci_write_config_word(pDev, CorePllControl, tmp); + OS_DELAY(1000000); + + STG_WRITE_REG(SoftwareReset, PMX2_SOFTRESET_ALL); + +#if 0 + /* Enable Primary Core Thread0 */ + tmp = ((STG_READ_REG(Thread0Enable)) | SET_BIT(0)); + STG_WRITE_REG(Thread0Enable, tmp); + + /* Enable Primary Core Thread1 */ + tmp = ((STG_READ_REG(Thread1Enable)) | SET_BIT(0)); + STG_WRITE_REG(Thread1Enable, tmp); +#endif + + return 0; +} --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/STG4000Interface.h 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/STG4000Interface.h 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * linux/drivers/video/kyro/STG4000Interface.h + * + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#ifndef _STG4000INTERFACE_H +#define _STG4000INTERFACE_H + +struct pci_dev; /* forward reference */ + +/* + * Ramdac Setup + */ +extern int InitialiseRamdac(volatile STG4000REG *pSTGReg, u32 displayDepth, + u32 displayWidth, u32 displayHeight, + s32 HSyncPolarity, s32 VSyncPolarity, + u32 *pixelClock); + +extern void DisableRamdacOutput(volatile STG4000REG * pSTGReg); +extern void EnableRamdacOutput(volatile STG4000REG * pSTGReg); + +/* + * Timing generator setup + */ +extern void DisableVGA(volatile STG4000REG * pSTGReg); +extern void StopVTG(volatile STG4000REG * pSTGReg); +extern void StartVTG(volatile STG4000REG * pSTGReg); +extern void SetupVTG(volatile STG4000REG * pSTGReg, + const vtg_settings_t * pTiming); + +extern u32 ProgramClock(u32 refClock, u32 coreClock, u32 *FOut, u32 *ROut, u32 *POut); +extern int SetCoreClockPLL(volatile STG4000REG * pSTGReg, struct pci_dev *pDev); + +/* + * Overlay setup + */ +extern void ResetOverlayRegisters(volatile STG4000REG * pSTGReg); + +extern int CreateOverlaySurface(volatile STG4000REG * pSTGReg, + u32 ulWidth, u32 ulHeight, + int bLinear, + u32 ulOverlayOffset, + u32 * retStride, u32 * retUVStride); + +extern int SetOverlayBlendMode(volatile STG4000REG * pSTGReg, + OVRL_BLEND_MODE mode, + u32 ulAlpha, u32 ulColorKey); + +extern int SetOverlayViewPort(volatile STG4000REG * pSTGReg, + u32 left, u32 top, + u32 right, u32 bottom); + +extern void EnableOverlayPlane(volatile STG4000REG * pSTGReg); + +#endif /* _STG4000INTERFACE_H */ --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/STG4000OverlayDevice.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/STG4000OverlayDevice.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,609 @@ +/* + * linux/drivers/video/kyro/STG4000OverlayDevice.c + * + * Copyright (C) 2000 Imagination Technologies Ltd + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#include +#include +#include + +#include "STG4000Reg.h" + +/* HW Defines */ + +#define STG4000_NO_SCALING 0x800 +#define STG4000_NO_DECIMATION 0xFFFFFFFF + +/* Primary surface */ +#define STG4000_PRIM_NUM_PIX 5 +#define STG4000_PRIM_ALIGN 4 +#define STG4000_PRIM_ADDR_BITS 20 + +#define STG4000_PRIM_MIN_WIDTH 640 +#define STG4000_PRIM_MAX_WIDTH 1600 +#define STG4000_PRIM_MIN_HEIGHT 480 +#define STG4000_PRIM_MAX_HEIGHT 1200 + +/* Overlay surface */ +#define STG4000_OVRL_NUM_PIX 4 +#define STG4000_OVRL_ALIGN 2 +#define STG4000_OVRL_ADDR_BITS 20 +#define STG4000_OVRL_NUM_MODES 5 + +#define STG4000_OVRL_MIN_WIDTH 0 +#define STG4000_OVRL_MAX_WIDTH 720 +#define STG4000_OVRL_MIN_HEIGHT 0 +#define STG4000_OVRL_MAX_HEIGHT 576 + +/* Decimation and Scaling */ +u32 adwDecim8[33] = { + 0xffffffff, 0xfffeffff, 0xffdffbff, 0xfefefeff, 0xfdf7efbf, + 0xfbdf7bdf, 0xf7bbddef, 0xeeeeeeef, 0xeeddbb77, 0xedb76db7, + 0xdb6db6db, 0xdb5b5b5b, 0xdab5ad6b, 0xd5ab55ab, 0xd555aaab, + 0xaaaaaaab, 0xaaaa5555, 0xaa952a55, 0xa94a5295, 0xa5252525, + 0xa4924925, 0x92491249, 0x91224489, 0x91111111, 0x90884211, + 0x88410821, 0x88102041, 0x81010101, 0x80800801, 0x80010001, + 0x80000001, 0x00000001, 0x00000000 +}; + +typedef struct _OVRL_SRC_DEST { + /*clipped on-screen pixel position of overlay */ + u32 ulDstX1; + u32 ulDstY1; + u32 ulDstX2; + u32 ulDstY2; + + /*clipped pixel pos of source data within buffer thses need to be 128 bit word aligned */ + u32 ulSrcX1; + u32 ulSrcY1; + u32 ulSrcX2; + u32 ulSrcY2; + + /* on-screen pixel position of overlay */ + s32 lDstX1; + s32 lDstY1; + s32 lDstX2; + s32 lDstY2; +} OVRL_SRC_DEST; + +static u32 ovlWidth, ovlHeight, ovlStride; +static int ovlLinear; + +void ResetOverlayRegisters(volatile STG4000REG * pSTGReg) +{ + u32 tmp; + + /* Set Overlay address to default */ + tmp = STG_READ_REG(DACOverlayAddr); + CLEAR_BITS_FRM_TO(0, 20); + CLEAR_BIT(31); + STG_WRITE_REG(DACOverlayAddr, tmp); + + /* Set Overlay U address */ + tmp = STG_READ_REG(DACOverlayUAddr); + CLEAR_BITS_FRM_TO(0, 20); + STG_WRITE_REG(DACOverlayUAddr, tmp); + + /* Set Overlay V address */ + tmp = STG_READ_REG(DACOverlayVAddr); + CLEAR_BITS_FRM_TO(0, 20); + STG_WRITE_REG(DACOverlayVAddr, tmp); + + /* Set Overlay Size */ + tmp = STG_READ_REG(DACOverlaySize); + CLEAR_BITS_FRM_TO(0, 10); + CLEAR_BITS_FRM_TO(12, 31); + STG_WRITE_REG(DACOverlaySize, tmp); + + /* Set Overlay Vt Decimation */ + tmp = STG4000_NO_DECIMATION; + STG_WRITE_REG(DACOverlayVtDec, tmp); + + /* Set Overlay format to default value */ + tmp = STG_READ_REG(DACPixelFormat); + CLEAR_BITS_FRM_TO(4, 7); + CLEAR_BITS_FRM_TO(16, 22); + STG_WRITE_REG(DACPixelFormat, tmp); + + /* Set Vertical scaling to default */ + tmp = STG_READ_REG(DACVerticalScal); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 22); + tmp |= STG4000_NO_SCALING; /* Set to no scaling */ + STG_WRITE_REG(DACVerticalScal, tmp); + + /* Set Horizontal Scaling to default */ + tmp = STG_READ_REG(DACHorizontalScal); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 17); + tmp |= STG4000_NO_SCALING; /* Set to no scaling */ + STG_WRITE_REG(DACHorizontalScal, tmp); + + /* Set Blend mode to Alpha Blend */ + /* ????? SG 08/11/2001 Surely this isn't the alpha blend mode, + hopefully its overwrite + */ + tmp = STG_READ_REG(DACBlendCtrl); + CLEAR_BITS_FRM_TO(0, 30); + tmp = (GRAPHICS_MODE << 28); + STG_WRITE_REG(DACBlendCtrl, tmp); + +} + +/*-------------------------------------------------------------------------*/ + +int CreateOverlaySurface(volatile STG4000REG * pSTGReg, + u32 inWidth, + u32 inHeight, + int bLinear, + u32 ulOverlayOffset, + u32 * retStride, u32 * retUVStride) +{ + u32 tmp; + u32 ulStride; + + if (inWidth > STG4000_OVRL_MAX_WIDTH || + inHeight > STG4000_OVRL_MAX_HEIGHT) { + return -EINVAL; + } + + /* Stride in 16 byte words - 16Bpp */ + if (bLinear) { + /* Format is 16bits so num 16 byte words is width/8 */ + if ((inWidth & 0x7) == 0) { /* inWidth % 8 */ + ulStride = (inWidth / 8); + } else { + /* Round up to next 16byte boundary */ + ulStride = ((inWidth + 8) / 8); + } + } else { + /* Y component is 8bits so num 16 byte words is width/16 */ + if ((inWidth & 0xf) == 0) { /* inWidth % 16 */ + ulStride = (inWidth / 16); + } else { + /* Round up to next 16byte boundary */ + ulStride = ((inWidth + 16) / 16); + } + } + + + /* Set Overlay address and Format mode */ + tmp = STG_READ_REG(DACOverlayAddr); + CLEAR_BITS_FRM_TO(0, 20); + if (bLinear) { + CLEAR_BIT(31); /* Overlay format to Linear */ + } else { + tmp |= SET_BIT(31); /* Overlay format to Planer */ + } + + /* Only bits 24:4 of the Overlay address */ + tmp |= (ulOverlayOffset >> 4); + STG_WRITE_REG(DACOverlayAddr, tmp); + + if (!bLinear) { + u32 uvSize = + (inWidth & 0x1) ? (inWidth + 1 / 2) : (inWidth / 2); + u32 uvStride; + u32 ulOffset; + /* Y component is 8bits so num 32 byte words is width/32 */ + if ((uvSize & 0xf) == 0) { /* inWidth % 16 */ + uvStride = (uvSize / 16); + } else { + /* Round up to next 32byte boundary */ + uvStride = ((uvSize + 16) / 16); + } + + ulOffset = ulOverlayOffset + (inHeight * (ulStride * 16)); + /* Align U,V data to 32byte boundary */ + if ((ulOffset & 0x1f) != 0) + ulOffset = (ulOffset + 32L) & 0xffffffE0L; + + tmp = STG_READ_REG(DACOverlayUAddr); + CLEAR_BITS_FRM_TO(0, 20); + tmp |= (ulOffset >> 4); + STG_WRITE_REG(DACOverlayUAddr, tmp); + + ulOffset += (inHeight / 2) * (uvStride * 16); + /* Align U,V data to 32byte boundary */ + if ((ulOffset & 0x1f) != 0) + ulOffset = (ulOffset + 32L) & 0xffffffE0L; + + tmp = STG_READ_REG(DACOverlayVAddr); + CLEAR_BITS_FRM_TO(0, 20); + tmp |= (ulOffset >> 4); + STG_WRITE_REG(DACOverlayVAddr, tmp); + + *retUVStride = uvStride * 16; + } + + + /* Set Overlay YUV pixel format + * Make sure that LUT not used - ?????? + */ + tmp = STG_READ_REG(DACPixelFormat); + /* Only support Planer or UYVY linear formats */ + CLEAR_BITS_FRM_TO(4, 9); + STG_WRITE_REG(DACPixelFormat, tmp); + + ovlWidth = inWidth; + ovlHeight = inHeight; + ovlStride = ulStride; + ovlLinear = bLinear; + *retStride = ulStride << 4; /* In bytes */ + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +int SetOverlayBlendMode(volatile STG4000REG * pSTGReg, + OVRL_BLEND_MODE mode, + u32 ulAlpha, u32 ulColorKey) +{ + u32 tmp; + + tmp = STG_READ_REG(DACBlendCtrl); + CLEAR_BITS_FRM_TO(28, 30); + tmp |= (mode << 28); + + switch (mode) { + case COLOR_KEY: + CLEAR_BITS_FRM_TO(0, 23); + tmp |= (ulColorKey & 0x00FFFFFF); + break; + + case GLOBAL_ALPHA: + CLEAR_BITS_FRM_TO(24, 27); + tmp |= ((ulAlpha & 0xF) << 24); + break; + + case CK_PIXEL_ALPHA: + CLEAR_BITS_FRM_TO(0, 23); + tmp |= (ulColorKey & 0x00FFFFFF); + break; + + case CK_GLOBAL_ALPHA: + CLEAR_BITS_FRM_TO(0, 23); + tmp |= (ulColorKey & 0x00FFFFFF); + CLEAR_BITS_FRM_TO(24, 27); + tmp |= ((ulAlpha & 0xF) << 24); + break; + + case GRAPHICS_MODE: + case PER_PIXEL_ALPHA: + break; + + default: + return -EINVAL; + } + + STG_WRITE_REG(DACBlendCtrl, tmp); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +void EnableOverlayPlane(volatile STG4000REG * pSTGReg) +{ + u32 tmp; + /* Enable Overlay */ + tmp = STG_READ_REG(DACPixelFormat); + tmp |= SET_BIT(7); + STG_WRITE_REG(DACPixelFormat, tmp); + + /* Set video stream control */ + tmp = STG_READ_REG(DACStreamCtrl); + tmp |= SET_BIT(1); /* video stream */ + STG_WRITE_REG(DACStreamCtrl, tmp); +} + +/*-------------------------------------------------------------------------*/ + +static u32 Overlap(u32 ulBits, u32 ulPattern) +{ + u32 ulCount = 0; + + while (ulBits) { + if (!(ulPattern & 1)) + ulCount++; + ulBits--; + ulPattern = ulPattern >> 1; + } + + return ulCount; + +} + +int SetOverlayViewPort(volatile STG4000REG * pSTGReg, + u32 left, u32 top, + u32 right, u32 bottom) +{ + OVRL_SRC_DEST srcDest; + + u32 ulSrcTop, ulSrcBottom; + u32 ulSrc, ulDest; + u32 ulFxScale, ulFxOffset; + u32 ulHeight, ulWidth; + u32 ulPattern; + u32 ulDecimate, ulDecimated; + u32 ulApplied; + u32 ulDacXScale, ulDacYScale; + u32 ulScale; + u32 ulLeft, ulRight; + u32 ulSrcLeft, ulSrcRight; + u32 ulScaleLeft, ulScaleRight; + u32 ulhDecim; + u32 ulsVal; + u32 ulVertDecFactor; + int bResult; + u32 ulClipOff = 0; + u32 ulBits = 0; + u32 ulsAdd = 0; + u32 tmp, ulStride; + u32 ulExcessPixels, ulClip, ulExtraLines; + + + srcDest.ulSrcX1 = 0; + srcDest.ulSrcY1 = 0; + srcDest.ulSrcX2 = ovlWidth - 1; + srcDest.ulSrcY2 = ovlHeight - 1; + + srcDest.ulDstX1 = left; + srcDest.ulDstY1 = top; + srcDest.ulDstX2 = right; + srcDest.ulDstY2 = bottom; + + srcDest.lDstX1 = srcDest.ulDstX1; + srcDest.lDstY1 = srcDest.ulDstY1; + srcDest.lDstX2 = srcDest.ulDstX2; + srcDest.lDstY2 = srcDest.ulDstY2; + + /************* Vertical decimation/scaling ******************/ + + /* Get Src Top and Bottom */ + ulSrcTop = srcDest.ulSrcY1; + ulSrcBottom = srcDest.ulSrcY2; + + ulSrc = ulSrcBottom - ulSrcTop; + ulDest = srcDest.lDstY2 - srcDest.lDstY1; /* on-screen overlay */ + + if (ulSrc <= 1) + return -EINVAL; + + /* First work out the position we are to display as offset from the + * source of the buffer + */ + ulFxScale = (ulDest << 11) / ulSrc; /* fixed point scale factor */ + ulFxOffset = (srcDest.lDstY2 - srcDest.ulDstY2) << 11; + + ulSrcBottom = ulSrcBottom - (ulFxOffset / ulFxScale); + ulSrc = ulSrcBottom - ulSrcTop; + ulHeight = ulSrc; + + ulDest = srcDest.ulDstY2 - (srcDest.ulDstY1 - 1); + ulPattern = adwDecim8[ulBits]; + + /* At this point ulSrc represents the input decimator */ + if (ulSrc > ulDest) { + ulDecimate = ulSrc - ulDest; + ulBits = 0; + ulApplied = ulSrc / 32; + + while (((ulBits * ulApplied) + + Overlap((ulSrc % 32), + adwDecim8[ulBits])) < ulDecimate) + ulBits++; + + ulPattern = adwDecim8[ulBits]; + ulDecimated = + (ulBits * ulApplied) + Overlap((ulSrc % 32), + ulPattern); + ulSrc = ulSrc - ulDecimated; /* the number number of lines that will go into the scaler */ + } + + if (ulBits && (ulBits != 32)) { + ulVertDecFactor = (63 - ulBits) / (32 - ulBits); /* vertical decimation factor scaled up to nearest integer */ + } else { + ulVertDecFactor = 1; + } + + ulDacYScale = ((ulSrc - 1) * 2048) / (ulDest + 1); + + tmp = STG_READ_REG(DACOverlayVtDec); /* Decimation */ + CLEAR_BITS_FRM_TO(0, 31); + tmp = ulPattern; + STG_WRITE_REG(DACOverlayVtDec, tmp); + + /***************** Horizontal decimation/scaling ***************************/ + + /* + * Now we handle the horizontal case, this is a simplified verison of + * the vertical case in that we decimate by factors of 2. as we are + * working in words we should always be able to decimate by these + * factors. as we always have to have a buffer which is aligned to a + * whole number of 128 bit words, we must align the left side to the + * lowest to the next lowest 128 bit boundary, and the right hand edge + * to the next largets boundary, (in a similar way to how we didi it in + * PMX1) as the left and right hand edges are aligned to these + * boundaries normally this only becomes an issue when we are chopping + * of one of the sides We shall work out vertical stuff first + */ + ulSrc = srcDest.ulSrcX2 - srcDest.ulSrcX1; + ulDest = srcDest.lDstX2 - srcDest.lDstX1; +#ifdef _OLDCODE + ulLeft = srcDest.ulDstX1; + ulRight = srcDest.ulDstX2; +#else + if (srcDest.ulDstX1 > 2) { + ulLeft = srcDest.ulDstX1 + 2; + ulRight = srcDest.ulDstX2 + 1; + } else { + ulLeft = srcDest.ulDstX1; + ulRight = srcDest.ulDstX2 + 1; + } +#endif + /* first work out the position we are to display as offset from the source of the buffer */ + bResult = 1; + + do { + if (ulDest == 0) + return -EINVAL; + + /* source pixels per dest pixel <<11 */ + ulFxScale = ((ulSrc - 1) << 11) / (ulDest); + + /* then number of destination pixels out we are */ + ulFxOffset = ulFxScale * ((srcDest.ulDstX1 - srcDest.lDstX1) + ulClipOff); + ulFxOffset >>= 11; + + /* this replaces the code which was making a decision as to use either ulFxOffset or ulSrcX1 */ + ulSrcLeft = srcDest.ulSrcX1 + ulFxOffset; + + /* then number of destination pixels out we are */ + ulFxOffset = ulFxScale * (srcDest.lDstX2 - srcDest.ulDstX2); + ulFxOffset >>= 11; + + ulSrcRight = srcDest.ulSrcX2 - ulFxOffset; + + /* + * we must align these to our 128 bit boundaries. we shall + * round down the pixel pos to the nearest 8 pixels. + */ + ulScaleLeft = ulSrcLeft; + ulScaleRight = ulSrcRight; + + /* shift fxscale until it is in the range of the scaler */ + ulhDecim = 0; + ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2); + + while (ulScale > 0x800) { + ulhDecim++; + ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2); + } + + /* + * to try and get the best values We first try and use + * src/dwdest for the scale factor, then we move onto src-1 + * + * we want to check to see if we will need to clip data, if so + * then we should clip our source so that we don't need to + */ + if (!ovlLinear) { + ulSrcLeft &= ~0x1f; + + /* + * we must align the right hand edge to the next 32 + * pixel` boundary, must be on a 256 boundary so u, and + * v are 128 bit aligned + */ + ulSrcRight = (ulSrcRight + 0x1f) & ~0x1f; + } else { + ulSrcLeft &= ~0x7; + + /* + * we must align the right hand edge to the next + * 8pixel` boundary + */ + ulSrcRight = (ulSrcRight + 0x7) & ~0x7; + } + + /* this is the input size line store needs to cope with */ + ulWidth = ulSrcRight - ulSrcLeft; + + /* + * use unclipped value to work out scale factror this is the + * scale factor we want we shall now work out the horizonal + * decimation and scaling + */ + ulsVal = ((ulWidth / 8) >> ulhDecim); + + if ((ulWidth != (ulsVal << ulhDecim) * 8)) + ulsAdd = 1; + + /* input pixels to scaler; */ + ulSrc = ulWidth >> ulhDecim; + + if (ulSrc <= 2) + return -EINVAL; + + ulExcessPixels = ((((ulScaleLeft - ulSrcLeft)) << (11 - ulhDecim)) / ulScale); + + ulClip = (ulSrc << 11) / ulScale; + ulClip -= (ulRight - ulLeft); + ulClip += ulExcessPixels; + + if (ulClip) + ulClip--; + + /* We may need to do more here if we really have a HW rev < 5 */ + } while (!bResult); + + ulExtraLines = (1 << ulhDecim) * ulVertDecFactor; + ulExtraLines += 64; + ulHeight += ulExtraLines; + + ulDacXScale = ulScale; + + + tmp = STG_READ_REG(DACVerticalScal); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 22); /* Vertical Scaling */ + + /* Calculate new output line stride, this is always the number of 422 + words in the line buffer, so it doesn't matter if the + mode is 420. Then set the vertical scale register. + */ + ulStride = (ulWidth >> (ulhDecim + 3)) + ulsAdd; + tmp |= ((ulStride << 16) | (ulDacYScale)); /* DAC_LS_CTRL = stride */ + STG_WRITE_REG(DACVerticalScal, tmp); + + /* Now set up the overlay size using the modified width and height + from decimate and scaling calculations + */ + tmp = STG_READ_REG(DACOverlaySize); + CLEAR_BITS_FRM_TO(0, 10); + CLEAR_BITS_FRM_TO(12, 31); + + if (ovlLinear) { + tmp |= + (ovlStride | ((ulHeight + 1) << 12) | + (((ulWidth / 8) - 1) << 23)); + } else { + tmp |= + (ovlStride | ((ulHeight + 1) << 12) | + (((ulWidth / 32) - 1) << 23)); + } + + STG_WRITE_REG(DACOverlaySize, tmp); + + /* Set Video Window Start */ + tmp = ((ulLeft << 16)) | (srcDest.ulDstY1); + STG_WRITE_REG(DACVidWinStart, tmp); + + /* Set Video Window End */ + tmp = ((ulRight) << 16) | (srcDest.ulDstY2); + STG_WRITE_REG(DACVidWinEnd, tmp); + + /* Finally set up the rest of the overlay regs in the order + done in the IMG driver + */ + tmp = STG_READ_REG(DACPixelFormat); + tmp = ((ulExcessPixels << 16) | tmp) & 0x7fffffff; + STG_WRITE_REG(DACPixelFormat, tmp); + + tmp = STG_READ_REG(DACHorizontalScal); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 17); + tmp |= ((ulhDecim << 16) | (ulDacXScale)); + STG_WRITE_REG(DACHorizontalScal, tmp); + + return 0; +} + --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/STG4000Ramdac.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/STG4000Ramdac.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,177 @@ +/* + * linux/drivers/video/kyro/STG4000Ramdac.c + * + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#include +#include +#include + +#include "kyro.h" + +#include "STG4000Reg.h" +#include "STG4000Interface.h" + +static u32 STG_PIXEL_BUS_WIDTH = 128; /* 128 bit bus width */ +static u32 REF_CLOCK = 14318; + + +/* ------------------------------------------------------------- + REQUIRED STATE FROM CLASS +*/ + +STG4000REG *pSTGReg; + +/* ---------------------------------------------------------------*/ + +int InitialiseRamdac(volatile STG4000REG * pSTGReg, + u32 displayDepth, + u32 displayWidth, + u32 displayHeight, + s32 HSyncPolarity, + s32 VSyncPolarity, u32 * pixelClock) +{ + u32 tmp = 0; + u32 F = 0, R = 0, P = 0; + u32 stride = 0; + u32 ulPdiv = 0; + u32 physicalPixelDepth = 0; + /* Make sure DAC is in Reset */ + tmp = STG_READ_REG(SoftwareReset); + + if (tmp & 0x1) { + CLEAR_BIT(1); + STG_WRITE_REG(SoftwareReset, tmp); + } + + /* Set Pixel Format */ + tmp = STG_READ_REG(DACPixelFormat); + CLEAR_BITS_FRM_TO(0, 2); + + /* Set LUT not used from 16bpp to 32 bpp ??? */ + CLEAR_BITS_FRM_TO(8, 9); + + switch (displayDepth) { + case 16: + { + physicalPixelDepth = 16; + tmp |= _16BPP; + break; + } + /*--- case 16 */ + case 32: + { + /* Set for 32 bits per pixel */ + physicalPixelDepth = 32; + tmp |= _32BPP; + break; + } + /*--- case 32 */ + default: + return -EINVAL; + } + /*--- switch(displayDepth) */ + + STG_WRITE_REG(DACPixelFormat, tmp); + + /* Workout Bus transfer bandwidth according to pixel format */ + ulPdiv = STG_PIXEL_BUS_WIDTH / physicalPixelDepth; + + /* Get Screen Stride in pixels */ + stride = displayWidth; + + /* Set Primary size info */ + tmp = STG_READ_REG(DACPrimSize); + CLEAR_BITS_FRM_TO(0, 10); + CLEAR_BITS_FRM_TO(12, 31); + tmp |= + ((((displayHeight - 1) << 12) | (((displayWidth / ulPdiv) - + 1) << 23)) + | (stride / ulPdiv)); + STG_WRITE_REG(DACPrimSize, tmp); + + + /* Set Pixel Clock */ + *pixelClock = ProgramClock(REF_CLOCK, *pixelClock, &F, &R, &P); + + /* Set DAC PLL Mode */ + tmp = STG_READ_REG(DACPLLMode); + CLEAR_BITS_FRM_TO(0, 15); + /* tmp |= ((P-1) | ((F-2) << 2) | ((R-2) << 11)); */ + tmp |= ((P) | ((F - 2) << 2) | ((R - 2) << 11)); + STG_WRITE_REG(DACPLLMode, tmp); + + /* Set Prim Address */ + tmp = STG_READ_REG(DACPrimAddress); + CLEAR_BITS_FRM_TO(0, 20); + CLEAR_BITS_FRM_TO(20, 31); + STG_WRITE_REG(DACPrimAddress, tmp); + + /* Set Cursor details with HW Cursor disabled */ + tmp = STG_READ_REG(DACCursorCtrl); + tmp &= ~SET_BIT(31); + STG_WRITE_REG(DACCursorCtrl, tmp); + + tmp = STG_READ_REG(DACCursorAddr); + CLEAR_BITS_FRM_TO(0, 20); + STG_WRITE_REG(DACCursorAddr, tmp); + + /* Set Video Window */ + tmp = STG_READ_REG(DACVidWinStart); + CLEAR_BITS_FRM_TO(0, 10); + CLEAR_BITS_FRM_TO(16, 26); + STG_WRITE_REG(DACVidWinStart, tmp); + + tmp = STG_READ_REG(DACVidWinEnd); + CLEAR_BITS_FRM_TO(0, 10); + CLEAR_BITS_FRM_TO(16, 26); + STG_WRITE_REG(DACVidWinEnd, tmp); + + /* Set DAC Border Color to default */ + tmp = STG_READ_REG(DACBorderColor); + CLEAR_BITS_FRM_TO(0, 23); + STG_WRITE_REG(DACBorderColor, tmp); + + /* Set Graphics and Overlay Burst Control */ + STG_WRITE_REG(DACBurstCtrl, 0x0404); + + /* Set CRC Trigger to default */ + tmp = STG_READ_REG(DACCrcTrigger); + CLEAR_BIT(0); + STG_WRITE_REG(DACCrcTrigger, tmp); + + /* Set Video Port Control to default */ + tmp = STG_READ_REG(DigVidPortCtrl); + CLEAR_BIT(8); + CLEAR_BITS_FRM_TO(16, 27); + CLEAR_BITS_FRM_TO(1, 3); + CLEAR_BITS_FRM_TO(10, 11); + STG_WRITE_REG(DigVidPortCtrl, tmp); + + return 0; +} + + +/* Ramdac control, turning output to the screen on and off */ +void DisableRamdacOutput(volatile STG4000REG * pSTGReg) +{ + u32 tmp; + + /* Disable DAC for Graphics Stream Control */ + tmp = (STG_READ_REG(DACStreamCtrl)) & ~SET_BIT(0); + STG_WRITE_REG(DACStreamCtrl, tmp); +} + +void EnableRamdacOutput(volatile STG4000REG * pSTGReg) +{ + u32 tmp; + + /* Enable DAC for Graphics Stream Control */ + tmp = (STG_READ_REG(DACStreamCtrl)) | SET_BIT(0); + STG_WRITE_REG(DACStreamCtrl, tmp); +} --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/STG4000Reg.h 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/STG4000Reg.h 2005-01-10 22:42:25.000000000 +0000 @@ -0,0 +1,285 @@ +/* + * linux/drivers/video/kyro/STG4000Reg.h + * + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#ifndef _STG4000REG_H +#define _STG4000REG_H + + +#define DWFILL unsigned long :32 +#define WFILL unsigned short :16 + +/* + * Macros that access memory mapped card registers in PCI space + * Add an appropraite section for your OS or processor architecture. + */ +#if defined(__KERNEL__) +#include +#include +#define STG_WRITE_REG(reg,data) (writel(data,(unsigned long)&pSTGReg->reg)) +#define STG_READ_REG(reg) (readl((unsigned long)&pSTGReg->reg)) +#else +#define STG_WRITE_REG(reg,data) (pSTGReg->reg = data) +#define STG_READ_REG(reg) (pSTGReg->reg) +#endif /* __KERNEL__ */ + +#define SET_BIT(n) (1<<(n)) +#define CLEAR_BIT(n) (tmp &= ~(1< +#include "kyro.h" + +#include "STG4000Reg.h" +#include "STG4000Interface.h" + +void DisableVGA(volatile STG4000REG * pSTGReg) +{ + u32 tmp; + volatile u32 count, i; + + /* Reset the VGA registers */ + tmp = STG_READ_REG(SoftwareReset); + CLEAR_BIT(8); + STG_WRITE_REG(SoftwareReset, tmp); + + /* Just for Delay */ + for (i = 0; i < 1000; i++) { + count++; + } + + /* Pull-out the VGA registers from reset */ + tmp = STG_READ_REG(SoftwareReset); + tmp |= SET_BIT(8); + STG_WRITE_REG(SoftwareReset, tmp); +} + + +void StopVTG(volatile STG4000REG * pSTGReg) +{ + u32 tmp = 0; + + /* Stop Ver and Hor Sync Generator */ + tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2); + CLEAR_BIT(31); + STG_WRITE_REG(DACSyncCtrl, tmp); +} + +void StartVTG(volatile STG4000REG * pSTGReg) +{ + u32 tmp = 0; + + /* Start Ver and Hor Sync Generator */ + tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31)); + CLEAR_BIT(0); + CLEAR_BIT(2); + STG_WRITE_REG(DACSyncCtrl, tmp); +} + +void SetupVTG(volatile STG4000REG * pSTGReg, + const vtg_settings_t * pTiming) +{ + u32 tmp = 0; + u32 margins = 0; + u32 ulBorder; + u32 xRes = pTiming->XRES; + u32 yRes = pTiming->YRES; + + /* Horizontal */ + u32 HAddrTime, HRightBorder, HLeftBorder; + u32 HBackPorcStrt, HFrontPorchStrt, HTotal, + HLeftBorderStrt, HRightBorderStrt, HDisplayStrt; + + /* Vertical */ + u32 VDisplayStrt, VBottomBorder, VTopBorder; + u32 VBackPorchStrt, VTotal, VTopBorderStrt, + VFrontPorchStrt, VBottomBorderStrt, VAddrTime; + + /* Need to calculate the right border */ + if ((xRes == 640) && (yRes == 480)) { + if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) { + margins = 8; + } + } + + /* Work out the Border */ + ulBorder = + (pTiming->HTot - + (pTiming->HST + (pTiming->HBP - margins) + xRes + + (pTiming->HFP - margins))) >> 1; + + /* Border the same for Vertical and Horizontal */ + VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder; + + /************ Get Timing values for Horizontal ******************/ + HAddrTime = xRes; + HBackPorcStrt = pTiming->HST; + HTotal = pTiming->HTot; + HDisplayStrt = + pTiming->HST + (pTiming->HBP - margins) + HLeftBorder; + HLeftBorderStrt = HDisplayStrt - HLeftBorder; + HFrontPorchStrt = + pTiming->HST + (pTiming->HBP - margins) + HLeftBorder + + HAddrTime + HRightBorder; + HRightBorderStrt = HFrontPorchStrt - HRightBorder; + + /************ Get Timing values for Vertical ******************/ + VAddrTime = yRes; + VBackPorchStrt = pTiming->VST; + VTotal = pTiming->VTot; + VDisplayStrt = + pTiming->VST + (pTiming->VBP - margins) + VTopBorder; + VTopBorderStrt = VDisplayStrt - VTopBorder; + VFrontPorchStrt = + pTiming->VST + (pTiming->VBP - margins) + VTopBorder + + VAddrTime + VBottomBorder; + VBottomBorderStrt = VFrontPorchStrt - VBottomBorder; + + /* Set Hor Timing 1, 2, 3 */ + tmp = STG_READ_REG(DACHorTim1); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (HTotal) | (HBackPorcStrt << 16); + STG_WRITE_REG(DACHorTim1, tmp); + + tmp = STG_READ_REG(DACHorTim2); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (HDisplayStrt << 16) | HLeftBorderStrt; + STG_WRITE_REG(DACHorTim2, tmp); + + + tmp = STG_READ_REG(DACHorTim3); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt; + STG_WRITE_REG(DACHorTim3, tmp); + + /* Set Ver Timing 1, 2, 3 */ + tmp = STG_READ_REG(DACVerTim1); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (VBackPorchStrt << 16) | (VTotal); + STG_WRITE_REG(DACVerTim1, tmp); + + tmp = STG_READ_REG(DACVerTim2); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (VDisplayStrt << 16) | VTopBorderStrt; + STG_WRITE_REG(DACVerTim2, tmp); + + tmp = STG_READ_REG(DACVerTim3); + CLEAR_BITS_FRM_TO(0, 11); + CLEAR_BITS_FRM_TO(16, 27); + tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt; + STG_WRITE_REG(DACVerTim3, tmp); + + + /* Set Verical and Horizontal Polarity */ + tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1); + + if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */ + tmp &= ~0x8; + } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */ + tmp &= ~0x2; + } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */ + tmp &= ~0xA; + } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */ + tmp &= ~0x0; + } + + STG_WRITE_REG(DACSyncCtrl, tmp); +} --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/kyro.h 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/kyro.h 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * linux/drivers/video/kyro/kryo.h + * + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#ifndef _KYRO_H +#define _KYRO_H + +/* + * Video Timings + */ +typedef struct { + u32 HTot; /* Hor Total Time */ + u32 HFP; /* Hor Front Porch */ + u32 HST; /* Hor Sync Time */ + u32 HBP; /* Hor Back Porch */ + s32 HSP; /* Hor Sync Polarity */ + u32 VTot; /* Ver Total Time */ + u32 VFP; /* Ver Front Porch */ + u32 VST; /* Ver Sync Time */ + u32 VBP; /* Ver Back Porch */ + s32 VSP; /* Ver Sync Polarity */ + u32 XRES; /* X Resolution */ + u32 YRES; /* Y Resolution */ + u32 VFREQ; /* Ver Frequency */ + u32 PIXCLK; /* Pixel Clock */ + u32 HCLK; /* Hor Clock */ + + /* Usefull to hold depth here for Linux */ + u8 PIXDEPTH; +} vtg_settings_t; + + +extern int kyro_video_timings_lookup(u32 h_pixels, u32 v_lines, u32 vfreq, + vtg_settings_t *pVS); + +extern int kyro_dev_init(void); +extern void kyro_dev_reset(void); + +extern unsigned char *kyro_dev_physical_fb_ptr(void); +extern unsigned char *kyro_dev_virtual_fb_ptr(void); +extern void *kyro_dev_physical_regs_ptr(void); +extern void *kyro_dev_virtual_regs_ptr(void); +extern unsigned int kyro_dev_fb_size(void); +extern unsigned int kyro_dev_regs_size(void); + +extern int kyro_dev_video_mode_set(const vtg_settings_t * pTiming, + u8 depth, int bClearMemory); + +extern int kyro_dev_overlay_create(u32 width, u32 height, int bLinear); +extern u32 kyro_dev_overlay_offset(void); +extern int kyro_dev_overlay_viewport_set(u32 x, u32 y, u32 width, u32 height); + +/****************************************************************************/ + +/* + * benedict.gaster@superh.com + * Added the follow IOCTLS for the creation of overlay services... + */ + +#define KYRO_IOC_MAGIC 'k' + +#define KYRO_IOCTL_OVERLAY_CREATE _IO(KYRO_IOC_MAGIC, 0) +#define KYRO_IOCTL_OVERLAY_VIEWPORT_SET _IO(KYRO_IOC_MAGIC, 1) +#define KYRO_IOCTL_SET_VIDEO_MODE _IO(KYRO_IOC_MAGIC, 2) +#define KYRO_IOCTL_UVSTRIDE _IO(KYRO_IOC_MAGIC, 3) +#define KYRO_IOCTL_OVERLAY_OFFSET _IO(KYRO_IOC_MAGIC, 4) +#define KYRO_IOCTL_STRIDE _IO(KYRO_IOC_MAGIC, 5) + +/* + * The follow 3 structures are used to pass data from user space into the kernel + * for the creation of overlay surfaces and setting the video mode. + */ + +typedef struct _OVERLAY_CREATE { + u32 ulWidth; + u32 ulHeight; + int bLinear; +} overlay_create; + +typedef struct _OVERLAY_VIEWPORT_SET { + u32 xOrgin; + u32 yOrgin; + u32 xSize; + u32 ySize; +} overlay_viewport_set; + +typedef struct _SET_VIDEO_MODE { + u32 ulWidth; + u32 ulHeight; + u32 ulScan; + u8 displayDepth; + int bLinear; +} set_video_mode; + +/****************************************************************************/ + + +#endif /* _KYRO_H */ --- ../../kernel.org/linux-2.4.29-rc1/drivers/video/kyro/kyrofb.c 1970-01-01 01:00:00.000000000 +0100 +++ dropin/drivers/video/kyro/kyrofb.c 2005-01-10 22:34:21.000000000 +0000 @@ -0,0 +1,953 @@ +/* + * linux/drivers/video/kyro/kyrofb.c + * + * Copyright (C) 2002 STMicroelectronics + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include