Commit e78df3d0 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.5-rmk

into home.transmeta.com:/home/torvalds/v2.5/linux
parents bc0b0607 49744e17
...@@ -552,8 +552,6 @@ MODULE_AUTHOR("Stephen Rothwell"); ...@@ -552,8 +552,6 @@ MODULE_AUTHOR("Stephen Rothwell");
MODULE_DESCRIPTION("Advanced Power Management"); MODULE_DESCRIPTION("Advanced Power Management");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;
#ifndef MODULE #ifndef MODULE
static int __init apm_setup(char *str) static int __init apm_setup(char *str)
{ {
......
...@@ -69,6 +69,7 @@ extern void __udivmoddi4(void); ...@@ -69,6 +69,7 @@ extern void __udivmoddi4(void);
extern void __udivsi3(void); extern void __udivsi3(void);
extern void __umodsi3(void); extern void __umodsi3(void);
extern void abort(void); extern void abort(void);
extern void do_div64(void);
extern void ret_from_exception(void); extern void ret_from_exception(void);
extern void fpundefinstr(void); extern void fpundefinstr(void);
...@@ -234,6 +235,7 @@ EXPORT_SYMBOL_NOVERS(__umoddi3); ...@@ -234,6 +235,7 @@ EXPORT_SYMBOL_NOVERS(__umoddi3);
EXPORT_SYMBOL_NOVERS(__udivmoddi4); EXPORT_SYMBOL_NOVERS(__udivmoddi4);
EXPORT_SYMBOL_NOVERS(__udivsi3); EXPORT_SYMBOL_NOVERS(__udivsi3);
EXPORT_SYMBOL_NOVERS(__umodsi3); EXPORT_SYMBOL_NOVERS(__umodsi3);
EXPORT_SYMBOL_NOVERS(do_div64);
/* bitops */ /* bitops */
EXPORT_SYMBOL(_set_bit_le); EXPORT_SYMBOL(_set_bit_le);
......
...@@ -997,11 +997,11 @@ ENTRY(fp_enter) ...@@ -997,11 +997,11 @@ ENTRY(fp_enter)
* previous and next are guaranteed not to be the same. * previous and next are guaranteed not to be the same.
*/ */
ENTRY(__switch_to) ENTRY(__switch_to)
add ip, r0, #TI_CPU_SAVE add ip, r1, #TI_CPU_SAVE
ldr r2, [r1, #TI_CPU_DOMAIN]! ldr r3, [r2, #TI_CPU_DOMAIN]!
stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack
mcr p15, 0, r2, c3, c0 @ Set domain register mcr p15, 0, r3, c3, c0, 0 @ Set domain register
ldmib r1, {r4 - sl, fp, sp, pc} @ Load all regs saved previously ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
__INIT __INIT
/* /*
......
...@@ -75,7 +75,6 @@ no_work_pending: ...@@ -75,7 +75,6 @@ no_work_pending:
* This is how we return from a fork. * This is how we return from a fork.
*/ */
ENTRY(ret_from_fork) ENTRY(ret_from_fork)
ldr r0, [r0, #TI_TASK]
bl schedule_tail bl schedule_tail
get_thread_info tsk get_thread_info tsk
ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
......
...@@ -13,7 +13,7 @@ obj-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ ...@@ -13,7 +13,7 @@ obj-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
strnlen_user.o strchr.o strrchr.o testchangebit.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \
testclearbit.o testsetbit.o uaccess.o getuser.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \
putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
ucmpdi2.o udivdi3.o lib1funcs.o ucmpdi2.o udivdi3.o lib1funcs.o div64.o
obj-m := obj-m :=
obj-n := obj-n :=
......
#include <linux/linkage.h>
ql .req r0 @ quotient low
qh .req r1 @ quotient high
dl .req r3 @ divisor low
dh .req r2 @ divisor high
nl .req r4 @ dividend low
nh .req r5 @ dividend high
ENTRY(do_div64)
stmfd sp!, {r4, r5, lr}
mov nl, r0
movs nh, r1 @ if high bits are zero
movne lr, #33
moveq lr, #1 @ only divide low bits
moveq nh, r0
1: cmp nh, dh
bls 2f
add lr, lr, #1
movs dh, dh, lsl #1 @ left justify divisor
bpl 1b
2: movs nh, r1
moveq dl, dh
moveq dh, #0
movne dl, #0
mov ql, #0
mov qh, #0
3: subs ip, nl, dl @ trial subtraction
sbcs ip, nh, dh
movcs nh, ip @ only update if successful
subcs nl, nl, dl @ (repeat the subtraction)
adcs ql, ql, ql @ C=1 if successful, shift into
adc qh, qh, qh @ quotient
movs dh, dh, lsr #1 @ shift base high part right
mov dl, dl, rrx @ shift base low part right
subs lr, lr, #1
bne 3b
mov r2, nl
ldmfd sp!, {r4, r5, pc}
...@@ -25,10 +25,13 @@ ...@@ -25,10 +25,13 @@
#define MAX_SLOTS 21 #define MAX_SLOTS 21
#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \ #define PCICMD_ABORT ((PCI_STATUS_REC_MASTER_ABORT| \
PCI_STATUS_REC_MASTER_ABORT | \ PCI_STATUS_REC_TARGET_ABORT)<<16)
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY) << 16) #define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY) << 16)
extern int setup_arm_irq(int, struct irqaction *); extern int setup_arm_irq(int, struct irqaction *);
extern void pcibios_report_status(u_int status_mask, int warn); extern void pcibios_report_status(u_int status_mask, int warn);
...@@ -84,6 +87,12 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -84,6 +87,12 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
*value = v; *value = v;
v = *CSR_PCICMD;
if (v & PCICMD_ABORT) {
*CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
return -1;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
...@@ -92,6 +101,7 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -92,6 +101,7 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value) int size, u32 value)
{ {
unsigned long addr = dc21285_base_address(bus, devfn); unsigned long addr = dc21285_base_address(bus, devfn);
u32 v;
if (addr) if (addr)
switch (size) { switch (size) {
...@@ -109,6 +119,12 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -109,6 +119,12 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
break; break;
} }
v = *CSR_PCICMD;
if (v & PCICMD_ABORT) {
*CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
return -1;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
...@@ -148,16 +164,16 @@ static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -148,16 +164,16 @@ static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
cmd = cmd & 0xffff; cmd = cmd & 0xffff;
if (status & PCI_STATUS_REC_MASTER_ABORT) { if (status & PCI_STATUS_REC_MASTER_ABORT) {
printk(KERN_DEBUG "PCI: master abort: "); printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n",
pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT, 1); instruction_pointer(regs));
printk("\n");
cmd |= PCI_STATUS_REC_MASTER_ABORT << 16; cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
} }
if (status & PCI_STATUS_REC_TARGET_ABORT) { if (status & PCI_STATUS_REC_TARGET_ABORT) {
printk(KERN_DEBUG "PCI: target abort: "); printk(KERN_DEBUG "PCI: target abort: ");
pcibios_report_status(PCI_STATUS_SIG_TARGET_ABORT, 1); pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT, 1);
printk("\n"); printk("\n");
cmd |= PCI_STATUS_REC_TARGET_ABORT << 16; cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
...@@ -289,6 +305,38 @@ void __init dc21285_preinit(void) ...@@ -289,6 +305,38 @@ void __init dc21285_preinit(void)
"%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ? "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ?
"central function" : "addin"); "central function" : "addin");
if (footbridge_cfn_mode()) {
/*
* Clear any existing errors - we aren't
* interested in historical data...
*/
*CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
SA110_CNTL_RXSERR;
*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
}
init_timer(&serr_timer);
init_timer(&perr_timer);
serr_timer.data = IRQ_PCI_SERR;
serr_timer.function = dc21285_enable_error;
perr_timer.data = IRQ_PCI_PERR;
perr_timer.function = dc21285_enable_error;
/*
* We don't care if these fail.
*/
request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT,
"PCI system error", &serr_timer);
request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT,
"PCI parity error", &perr_timer);
request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT,
"PCI abort", NULL);
request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT,
"Discard timer", NULL);
request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT,
"PCI data parity", NULL);
if (cfn_mode) { if (cfn_mode) {
static struct resource csrio; static struct resource csrio;
...@@ -324,35 +372,5 @@ void __init dc21285_preinit(void) ...@@ -324,35 +372,5 @@ void __init dc21285_preinit(void)
void __init dc21285_postinit(void) void __init dc21285_postinit(void)
{ {
if (footbridge_cfn_mode()) {
/*
* Clear any existing errors - we aren't
* interested in historical data...
*/
*CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
SA110_CNTL_RXSERR;
*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
}
/*
* Initialise PCI error IRQ after we've finished probing
*/
request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, "PCI abort", NULL);
request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, "Discard timer", NULL);
request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, "PCI data parity", NULL);
init_timer(&serr_timer);
init_timer(&perr_timer);
serr_timer.data = IRQ_PCI_SERR;
serr_timer.function = dc21285_enable_error;
perr_timer.data = IRQ_PCI_PERR;
perr_timer.function = dc21285_enable_error;
request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT,
"PCI system error", &serr_timer);
request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT,
"PCI parity error", &perr_timer);
register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0); register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
} }
...@@ -117,6 +117,8 @@ static int __init assabet_init(void) ...@@ -117,6 +117,8 @@ static int __init assabet_init(void)
PGSR = 0; PGSR = 0;
PCFR = 0; PCFR = 0;
PSDR = 0; PSDR = 0;
PPDR |= PPC_TXD3 | PPC_TXD1;
PPSR |= PPC_TXD3 | PPC_TXD1;
sa1100fb_lcd_power = assabet_lcd_power; sa1100fb_lcd_power = assabet_lcd_power;
sa1100fb_backlight_power = assabet_backlight_power; sa1100fb_backlight_power = assabet_backlight_power;
......
...@@ -234,6 +234,8 @@ static int sa1110_target(struct cpufreq_policy *policy, ...@@ -234,6 +234,8 @@ static int sa1110_target(struct cpufreq_policy *policy,
(sa11x0_ppcr_to_freq(ppcr-1) >= policy->min)) (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min))
ppcr--; ppcr--;
break; break;
default:
return -EINVAL;
} }
freqs.old = sa11x0_getspeed(); freqs.old = sa11x0_getspeed();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README, # To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk # or contact rmk@arm.linux.org.uk
# #
# Last update: Wed Mar 5 22:11:59 2003 # Last update: Tue Mar 25 16:34:29 2003
# #
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -305,3 +305,11 @@ meg03 ARCH_MEG03 MEG03 293 ...@@ -305,3 +305,11 @@ meg03 ARCH_MEG03 MEG03 293
pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294 pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294
nwsc ARCH_NWSC NWSC 295 nwsc ARCH_NWSC NWSC 295
nwlarm ARCH_NWLARM NWLARM 296 nwlarm ARCH_NWLARM NWLARM 296
ixp425_mguard ARCH_IXP425_MGUARD IXP425_MGUARD 297
pxa_netdcu4 ARCH_PXA_NETDCU4 PXA_NETDCU4 298
ixdp2401 ARCH_IXDP2401 IXDP2401 299
ixdp2801 ARCH_IXDP2801 IXDP2801 300
zodiac ARCH_ZODIAC ZODIAC 301
armmodul ARCH_ARMMODUL ARMMODUL 302
ketop SA1100_KETOP KETOP 303
av7200 ARCH_AV7200 AV7200 304
...@@ -199,12 +199,12 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa ...@@ -199,12 +199,12 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
printk("Using default partitions for %s\n",BOARD_NAME); printk("Using default partitions for %s\n",BOARD_NAME);
npartitions=1; npartitions=1;
parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL); parts = kmalloc(npartitions*sizeof(*parts)+strlen(name)+1, GFP_KERNEL);
memzero(parts,npartitions*sizeof(*parts)+strlen(name));
if (!parts) { if (!parts) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
memzero(parts,npartitions*sizeof(*parts)+strlen(name));
i=0; i=0;
names = (char *)&parts[npartitions]; names = (char *)&parts[npartitions];
parts[i].name = names; parts[i].name = names;
...@@ -218,10 +218,11 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa ...@@ -218,10 +218,11 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
parts[i].size = FLASH_SIZE-0x00180000; parts[i].size = FLASH_SIZE-0x00180000;
parts[i].offset = 0x00180000; parts[i].offset = 0x00180000;
#endif #endif
ret = npartitions;
out: out:
*pparts = parts; *pparts = parts;
return npartitions; return ret;
} }
......
...@@ -501,10 +501,11 @@ static struct console serial21285_console = ...@@ -501,10 +501,11 @@ static struct console serial21285_console =
.index = -1, .index = -1,
}; };
static void __init rs285_console_init(void) static int __init rs285_console_init(void)
{ {
serial21285_setup_ports(); serial21285_setup_ports();
register_console(&serial21285_console); register_console(&serial21285_console);
return 0;
} }
console_initcall(rs285_console_init); console_initcall(rs285_console_init);
......
...@@ -31,7 +31,7 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbim ...@@ -31,7 +31,7 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbim
obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER) += cyberfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o cfbimgblt.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o cfbimgblt.o
obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
......
...@@ -55,12 +55,6 @@ ...@@ -55,12 +55,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include "cyber2000fb.h" #include "cyber2000fb.h"
struct cfb_info { struct cfb_info {
...@@ -147,167 +141,114 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb) ...@@ -147,167 +141,114 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
/* /*
* Hardware Cyber2000 Acceleration * Hardware Cyber2000 Acceleration
*/ */
static void cyber2000_accel_wait(struct cfb_info *cfb)
{
int count = 100000;
while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
if (!count--) {
debug_printf("accel_wait timed out\n");
cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
return;
}
udelay(1);
}
}
static void cyber2000_accel_setup(struct display *display)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cfb->dispsw->setup(display);
}
static void static void
cyber2000_accel_bmove(struct display *display, int sy, int sx, int dy, int dx, cyber2000fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
int height, int width)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &display->var; unsigned long dst, col;
u_long src, dst;
u_int fh, fw, cmd = CO_CMD_L_PATTERN_FGCOL;
fw = fontwidth(display);
sx *= fw;
dx *= fw;
width *= fw;
width -= 1;
if (sx < dx) {
sx += width;
dx += width;
cmd |= CO_CMD_L_INC_LEFT;
}
fh = fontheight(display);
sy *= fh;
dy *= fh;
height *= fh;
height -= 1;
if (sy < dy) { if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
sy += height; cfb_fillrect(info, rect);
dy += height; return;
cmd |= CO_CMD_L_INC_UP;
} }
src = sx + sy * var->xres_virtual; cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
dst = dx + dy * var->xres_virtual; cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb);
cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
cyber2000_accel_wait(cfb); col = rect->color;
cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); if (cfb->fb.var.bits_per_pixel > 8)
cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); col = ((u32 *)cfb->fb.pseudo_palette)[col];
cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb); cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
if (var->bits_per_pixel == 24) { dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
if (cfb->fb.var.bits_per_pixel == 24) {
cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
dst *= 3; dst *= 3;
src *= 3;
} }
cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb); cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
cyber2000fb_writew(CO_CMD_H_FGSRCMAP|CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
} }
static void static void
cyber2000_accel_clear(struct vc_data *conp, struct display *display, int sy, cyber2000fb_copyarea(struct fb_info *info, struct fb_copyarea *region)
int sx, int height, int width)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &display->var; unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
u_long dst; unsigned long src, dst;
u_int fw, fh;
u32 bgx = attr_bgcol_ec(display, conp); if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
cfb_copyarea(info, region);
return;
}
fw = fontwidth(display); if (region->sx < region->dx) {
fh = fontheight(display); region->sx += region->width - 1;
region->dx += region->width - 1;
cmd |= CO_CMD_L_INC_LEFT;
}
dst = sx * fw + sy * var->xres_virtual * fh; if (region->sy < region->dy) {
width = width * fw - 1; region->sy += region->height - 1;
height = height * fh - 1; region->dy += region->height - 1;
cmd |= CO_CMD_L_INC_UP;
}
cyber2000_accel_wait(cfb); cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb);
if (var->bits_per_pixel == 24) { src = region->sx + region->sy * cfb->fb.var.xres_virtual;
dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
if (cfb->fb.var.bits_per_pixel == 24) {
cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
src *= 3;
dst *= 3; dst *= 3;
} }
cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
if (var->bits_per_pixel == 16)
bgx = ((u16 *)display->dispsw_data)[bgx];
else if (var->bits_per_pixel >= 24)
bgx = ((u32 *)display->dispsw_data)[bgx];
cyber2000fb_writel(bgx, CO_REG_FGCOLOUR, cfb);
cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb); cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER,
} CO_REG_CMD_H, cfb);
static void
cyber2000_accel_putc(struct vc_data *conp, struct display *display, int c,
int yy, int xx)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cyber2000_accel_wait(cfb);
cfb->dispsw->putc(conp, display, c, yy, xx);
} }
static void static void
cyber2000_accel_putcs(struct vc_data *conp, struct display *display, cyber2000fb_imageblit(struct fb_info *info, struct fb_image *image)
const unsigned short *s, int count, int yy, int xx)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
cyber2000_accel_wait(cfb); // if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
cfb->dispsw->putcs(conp, display, s, count, yy, xx); cfb_imageblit(info, image);
return;
// }
} }
static void cyber2000_accel_revc(struct display *display, int xx, int yy) static int cyber2000fb_sync(struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
int count = 100000;
cyber2000_accel_wait(cfb);
cfb->dispsw->revc(display, xx, yy);
}
static void if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
cyber2000_accel_clear_margins(struct vc_data *conp, struct display *display, return 0;
int bottom_only)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cfb->dispsw->clear_margins(conp, display, bottom_only); while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
if (!count--) {
debug_printf("accel_wait timed out\n");
cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
break;
}
udelay(1);
}
return 0;
} }
static struct display_switch fbcon_cyber_accel = { /*
.setup = cyber2000_accel_setup, * ===========================================================================
.bmove = cyber2000_accel_bmove, */
.clear = cyber2000_accel_clear,
.putc = cyber2000_accel_putc,
.putcs = cyber2000_accel_putcs,
.revc = cyber2000_accel_revc,
.clear_margins = cyber2000_accel_clear_margins,
.fontwidthmask = FONTWIDTH(8)|FONTWIDTH(16)
};
static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf) static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
{ {
...@@ -324,7 +265,7 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -324,7 +265,7 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info) u_int transp, struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &cfb->display->var; struct fb_var_screeninfo *var = &cfb->fb.var;
u32 pseudo_val; u32 pseudo_val;
int ret = 1; int ret = 1;
...@@ -332,7 +273,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -332,7 +273,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
default: default:
return 1; return 1;
#ifdef FBCON_HAS_CFB8
/* /*
* Pseudocolour: * Pseudocolour:
* 8 8 * 8 8
...@@ -359,7 +299,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -359,7 +299,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
cyber2000fb_writeb(green, 0x3c9, cfb); cyber2000fb_writeb(green, 0x3c9, cfb);
cyber2000fb_writeb(blue, 0x3c9, cfb); cyber2000fb_writeb(blue, 0x3c9, cfb);
return 0; return 0;
#endif
/* /*
* Direct colour: * Direct colour:
...@@ -455,13 +394,8 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -455,13 +394,8 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/* /*
* Now set our pseudo palette for the CFB16/24/32 drivers. * Now set our pseudo palette for the CFB16/24/32 drivers.
*/ */
if (regno < 16) { if (regno < 16)
if (var->bits_per_pixel == 16) ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
((u16 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
else
((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
ret = 0;
}
return ret; return ret;
} }
...@@ -800,20 +734,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, ...@@ -800,20 +734,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
} }
/* /*
* Decode the info required for the hardware. * Set the User Defined Part of the Display
* This involves the PLL parameters for the dot clock,
* CRTC registers, and accelerator settings.
*/ */
static int static int
cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
struct par_info *hw)
{ {
struct cfb_info *cfb = (struct cfb_info *)info;
struct par_info hw;
unsigned int mem; unsigned int mem;
int err; int err;
hw->width = var->xres_virtual;
hw->ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
var->transp.msb_right = 0; var->transp.msb_right = 0;
var->red.msb_right = 0; var->red.msb_right = 0;
var->green.msb_right = 0; var->green.msb_right = 0;
...@@ -822,10 +752,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -822,10 +752,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
case 8: /* PSEUDOCOLOUR, 256 */ case 8: /* PSEUDOCOLOUR, 256 */
hw->co_pixfmt = CO_PIXFMT_8BPP;
hw->pitch = hw->width >> 3;
hw->extseqmisc = EXT_SEQ_MISC_8;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 0; var->red.offset = 0;
...@@ -838,13 +764,8 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -838,13 +764,8 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
case 16:/* DIRECTCOLOUR, 64k or 32k */ case 16:/* DIRECTCOLOUR, 64k or 32k */
hw->co_pixfmt = CO_PIXFMT_16BPP;
hw->pitch = hw->width >> 2;
switch (var->green.length) { switch (var->green.length) {
case 6: /* RGB565, 64k */ case 6: /* RGB565, 64k */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB565;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 11; var->red.offset = 11;
...@@ -857,8 +778,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -857,8 +778,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
default: default:
case 5: /* RGB555, 32k */ case 5: /* RGB555, 32k */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB555;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 10; var->red.offset = 10;
...@@ -870,8 +789,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -870,8 +789,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
break; break;
case 4: /* RGB444, 4k + transparency? */ case 4: /* RGB444, 4k + transparency? */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB444;
var->transp.offset = 12; var->transp.offset = 12;
var->transp.length = 4; var->transp.length = 4;
var->red.offset = 8; var->red.offset = 8;
...@@ -886,12 +803,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -886,12 +803,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24:/* TRUECOLOUR, 16m */ case 24:/* TRUECOLOUR, 16m */
hw->co_pixfmt = CO_PIXFMT_24BPP;
hw->width *= 3;
hw->pitch = hw->width >> 3;
hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw->extseqmisc = EXT_SEQ_MISC_24_RGB888;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 16; var->red.offset = 16;
...@@ -904,11 +815,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -904,11 +815,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32:/* TRUECOLOUR, 16m */ case 32:/* TRUECOLOUR, 16m */
hw->co_pixfmt = CO_PIXFMT_32BPP;
hw->pitch = hw->width >> 1;
hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw->extseqmisc = EXT_SEQ_MISC_32;
var->transp.offset = 24; var->transp.offset = 24;
var->transp.length = 8; var->transp.length = 8;
var->red.offset = 16; var->red.offset = 16;
...@@ -933,127 +839,107 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -933,127 +839,107 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
if (var->xres > var->xres_virtual) if (var->xres > var->xres_virtual)
var->xres = var->xres_virtual; var->xres = var->xres_virtual;
err = cyber2000fb_decode_clock(hw, cfb, var); err = cyber2000fb_decode_clock(&hw, cfb, var);
if (err) if (err)
return err; return err;
err = cyber2000fb_decode_crtc(hw, cfb, var); err = cyber2000fb_decode_crtc(&hw, cfb, var);
if (err) if (err)
return err; return err;
hw->width -= 1;
hw->fetch = hw->pitch;
if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
hw->fetch <<= 1;
hw->fetch += 1;
return 0; return 0;
} }
/* static int cyber2000fb_set_par(struct fb_info *info)
* Set the User Defined Part of the Display
*/
static int
cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
struct display *display; struct fb_var_screeninfo *var = &cfb->fb.var;
struct par_info hw; struct par_info hw;
int err, chgvar; unsigned int mem;
/*
* CONUPDATE and SMOOTH_XPAN are equal. However,
* SMOOTH_XPAN is only used internally by fbcon.
*/
if (var->vmode & FB_VMODE_CONUPDATE) {
var->vmode |= FB_VMODE_YWRAP;
var->xoffset = cfb->display->var.xoffset;
var->yoffset = cfb->display->var.yoffset;
}
err = cyber2000fb_decode_var(var, cfb, &hw);
if (err)
return err;
if (var->activate & FB_ACTIVATE_TEST)
return 0;
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) hw.width = var->xres_virtual;
return -EINVAL; hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
if (con < 0) { switch (var->bits_per_pixel) {
display = cfb->fb.disp; case 8:
} else { hw.co_pixfmt = CO_PIXFMT_8BPP;
display = fb_display + con; hw.pitch = hw.width >> 3;
} hw.extseqmisc = EXT_SEQ_MISC_8;
break;
chgvar = cfb->fb.var.xres != var->xres || case 16:
cfb->fb.var.yres != var->yres || hw.co_pixfmt = CO_PIXFMT_16BPP;
cfb->fb.var.xres_virtual != var->xres_virtual || hw.pitch = hw.width >> 2;
cfb->fb.var.yres_virtual != var->yres_virtual ||
cfb->fb.var.bits_per_pixel != var->bits_per_pixel;
if (memcmp(&cfb->fb.var.red, &var->red, sizeof(var->red)) || switch (var->green.length) {
memcmp(&cfb->fb.var.green, &var->green, sizeof(var->green)) || case 6: /* RGB565, 64k */
memcmp(&cfb->fb.var.blue, &var->blue, sizeof(var->blue))) hw.extseqmisc = EXT_SEQ_MISC_16_RGB565;
chgvar = 1; break;
case 5: /* RGB555, 32k */
hw.extseqmisc = EXT_SEQ_MISC_16_RGB555;
break;
case 4: /* RGB444, 4k + transparency? */
hw.extseqmisc = EXT_SEQ_MISC_16_RGB444;
break;
default:
BUG();
}
case 24:/* TRUECOLOUR, 16m */
hw.co_pixfmt = CO_PIXFMT_24BPP;
hw.width *= 3;
hw.pitch = hw.width >> 3;
hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw.extseqmisc = EXT_SEQ_MISC_24_RGB888;
break;
if (con >= 0 && chgvar == 0) case 32:/* TRUECOLOUR, 16m */
return 0; hw.co_pixfmt = CO_PIXFMT_32BPP;
hw.pitch = hw.width >> 1;
hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw.extseqmisc = EXT_SEQ_MISC_32;
break;
if (con < 0) default:
chgvar = 0; BUG();
}
/* /*
* If we are setting all the virtual consoles, also set the * Sigh, this is absolutely disgusting, but caused by
* defaults used to create new consoles. * the way the fbcon developers want to separate out
* the "checking" and the "setting" of the video mode.
*
* If the mode is not suitable for the hardware here,
* we can't prevent it being set by returning an error.
*
* In theory, since NetWinders contain just one VGA card,
* we should never end up hitting this problem.
*/ */
err = var->activate; BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0);
var->activate = FB_ACTIVATE_NOW; BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0);
if (err & FB_ACTIVATE_ALL)
cfb->fb.disp->var = *var; hw.width -= 1;
hw.fetch = hw.pitch;
if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
hw.fetch <<= 1;
hw.fetch += 1;
cfb->fb.var = *var;
cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
switch (var->bits_per_pixel) { /*
#ifdef FBCON_HAS_CFB8 * Same here - if the size of the video mode exceeds the
case 8: /* PSEUDOCOLOUR, 256 */ * available RAM, we can't prevent this mode being set.
cfb->dispsw = &fbcon_cfb8; *
display->dispsw_data = NULL; * In theory, since NetWinders contain just one VGA card,
break; * we should never end up hitting this problem.
#endif */
#ifdef FBCON_HAS_CFB16 mem = cfb->fb.fix.line_length * var->yres_virtual;
case 16:/* DIRECTCOLOUR */ BUG_ON(mem > cfb->fb.fix.smem_len);
cfb->dispsw = &fbcon_cfb16;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB24
case 24:/* TRUECOLOUR, 16m */
cfb->dispsw = &fbcon_cfb24;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:/* TRUECOLOUR, 16m */
cfb->dispsw = &fbcon_cfb32;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
default:/* in theory this should never happen */
printk(KERN_WARNING "%s: no support for %dbpp\n",
cfb->fb.fix.id, var->bits_per_pixel);
cfb->dispsw = &fbcon_dummy;
break;
}
/* /*
* 8bpp displays are always pseudo colour. * 8bpp displays are always pseudo colour. 16bpp and above
* 16bpp and above are direct colour or true colour, depending * are direct colour or true colour, depending on whether
* on whether the RAMDAC palettes are bypassed. (Direct colour * the RAMDAC palettes are bypassed. (Direct colour has
* has palettes, true colour does not.) * palettes, true colour does not.)
*/ */
if (var->bits_per_pixel == 8) if (var->bits_per_pixel == 8)
cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
...@@ -1062,20 +948,8 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -1062,20 +948,8 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
else else
cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR; cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
if (var->accel_flags & FB_ACCELF_TEXT && cfb->dispsw != &fbcon_dummy)
display->dispsw = &fbcon_cyber_accel;
else
display->dispsw = cfb->dispsw;
display->can_soft_blank = 1;
display->inverse = 0;
cyber2000fb_set_timing(cfb, &hw); cyber2000fb_set_timing(cfb, &hw);
cyber2000fb_update_start(cfb, var); cyber2000fb_update_start(cfb, var);
fb_set_cmap(&cfb->fb.cmap, 1, &cfb->fb);
if (chgvar && cfb->fb.changevar)
cfb->fb.changevar(con);
return 0; return 0;
} }
...@@ -1085,85 +959,22 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -1085,85 +959,22 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
* Pan or Wrap the Display * Pan or Wrap the Display
*/ */
static int static int
cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con, cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
u_int y_bottom;
y_bottom = var->yoffset;
if (!(var->vmode & FB_VMODE_YWRAP))
y_bottom += var->yres;
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
if (y_bottom > cfb->display->var.yres_virtual)
return -EINVAL;
if (cyber2000fb_update_start(cfb, var)) if (cyber2000fb_update_start(cfb, var))
return -EINVAL; return -EINVAL;
cfb->display->var.xoffset = var->xoffset; cfb->fb.var.xoffset = var->xoffset;
cfb->display->var.yoffset = var->yoffset; cfb->fb.var.yoffset = var->yoffset;
if (var->vmode & FB_VMODE_YWRAP) { if (var->vmode & FB_VMODE_YWRAP) {
cfb->display->var.vmode |= FB_VMODE_YWRAP; cfb->fb.var.vmode |= FB_VMODE_YWRAP;
} else { } else {
cfb->display->var.vmode &= ~FB_VMODE_YWRAP; cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
}
return 0;
}
/*
* Update the `var' structure (called by fbcon.c)
*
* This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
* Since it's called by a kernel driver, no range checking is done.
*/
static int cyber2000fb_updatevar(int con, struct fb_info *info)
{
struct cfb_info *cfb = (struct cfb_info *)info;
return cyber2000fb_update_start(cfb, &fb_display[con].var);
}
static int cyber2000fb_switch(int con, struct fb_info *info)
{
struct cfb_info *cfb = (struct cfb_info *)info;
struct display *display = cfb->display;
struct fb_cmap *cmap;
if (display) {
/*
* Save the old colormap and video mode.
*/
if (display->cmap.len)
fb_copy_cmap(&cfb->fb.cmap, &display->cmap, 0);
} }
cfb->display = display = fb_display + con;
/*
* Install the new colormap and change the video mode. By default,
* fbcon sets all the colormaps and video modes to the default
* values at bootup.
*
* Really, we want to set the colourmap size depending on the
* depth of the new video mode. For now, we leave it at its
* default 256 entry.
*/
if (display->cmap.len)
cmap = &display->cmap;
else
cmap = fb_default_cmap(1 << display->var.bits_per_pixel);
fb_copy_cmap(cmap, &cfb->fb.cmap, 0);
display->var.activate = FB_ACTIVATE_NOW;
cyber2000fb_set_var(&display->var, con, &cfb->fb);
return 0; return 0;
} }
...@@ -1243,12 +1054,16 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) ...@@ -1243,12 +1054,16 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
static struct fb_ops cyber2000fb_ops = { static struct fb_ops cyber2000fb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_set_var = cyber2000fb_set_var, .fb_check_var = cyber2000fb_check_var,
.fb_get_cmap = gen_get_cmap, .fb_set_par = cyber2000fb_set_par,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = cyber2000fb_setcolreg, .fb_setcolreg = cyber2000fb_setcolreg,
.fb_pan_display = cyber2000fb_pan_display,
.fb_blank = cyber2000fb_blank, .fb_blank = cyber2000fb_blank,
.fb_pan_display = cyber2000fb_pan_display,
.fb_fillrect = cyber2000fb_fillrect,
.fb_copyarea = cyber2000fb_copyarea,
.fb_imageblit = cyber2000fb_imageblit,
.fb_cursor = soft_cursor,
.fb_sync = cyber2000fb_sync,
}; };
/* /*
...@@ -1295,7 +1110,7 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb) ...@@ -1295,7 +1110,7 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
{ {
memcpy(var, &cfb->display->var, sizeof(struct fb_var_screeninfo)); memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
} }
/* /*
...@@ -1313,8 +1128,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) ...@@ -1313,8 +1128,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
info->info = int_cfb_info; info->info = int_cfb_info;
strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name)); strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
MOD_INC_USE_COUNT;
} }
return int_cfb_info != NULL; return int_cfb_info != NULL;
...@@ -1325,7 +1138,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) ...@@ -1325,7 +1138,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
*/ */
void cyber2000fb_detach(int idx) void cyber2000fb_detach(int idx)
{ {
MOD_DEC_USE_COUNT;
} }
EXPORT_SYMBOL(cyber2000fb_attach); EXPORT_SYMBOL(cyber2000fb_attach);
...@@ -1411,13 +1223,13 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) ...@@ -1411,13 +1223,13 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
{ {
struct cfb_info *cfb; struct cfb_info *cfb;
cfb = kmalloc(sizeof(struct cfb_info) + sizeof(struct display) + cfb = kmalloc(sizeof(struct cfb_info) +
sizeof(u32) * 16, GFP_KERNEL); sizeof(u32) * 16, GFP_KERNEL);
if (!cfb) if (!cfb)
return NULL; return NULL;
memset(cfb, 0, sizeof(struct cfb_info) + sizeof(struct display)); memset(cfb, 0, sizeof(struct cfb_info));
cfb->id = id; cfb->id = id;
...@@ -1467,17 +1279,10 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) ...@@ -1467,17 +1279,10 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
cfb->fb.var.width = -1; cfb->fb.var.width = -1;
cfb->fb.var.accel_flags = FB_ACCELF_TEXT; cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
strcpy(cfb->fb.modename, cfb->fb.fix.id);
strcpy(cfb->fb.fontname, default_font);
cfb->fb.fbops = &cyber2000fb_ops; cfb->fb.fbops = &cyber2000fb_ops;
cfb->fb.changevar = NULL;
cfb->fb.switch_con = cyber2000fb_switch;
cfb->fb.updatevar = cyber2000fb_updatevar;
cfb->fb.flags = FBINFO_FLAG_DEFAULT; cfb->fb.flags = FBINFO_FLAG_DEFAULT;
cfb->fb.node = NODEV; cfb->fb.node = NODEV;
cfb->fb.disp = (struct display *)(cfb + 1); cfb->fb.pseudo_palette = (void *)(cfb + 1);
cfb->fb.pseudo_palette = (void *)(cfb->fb.disp + 1);
fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
...@@ -1575,7 +1380,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) ...@@ -1575,7 +1380,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
if (cfb->fb.var.yres_virtual < cfb->fb.var.yres) if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
cfb->fb.var.yres_virtual = cfb->fb.var.yres; cfb->fb.var.yres_virtual = cfb->fb.var.yres;
cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb); // fb_set_var(&cfb->fb.var, -1, &cfb->fb);
/* /*
* Calculate the hsync and vsync frequencies. Note that * Calculate the hsync and vsync frequencies. Note that
...@@ -1614,8 +1419,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb) ...@@ -1614,8 +1419,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
* Restore the old video mode and the palette. * Restore the old video mode and the palette.
* We also need to tell fbcon to redraw the console. * We also need to tell fbcon to redraw the console.
*/ */
cfb->fb.var.activate = FB_ACTIVATE_NOW; cyber2000fb_set_par(&cfb->fb);
cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
} }
#ifdef CONFIG_ARCH_SHARK #ifdef CONFIG_ARCH_SHARK
......
...@@ -1111,13 +1111,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) ...@@ -1111,13 +1111,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
#elif defined(__mips__) #elif defined(__mips__)
pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
#elif defined(__arm__)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#elif defined(__sh__) #elif defined(__sh__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE; pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
#elif defined(__hppa__) #elif defined(__hppa__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
#elif defined(__ia64__) #elif defined(__ia64__) || defined(__arm__)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#else #else
#warning What do we have to do here?? #warning What do we have to do here??
......
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
/* We're not 64-bit, but... */ /* We're not 64-bit, but... */
#define do_div(n,base) \ #define do_div(n,base) \
({ \ ({ \
int __res; \ register int __res asm("r2") = base; \
__res = ((unsigned long)n) % (unsigned int)base; \ register unsigned long long __n asm("r0") = n; \
n = ((unsigned long)n) / (unsigned int)base; \ asm("bl do_div64" \
: "=r" (__n), "=r" (__res) \
: "0" (__n), "1" (__res) \
: "r3", "ip", "lr", "cc"); \
n = __n; \
__res; \ __res; \
}) })
......
...@@ -103,6 +103,7 @@ ...@@ -103,6 +103,7 @@
* entries are stored 1024 bytes below. * entries are stored 1024 bytes below.
*/ */
#define L_PTE_PRESENT (1 << 0) #define L_PTE_PRESENT (1 << 0)
#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
#define L_PTE_YOUNG (1 << 1) #define L_PTE_YOUNG (1 << 1)
#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */ #define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */
#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */ #define L_PTE_CACHEABLE (1 << 3) /* matches PTE */
...@@ -173,6 +174,7 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd) ...@@ -173,6 +174,7 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd)
#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) #define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
#define PTE_BIT_FUNC(fn,op) \ #define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
...@@ -196,6 +198,11 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); ...@@ -196,6 +198,11 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
#define pgtable_cache_init() do { } while (0) #define pgtable_cache_init() do { } while (0)
#define pte_to_pgoff(x) (pte_val(x) >> 2)
#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
#define PTE_FILE_MAX_BITS 30
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __ASM_PROC_PGTABLE_H */ #endif /* __ASM_PROC_PGTABLE_H */
...@@ -65,12 +65,13 @@ extern int cpu_architecture(void); ...@@ -65,12 +65,13 @@ extern int cpu_architecture(void);
* The `mb' is to tell GCC not to cache `current' across this call. * The `mb' is to tell GCC not to cache `current' across this call.
*/ */
struct thread_info; struct thread_info;
extern struct thread_info *__switch_to(struct thread_info *, struct thread_info *); struct task_struct;
extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
#define switch_to(prev,next,last) \ #define switch_to(prev,next,last) \
do { \ do { \
__switch_to(prev->thread_info,next->thread_info); \ last = __switch_to(prev,prev->thread_info,next->thread_info); \
mb(); \ mb(); \
} while (0) } while (0)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
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