Commit 7286d2a3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:

 - Added fw_cfg support for parisc on qemu

 - Added font support in sti text console driver for byte- and word-mode
   ROMs

 - Switch to more fine grained lws locks and improve spinlock handling

 - Add ioread64_hi_lo() and iowrite64_hi_lo() to avoid 0-day linking
   errors

 - Mark pointers volatile in __xchg8(), __xchg32() and __xchg64() to
   help compiler

 - Header file cleanups, mostly removal of unused HP-UX compat defines

 - Drop one bit from our O_NONBLOCK define to become now 000200000

 - Add MAP_UNINITIALIZED define to avoid userspace compile errors

 - Drop CONFIG_IDE from defconfigs

 - Speed up synchronize_caches() on UP machines

 - Rewrite tlb flush threshold calculation

 - Comment fixes and cleanups

* 'parisc-5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc/sticon: Add user font support
  parisc/sticon: Always register sticon console driver
  parisc: Add MAP_UNINITIALIZED define
  parisc: Improve spinlock handling
  parisc: Install vmlinuz instead of zImage file
  parisc: Rewrite tlb flush threshold calculation
  parisc: Switch to more fine grained lws locks
  parisc: Mark pointers volatile in __xchg8(), __xchg32() and __xchg64()
  parisc: Fix comments and enable interrupts later
  parisc: Add alternative patching to synchronize_caches define
  parisc: Add ioread64_hi_lo() and iowrite64_hi_lo()
  parisc: disable CONFIG_IDE in defconfigs
  parisc: Drop useless comments in uapi/asm/signal.h
  parisc: Define O_NONBLOCK to become 000200000
  parisc: Drop HP-UX specific fcntl and signal flags
  parisc: Avoid external interrupts when IPI finishes
  parisc: Add qemu fw_cfg interface
  fw_cfg: Add support for parisc architecture
parents 578a7155 7ff3f14d
...@@ -375,5 +375,6 @@ config KEXEC_FILE ...@@ -375,5 +375,6 @@ config KEXEC_FILE
endmenu endmenu
source "drivers/firmware/Kconfig"
source "drivers/parisc/Kconfig" source "drivers/parisc/Kconfig"
...@@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y ...@@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=6144 CONFIG_BLK_DEV_RAM_SIZE=6144
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_BLK_DEV_NS87415=y
CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR=y
...@@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y ...@@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_ZALON=y CONFIG_SCSI_ZALON=y
CONFIG_SCSI_DH=y CONFIG_SCSI_DH=y
CONFIG_ATA=y CONFIG_ATA=y
CONFIG_ATA_GENERIC=y
CONFIG_PATA_NS87415=y
CONFIG_MD=y CONFIG_MD=y
CONFIG_BLK_DEV_MD=m CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m CONFIG_MD_LINEAR=m
......
...@@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y ...@@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y
CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y CONFIG_DEVTMPFS_MOUNT=y
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
CONFIG_IDE=y
CONFIG_IDE_GD=m
CONFIG_IDE_GD_ATAPI=y
CONFIG_BLK_DEV_IDECD=m
CONFIG_BLK_DEV_NS87415=y
# CONFIG_SCSI_PROC_FS is not set # CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR=y
...@@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y ...@@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y
CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_DH=y CONFIG_SCSI_DH=y
CONFIG_ATA=y CONFIG_ATA=y
CONFIG_PATA_NS87415=y
CONFIG_PATA_SIL680=y CONFIG_PATA_SIL680=y
CONFIG_ATA_GENERIC=y CONFIG_ATA_GENERIC=y
CONFIG_MD=y CONFIG_MD=y
......
...@@ -2,11 +2,15 @@ ...@@ -2,11 +2,15 @@
#ifndef __ASM_BARRIER_H #ifndef __ASM_BARRIER_H
#define __ASM_BARRIER_H #define __ASM_BARRIER_H
#include <asm/alternative.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* The synchronize caches instruction executes as a nop on systems in /* The synchronize caches instruction executes as a nop on systems in
which all memory references are performed in order. */ which all memory references are performed in order. */
#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") #define synchronize_caches() asm volatile("sync" \
ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \
: : : "memory")
#if defined(CONFIG_SMP) #if defined(CONFIG_SMP)
#define mb() do { synchronize_caches(); } while (0) #define mb() do { synchronize_caches(); } while (0)
......
...@@ -14,22 +14,22 @@ ...@@ -14,22 +14,22 @@
extern void __xchg_called_with_bad_pointer(void); extern void __xchg_called_with_bad_pointer(void);
/* __xchg32/64 defined in arch/parisc/lib/bitops.c */ /* __xchg32/64 defined in arch/parisc/lib/bitops.c */
extern unsigned long __xchg8(char, char *); extern unsigned long __xchg8(char, volatile char *);
extern unsigned long __xchg32(int, int *); extern unsigned long __xchg32(int, volatile int *);
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
extern unsigned long __xchg64(unsigned long, unsigned long *); extern unsigned long __xchg64(unsigned long, volatile unsigned long *);
#endif #endif
/* optimizer better get rid of switch since size is a constant */ /* optimizer better get rid of switch since size is a constant */
static inline unsigned long static inline unsigned long
__xchg(unsigned long x, __volatile__ void *ptr, int size) __xchg(unsigned long x, volatile void *ptr, int size)
{ {
switch (size) { switch (size) {
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
case 8: return __xchg64(x, (unsigned long *) ptr); case 8: return __xchg64(x, (volatile unsigned long *) ptr);
#endif #endif
case 4: return __xchg32((int) x, (int *) ptr); case 4: return __xchg32((int) x, (volatile int *) ptr);
case 1: return __xchg8((char) x, (char *) ptr); case 1: return __xchg8((char) x, (volatile char *) ptr);
} }
__xchg_called_with_bad_pointer(); __xchg_called_with_bad_pointer();
return x; return x;
......
...@@ -16,7 +16,7 @@ static inline void ...@@ -16,7 +16,7 @@ static inline void
_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
{ {
extern u32 lws_lock_start[]; extern u32 lws_lock_start[];
long index = ((long)uaddr & 0xf0) >> 2; long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
local_irq_save(*flags); local_irq_save(*flags);
arch_spin_lock(s); arch_spin_lock(s);
...@@ -26,7 +26,7 @@ static inline void ...@@ -26,7 +26,7 @@ static inline void
_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
{ {
extern u32 lws_lock_start[]; extern u32 lws_lock_start[];
long index = ((long)uaddr & 0xf0) >> 2; long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
arch_spin_unlock(s); arch_spin_unlock(s);
local_irq_restore(*flags); local_irq_restore(*flags);
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
#include <uapi/asm/socket.h> #include <uapi/asm/socket.h>
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we /* O_NONBLOCK clashed with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here. * had to define SOCK_NONBLOCK to a different value here.
*/ */
#define SOCK_NONBLOCK 0x40000000 #define SOCK_NONBLOCK 0x40000000
......
...@@ -10,13 +10,21 @@ ...@@ -10,13 +10,21 @@
static inline int arch_spin_is_locked(arch_spinlock_t *x) static inline int arch_spin_is_locked(arch_spinlock_t *x)
{ {
volatile unsigned int *a = __ldcw_align(x); volatile unsigned int *a = __ldcw_align(x);
return *a == 0; return READ_ONCE(*a) == 0;
} }
#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) static inline void arch_spin_lock(arch_spinlock_t *x)
{
volatile unsigned int *a;
a = __ldcw_align(x);
while (__ldcw(a) == 0)
while (*a == 0)
continue;
}
static inline void arch_spin_lock_flags(arch_spinlock_t *x, static inline void arch_spin_lock_flags(arch_spinlock_t *x,
unsigned long flags) unsigned long flags)
{ {
volatile unsigned int *a; volatile unsigned int *a;
...@@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, ...@@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
while (*a == 0) while (*a == 0)
if (flags & PSW_SM_I) { if (flags & PSW_SM_I) {
local_irq_enable(); local_irq_enable();
cpu_relax();
local_irq_disable(); local_irq_disable();
} else }
cpu_relax();
} }
#define arch_spin_lock_flags arch_spin_lock_flags #define arch_spin_lock_flags arch_spin_lock_flags
...@@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x) ...@@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x)
static inline int arch_spin_trylock(arch_spinlock_t *x) static inline int arch_spin_trylock(arch_spinlock_t *x)
{ {
volatile unsigned int *a; volatile unsigned int *a;
int ret;
a = __ldcw_align(x); a = __ldcw_align(x);
ret = __ldcw(a) != 0; return __ldcw(a) != 0;
return ret;
} }
/* /*
......
...@@ -3,22 +3,19 @@ ...@@ -3,22 +3,19 @@
#define _PARISC_FCNTL_H #define _PARISC_FCNTL_H
#define O_APPEND 000000010 #define O_APPEND 000000010
#define O_BLKSEEK 000000100 /* HPUX only */
#define O_CREAT 000000400 /* not fcntl */ #define O_CREAT 000000400 /* not fcntl */
#define O_EXCL 000002000 /* not fcntl */ #define O_EXCL 000002000 /* not fcntl */
#define O_LARGEFILE 000004000 #define O_LARGEFILE 000004000
#define __O_SYNC 000100000 #define __O_SYNC 000100000
#define O_SYNC (__O_SYNC|O_DSYNC) #define O_SYNC (__O_SYNC|O_DSYNC)
#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ #define O_NONBLOCK 000200000
#define O_NOCTTY 000400000 /* not fcntl */ #define O_NOCTTY 000400000 /* not fcntl */
#define O_DSYNC 001000000 /* HPUX only */ #define O_DSYNC 001000000
#define O_RSYNC 002000000 /* HPUX only */
#define O_NOATIME 004000000 #define O_NOATIME 004000000
#define O_CLOEXEC 010000000 /* set close_on_exec */ #define O_CLOEXEC 010000000 /* set close_on_exec */
#define O_DIRECTORY 000010000 /* must be a directory */ #define O_DIRECTORY 000010000 /* must be a directory */
#define O_NOFOLLOW 000000200 /* don't follow links */ #define O_NOFOLLOW 000000200 /* don't follow links */
#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */
#define O_PATH 020000000 #define O_PATH 020000000
#define __O_TMPFILE 040000000 #define __O_TMPFILE 040000000
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */ #define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */
#define MAP_HUGETLB 0x80000 /* create a huge page mapping */ #define MAP_HUGETLB 0x80000 /* create a huge page mapping */
#define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */
#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */
#define MS_SYNC 1 /* synchronous memory sync */ #define MS_SYNC 1 /* synchronous memory sync */
#define MS_ASYNC 2 /* sync memory asynchronously */ #define MS_ASYNC 2 /* sync memory asynchronously */
......
...@@ -35,11 +35,11 @@ ...@@ -35,11 +35,11 @@
#define SIGURG 29 #define SIGURG 29
#define SIGXFSZ 30 #define SIGXFSZ 30
#define SIGUNUSED 31 #define SIGUNUSED 31
#define SIGSYS 31 /* Linux doesn't use this */ #define SIGSYS 31
/* These should not be considered constants from userland. */ /* These should not be considered constants from userland. */
#define SIGRTMIN 32 #define SIGRTMIN 32
#define SIGRTMAX _NSIG /* it's 44 under HP/UX */ #define SIGRTMAX _NSIG
/* /*
* SA_FLAGS values: * SA_FLAGS values:
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
#define SA_NODEFER 0x00000020 #define SA_NODEFER 0x00000020
#define SA_RESTART 0x00000040 #define SA_RESTART 0x00000040
#define SA_NOCLDWAIT 0x00000080 #define SA_NOCLDWAIT 0x00000080
#define _SA_SIGGFAULT 0x00000100 /* HPUX */
#define SA_NOMASK SA_NODEFER #define SA_NOMASK SA_NODEFER
#define SA_ONESHOT SA_RESETHAND #define SA_ONESHOT SA_RESETHAND
......
...@@ -43,7 +43,7 @@ fi ...@@ -43,7 +43,7 @@ fi
# Default install # Default install
if [ "$(basename $2)" = "zImage" ]; then if [ "$(basename $2)" = "vmlinuz" ]; then
# Compressed install # Compressed install
echo "Installing compressed kernel" echo "Installing compressed kernel"
base=vmlinuz base=vmlinuz
......
...@@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); ...@@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm);
static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD; static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD;
#define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */ #define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */
static unsigned long parisc_tlb_flush_threshold __ro_after_init = FLUSH_TLB_THRESHOLD; static unsigned long parisc_tlb_flush_threshold __ro_after_init = ~0UL;
void __init parisc_setup_cache_timing(void) void __init parisc_setup_cache_timing(void)
{ {
unsigned long rangetime, alltime; unsigned long rangetime, alltime;
unsigned long size, start; unsigned long size;
unsigned long threshold; unsigned long threshold;
alltime = mfctl(16); alltime = mfctl(16);
...@@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void) ...@@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void)
goto set_tlb_threshold; goto set_tlb_threshold;
} }
size = 0; size = (unsigned long)_end - (unsigned long)_text;
start = (unsigned long) _text;
rangetime = mfctl(16); rangetime = mfctl(16);
while (start < (unsigned long) _end) { flush_tlb_kernel_range((unsigned long)_text, (unsigned long)_end);
flush_tlb_kernel_range(start, start + PAGE_SIZE);
start += PAGE_SIZE;
size += PAGE_SIZE;
}
rangetime = mfctl(16) - rangetime; rangetime = mfctl(16) - rangetime;
alltime = mfctl(16); alltime = mfctl(16);
...@@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void) ...@@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void)
threshold/1024); threshold/1024);
set_tlb_threshold: set_tlb_threshold:
if (threshold > parisc_tlb_flush_threshold) if (threshold > FLUSH_TLB_THRESHOLD)
parisc_tlb_flush_threshold = threshold; parisc_tlb_flush_threshold = threshold;
else
parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD;
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
parisc_tlb_flush_threshold/1024); parisc_tlb_flush_threshold/1024);
} }
......
...@@ -899,20 +899,20 @@ intr_check_sig: ...@@ -899,20 +899,20 @@ intr_check_sig:
* Only do signals if we are returning to user space * Only do signals if we are returning to user space
*/ */
LDREG PT_IASQ0(%r16), %r20 LDREG PT_IASQ0(%r16), %r20
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
LDREG PT_IASQ1(%r16), %r20 LDREG PT_IASQ1(%r16), %r20
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
/* NOTE: We need to enable interrupts if we have to deliver
* signals. We used to do this earlier but it caused kernel
* stack overflows. */
ssm PSW_SM_I, %r0
copy %r0, %r25 /* long in_syscall = 0 */ copy %r0, %r25 /* long in_syscall = 0 */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
#endif #endif
/* NOTE: We need to enable interrupts if we have to deliver
* signals. We used to do this earlier but it caused kernel
* stack overflows. */
ssm PSW_SM_I, %r0
BL do_notify_resume,%r2 BL do_notify_resume,%r2
copy %r16, %r26 /* struct pt_regs *regs */ copy %r16, %r26 /* struct pt_regs *regs */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/platform_device.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mmzone.h> #include <asm/mmzone.h>
...@@ -641,4 +642,33 @@ void __init do_device_inventory(void) ...@@ -641,4 +642,33 @@ void __init do_device_inventory(void)
if (pa_serialize_tlb_flushes) if (pa_serialize_tlb_flushes)
pr_info("Merced bus found: Enable PxTLB serialization.\n"); pr_info("Merced bus found: Enable PxTLB serialization.\n");
#endif #endif
#if defined(CONFIG_FW_CFG_SYSFS)
if (running_on_qemu) {
struct resource res[3] = {0,};
unsigned int base;
base = ((unsigned long long) PAGE0->pad0[2] << 32)
| PAGE0->pad0[3]; /* SeaBIOS stored it here */
res[0].name = "fw_cfg";
res[0].start = base;
res[0].end = base + 8 - 1;
res[0].flags = IORESOURCE_MEM;
res[1].name = "ctrl";
res[1].start = 0;
res[1].flags = IORESOURCE_REG;
res[2].name = "data";
res[2].start = 4;
res[2].flags = IORESOURCE_REG;
if (base) {
pr_info("Found qemu fw_cfg interface at %#08x\n", base);
platform_device_register_simple("fw_cfg",
PLATFORM_DEVID_NONE, res, 3);
}
}
#endif
} }
...@@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id) ...@@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id)
this_cpu, which); this_cpu, which);
return IRQ_NONE; return IRQ_NONE;
} /* Switch */ } /* Switch */
/* let in any pending interrupts */
local_irq_enable(); /* before doing more, let in any pending interrupts */
local_irq_disable(); if (ops) {
local_irq_enable();
local_irq_disable();
}
} /* while (ops) */ } /* while (ops) */
} }
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -571,8 +571,8 @@ lws_compare_and_swap: ...@@ -571,8 +571,8 @@ lws_compare_and_swap:
ldil L%lws_lock_start, %r20 ldil L%lws_lock_start, %r20
ldo R%lws_lock_start(%r20), %r28 ldo R%lws_lock_start(%r20), %r28
/* Extract four bits from r26 and hash lock (Bits 4-7) */ /* Extract eight bits from r26 and hash lock (Bits 3-11) */
extru %r26, 27, 4, %r20 extru %r26, 28, 8, %r20
/* Find lock to use, the hash is either one of 0 to /* Find lock to use, the hash is either one of 0 to
15, multiplied by 16 (keep it 16-byte aligned) 15, multiplied by 16 (keep it 16-byte aligned)
...@@ -761,8 +761,8 @@ cas2_lock_start: ...@@ -761,8 +761,8 @@ cas2_lock_start:
ldil L%lws_lock_start, %r20 ldil L%lws_lock_start, %r20
ldo R%lws_lock_start(%r20), %r28 ldo R%lws_lock_start(%r20), %r28
/* Extract four bits from r26 and hash lock (Bits 4-7) */ /* Extract eight bits from r26 and hash lock (Bits 3-11) */
extru %r26, 27, 4, %r20 extru %r26, 28, 8, %r20
/* Find lock to use, the hash is either one of 0 to /* Find lock to use, the hash is either one of 0 to
15, multiplied by 16 (keep it 16-byte aligned) 15, multiplied by 16 (keep it 16-byte aligned)
...@@ -950,7 +950,7 @@ END(sys_call_table64) ...@@ -950,7 +950,7 @@ END(sys_call_table64)
.align L1_CACHE_BYTES .align L1_CACHE_BYTES
ENTRY(lws_lock_start) ENTRY(lws_lock_start)
/* lws locks */ /* lws locks */
.rept 16 .rept 256
/* Keep locks aligned at 16-bytes */ /* Keep locks aligned at 16-bytes */
.word 1 .word 1
.word 0 .word 0
......
...@@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { ...@@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
#endif #endif
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
unsigned long __xchg64(unsigned long x, unsigned long *ptr) unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr)
{ {
unsigned long temp, flags; unsigned long temp, flags;
...@@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr) ...@@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr)
} }
#endif #endif
unsigned long __xchg32(int x, int *ptr) unsigned long __xchg32(int x, volatile int *ptr)
{ {
unsigned long flags; unsigned long flags;
long temp; long temp;
...@@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr) ...@@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr)
} }
unsigned long __xchg8(char x, char *ptr) unsigned long __xchg8(char x, volatile char *ptr)
{ {
unsigned long flags; unsigned long flags;
long temp; long temp;
......
...@@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr) ...@@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr)
return *((u64 *)addr); return *((u64 *)addr);
} }
u64 ioread64_hi_lo(const void __iomem *addr)
{
u32 low, high;
high = ioread32(addr + sizeof(u32));
low = ioread32(addr);
return low + ((u64)high << 32);
}
void iowrite8(u8 datum, void __iomem *addr) void iowrite8(u8 datum, void __iomem *addr)
{ {
if (unlikely(INDIRECT_ADDR(addr))) { if (unlikely(INDIRECT_ADDR(addr))) {
...@@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr) ...@@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr)
} }
} }
void iowrite64_hi_lo(u64 val, void __iomem *addr)
{
iowrite32(val >> 32, addr + sizeof(u32));
iowrite32(val, addr);
}
/* Repeating interfaces */ /* Repeating interfaces */
void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
...@@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32); ...@@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32);
EXPORT_SYMBOL(ioread32be); EXPORT_SYMBOL(ioread32be);
EXPORT_SYMBOL(ioread64); EXPORT_SYMBOL(ioread64);
EXPORT_SYMBOL(ioread64be); EXPORT_SYMBOL(ioread64be);
EXPORT_SYMBOL(ioread64_hi_lo);
EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16); EXPORT_SYMBOL(iowrite16);
EXPORT_SYMBOL(iowrite16be); EXPORT_SYMBOL(iowrite16be);
...@@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32); ...@@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32);
EXPORT_SYMBOL(iowrite32be); EXPORT_SYMBOL(iowrite32be);
EXPORT_SYMBOL(iowrite64); EXPORT_SYMBOL(iowrite64);
EXPORT_SYMBOL(iowrite64be); EXPORT_SYMBOL(iowrite64be);
EXPORT_SYMBOL(iowrite64_hi_lo);
EXPORT_SYMBOL(ioread8_rep); EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep); EXPORT_SYMBOL(ioread16_rep);
EXPORT_SYMBOL(ioread32_rep); EXPORT_SYMBOL(ioread32_rep);
......
...@@ -186,7 +186,7 @@ config RASPBERRYPI_FIRMWARE ...@@ -186,7 +186,7 @@ config RASPBERRYPI_FIRMWARE
config FW_CFG_SYSFS config FW_CFG_SYSFS
tristate "QEMU fw_cfg device support in sysfs" tristate "QEMU fw_cfg device support in sysfs"
depends on SYSFS && (ARM || ARM64 || PPC_PMAC || SPARC || X86) depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86)
depends on HAS_IOPORT_MAP depends on HAS_IOPORT_MAP
default n default n
help help
......
...@@ -215,6 +215,9 @@ static void fw_cfg_io_cleanup(void) ...@@ -215,6 +215,9 @@ static void fw_cfg_io_cleanup(void)
# define FW_CFG_CTRL_OFF 0x08 # define FW_CFG_CTRL_OFF 0x08
# define FW_CFG_DATA_OFF 0x00 # define FW_CFG_DATA_OFF 0x00
# define FW_CFG_DMA_OFF 0x10 # define FW_CFG_DMA_OFF 0x10
# elif defined(CONFIG_PARISC) /* parisc */
# define FW_CFG_CTRL_OFF 0x00
# define FW_CFG_DATA_OFF 0x04
# elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */ # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */
# define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_CTRL_OFF 0x00
# define FW_CFG_DATA_OFF 0x02 # define FW_CFG_DATA_OFF 0x02
......
...@@ -119,6 +119,7 @@ config STI_CONSOLE ...@@ -119,6 +119,7 @@ config STI_CONSOLE
bool "STI text console" bool "STI text console"
depends on PARISC && HAS_IOMEM depends on PARISC && HAS_IOMEM
select FONT_SUPPORT select FONT_SUPPORT
select CRC32
default y default y
help help
The STI console is the builtin display/keyboard on HP-PARISC The STI console is the builtin display/keyboard on HP-PARISC
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* linux/drivers/video/console/sticon.c - console driver using HP's STI firmware * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware
* *
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2002 Helge Deller <deller@gmx.de> * Copyright (C) 2002-2020 Helge Deller <deller@gmx.de>
* *
* Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
* which were * which were
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/selection.h> #include <linux/selection.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h>
#include <linux/font.h>
#include <linux/crc32.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -52,27 +55,15 @@ ...@@ -52,27 +55,15 @@
#define BLANK 0 #define BLANK 0
static int vga_is_gfx; static int vga_is_gfx;
/* this is the sti_struct used for this console */ #define STI_DEF_FONT sticon_sti->font
static struct sti_struct *sticon_sti;
/* Software scrollback */
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long /* softback_top, */ softback_end;
static int softback_lines;
/* software cursor */
static int cursor_drawn;
#define CURSOR_DRAW_DELAY (1)
#define DEFAULT_CURSOR_BLINK_RATE (20)
static int vbl_cursor_cnt; /* borrowed from fbcon.c */
#define FNTREFCOUNT(fd) (fd->refcount)
#define FNTCRC(fd) (fd->crc)
static struct sti_cooked_font *font_data[MAX_NR_CONSOLES];
static inline void cursor_undrawn(void) /* this is the sti_struct used for this console */
{ static struct sti_struct *sticon_sti;
vbl_cursor_cnt = 0;
cursor_drawn = 0;
}
static const char *sticon_startup(void) static const char *sticon_startup(void)
{ {
...@@ -81,61 +72,43 @@ static const char *sticon_startup(void) ...@@ -81,61 +72,43 @@ static const char *sticon_startup(void)
static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
{ {
int redraw_cursor = 0;
if (vga_is_gfx || console_blanked) if (vga_is_gfx || console_blanked)
return; return;
if (conp->vc_mode != KD_TEXT) if (conp->vc_mode != KD_TEXT)
return; return;
#if 0
if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
cursor_undrawn();
redraw_cursor = 1;
}
#endif
sti_putc(sticon_sti, c, ypos, xpos); sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]);
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
} }
static void sticon_putcs(struct vc_data *conp, const unsigned short *s, static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
int count, int ypos, int xpos) int count, int ypos, int xpos)
{ {
int redraw_cursor = 0;
if (vga_is_gfx || console_blanked) if (vga_is_gfx || console_blanked)
return; return;
if (conp->vc_mode != KD_TEXT) if (conp->vc_mode != KD_TEXT)
return; return;
#if 0
if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
(p->cursor_x < (xpos + count))) {
cursor_undrawn();
redraw_cursor = 1;
}
#endif
while (count--) { while (count--) {
sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++); sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++,
font_data[conp->vc_num]);
} }
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
} }
static void sticon_cursor(struct vc_data *conp, int mode) static void sticon_cursor(struct vc_data *conp, int mode)
{ {
unsigned short car1; unsigned short car1;
/* no cursor update if screen is blanked */
if (vga_is_gfx || console_blanked)
return;
car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
switch (mode) { switch (mode) {
case CM_ERASE: case CM_ERASE:
sti_putc(sticon_sti, car1, conp->state.y, conp->state.x); sti_putc(sticon_sti, car1, conp->state.y, conp->state.x,
font_data[conp->vc_num]);
break; break;
case CM_MOVE: case CM_MOVE:
case CM_DRAW: case CM_DRAW:
...@@ -146,7 +119,7 @@ static void sticon_cursor(struct vc_data *conp, int mode) ...@@ -146,7 +119,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
case CUR_TWO_THIRDS: case CUR_TWO_THIRDS:
case CUR_BLOCK: case CUR_BLOCK:
sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
conp->state.y, conp->state.x); conp->state.y, conp->state.x, font_data[conp->vc_num]);
break; break;
} }
break; break;
...@@ -165,42 +138,164 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t, ...@@ -165,42 +138,164 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t,
switch (dir) { switch (dir) {
case SM_UP: case SM_UP:
sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols,
sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); font_data[conp->vc_num]);
sti_clear(sti, b - count, 0, count, conp->vc_cols,
conp->vc_video_erase_char, font_data[conp->vc_num]);
break; break;
case SM_DOWN: case SM_DOWN:
sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols,
sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); font_data[conp->vc_num]);
sti_clear(sti, t, 0, count, conp->vc_cols,
conp->vc_video_erase_char, font_data[conp->vc_num]);
break; break;
} }
return false; return false;
} }
static int sticon_set_def_font(int unit, struct console_font *op)
{
if (font_data[unit] != STI_DEF_FONT) {
if (--FNTREFCOUNT(font_data[unit]) == 0) {
kfree(font_data[unit]->raw_ptr);
kfree(font_data[unit]);
}
font_data[unit] = STI_DEF_FONT;
}
return 0;
}
static int sticon_set_font(struct vc_data *vc, struct console_font *op)
{
struct sti_struct *sti = sticon_sti;
int vc_cols, vc_rows, vc_old_cols, vc_old_rows;
int unit = vc->vc_num;
int w = op->width;
int h = op->height;
int size, i, bpc, pitch;
struct sti_rom_font *new_font;
struct sti_cooked_font *cooked_font;
unsigned char *data = op->data, *p;
if ((w < 6) || (h < 6) || (w > 32) || (h > 32)
|| (op->charcount != 256 && op->charcount != 512))
return -EINVAL;
pitch = ALIGN(w, 8) / 8;
bpc = pitch * h;
size = bpc * op->charcount;
new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM);
if (!new_font)
return -ENOMEM;
new_font->first_char = 0;
new_font->last_char = op->charcount - 1;
new_font->width = w;
new_font->height = h;
new_font->font_type = STI_FONT_HPROMAN8;
new_font->bytes_per_char = bpc;
new_font->underline_height = 0;
new_font->underline_pos = 0;
cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
if (!cooked_font) {
kfree(new_font);
return -ENOMEM;
}
cooked_font->raw = new_font;
cooked_font->raw_ptr = new_font;
cooked_font->width = w;
cooked_font->height = h;
FNTREFCOUNT(cooked_font) = 0; /* usage counter */
p = (unsigned char *) new_font;
p += sizeof(*new_font);
for (i = 0; i < op->charcount; i++) {
memcpy(p, data, bpc);
data += pitch*32;
p += bpc;
}
FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font));
sti_font_convert_bytemode(sti, cooked_font);
new_font = cooked_font->raw_ptr;
/* check if font is already used by other console */
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (font_data[i] != STI_DEF_FONT
&& (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) {
kfree(new_font);
kfree(cooked_font);
/* current font is the same as the new one */
if (i == unit)
return 0;
cooked_font = font_data[i];
new_font = cooked_font->raw_ptr;
break;
}
}
/* clear screen with old font: we now may have less rows */
vc_old_rows = vc->vc_rows;
vc_old_cols = vc->vc_cols;
sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols,
vc->vc_video_erase_char, font_data[vc->vc_num]);
/* delete old font in case it is a user font */
sticon_set_def_font(unit, NULL);
FNTREFCOUNT(cooked_font)++;
font_data[unit] = cooked_font;
vc_cols = sti_onscreen_x(sti) / cooked_font->width;
vc_rows = sti_onscreen_y(sti) / cooked_font->height;
vc_resize(vc, vc_cols, vc_rows);
/* need to repaint screen if cols & rows are same as old font */
if (vc_cols == vc_old_cols && vc_rows == vc_old_rows)
update_screen(vc);
return 0;
}
static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name)
{
return sticon_set_def_font(vc->vc_num, op);
}
static int sticon_font_set(struct vc_data *vc, struct console_font *font,
unsigned int flags)
{
return sticon_set_font(vc, font);
}
static void sticon_init(struct vc_data *c, int init) static void sticon_init(struct vc_data *c, int init)
{ {
struct sti_struct *sti = sticon_sti; struct sti_struct *sti = sticon_sti;
int vc_cols, vc_rows; int vc_cols, vc_rows;
sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0); sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
vc_cols = sti_onscreen_x(sti) / sti->font_width; vc_cols = sti_onscreen_x(sti) / sti->font->width;
vc_rows = sti_onscreen_y(sti) / sti->font_height; vc_rows = sti_onscreen_y(sti) / sti->font->height;
c->vc_can_do_color = 1; c->vc_can_do_color = 1;
if (init) { if (init) {
c->vc_cols = vc_cols; c->vc_cols = vc_cols;
c->vc_rows = vc_rows; c->vc_rows = vc_rows;
} else { } else {
/* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */
/* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */
vc_resize(c, vc_cols, vc_rows); vc_resize(c, vc_cols, vc_rows);
/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */
} }
} }
static void sticon_deinit(struct vc_data *c) static void sticon_deinit(struct vc_data *c)
{ {
int i;
/* free memory used by user font */
for (i = 0; i < MAX_NR_CONSOLES; i++)
sticon_set_def_font(i, NULL);
} }
static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
...@@ -209,7 +304,8 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, ...@@ -209,7 +304,8 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
if (!height || !width) if (!height || !width)
return; return;
sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char); sti_clear(sticon_sti, sy, sx, height, width,
conp->vc_video_erase_char, font_data[conp->vc_num]);
} }
static int sticon_switch(struct vc_data *conp) static int sticon_switch(struct vc_data *conp)
...@@ -224,64 +320,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) ...@@ -224,64 +320,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
vga_is_gfx = 0; vga_is_gfx = 0;
return 1; return 1;
} }
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK,
font_data[c->vc_num]);
if (mode_switch) if (mode_switch)
vga_is_gfx = 1; vga_is_gfx = 1;
return 1; return 1;
} }
static u16 *sticon_screen_pos(const struct vc_data *conp, int offset)
{
int line;
unsigned long p;
if (conp->vc_num != fg_console || !softback_lines)
return (u16 *)(conp->vc_origin + offset);
line = offset / conp->vc_size_row;
if (line >= softback_lines)
return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
p = softback_curr + offset;
if (p >= softback_end)
p += softback_buf - softback_end;
return (u16 *)p;
}
static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
int *px, int *py)
{
int x, y;
unsigned long ret;
if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
unsigned long offset = (pos - conp->vc_origin) / 2;
x = offset % conp->vc_cols;
y = offset / conp->vc_cols;
if (conp->vc_num == fg_console)
y += softback_lines;
ret = pos + (conp->vc_cols - x) * 2;
} else if (conp->vc_num == fg_console && softback_lines) {
unsigned long offset = pos - softback_curr;
if (pos < softback_curr)
offset += softback_end - softback_buf;
offset /= 2;
x = offset % conp->vc_cols;
y = offset / conp->vc_cols;
ret = pos + (conp->vc_cols - x) * 2;
if (ret == softback_end)
ret = softback_buf;
if (ret == softback_in)
ret = conp->vc_origin;
} else {
/* Should not happen */
x = y = 0;
ret = conp->vc_origin;
}
if (px) *px = x;
if (py) *py = y;
return ret;
}
static u8 sticon_build_attr(struct vc_data *conp, u8 color, static u8 sticon_build_attr(struct vc_data *conp, u8 color,
enum vc_intensity intens, enum vc_intensity intens,
bool blink, bool underline, bool reverse, bool blink, bool underline, bool reverse,
...@@ -312,10 +357,6 @@ static void sticon_invert_region(struct vc_data *conp, u16 *p, int count) ...@@ -312,10 +357,6 @@ static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
} }
} }
static void sticon_save_screen(struct vc_data *conp)
{
}
static const struct consw sti_con = { static const struct consw sti_con = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.con_startup = sticon_startup, .con_startup = sticon_startup,
...@@ -328,18 +369,18 @@ static const struct consw sti_con = { ...@@ -328,18 +369,18 @@ static const struct consw sti_con = {
.con_scroll = sticon_scroll, .con_scroll = sticon_scroll,
.con_switch = sticon_switch, .con_switch = sticon_switch,
.con_blank = sticon_blank, .con_blank = sticon_blank,
.con_save_screen = sticon_save_screen, .con_font_set = sticon_font_set,
.con_font_default = sticon_font_default,
.con_build_attr = sticon_build_attr, .con_build_attr = sticon_build_attr,
.con_invert_region = sticon_invert_region, .con_invert_region = sticon_invert_region,
.con_screen_pos = sticon_screen_pos,
.con_getxy = sticon_getxy,
}; };
static int __init sticonsole_init(void) static int __init sticonsole_init(void)
{ {
int err; int err, i;
/* already initialized ? */ /* already initialized ? */
if (sticon_sti) if (sticon_sti)
return 0; return 0;
...@@ -348,14 +389,16 @@ static int __init sticonsole_init(void) ...@@ -348,14 +389,16 @@ static int __init sticonsole_init(void)
if (!sticon_sti) if (!sticon_sti)
return -ENODEV; return -ENODEV;
if (conswitchp == &dummy_con) { for (i = 0; i < MAX_NR_CONSOLES; i++)
printk(KERN_INFO "sticon: Initializing STI text console.\n"); font_data[i] = STI_DEF_FONT;
console_lock();
err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1); pr_info("sticon: Initializing STI text console.\n");
console_unlock(); console_lock();
return err; err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1,
} PAGE0->mem_cons.cl_class != CL_DUPLEX);
return 0; console_unlock();
return err;
} }
module_init(sticonsole_init); module_init(sticonsole_init);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* core code for console driver using HP's STI firmware * core code for console driver using HP's STI firmware
* *
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2001-2013 Helge Deller <deller@gmx.de> * Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de> * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
* *
* TODO: * TODO:
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
* *
*/ */
#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -133,16 +135,17 @@ static const struct sti_font_flags default_font_flags = { ...@@ -133,16 +135,17 @@ static const struct sti_font_flags default_font_flags = {
}; };
void void
sti_putc(struct sti_struct *sti, int c, int y, int x) sti_putc(struct sti_struct *sti, int c, int y, int x,
struct sti_cooked_font *font)
{ {
struct sti_font_inptr *inptr = &sti->sti_data->font_inptr; struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
struct sti_font_inptr inptr_default = { struct sti_font_inptr inptr_default = {
.font_start_addr= STI_PTR(sti->font->raw), .font_start_addr = STI_PTR(font->raw),
.index = c_index(sti, c), .index = c_index(sti, c),
.fg_color = c_fg(sti, c), .fg_color = c_fg(sti, c),
.bg_color = c_bg(sti, c), .bg_color = c_bg(sti, c),
.dest_x = x * sti->font_width, .dest_x = x * font->width,
.dest_y = y * sti->font_height, .dest_y = y * font->height,
}; };
struct sti_font_outptr *outptr = &sti->sti_data->font_outptr; struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
s32 ret; s32 ret;
...@@ -193,18 +196,18 @@ sti_set(struct sti_struct *sti, int src_y, int src_x, ...@@ -193,18 +196,18 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
void void
sti_clear(struct sti_struct *sti, int src_y, int src_x, sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c) int height, int width, int c, struct sti_cooked_font *font)
{ {
struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
struct sti_blkmv_inptr inptr_default = { struct sti_blkmv_inptr inptr_default = {
.fg_color = c_fg(sti, c), .fg_color = c_fg(sti, c),
.bg_color = c_bg(sti, c), .bg_color = c_bg(sti, c),
.src_x = src_x * sti->font_width, .src_x = src_x * font->width,
.src_y = src_y * sti->font_height, .src_y = src_y * font->height,
.dest_x = src_x * sti->font_width, .dest_x = src_x * font->width,
.dest_y = src_y * sti->font_height, .dest_y = src_y * font->height,
.width = width * sti->font_width, .width = width * font->width,
.height = height* sti->font_height, .height = height * font->height,
}; };
struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret; s32 ret;
...@@ -225,16 +228,17 @@ static const struct sti_blkmv_flags default_blkmv_flags = { ...@@ -225,16 +228,17 @@ static const struct sti_blkmv_flags default_blkmv_flags = {
void void
sti_bmove(struct sti_struct *sti, int src_y, int src_x, sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width) int dst_y, int dst_x, int height, int width,
struct sti_cooked_font *font)
{ {
struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
struct sti_blkmv_inptr inptr_default = { struct sti_blkmv_inptr inptr_default = {
.src_x = src_x * sti->font_width, .src_x = src_x * font->width,
.src_y = src_y * sti->font_height, .src_y = src_y * font->height,
.dest_x = dst_x * sti->font_width, .dest_x = dst_x * font->width,
.dest_y = dst_y * sti->font_height, .dest_y = dst_y * font->height,
.width = width * sti->font_width, .width = width * font->width,
.height = height* sti->font_height, .height = height * font->height,
}; };
struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret; s32 ret;
...@@ -301,36 +305,32 @@ __setup("sti=", sti_setup); ...@@ -301,36 +305,32 @@ __setup("sti=", sti_setup);
static char *font_name[MAX_STI_ROMS]; static char *font_name;
static int font_index[MAX_STI_ROMS], static int font_index,
font_height[MAX_STI_ROMS], font_height,
font_width[MAX_STI_ROMS]; font_width;
#ifndef MODULE #ifndef MODULE
static int sti_font_setup(char *str) static int sti_font_setup(char *str)
{ {
char *x; /*
int i = 0; * The default font can be selected in various ways.
* a) sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 selects
* an built-in Linux framebuffer font.
* b) sti_font=<index>, where index is (1..x) with 1 selecting
* the first HP STI ROM built-in font..
*/
/* we accept sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 if (*str >= '0' && *str <= '9') {
* or sti_font=7 style command lines. */ char *x;
while (i<MAX_STI_ROMS && str && *str) { if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
if (*str>='0' && *str<='9') { font_height = simple_strtoul(str, NULL, 0);
if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) { font_width = simple_strtoul(x+1, NULL, 0);
font_height[i] = simple_strtoul(str, NULL, 0);
font_width[i] = simple_strtoul(x+1, NULL, 0);
} else {
font_index[i] = simple_strtoul(str, NULL, 0);
}
} else { } else {
font_name[i] = str; /* fb font name */ font_index = simple_strtoul(str, NULL, 0);
} }
} else {
if ((x = strchr(str, ','))) font_name = str; /* fb font name */
*x++ = 0;
str = x;
i++;
} }
return 1; return 1;
...@@ -344,7 +344,7 @@ static int sti_font_setup(char *str) ...@@ -344,7 +344,7 @@ static int sti_font_setup(char *str)
* framebuffer font names (e.g. VGA8x16, SUN22x18). * framebuffer font names (e.g. VGA8x16, SUN22x18).
* This is only available if the fonts have been statically compiled * This is only available if the fonts have been statically compiled
* in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options. * in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options.
* - sti_font=<number> * - sti_font=<number> (<number> = 1,2,3,...)
* most STI ROMs have built-in HP specific fonts, which can be selected * most STI ROMs have built-in HP specific fonts, which can be selected
* by giving the desired number to the sticon driver. * by giving the desired number to the sticon driver.
* NOTE: This number is machine and STI ROM dependend. * NOTE: This number is machine and STI ROM dependend.
...@@ -364,8 +364,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, ...@@ -364,8 +364,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
{ {
struct sti_glob_cfg_ext *cfg; struct sti_glob_cfg_ext *cfg;
DPRINTK((KERN_INFO pr_debug("%d text planes\n"
"%d text planes\n"
"%4d x %4d screen resolution\n" "%4d x %4d screen resolution\n"
"%4d x %4d offscreen\n" "%4d x %4d offscreen\n"
"%4d x %4d layout\n" "%4d x %4d layout\n"
...@@ -382,12 +381,11 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, ...@@ -382,12 +381,11 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5], glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7], glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
glob_cfg->reent_lvl, glob_cfg->reent_lvl,
glob_cfg->save_addr)); glob_cfg->save_addr);
/* dump extended cfg */ /* dump extended cfg */
cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr);
DPRINTK(( KERN_INFO pr_debug("monitor %d\n"
"monitor %d\n"
"in friendly mode: %d\n" "in friendly mode: %d\n"
"power consumption %d watts\n" "power consumption %d watts\n"
"freq ref %d\n" "freq ref %d\n"
...@@ -396,20 +394,19 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, ...@@ -396,20 +394,19 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
cfg->friendly_boot, cfg->friendly_boot,
cfg->power, cfg->power,
cfg->freq_ref, cfg->freq_ref,
cfg->sti_mem_addr, sti_mem_request)); cfg->sti_mem_addr, sti_mem_request);
} }
static void sti_dump_outptr(struct sti_struct *sti) static void sti_dump_outptr(struct sti_struct *sti)
{ {
DPRINTK((KERN_INFO pr_debug("%d bits per pixel\n"
"%d bits per pixel\n"
"%d used bits\n" "%d used bits\n"
"%d planes\n" "%d planes\n"
"attributes %08x\n", "attributes %08x\n",
sti->sti_data->inq_outptr.bits_per_pixel, sti->sti_data->inq_outptr.bits_per_pixel,
sti->sti_data->inq_outptr.bits_used, sti->sti_data->inq_outptr.bits_used,
sti->sti_data->inq_outptr.planes, sti->sti_data->inq_outptr.planes,
sti->sti_data->inq_outptr.attributes)); sti->sti_data->inq_outptr.attributes);
} }
static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
...@@ -448,8 +445,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, ...@@ -448,8 +445,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
if (offs != PCI_ROM_ADDRESS && if (offs != PCI_ROM_ADDRESS &&
(offs < PCI_BASE_ADDRESS_0 || (offs < PCI_BASE_ADDRESS_0 ||
offs > PCI_BASE_ADDRESS_5)) { offs > PCI_BASE_ADDRESS_5)) {
printk (KERN_WARNING pr_warn("STI pci region mapping for region %d (%02x) can't be mapped\n",
"STI pci region mapping for region %d (%02x) can't be mapped\n",
i,sti->rm_entry[i]); i,sti->rm_entry[i]);
continue; continue;
} }
...@@ -464,14 +460,14 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, ...@@ -464,14 +460,14 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
if (len) if (len)
glob_cfg->region_ptrs[i] = sti->regions_phys[i]; glob_cfg->region_ptrs[i] = sti->regions_phys[i];
DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " pr_debug("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
"btlb=%d, sysonly=%d, cache=%d, last=%d\n", "btlb=%d, sysonly=%d, cache=%d, last=%d\n",
i, sti->regions_phys[i], glob_cfg->region_ptrs[i], i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
len/1024, len/1024,
sti->regions[i].region_desc.btlb, sti->regions[i].region_desc.btlb,
sti->regions[i].region_desc.sys_only, sti->regions[i].region_desc.sys_only,
sti->regions[i].region_desc.cache, sti->regions[i].region_desc.cache,
sti->regions[i].region_desc.last)); sti->regions[i].region_desc.last);
/* last entry reached ? */ /* last entry reached ? */
if (sti->regions[i].region_desc.last) if (sti->regions[i].region_desc.last)
...@@ -479,8 +475,8 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, ...@@ -479,8 +475,8 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
} }
if (++i<8 && sti->regions[i].region) if (++i<8 && sti->regions[i].region)
printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n", pr_warn("future ptr (0x%8x) not yet supported !\n",
__FILE__, sti->regions[i].region); sti->regions[i].region);
glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr); glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
...@@ -538,6 +534,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) ...@@ -538,6 +534,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
} }
cooked_font->raw = nf; cooked_font->raw = nf;
cooked_font->raw_ptr = nf;
cooked_font->next_font = NULL; cooked_font->next_font = NULL;
cooked_rom->font_start = cooked_font; cooked_rom->font_start = cooked_font;
...@@ -552,24 +549,38 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) ...@@ -552,24 +549,38 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
} }
#endif #endif
static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, static int sti_search_font(struct sti_cooked_rom *rom, int height, int width)
int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) {
struct sti_cooked_font *font;
int i = 0;
for (font = rom->font_start; font; font = font->next_font, i++) {
if ((font->raw->width == width) &&
(font->raw->height == height))
return i;
}
return 0;
}
static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom)
{ {
struct sti_cooked_font *font; struct sti_cooked_font *font;
int i; int i;
int index = num_sti_roms;
/* check for framebuffer-font first */ /* check for framebuffer-font first */
if ((font = sti_select_fbfont(rom, font_name[index]))) if (!font_index) {
return font; font = sti_select_fbfont(rom, font_name);
if (font)
return font;
}
if (font_width[index] && font_height[index]) if (font_width && font_height)
font_index[index] = search_font_fnc(rom, font_index = sti_search_font(rom,
font_height[index], font_width[index]); font_height, font_width);
for (font = rom->font_start, i = font_index[index]; for (font = rom->font_start, i = font_index - 1;
font && (i > 0); font && (i > 0);
font = font->next_font, i--); font = font->next_font, i--);
if (font) if (font)
return font; return font;
...@@ -578,20 +589,35 @@ static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, ...@@ -578,20 +589,35 @@ static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
} }
static void sti_dump_rom(struct sti_rom *rom) static void sti_dump_rom(struct sti_struct *sti)
{ {
printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n", struct sti_rom *rom = sti->rom->raw;
struct sti_cooked_font *font_start;
int nr;
pr_info(" id %04x-%04x, conforms to spec rev. %d.%02x\n",
rom->graphics_id[0], rom->graphics_id[0],
rom->graphics_id[1], rom->graphics_id[1],
rom->revno[0] >> 4, rom->revno[0] >> 4,
rom->revno[0] & 0x0f); rom->revno[0] & 0x0f);
DPRINTK((" supports %d monitors\n", rom->num_mons)); pr_debug(" supports %d monitors\n", rom->num_mons);
DPRINTK((" font start %08x\n", rom->font_start)); pr_debug(" font start %08x\n", rom->font_start);
DPRINTK((" region list %08x\n", rom->region_list)); pr_debug(" region list %08x\n", rom->region_list);
DPRINTK((" init_graph %08x\n", rom->init_graph)); pr_debug(" init_graph %08x\n", rom->init_graph);
DPRINTK((" bus support %02x\n", rom->bus_support)); pr_debug(" bus support %02x\n", rom->bus_support);
DPRINTK((" ext bus support %02x\n", rom->ext_bus_support)); pr_debug(" ext bus support %02x\n", rom->ext_bus_support);
DPRINTK((" alternate code type %d\n", rom->alt_code_type)); pr_debug(" alternate code type %d\n", rom->alt_code_type);
font_start = sti->rom->font_start;
nr = 0;
while (font_start) {
struct sti_rom_font *f = font_start->raw;
pr_info(" built-in font #%d: size %dx%d, chars %d-%d, bpc %d\n", ++nr,
f->width, f->height,
f->first_char, f->last_char, f->bytes_per_char);
font_start = font_start->next_font;
}
} }
...@@ -628,39 +654,34 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom, ...@@ -628,39 +654,34 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
return 1; return 1;
} }
static int sti_search_font(struct sti_cooked_rom *rom, int height, int width)
{
struct sti_cooked_font *font;
int i = 0;
for (font = rom->font_start; font; font = font->next_font, i++) {
if ((font->raw->width == width) &&
(font->raw->height == height))
return i;
}
return 0;
}
#define BMODE_RELOCATE(offset) offset = (offset) / 4; #define BMODE_RELOCATE(offset) offset = (offset) / 4;
#define BMODE_LAST_ADDR_OFFS 0x50 #define BMODE_LAST_ADDR_OFFS 0x50
static void *sti_bmode_font_raw(struct sti_cooked_font *f) void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f)
{ {
unsigned char *n, *p, *q; unsigned char *n, *p, *q;
int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); int size = f->raw->bytes_per_char * 256 + sizeof(struct sti_rom_font);
struct sti_rom_font *old_font;
if (sti->wordmode)
return;
old_font = f->raw_ptr;
n = kcalloc(4, size, STI_LOWMEM); n = kcalloc(4, size, STI_LOWMEM);
f->raw_ptr = n;
if (!n) if (!n)
return NULL; return;
p = n + 3; p = n + 3;
q = (unsigned char *)f->raw; q = (unsigned char *) f->raw;
while (size--) { while (size--) {
*p = *q++; *p = *q++;
p+=4; p += 4;
} }
return n + 3; /* store new ptr to byte-mode font and delete old font */
f->raw = (struct sti_rom_font *) (n + 3);
kfree(old_font);
} }
EXPORT_SYMBOL(sti_font_convert_bytemode);
static void sti_bmode_rom_copy(unsigned long base, unsigned long count, static void sti_bmode_rom_copy(unsigned long base, unsigned long count,
void *dest) void *dest)
...@@ -747,7 +768,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, ...@@ -747,7 +768,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
goto out_err; goto out_err;
if (!sti_cook_fonts(cooked, raw)) { if (!sti_cook_fonts(cooked, raw)) {
printk(KERN_ERR "No font found for STI at %08lx\n", address); pr_warn("No font found for STI at %08lx\n", address);
goto out_err; goto out_err;
} }
...@@ -756,7 +777,8 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, ...@@ -756,7 +777,8 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
address = (unsigned long) STI_PTR(raw); address = (unsigned long) STI_PTR(raw);
pr_info("STI ROM supports 32 %sbit firmware functions.\n", pr_info("STI %s ROM supports 32 %sbit firmware functions.\n",
wordmode ? "word mode" : "byte mode",
raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64 raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
? "and 64 " : ""); ? "and 64 " : "");
...@@ -767,18 +789,17 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, ...@@ -767,18 +789,17 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
sti->rom = cooked; sti->rom = cooked;
sti->rom->raw = raw; sti->rom->raw = raw;
sti_dump_rom(sti);
sti->font = sti_select_font(sti->rom, sti_search_font);
sti->font_width = sti->font->raw->width; sti->wordmode = wordmode;
sti->font_height = sti->font->raw->height; sti->font = sti_select_font(sti->rom);
if (!wordmode) sti->font->width = sti->font->raw->width;
sti->font->raw = sti_bmode_font_raw(sti->font); sti->font->height = sti->font->raw->height;
sti_font_convert_bytemode(sti, sti->font);
sti->sti_mem_request = raw->sti_mem_req; sti->sti_mem_request = raw->sti_mem_req;
sti->graphics_id[0] = raw->graphics_id[0]; sti->graphics_id[0] = raw->graphics_id[0];
sti->graphics_id[1] = raw->graphics_id[1]; sti->graphics_id[1] = raw->graphics_id[1];
sti_dump_rom(raw);
/* check if the ROM routines in this card are compatible */ /* check if the ROM routines in this card are compatible */
if (wordmode || sti->graphics_id[1] != 0x09A02587) if (wordmode || sti->graphics_id[1] != 0x09A02587)
...@@ -804,9 +825,9 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, ...@@ -804,9 +825,9 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
return 1; return 1;
msg_not_supported: msg_not_supported:
printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n"); pr_warn("Sorry, this GSC/STI card is not yet supported.\n");
printk(KERN_ERR "Please see http://parisc-linux.org/faq/" pr_warn("Please see https://parisc.wiki.kernel.org/"
"graphics-howto.html for more info.\n"); "index.php/Graphics_howto for more info.\n");
/* fall through */ /* fall through */
out_err: out_err:
kfree(raw); kfree(raw);
...@@ -823,7 +844,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, ...@@ -823,7 +844,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
u32 sig; u32 sig;
if (num_sti_roms >= MAX_STI_ROMS) { if (num_sti_roms >= MAX_STI_ROMS) {
printk(KERN_WARNING "maximum number of STI ROMS reached !\n"); pr_warn("maximum number of STI ROMS reached !\n");
return NULL; return NULL;
} }
...@@ -849,16 +870,15 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, ...@@ -849,16 +870,15 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
if (i != 1) { if (i != 1) {
/* The ROM could have multiple architecture /* The ROM could have multiple architecture
* dependent images (e.g. i386, parisc,...) */ * dependent images (e.g. i386, parisc,...) */
printk(KERN_WARNING pr_warn("PCI ROM is not a STI ROM type image (0x%8x)\n", i);
"PCI ROM is not a STI ROM type image (0x%8x)\n", i);
goto out_err; goto out_err;
} }
sti->pd = pd; sti->pd = pd;
i = gsc_readl(address+0x0c); i = gsc_readl(address+0x0c);
DPRINTK(("PCI ROM size (from header) = %d kB\n", pr_debug("PCI ROM size (from header) = %d kB\n",
le16_to_cpu(i>>16)*512/1024)); le16_to_cpu(i>>16)*512/1024);
rm_offset = le16_to_cpu(i & 0xffff); rm_offset = le16_to_cpu(i & 0xffff);
if (rm_offset) { if (rm_offset) {
/* read 16 bytes from the pci region mapper array */ /* read 16 bytes from the pci region mapper array */
...@@ -867,29 +887,24 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, ...@@ -867,29 +887,24 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
*rm++ = gsc_readl(address+rm_offset+0x04); *rm++ = gsc_readl(address+rm_offset+0x04);
*rm++ = gsc_readl(address+rm_offset+0x08); *rm++ = gsc_readl(address+rm_offset+0x08);
*rm++ = gsc_readl(address+rm_offset+0x0c); *rm++ = gsc_readl(address+rm_offset+0x0c);
DPRINTK(("PCI region Mapper offset = %08x: ",
rm_offset));
for (i=0; i<16; i++)
DPRINTK(("%02x ", sti->rm_entry[i]));
DPRINTK(("\n"));
} }
address += le32_to_cpu(gsc_readl(address+8)); address += le32_to_cpu(gsc_readl(address+8));
DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address)); pr_debug("sig %04x, PCI STI ROM at %08lx\n", sig, address);
goto test_rom; goto test_rom;
} }
ok = 0; ok = 0;
if ((sig & 0xff) == 0x01) { if ((sig & 0xff) == 0x01) {
DPRINTK((" byte mode ROM at %08lx, hpa at %08lx\n", pr_debug(" byte mode ROM at %08lx, hpa at %08lx\n",
address, hpa)); address, hpa);
ok = sti_read_rom(0, sti, address); ok = sti_read_rom(0, sti, address);
} }
if ((sig & 0xffff) == 0x0303) { if ((sig & 0xffff) == 0x0303) {
DPRINTK((" word mode ROM at %08lx, hpa at %08lx\n", pr_debug(" word mode ROM at %08lx, hpa at %08lx\n",
address, hpa)); address, hpa);
ok = sti_read_rom(1, sti, address); ok = sti_read_rom(1, sti, address);
} }
...@@ -906,7 +921,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, ...@@ -906,7 +921,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
unsigned long rom_base; unsigned long rom_base;
rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE); rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE);
pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE); pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE);
DPRINTK((KERN_DEBUG "STI PCI ROM disabled\n")); pr_debug("STI PCI ROM disabled\n");
} }
if (sti_init_graph(sti)) if (sti_init_graph(sti))
...@@ -981,14 +996,14 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) ...@@ -981,14 +996,14 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE); rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE);
if (rom_base) { if (rom_base) {
pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE); pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE);
DPRINTK((KERN_DEBUG "STI PCI ROM enabled at 0x%08lx\n", rom_base)); pr_debug("STI PCI ROM enabled at 0x%08lx\n", rom_base);
} }
printk(KERN_INFO "STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n", pr_info("STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n",
rom_base, rom_len/1024, fb_base, fb_len/1024/1024); rom_base, rom_len/1024, fb_base, fb_len/1024/1024);
DPRINTK((KERN_DEBUG "Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n", pr_debug("Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n",
rom_base, fb_base)); rom_base, fb_base);
sti = sti_try_rom_generic(rom_base, fb_base, pd); sti = sti_try_rom_generic(rom_base, fb_base, pd);
if (sti) { if (sti) {
...@@ -998,8 +1013,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) ...@@ -998,8 +1013,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
} }
if (!sti) { if (!sti) {
printk(KERN_WARNING "Unable to handle STI device '%s'\n", pr_warn("Unable to handle STI device '%s'\n", pci_name(pd));
pci_name(pd));
return -ENODEV; return -ENODEV;
} }
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
...@@ -1058,7 +1072,7 @@ static void sti_init_roms(void) ...@@ -1058,7 +1072,7 @@ static void sti_init_roms(void)
sticore_initialized = 1; sticore_initialized = 1;
printk(KERN_INFO "STI GSC/PCI core graphics driver " pr_info("STI GSC/PCI core graphics driver "
STI_DRIVERVERSION "\n"); STI_DRIVERVERSION "\n");
/* Register drivers for native & PCI cards */ /* Register drivers for native & PCI cards */
......
...@@ -4,12 +4,6 @@ ...@@ -4,12 +4,6 @@
/* generic STI structures & functions */ /* generic STI structures & functions */
#if 0
#define DPRINTK(x) printk x
#else
#define DPRINTK(x)
#endif
#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ #define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */
#define STI_REGION_MAX 8 /* hardcoded STI constants */ #define STI_REGION_MAX 8 /* hardcoded STI constants */
...@@ -246,8 +240,12 @@ struct sti_rom_font { ...@@ -246,8 +240,12 @@ struct sti_rom_font {
/* sticore internal font handling */ /* sticore internal font handling */
struct sti_cooked_font { struct sti_cooked_font {
struct sti_rom_font *raw; struct sti_rom_font *raw; /* native ptr for STI functions */
void *raw_ptr; /* kmalloc'ed font data */
struct sti_cooked_font *next_font; struct sti_cooked_font *next_font;
int height, width;
int refcount;
u32 crc;
}; };
struct sti_cooked_rom { struct sti_cooked_rom {
...@@ -341,9 +339,6 @@ struct sti_all_data { ...@@ -341,9 +339,6 @@ struct sti_all_data {
struct sti_struct { struct sti_struct {
spinlock_t lock; spinlock_t lock;
/* the following fields needs to be filled in by the word/byte routines */
int font_width;
int font_height;
/* char **mon_strings; */ /* char **mon_strings; */
int sti_mem_request; int sti_mem_request;
u32 graphics_id[2]; u32 graphics_id[2];
...@@ -362,6 +357,7 @@ struct sti_struct { ...@@ -362,6 +357,7 @@ struct sti_struct {
struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */
int wordmode;
struct sti_cooked_font *font; /* ptr to selected font (cooked) */ struct sti_cooked_font *font; /* ptr to selected font (cooked) */
struct pci_dev *pd; struct pci_dev *pd;
...@@ -380,6 +376,7 @@ struct sti_struct { ...@@ -380,6 +376,7 @@ struct sti_struct {
/* sticore interface functions */ /* sticore interface functions */
struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f);
/* sticore main function to call STI firmware */ /* sticore main function to call STI firmware */
...@@ -391,12 +388,14 @@ int sti_call(const struct sti_struct *sti, unsigned long func, ...@@ -391,12 +388,14 @@ int sti_call(const struct sti_struct *sti, unsigned long func,
/* functions to call the STI ROM directly */ /* functions to call the STI ROM directly */
void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_putc(struct sti_struct *sti, int c, int y, int x,
struct sti_cooked_font *font);
void sti_set(struct sti_struct *sti, int src_y, int src_x, void sti_set(struct sti_struct *sti, int src_y, int src_x,
int height, int width, u8 color); int height, int width, u8 color);
void sti_clear(struct sti_struct *sti, int src_y, int src_x, void sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c); int height, int width, int c, struct sti_cooked_font *font);
void sti_bmove(struct sti_struct *sti, int src_y, int src_x, void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width); int dst_y, int dst_x, int height, int width,
struct sti_cooked_font *font);
#endif /* STICORE_H */ #endif /* STICORE_H */
...@@ -39,6 +39,5 @@ ...@@ -39,6 +39,5 @@
#define MADV_SOFT_OFFLINE 101 #define MADV_SOFT_OFFLINE 101
/* MAP_32BIT is undefined on parisc, fix it for perf */ /* MAP_32BIT is undefined on parisc, fix it for perf */
#define MAP_32BIT 0 #define MAP_32BIT 0
/* MAP_UNINITIALIZED is undefined on parisc, fix it for perf */
#define MAP_UNINITIALIZED 0 #define MAP_UNINITIALIZED 0
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment