Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b58b80ea
Commit
b58b80ea
authored
Oct 28, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updates to STI framebuffer and STI console. Cleanup of include/video and a few minor fixes.
parent
76e97c93
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1725 additions
and
477 deletions
+1725
-477
drivers/video/Makefile
drivers/video/Makefile
+1
-1
drivers/video/console/Config.in
drivers/video/console/Config.in
+1
-1
drivers/video/console/Makefile
drivers/video/console/Makefile
+1
-1
drivers/video/console/fbcon-sti.c
drivers/video/console/fbcon-sti.c
+10
-58
drivers/video/console/fbcon.c
drivers/video/console/fbcon.c
+2
-2
drivers/video/console/font.h
drivers/video/console/font.h
+0
-0
drivers/video/console/font_6x11.c
drivers/video/console/font_6x11.c
+1
-1
drivers/video/console/font_8x16.c
drivers/video/console/font_8x16.c
+1
-1
drivers/video/console/font_8x8.c
drivers/video/console/font_8x8.c
+1
-1
drivers/video/console/font_acorn_8x8.c
drivers/video/console/font_acorn_8x8.c
+1
-1
drivers/video/console/font_mini_4x6.c
drivers/video/console/font_mini_4x6.c
+1
-1
drivers/video/console/font_pearl_8x8.c
drivers/video/console/font_pearl_8x8.c
+1
-1
drivers/video/console/font_sun12x22.c
drivers/video/console/font_sun12x22.c
+1
-1
drivers/video/console/font_sun8x16.c
drivers/video/console/font_sun8x16.c
+1
-1
drivers/video/console/fonts.c
drivers/video/console/fonts.c
+1
-1
drivers/video/console/newport_con.c
drivers/video/console/newport_con.c
+1
-1
drivers/video/console/sti-bmode.h
drivers/video/console/sti-bmode.h
+0
-287
drivers/video/console/sti.h
drivers/video/console/sti.h
+0
-0
drivers/video/console/sticore.c
drivers/video/console/sticore.c
+0
-0
drivers/video/fbgen.c
drivers/video/fbgen.c
+1
-0
drivers/video/fbmem.c
drivers/video/fbmem.c
+1
-1
drivers/video/macmodes.c
drivers/video/macmodes.c
+1
-1
drivers/video/macmodes.h
drivers/video/macmodes.h
+0
-0
drivers/video/offb.c
drivers/video/offb.c
+1
-1
drivers/video/sticore.h
drivers/video/sticore.h
+407
-0
drivers/video/stifb.c
drivers/video/stifb.c
+1289
-114
No files found.
drivers/video/Makefile
View file @
b58b80ea
...
...
@@ -63,7 +63,7 @@ obj-$(CONFIG_FB_TCX) += tcxfb.o sbusfb.o
obj-$(CONFIG_FB_CGFOURTEEN)
+=
cgfourteenfb.o sbusfb.o
obj-$(CONFIG_FB_P9100)
+=
p9100fb.o sbusfb.o
obj-$(CONFIG_FB_LEO)
+=
leofb.o sbusfb.o
obj-$(CONFIG_FB_STI)
+=
stifb.o sticore.o
obj-$(CONFIG_FB_STI)
+=
stifb.o
console/
sticore.o
obj-$(CONFIG_FB_PMAG_BA)
+=
pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_PMAGB_B)
+=
pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_MAXINE)
+=
maxinefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
...
...
drivers/video/console/Config.in
View file @
b58b80ea
...
...
@@ -17,7 +17,7 @@ if [ "$CONFIG_VT" != "n" ]; then
# fi
# fi
fi
tristate 'MDA text console
(dual-headed)
' CONFIG_MDA_CONSOLE
tristate 'MDA text console ' CONFIG_MDA_CONSOLE
if [ "$CONFIG_SGI_IP22" = "y" ]; then
tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
...
...
drivers/video/console/Makefile
View file @
b58b80ea
...
...
@@ -14,7 +14,7 @@ export-objs := fbcon.o fbcon-accel.o fbcon-afb.o fbcon-ilbm.o \
obj-$(CONFIG_DUMMY_CONSOLE)
+=
dummycon.o
obj-$(CONFIG_SGI_NEWPORT_CONSOLE)
+=
newport_con.o
obj-$(CONFIG_PROM_CONSOLE)
+=
promcon.o promcon_tbl.o
obj-$(CONFIG_STI_CONSOLE)
+=
sticon.o stico
n-bmode.o ../stico
re.o
obj-$(CONFIG_STI_CONSOLE)
+=
sticon.o sticore.o
obj-$(CONFIG_VGA_CONSOLE)
+=
vgacon.o
obj-$(CONFIG_MDA_CONSOLE)
+=
mdacon.o
...
...
drivers/video/console/fbcon-sti.c
View file @
b58b80ea
...
...
@@ -17,42 +17,18 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <asm/gsc.h>
/* for gsc_read/write */
#include <asm/types.h>
#include
"fbcon.h"
#include
"fbcon-mfb.h"
#include
<video/fbcon.h>
#include
<video/fbcon-mfb.h>
#include "sti.h"
/* Translate an address as it would be found in a 2048x2048x1 bit frame
* buffer into a logical address Artist actually expects. Addresses fed
* into Artist look like this:
* fixed Y X
* FFFF FFFF LLLL LLLL LLLC CCCC CCCC CC00
*
* our "RAM" addresses look like this:
*
* FFFF FFFF 0000 0LLL LLLL LLLL CCCC CCCC [CCC]
*
* */
#include "../sticore.h"
static
inline
u32
ram2log
(
void
*
addr
)
{
u32
a
=
(
unsigned
long
)
addr
;
u32
r
;
#if 0
r = a & 0xff000000; /* fixed part */
r += ((a & 0x000000ff) << 5);
r += ((a & 0x00ffff00) << 3);
#else
r
=
a
&
0xff000000
;
/* fixed part */
r
+=
((
a
&
0x000000ff
)
<<
5
);
r
+=
((
a
&
0x0007ff00
)
<<
5
);
#endif
return
r
;
return
(
unsigned
long
)
addr
;
}
/* All those functions need better names. */
...
...
@@ -74,30 +50,6 @@ memcpy_fromhp_tohp(void *dest, void *src, int count)
}
}
static
void
memcpy_tohp
(
void
*
dest
,
void
*
src
,
int
count
)
{
unsigned
long
d
=
(
unsigned
long
)
dest
;
u32
*
s
=
(
u32
*
)
src
;
count
+=
3
;
count
&=
~
3
;
/* XXX */
d
=
ram2log
(
dest
);
while
(
count
)
{
count
--
;
gsc_writel
(
*
s
++
,
d
);
d
+=
32
*
4
;
}
}
static
void
memcopy_fromhp
(
void
*
dest
,
void
*
src
,
int
count
)
{
/* FIXME */
printk
(
"uhm ...
\n
"
);
}
static
void
memset_tohp
(
void
*
dest
,
u32
word
,
int
count
)
...
...
@@ -139,10 +91,11 @@ writeb_hp(u8 b, void *dst)
static
void
fbcon_sti_setup
(
struct
display
*
p
)
{
if
(
p
->
line_length
)
p
->
next_line
=
p
->
line_length
;
else
/* in kernel 2.5 the value of sadly line_length disapeared */
if
(
p
->
var
.
xres_virtual
/*line_length*/
)
p
->
next_line
=
p
->
var
.
xres_virtual
>>
3
;
else
p
->
next_line
=
2048
;
/* default STI value */
p
->
next_plane
=
0
;
}
...
...
@@ -152,7 +105,7 @@ fbcon_sti_bmove(struct display *p, int sy, int sx,
int
height
,
int
width
)
{
#if 0 /* Unfortunately, still broken */
sti_bmove(
&
default_sti /* FIXME */, sy, sx, dy, dx, height, width);
sti_bmove(default_sti /* FIXME */, sy, sx, dy, dx, height, width);
#else
u8
*
src
,
*
dest
;
u_int
rows
;
...
...
@@ -285,7 +238,6 @@ static void fbcon_sti_revc(struct display *p,
u8
*
dest
,
d
;
u_int
rows
;
dest
=
p
->
fb_info
->
screen_base
+
yy
*
fontheight
(
p
)
*
p
->
next_line
+
xx
;
for
(
rows
=
fontheight
(
p
);
rows
--
;
dest
+=
p
->
next_line
)
{
d
=
readb_hp
(
dest
);
...
...
drivers/video/console/fbcon.c
View file @
b58b80ea
...
...
@@ -99,11 +99,11 @@
#define INCLUDE_LINUX_LOGO_DATA
#include <asm/linux_logo.h>
#include
<video/fbcon.h>
#include
"fbcon.h"
#ifdef CONFIG_FBCON_ACCEL
#include "fbcon-accel.h"
#endif
#include
<video/font.h>
#include
"font.h"
#ifdef FBCONDEBUG
# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
...
...
include/video
/font.h
→
drivers/video/console
/font.h
View file @
b58b80ea
File moved
drivers/video/console/font_6x11.c
View file @
b58b80ea
...
...
@@ -4,7 +4,7 @@
/* */
/**********************************************/
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX (11*256)
...
...
drivers/video/console/font_8x16.c
View file @
b58b80ea
...
...
@@ -4,7 +4,7 @@
/* */
/**********************************************/
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 4096
...
...
drivers/video/console/font_8x8.c
View file @
b58b80ea
...
...
@@ -4,7 +4,7 @@
/* */
/**********************************************/
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 2048
...
...
drivers/video/console/font_acorn_8x8.c
View file @
b58b80ea
...
...
@@ -2,7 +2,7 @@
#include <linux/config.h>
#include
<video/font.h>
#include
"font.h"
static
unsigned
char
acorndata_8x8
[]
=
{
/* 00 */
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
/* ^@ */
...
...
drivers/video/console/font_mini_4x6.c
View file @
b58b80ea
...
...
@@ -39,7 +39,7 @@ __END__;
MSBit to LSBit = left to right.
*/
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 1536
...
...
drivers/video/console/font_pearl_8x8.c
View file @
b58b80ea
...
...
@@ -9,7 +9,7 @@
/* */
/**********************************************/
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 2048
...
...
drivers/video/console/font_sun12x22.c
View file @
b58b80ea
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 11264
...
...
drivers/video/console/font_sun8x16.c
View file @
b58b80ea
#include
<video/font.h>
#include
"font.h"
#define FONTDATAMAX 4096
...
...
drivers/video/console/fonts.c
View file @
b58b80ea
...
...
@@ -19,7 +19,7 @@
#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
#endif
#include
<video/font.h>
#include
"font.h"
#define NO_FONTS
...
...
drivers/video/console/newport_con.c
View file @
b58b80ea
...
...
@@ -30,7 +30,7 @@
#define INCLUDE_LINUX_LOGO_DATA
#include <asm/linux_logo.h>
#include
<video/font.h>
#include
"font.h"
#define LOGO_W 80
#define LOGO_H 80
...
...
drivers/video/console/sti-bmode.h
deleted
100644 → 0
View file @
76e97c93
#define STI_REGION_MAX 8
#define STI_DEV_NAME_LENGTH 32
typedef
struct
{
u8
res
[
3
];
u8
data
;
}
__attribute__
((
packed
))
sti_u8
;
typedef
struct
{
sti_u8
data
[
2
];
}
__attribute__
((
packed
))
sti_u16
;
typedef
struct
{
sti_u8
data
[
4
];
}
__attribute__
((
packed
))
sti_u32
;
#define STI_U8( u8) ((u8).data)
#define STI_U16(u16) ((STI_U8((u16).data[0])<<8) | STI_U8((u16).data[1]))
#define STI_U32(u32) ((STI_U8((u32).data[0])<<24) | \
(STI_U8((u32).data[1])<<16) | \
(STI_U8((u32).data[2])<< 8) | \
(STI_U8((u32).data[3])<< 0))
struct
sti_rom_region
{
sti_u32
region
;
};
struct
sti_rom_font
{
sti_u16
first_char
;
sti_u16
last_char
;
sti_u8
width
;
sti_u8
height
;
sti_u8
font_type
;
sti_u8
bytes_per_char
;
sti_u32
next_font
;
sti_u8
underline_height
;
sti_u8
underline_pos
;
sti_u8
res008
[
2
];
};
struct
sti_rom
{
sti_u8
type
;
sti_u8
num_mons
;
sti_u8
revno
[
2
];
sti_u8
graphics_id
[
8
];
/* 0x010 */
sti_u32
font_start
;
/* 0x030 */
sti_u32
statesize
;
sti_u32
last_addr
;
sti_u32
region_list
;
sti_u16
reentsize
;
/* 0x070 */
sti_u16
maxtime
;
sti_u32
mon_tbl_addr
;
sti_u32
user_data_addr
;
sti_u32
sti_mem_req
;
sti_u32
user_data_size
;
/* 0x0b0 */
sti_u16
power
;
/* 0x0c0 */
sti_u8
bus_support
;
sti_u8
ext_bus_support
;
sti_u8
alt_code_type
;
/* 0x0d0 */
sti_u8
ext_dd_struct
[
3
];
sti_u32
cfb_addr
;
/* 0x0e0 */
sti_u8
res0f0
[
4
];
sti_u32
init_graph
;
/* 0x0e0 */
sti_u32
state_mgmt
;
sti_u32
font_unpmv
;
sti_u32
block_move
;
sti_u32
self_test
;
sti_u32
excep_hdlr
;
sti_u32
inq_conf
;
sti_u32
set_cm_entry
;
sti_u32
dma_ctrl
;
sti_u32
flow_ctrl
;
sti_u32
user_timing
;
sti_u32
process_mgr
;
sti_u32
sti_util
;
sti_u32
end_addr
;
sti_u32
res0b8
;
sti_u32
res0bc
;
sti_u32
init_graph_m68k
;
/* 0x0e0 */
sti_u32
state_mgmt_m68k
;
sti_u32
font_unpmv_m68k
;
sti_u32
block_move_m68k
;
sti_u32
self_test_m68k
;
sti_u32
excep_hdlr_m68k
;
sti_u32
inq_conf_m68k
;
sti_u32
set_cm_entry_m68k
;
sti_u32
dma_ctrl_m68k
;
sti_u32
flow_ctrl_m68k
;
sti_u32
user_timing_m68k
;
sti_u32
process_mgr_m68k
;
sti_u32
sti_util_m68k
;
sti_u32
end_addr_m68k
;
sti_u32
res0b8_m68k
;
sti_u32
res0bc_m68k
;
sti_u8
res040
[
7
*
4
];
};
struct
sti_cooked_font
{
struct
sti_rom_font
*
raw
;
struct
sti_cooked_font
*
next_font
;
};
struct
sti_cooked_rom
{
struct
sti_rom
*
raw
;
struct
sti_cooked_font
*
font_start
;
u32
*
region_list
;
};
struct
sti_glob_cfg_ext
{
u8
curr_mon
;
u8
friendly_boot
;
s16
power
;
s32
freq_ref
;
s32
*
sti_mem_addr
;
s32
*
future_ptr
;
};
struct
sti_glob_cfg
{
s32
text_planes
;
s16
onscreen_x
;
s16
onscreen_y
;
s16
offscreen_x
;
s16
offscreen_y
;
s16
total_x
;
s16
total_y
;
u32
region_ptrs
[
STI_REGION_MAX
];
s32
reent_lvl
;
s32
*
save_addr
;
struct
sti_glob_cfg_ext
*
ext_ptr
;
};
struct
sti_init_flags
{
u32
wait
:
1
;
u32
reset
:
1
;
u32
text
:
1
;
u32
nontext
:
1
;
u32
clear
:
1
;
u32
cmap_blk
:
1
;
u32
enable_be_timer
:
1
;
u32
enable_be_int
:
1
;
u32
no_chg_tx
:
1
;
u32
no_chg_ntx
:
1
;
u32
no_chg_bet
:
1
;
u32
no_chg_bei
:
1
;
u32
init_cmap_tx
:
1
;
u32
cmt_chg
:
1
;
u32
retain_ie
:
1
;
u32
pad
:
17
;
s32
*
future_ptr
;
};
struct
sti_init_inptr_ext
{
u8
config_mon_type
;
u8
pad
[
1
];
u16
inflight_data
;
s32
*
future_ptr
;
};
struct
sti_init_inptr
{
s32
text_planes
;
struct
sti_init_inptr_ext
*
ext_ptr
;
};
struct
sti_init_outptr
{
s32
errno
;
s32
text_planes
;
s32
*
future_ptr
;
};
struct
sti_conf_flags
{
u32
wait
:
1
;
u32
pad
:
31
;
s32
*
future_ptr
;
};
struct
sti_conf_inptr
{
s32
*
future_ptr
;
};
struct
sti_conf_outptr_ext
{
u32
crt_config
[
3
];
u32
crt_hdw
[
3
];
s32
*
future_ptr
;
};
struct
sti_conf_outptr
{
s32
errno
;
s16
onscreen_x
;
s16
onscreen_y
;
s16
offscreen_x
;
s16
offscreen_y
;
s16
total_x
;
s16
total_y
;
s32
bits_per_pixel
;
s32
bits_used
;
s32
planes
;
u8
dev_name
[
STI_DEV_NAME_LENGTH
];
u32
attributes
;
struct
sti_conf_outptr_ext
*
ext_ptr
;
};
struct
sti_font_inptr
{
u32
font_start_addr
;
s16
index
;
u8
fg_color
;
u8
bg_color
;
s16
dest_x
;
s16
dest_y
;
s32
*
future_ptr
;
};
struct
sti_font_flags
{
u32
wait
:
1
;
u32
non_text
:
1
;
u32
pad
:
30
;
s32
*
future_ptr
;
};
struct
sti_font_outptr
{
s32
errno
;
s32
*
future_ptr
;
};
struct
sti_blkmv_flags
{
u32
wait
:
1
;
u32
color
:
1
;
u32
clear
:
1
;
u32
non_text
:
1
;
u32
pad
:
28
;
s32
*
future_ptr
;
};
struct
sti_blkmv_inptr
{
u8
fg_color
;
u8
bg_color
;
s16
src_x
;
s16
src_y
;
s16
dest_x
;
s16
dest_y
;
s16
width
;
s16
height
;
s32
*
future_ptr
;
};
struct
sti_blkmv_outptr
{
s32
errno
;
s32
*
future_ptr
;
};
struct
sti_struct
{
spinlock_t
lock
;
struct
sti_cooked_rom
*
rom
;
unsigned
long
font_unpmv
;
unsigned
long
block_move
;
unsigned
long
init_graph
;
unsigned
long
inq_conf
;
struct
sti_glob_cfg
*
glob_cfg
;
struct
sti_rom_font
*
font
;
s32
text_planes
;
char
**
mon_strings
;
u32
*
regions
;
u8
*
pci_regions
;
};
#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
({ \
real32_call( func, (unsigned long)STI_PTR(flags), \
STI_PTR(inptr), STI_PTR(outptr), \
glob_cfg); \
})
drivers/video/sti.h
→
drivers/video/
console/
sti.h
View file @
b58b80ea
File moved
drivers/video/sticore.c
→
drivers/video/
console/
sticore.c
View file @
b58b80ea
File moved
drivers/video/fbgen.c
View file @
b58b80ea
...
...
@@ -86,6 +86,7 @@ int cfb_cursor(struct fb_info *info, struct fbcursor *cursor)
if
(
info
->
fbops
->
fb_imageblit
)
info
->
fbops
->
fb_imageblit
(
info
,
&
image
);
}
return
0
;
}
int
fb_pan_display
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
...
...
drivers/video/fbmem.c
View file @
b58b80ea
...
...
@@ -43,7 +43,7 @@
#include <linux/fb.h>
#ifdef CONFIG_VT
#include <linux/console.h>
#include
<video/fbcon.h>
#include
"console/fbcon.h"
#endif
/*
...
...
drivers/video/macmodes.c
View file @
b58b80ea
...
...
@@ -20,7 +20,7 @@
#include <linux/fb.h>
#include <linux/string.h>
#include
<video/macmodes.h>
#include
"macmodes.h"
/*
* MacOS video mode definitions
...
...
include
/video/macmodes.h
→
drivers
/video/macmodes.h
View file @
b58b80ea
File moved
drivers/video/offb.c
View file @
b58b80ea
...
...
@@ -32,7 +32,7 @@
#include <asm/bootx.h>
#endif
#include
<video/macmodes.h>
#include
"macmodes.h"
/* Supported palette hacks */
enum
{
...
...
drivers/video/sticore.h
0 → 100644
View file @
b58b80ea
#ifndef STICORE_H
#define STICORE_H
/* 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 STI_REGION_MAX 8
/* hardcoded STI constants */
#define STI_DEV_NAME_LENGTH 32
#define STI_MONITOR_MAX 256
#define STI_FONT_HPROMAN8 1
#define STI_FONT_KANA8 2
/* The latency of the STI functions cannot really be reduced by setting
* this to 0; STI doesn't seem to be designed to allow calling a different
* function (or the same function with different arguments) after a
* function exited with 1 as return value.
*
* As all of the functions below could be called from interrupt context,
* we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
* block. Really bad latency there.
*
* Probably the best solution to all this is have the generic code manage
* the screen buffer and a kernel thread to call STI occasionally.
*
* Luckily, the frame buffer guys have the same problem so we can just wait
* for them to fix it and steal their solution. prumpf
*/
#define STI_WAIT 1
#include <asm/io.h>
/* for USE_HPPA_IOREMAP */
#if USE_HPPA_IOREMAP
#define STI_PTR(p) (p)
#define PTR_STI(p) (p)
static
int
inline
STI_CALL
(
unsigned
long
func
,
void
*
flags
,
void
*
inptr
,
void
*
outptr
,
void
*
glob_cfg
)
{
int
(
*
f
)(
void
*
,
void
*
,
void
*
,
void
*
);
f
=
(
void
*
)
func
;
return
f
(
flags
,
inptr
,
outptr
,
glob_cfg
);
}
#else
/* !USE_HPPA_IOREMAP */
#define STI_PTR(p) ( virt_to_phys(p) )
#define PTR_STI(p) ( phys_to_virt((long)p) )
#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
({ \
pdc_sti_call( func, (unsigned long)STI_PTR(flags), \
(unsigned long)STI_PTR(inptr), \
(unsigned long)STI_PTR(outptr), \
(unsigned long)STI_PTR(glob_cfg)); \
})
#endif
/* USE_HPPA_IOREMAP */
#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
/* sti_font_xy() use the native font ROM ! */
#define sti_font_x(sti) (PTR_STI(sti->font)->width)
#define sti_font_y(sti) (PTR_STI(sti->font)->height)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
extern
struct
sti_struct
*
sti_init_roms
(
void
);
/* XXX: this probably should not be here, but we rely on STI being
initialized early and independently of stifb at the moment, so
there's no other way for stifb to find it. */
extern
struct
sti_struct
*
default_sti
;
extern
struct
display_switch
fbcon_sti
;
/* fbcon-sti.c */
int
sti_init_graph
(
struct
sti_struct
*
sti
);
void
sti_inq_conf
(
struct
sti_struct
*
sti
);
void
sti_putc
(
struct
sti_struct
*
sti
,
int
c
,
int
y
,
int
x
);
void
sti_set
(
struct
sti_struct
*
sti
,
int
src_y
,
int
src_x
,
int
height
,
int
width
,
u8
color
);
void
sti_clear
(
struct
sti_struct
*
sti
,
int
src_y
,
int
src_x
,
int
height
,
int
width
,
int
c
);
void
sti_bmove
(
struct
sti_struct
*
sti
,
int
src_y
,
int
src_x
,
int
dst_y
,
int
dst_x
,
int
height
,
int
width
);
/* STI function configuration structs */
typedef
union
region
{
struct
{
u32
offset
:
14
;
/* offset in 4kbyte page */
u32
sys_only
:
1
;
/* don't map to user space */
u32
cache
:
1
;
/* map to data cache */
u32
btlb
:
1
;
/* map to block tlb */
u32
last
:
1
;
/* last region in list */
u32
length
:
14
;
/* length in 4kbyte page */
}
region_desc
;
u32
region
;
/* complete region value */
}
region_t
;
#define REGION_OFFSET_TO_PHYS( rt, hpa ) \
(((rt).region_desc.offset << 12) + (hpa))
struct
sti_glob_cfg_ext
{
u8
curr_mon
;
/* current monitor configured */
u8
friendly_boot
;
/* in friendly boot mode */
s16
power
;
/* power calculation (in Watts) */
s32
freq_ref
;
/* frequency refrence */
u32
sti_mem_addr
;
/* pointer to global sti memory (size=sti_mem_request) */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_glob_cfg
{
s32
text_planes
;
/* number of planes used for text */
s16
onscreen_x
;
/* screen width in pixels */
s16
onscreen_y
;
/* screen height in pixels */
s16
offscreen_x
;
/* offset width in pixels */
s16
offscreen_y
;
/* offset height in pixels */
s16
total_x
;
/* frame buffer width in pixels */
s16
total_y
;
/* frame buffer height in pixels */
u32
region_ptrs
[
STI_REGION_MAX
];
/* region pointers */
s32
reent_lvl
;
/* storage for reentry level value */
u32
save_addr
;
/* where to save or restore reentrant state */
u32
ext_ptr
;
/* pointer to extended glob_cfg data structure */
};
/* STI init function structs */
struct
sti_init_flags
{
u32
wait
:
1
;
/* should routine idle wait or not */
u32
reset
:
1
;
/* hard reset the device? */
u32
text
:
1
;
/* turn on text display planes? */
u32
nontext
:
1
;
/* turn on non-text display planes? */
u32
clear
:
1
;
/* clear text display planes? */
u32
cmap_blk
:
1
;
/* non-text planes cmap black? */
u32
enable_be_timer
:
1
;
/* enable bus error timer */
u32
enable_be_int
:
1
;
/* enable bus error timer interrupt */
u32
no_chg_tx
:
1
;
/* don't change text settings */
u32
no_chg_ntx
:
1
;
/* don't change non-text settings */
u32
no_chg_bet
:
1
;
/* don't change berr timer settings */
u32
no_chg_bei
:
1
;
/* don't change berr int settings */
u32
init_cmap_tx
:
1
;
/* initialize cmap for text planes */
u32
cmt_chg
:
1
;
/* change current monitor type */
u32
retain_ie
:
1
;
/* don't allow reset to clear int enables */
u32
caller_bootrom
:
1
;
/* set only by bootrom for each call */
u32
caller_kernel
:
1
;
/* set only by kernel for each call */
u32
caller_other
:
1
;
/* set only by non-[BR/K] caller */
u32
pad
:
14
;
/* pad to word boundary */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_init_inptr_ext
{
u8
config_mon_type
;
/* configure to monitor type */
u8
pad
[
1
];
/* pad to word boundary */
u16
inflight_data
;
/* inflight data possible on PCI */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_init_inptr
{
s32
text_planes
;
/* number of planes to use for text */
u32
ext_ptr
;
/* pointer to extended init_graph inptr data structure*/
};
struct
sti_init_outptr
{
s32
errno
;
/* error number on failure */
s32
text_planes
;
/* number of planes used for text */
u32
future_ptr
;
/* pointer to future data */
};
/* STI configuration function structs */
struct
sti_conf_flags
{
u32
wait
:
1
;
/* should routine idle wait or not */
u32
pad
:
31
;
/* pad to word boundary */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_conf_inptr
{
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_conf_outptr_ext
{
u32
crt_config
[
3
];
/* hardware specific X11/OGL information */
u32
crt_hdw
[
3
];
u32
future_ptr
;
};
struct
sti_conf_outptr
{
s32
errno
;
/* error number on failure */
s16
onscreen_x
;
/* screen width in pixels */
s16
onscreen_y
;
/* screen height in pixels */
s16
offscreen_x
;
/* offscreen width in pixels */
s16
offscreen_y
;
/* offscreen height in pixels */
s16
total_x
;
/* frame buffer width in pixels */
s16
total_y
;
/* frame buffer height in pixels */
s32
bits_per_pixel
;
/* bits/pixel device has configured */
s32
bits_used
;
/* bits which can be accessed */
s32
planes
;
/* number of fb planes in system */
u8
dev_name
[
STI_DEV_NAME_LENGTH
];
/* null terminated product name */
u32
attributes
;
/* flags denoting attributes */
u32
ext_ptr
;
/* pointer to future data */
};
struct
sti_rom
{
u8
type
[
4
];
u8
res004
;
u8
num_mons
;
u8
revno
[
2
];
u32
graphics_id
[
2
];
u32
font_start
;
u32
statesize
;
u32
last_addr
;
u32
region_list
;
u16
reentsize
;
u16
maxtime
;
u32
mon_tbl_addr
;
u32
user_data_addr
;
u32
sti_mem_req
;
u32
user_data_size
;
u16
power
;
u8
bus_support
;
u8
ext_bus_support
;
u8
alt_code_type
;
u8
ext_dd_struct
[
3
];
u32
cfb_addr
;
u32
init_graph
;
u32
state_mgmt
;
u32
font_unpmv
;
u32
block_move
;
u32
self_test
;
u32
excep_hdlr
;
u32
inq_conf
;
u32
set_cm_entry
;
u32
dma_ctrl
;
u8
res040
[
7
*
4
];
u32
init_graph_addr
;
u32
state_mgmt_addr
;
u32
font_unp_addr
;
u32
block_move_addr
;
u32
self_test_addr
;
u32
excep_hdlr_addr
;
u32
inq_conf_addr
;
u32
set_cm_entry_addr
;
u32
image_unpack_addr
;
u32
pa_risx_addrs
[
7
];
};
struct
sti_rom_font
{
u16
first_char
;
u16
last_char
;
u8
width
;
u8
height
;
u8
font_type
;
/* language type */
u8
bytes_per_char
;
u32
next_font
;
u8
underline_height
;
u8
underline_pos
;
u8
res008
[
2
];
};
/* sticore internal font handling */
struct
sti_cooked_font
{
struct
sti_rom_font
*
raw
;
struct
sti_cooked_font
*
next_font
;
};
struct
sti_cooked_rom
{
struct
sti_rom
*
raw
;
struct
sti_cooked_font
*
font_start
;
};
/* STI font printing function structs */
struct
sti_font_inptr
{
u32
font_start_addr
;
/* address of font start */
s16
index
;
/* index into font table of character */
u8
fg_color
;
/* foreground color of character */
u8
bg_color
;
/* background color of character */
s16
dest_x
;
/* X location of character upper left */
s16
dest_y
;
/* Y location of character upper left */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_font_flags
{
u32
wait
:
1
;
/* should routine idle wait or not */
u32
non_text
:
1
;
/* font unpack/move in non_text planes =1, text =0 */
u32
pad
:
30
;
/* pad to word boundary */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_font_outptr
{
s32
errno
;
/* error number on failure */
u32
future_ptr
;
/* pointer to future data */
};
/* STI blockmove structs */
struct
sti_blkmv_flags
{
u32
wait
:
1
;
/* should routine idle wait or not */
u32
color
:
1
;
/* change color during move? */
u32
clear
:
1
;
/* clear during move? */
u32
non_text
:
1
;
/* block move in non_text planes =1, text =0 */
u32
pad
:
28
;
/* pad to word boundary */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_blkmv_inptr
{
u8
fg_color
;
/* foreground color after move */
u8
bg_color
;
/* background color after move */
s16
src_x
;
/* source upper left pixel x location */
s16
src_y
;
/* source upper left pixel y location */
s16
dest_x
;
/* dest upper left pixel x location */
s16
dest_y
;
/* dest upper left pixel y location */
s16
width
;
/* block width in pixels */
s16
height
;
/* block height in pixels */
u32
future_ptr
;
/* pointer to future data */
};
struct
sti_blkmv_outptr
{
s32
errno
;
/* error number on failure */
u32
future_ptr
;
/* pointer to future data */
};
/* internal generic STI struct */
struct
sti_struct
{
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; */
int
sti_mem_request
;
u32
graphics_id
[
2
];
struct
sti_cooked_rom
*
rom
;
unsigned
long
font_unpmv
;
unsigned
long
block_move
;
unsigned
long
init_graph
;
unsigned
long
inq_conf
;
/* all following fields are initialized by the generic routines */
int
text_planes
;
region_t
regions
[
STI_REGION_MAX
];
unsigned
long
regions_phys
[
STI_REGION_MAX
];
struct
sti_glob_cfg
*
glob_cfg
;
struct
sti_cooked_font
*
font
;
/* ptr to selected font (cooked) */
struct
sti_conf_outptr
outptr
;
/* configuration */
struct
sti_conf_outptr_ext
outptr_ext
;
/* PCI data structures (pg. 17ff from sti.pdf) */
struct
pci_dev
*
pd
;
u8
rm_entry
[
16
];
/* pci region mapper array == pci config space offset */
};
/* helper functions */
struct
sti_struct
*
sti_init_roms
(
void
);
struct
sti_struct
*
sti_get_rom
(
int
);
void
sti_rom_copy
(
unsigned
long
base
,
unsigned
long
count
,
void
*
dest
);
struct
sti_cooked_font
*
sti_select_font
(
struct
sti_cooked_rom
*
rom
,
int
(
*
search_font_fnc
)
(
struct
sti_cooked_rom
*
,
int
,
int
)
);
int
sti_read_rom
(
int
wordmode
,
struct
sti_struct
*
sti
,
unsigned
long
address
);
/* FIXME: Do we have another solution for this ? */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
static
inline
void
sti_flush
(
unsigned
long
from
,
unsigned
long
len
)
{
flush_data_cache
();
flush_kernel_dcache_range
(
from
,
len
);
flush_icache_range
(
from
,
from
+
len
);
}
#endif
/* STICORE_H */
drivers/video/stifb.c
View file @
b58b80ea
/*
* linux/drivers/video/stifb.c - Generic frame buffer driver for HP
* workstations with STI (standard text interface) video firmware.
* linux/drivers/video/sti/stifb.c -
* Frame buffer driver for HP workstations with STI (standard text interface)
* video firmware.
*
* Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
* Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*
* Based on:
* linux/drivers/video/artistfb.c -- Artist frame buffer driver
*
* - linux/drivers/video/artistfb.c -- Artist frame buffer driver
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
*
* based on skeletonfb, which was
* - based on skeletonfb, which was
* Created 28 Dec 1997 by Geert Uytterhoeven
* - HP Xhp cfb-based X11 window driver for XFree86
* (c)Copyright 1992 Hewlett-Packard Co.
*
*
* The following graphics display devices (NGLE family) are supported by this driver:
*
* HPA4070A known as "HCRX", a 1280x1024 color device with 8 planes
* HPA4071A known as "HCRX24", a 1280x1024 color device with 24 planes,
* optionally available with a hardware accelerator as HPA4071A_Z
* HPA1659A known as "CRX", a 1280x1024 color device with 8 planes
* HPA1439A known as "CRX24", a 1280x1024 color device with 24 planes,
* optionally available with a hardware accelerator.
* HPA1924A known as "GRX", a 1280x1024 grayscale device with 8 planes
* HPA2269A known as "Dual CRX", a 1280x1024 color device with 8 planes,
* implements support for two displays on a single graphics card.
* HP710C internal graphics support optionally available on the HP9000s710 SPU,
* supports 1280x1024 color displays with 8 planes.
* HP710G same as HP710C, 1280x1024 grayscale only
* HP710L same as HP710C, 1024x768 color only
* HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
* 1024x768 or 1280x1024 color displays on 8 planes (Artist)
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details. */
* for more details.
*/
/*
*
Notes:
*
*
This driver assumes that the video has been set up in 1bpp mode by
*
the firmware. Since HP video tends to be planar rather than
*
packed-pixel this will probably work anyway even if it isn't.
/*
TODO:
*
- remove the static fb_info to support multiple cards
*
- remove the completely untested 1bpp mode
*
- add support for h/w acceleration
*
- add hardware cursor
*
-
*/
/* on supported graphic devices you may:
* #define FALLBACK_TO_1BPP to fall back to 1 bpp, or
* #undef FALLBACK_TO_1BPP to reject support for unsupported cards */
#undef FALLBACK_TO_1BPP
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
...
...
@@ -32,179 +64,1322 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb32.h>
#include <asm/grfioctl.h>
/* for HP-UX compatibility */
#include "sticore.h"
#include "sti.h"
#ifdef __LP64__
/* return virtual address */
#define REGION_BASE(fb_info, index) \
(fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000)
#else
/* return virtual address */
#define REGION_BASE(fb_info, index) \
fb_info->sti->glob_cfg->region_ptrs[index]
#endif
static
struct
fb_ops
stifb_ops
;
#define NGLEDEVDEPROM_CRT_REGION 1
typedef
struct
{
__s32
video_config_reg
;
__s32
misc_video_start
;
__s32
horiz_timing_fmt
;
__s32
serr_timing_fmt
;
__s32
vert_timing_fmt
;
__s32
horiz_state
;
__s32
vert_state
;
__s32
vtg_state_elements
;
__s32
pipeline_delay
;
__s32
misc_video_end
;
}
video_setup_t
;
typedef
struct
{
__s16
sizeof_ngle_data
;
__s16
x_size_visible
;
/* visible screen dim in pixels */
__s16
y_size_visible
;
__s16
pad2
[
15
];
__s16
cursor_pipeline_delay
;
__s16
video_interleaves
;
__s32
pad3
[
11
];
}
ngle_rom_t
;
struct
stifb_info
{
struct
fb_info_gen
gen
;
struct
fb_info
info
;
unsigned
int
id
;
ngle_rom_t
ngle_rom
;
struct
sti_struct
*
sti
;
int
deviceSpecificConfig
;
struct
display
disp
;
};
struct
stifb_par
{
};
static
int
stifb_force_bpp
[
MAX_STI_ROMS
]
=
{
0
,
};
static
struct
stifb_info
fb_info
;
static
struct
display
disp
;
/* ------------------- chipset specific functions -------------------------- */
int
stifb_init
(
void
);
int
stifb_setup
(
char
*
);
/* offsets to graphic-chip internal registers */
extern
struct
display_switch
fbcon_sti
;
#define REG_1 0x000118
#define REG_2 0x000480
#define REG_3 0x0004a0
#define REG_4 0x000600
#define REG_6 0x000800
#define REG_8 0x000820
#define REG_9 0x000a04
#define REG_10 0x018000
#define REG_11 0x018004
#define REG_12 0x01800c
#define REG_13 0x018018
#define REG_14 0x01801c
#define REG_15 0x200000
#define REG_15b0 0x200000
#define REG_16b1 0x200005
#define REG_16b3 0x200007
#define REG_21 0x200218
#define REG_22 0x0005a0
#define REG_23 0x0005c0
#define REG_26 0x200118
#define REG_27 0x200308
#define REG_32 0x21003c
#define REG_33 0x210040
#define REG_34 0x200008
#define REG_35 0x018010
#define REG_38 0x210020
#define REG_39 0x210120
#define REG_40 0x210130
#define REG_42 0x210028
#define REG_43 0x21002c
#define REG_44 0x210030
#define REG_45 0x210034
/* ------------------- chipset specific functions -------------------------- */
#define READ_BYTE(fb,reg) __raw_readb((fb)->info.fix.mmio_start + (reg))
#define READ_WORD(fb,reg) __raw_readl((fb)->info.fix.mmio_start + (reg))
#define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
#define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
static
int
sti_encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
void
*
par
,
struct
fb_info_gen
*
info
)
#define ENABLE 1
/* for enabling/disabling screen */
#define DISABLE 0
#define NGLE_LOCK(fb_info) do { } while (0)
#define NGLE_UNLOCK(fb_info) do { } while (0)
static
void
SETUP_HW
(
struct
stifb_info
*
fb
)
{
/* XXX: what about smem_len? */
fix
->
smem_start
=
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
region_ptrs
[
1
];
fix
->
type
=
FB_TYPE_PLANES
;
/* well, sort of */
char
stat
;
return
0
;
do
{
stat
=
READ_BYTE
(
fb
,
REG_15b0
);
if
(
!
stat
)
stat
=
READ_BYTE
(
fb
,
REG_15b0
);
}
while
(
stat
);
}
static
int
sti_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
void
*
par
,
struct
fb_info_gen
*
info
)
static
void
SETUP_FB
(
struct
stifb_info
*
fb
)
{
unsigned
int
reg10_value
=
0
;
SETUP_HW
(
fb
);
switch
(
fb
->
id
)
{
case
CRT_ID_VISUALIZE_EG
:
case
S9000_ID_ARTIST
:
case
S9000_ID_A1659A
:
reg10_value
=
0x13601000
;
break
;
case
S9000_ID_A1439A
:
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
reg10_value
=
0xBBA0A000
;
else
reg10_value
=
0x13601000
;
break
;
case
S9000_ID_HCRX
:
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
reg10_value
=
0xBBA0A000
;
else
reg10_value
=
0x13602000
;
break
;
case
S9000_ID_TIMBER
:
case
CRX24_OVERLAY_PLANES
:
reg10_value
=
0x13602000
;
break
;
}
if
(
reg10_value
)
WRITE_WORD
(
reg10_value
,
fb
,
REG_10
);
WRITE_WORD
(
0x83000300
,
fb
,
REG_14
);
SETUP_HW
(
fb
);
WRITE_BYTE
(
1
,
fb
,
REG_16b1
);
}
static
void
START_IMAGE_COLORMAP_ACCESS
(
struct
stifb_info
*
fb
)
{
return
0
;
SETUP_HW
(
fb
);
WRITE_WORD
(
0xBBE0F000
,
fb
,
REG_10
);
WRITE_WORD
(
0x03000300
,
fb
,
REG_14
);
WRITE_WORD
(
~
0
,
fb
,
REG_13
);
}
static
int
sti_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
void
*
par
,
struct
fb_info_gen
*
info
)
static
void
WRITE_IMAGE_COLOR
(
struct
stifb_info
*
fb
,
int
index
,
int
color
)
{
var
->
xres
=
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
onscreen_x
;
var
->
yres
=
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
onscreen_y
;
var
->
xres_virtual
=
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
total_x
;
var
->
yres_virtual
=
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
total_y
;
var
->
xoffset
=
var
->
yoffset
=
0
;
SETUP_HW
(
fb
);
WRITE_WORD
(((
0x100
+
index
)
<<
2
),
fb
,
REG_3
);
WRITE_WORD
(
color
,
fb
,
REG_4
);
}
var
->
bits_per_pixel
=
1
;
var
->
grayscale
=
0
;
static
void
FINISH_IMAGE_COLORMAP_ACCESS
(
struct
stifb_info
*
fb
)
{
WRITE_WORD
(
0x400
,
fb
,
REG_2
);
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
{
WRITE_WORD
(
0x83000100
,
fb
,
REG_1
);
}
else
{
if
(
fb
->
id
==
S9000_ID_ARTIST
||
fb
->
id
==
CRT_ID_VISUALIZE_EG
)
WRITE_WORD
(
0x80000100
,
fb
,
REG_26
);
else
WRITE_WORD
(
0x80000100
,
fb
,
REG_1
);
}
SETUP_FB
(
fb
);
}
return
0
;
static
void
SETUP_RAMDAC
(
struct
stifb_info
*
fb
)
{
SETUP_HW
(
fb
);
WRITE_WORD
(
0x04000000
,
fb
,
0x1020
);
WRITE_WORD
(
0xff000000
,
fb
,
0x1028
);
}
static
void
CRX24_SETUP_RAMDAC
(
struct
stifb_info
*
fb
)
{
SETUP_HW
(
fb
);
WRITE_WORD
(
0x04000000
,
fb
,
0x1000
);
WRITE_WORD
(
0x02000000
,
fb
,
0x1004
);
WRITE_WORD
(
0xff000000
,
fb
,
0x1008
);
WRITE_WORD
(
0x05000000
,
fb
,
0x1000
);
WRITE_WORD
(
0x02000000
,
fb
,
0x1004
);
WRITE_WORD
(
0x03000000
,
fb
,
0x1008
);
}
#if 0
static void
HCRX_SETUP_RAMDAC(struct stifb_info *fb)
{
WRITE_WORD(0xffffffff, fb, REG_32);
}
#endif
static
void
CRX24_SET_OVLY_MASK
(
struct
stifb_info
*
fb
)
{
SETUP_HW
(
fb
);
WRITE_WORD
(
0x13a02000
,
fb
,
REG_11
);
WRITE_WORD
(
0x03000300
,
fb
,
REG_14
);
WRITE_WORD
(
0x000017f0
,
fb
,
REG_3
);
WRITE_WORD
(
0xffffffff
,
fb
,
REG_13
);
WRITE_WORD
(
0xffffffff
,
fb
,
REG_22
);
WRITE_WORD
(
0x00000000
,
fb
,
REG_23
);
}
static
void
ENABLE_DISABLE_DISPLAY
(
struct
stifb_info
*
fb
,
int
enable
)
{
unsigned
int
value
=
enable
?
0x43000000
:
0x03000000
;
SETUP_HW
(
fb
);
WRITE_WORD
(
0x06000000
,
fb
,
0x1030
);
WRITE_WORD
(
value
,
fb
,
0x1038
);
}
static
void
CRX24_ENABLE_DISABLE_DISPLAY
(
struct
stifb_info
*
fb
,
int
enable
)
{
unsigned
int
value
=
enable
?
0x10000000
:
0x30000000
;
SETUP_HW
(
fb
);
WRITE_WORD
(
0x01000000
,
fb
,
0x1000
);
WRITE_WORD
(
0x02000000
,
fb
,
0x1004
);
WRITE_WORD
(
value
,
fb
,
0x1008
);
}
static
void
ARTIST_ENABLE_DISABLE_DISPLAY
(
struct
stifb_info
*
fb
,
int
enable
)
{
u32
DregsMiscVideo
=
REG_21
;
u32
DregsMiscCtl
=
REG_27
;
SETUP_HW
(
fb
);
if
(
enable
)
{
WRITE_WORD
(
READ_WORD
(
fb
,
DregsMiscVideo
)
|
0x0A000000
,
fb
,
DregsMiscVideo
);
WRITE_WORD
(
READ_WORD
(
fb
,
DregsMiscCtl
)
|
0x00800000
,
fb
,
DregsMiscCtl
);
}
else
{
WRITE_WORD
(
READ_WORD
(
fb
,
DregsMiscVideo
)
&
~
0x0A000000
,
fb
,
DregsMiscVideo
);
WRITE_WORD
(
READ_WORD
(
fb
,
DregsMiscCtl
)
&
~
0x00800000
,
fb
,
DregsMiscCtl
);
}
}
#define GET_ROMTABLE_INDEX(fb) \
(READ_BYTE(fb, REG_16b3) - 1)
#define HYPER_CONFIG_PLANES_24 0x00000100
#define IS_24_DEVICE(fb) \
(fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
#define IS_888_DEVICE(fb) \
(!(IS_24_DEVICE(fb)))
#define GET_FIFO_SLOTS(fb, cnt, numslots) \
{ while (cnt < numslots) \
cnt = READ_WORD(fb, REG_34); \
cnt -= numslots; \
}
#define IndexedDcd 0
/* Pixel data is indexed (pseudo) color */
#define Otc04 2
/* Pixels in each longword transfer (4) */
#define Otc32 5
/* Pixels in each longword transfer (32) */
#define Ots08 3
/* Each pixel is size (8)d transfer (1) */
#define OtsIndirect 6
/* Each bit goes through FG/BG color(8) */
#define AddrLong 5
/* FB address is Long aligned (pixel) */
#define BINovly 0x2
/* 8 bit overlay */
#define BINapp0I 0x0
/* Application Buffer 0, Indexed */
#define BINapp1I 0x1
/* Application Buffer 1, Indexed */
#define BINapp0F8 0xa
/* Application Buffer 0, Fractional 8-8-8 */
#define BINattr 0xd
/* Attribute Bitmap */
#define RopSrc 0x3
#define BitmapExtent08 3
/* Each write hits ( 8) bits in depth */
#define BitmapExtent32 5
/* Each write hits (32) bits in depth */
#define DataDynamic 0
/* Data register reloaded by direct access */
#define MaskDynamic 1
/* Mask register reloaded by direct access */
#define MaskOtc 0
/* Mask contains Object Count valid bits */
#define MaskAddrOffset(offset) (offset)
#define StaticReg(en) (en)
#define BGx(en) (en)
#define FGx(en) (en)
#define BAJustPoint(offset) (offset)
#define BAIndexBase(base) (base)
#define BA(F,C,S,A,J,B,I) \
(((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))
#define IBOvals(R,M,X,S,D,L,B,F) \
(((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))
#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, val) \
WRITE_WORD(val, fb, REG_14)
#define NGLE_QUICK_SET_DST_BM_ACCESS(fb, val) \
WRITE_WORD(val, fb, REG_11)
#define NGLE_QUICK_SET_CTL_PLN_REG(fb, val) \
WRITE_WORD(val, fb, REG_12)
#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, plnmsk32) \
WRITE_WORD(plnmsk32, fb, REG_13)
#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, fg32) \
WRITE_WORD(fg32, fb, REG_35)
#define NGLE_SET_TRANSFERDATA(fb, val) \
WRITE_WORD(val, fb, REG_8)
#define NGLE_SET_DSTXY(fb, val) \
WRITE_WORD(val, fb, REG_6)
#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) ( \
(u32) (fbaddrbase) + \
( (unsigned int) ( (y) << 13 ) | \
(unsigned int) ( (x) << 2 ) ) \
)
#define NGLE_BINC_SET_DSTADDR(fb, addr) \
WRITE_WORD(addr, fb, REG_3)
#define NGLE_BINC_SET_SRCADDR(fb, addr) \
WRITE_WORD(addr, fb, REG_2)
#define NGLE_BINC_SET_DSTMASK(fb, mask) \
WRITE_WORD(mask, fb, REG_22)
#define NGLE_BINC_WRITE32(fb, data32) \
WRITE_WORD(data32, fb, REG_23)
#define START_COLORMAPLOAD(fb, cmapBltCtlData32) \
WRITE_WORD((cmapBltCtlData32), fb, REG_38)
#define SET_LENXY_START_RECFILL(fb, lenxy) \
WRITE_WORD(lenxy, fb, REG_9)
static
void
HYPER_ENABLE_DISABLE_DISPLAY
(
struct
stifb_info
*
fb
,
int
enable
)
{
u32
DregsHypMiscVideo
=
REG_33
;
unsigned
int
value
;
SETUP_HW
(
fb
);
value
=
READ_WORD
(
fb
,
DregsHypMiscVideo
);
if
(
enable
)
value
|=
0x0A000000
;
else
value
&=
~
0x0A000000
;
WRITE_WORD
(
value
,
fb
,
DregsHypMiscVideo
);
}
/* BufferNumbers used by SETUP_ATTR_ACCESS() */
#define BUFF0_CMAP0 0x00001e02
#define BUFF1_CMAP0 0x02001e02
#define BUFF1_CMAP3 0x0c001e02
#define ARTIST_CMAP0 0x00000102
#define HYPER_CMAP8 0x00000100
#define HYPER_CMAP24 0x00000800
static
void
SETUP_ATTR_ACCESS
(
struct
stifb_info
*
fb
,
unsigned
BufferNumber
)
{
SETUP_HW
(
fb
);
WRITE_WORD
(
0x2EA0D000
,
fb
,
REG_11
);
WRITE_WORD
(
0x23000302
,
fb
,
REG_14
);
WRITE_WORD
(
BufferNumber
,
fb
,
REG_12
);
WRITE_WORD
(
0xffffffff
,
fb
,
REG_8
);
}
static
void
SET_ATTR_SIZE
(
struct
stifb_info
*
fb
,
int
width
,
int
height
)
{
WRITE_WORD
(
0x00000000
,
fb
,
REG_6
);
WRITE_WORD
((
width
<<
16
)
|
height
,
fb
,
REG_9
);
WRITE_WORD
(
0x05000000
,
fb
,
REG_6
);
WRITE_WORD
(
0x00040001
,
fb
,
REG_9
);
}
static
void
FINISH_ATTR_ACCESS
(
struct
stifb_info
*
fb
)
{
SETUP_HW
(
fb
);
WRITE_WORD
(
0x00000000
,
fb
,
REG_12
);
}
static
void
elkSetupPlanes
(
struct
stifb_info
*
fb
)
{
SETUP_RAMDAC
(
fb
);
SETUP_FB
(
fb
);
}
static
void
ngleSetupAttrPlanes
(
struct
stifb_info
*
fb
,
int
BufferNumber
)
{
SETUP_ATTR_ACCESS
(
fb
,
BufferNumber
);
SET_ATTR_SIZE
(
fb
,
fb
->
info
.
var
.
xres
,
fb
->
info
.
var
.
yres
);
FINISH_ATTR_ACCESS
(
fb
);
SETUP_FB
(
fb
);
}
static
void
sti_get_par
(
void
*
par
,
struct
fb_info_gen
*
info
)
rattlerSetupPlanes
(
struct
stifb_info
*
fb
)
{
CRX24_SETUP_RAMDAC
(
fb
);
/* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */
WRITE_WORD
(
0x83000300
,
fb
,
REG_14
);
SETUP_HW
(
fb
);
WRITE_BYTE
(
1
,
fb
,
REG_16b1
);
/* XXX: replace by fb_setmem(), smem_start or screen_base ? */
memset_io
(
fb
->
info
.
fix
.
smem_start
,
0xff
,
fb
->
info
.
var
.
yres
*
fb
->
info
.
fix
.
line_length
);
CRX24_SET_OVLY_MASK
(
fb
);
SETUP_FB
(
fb
);
}
#define HYPER_CMAP_TYPE 0
#define NGLE_CMAP_INDEXED0_TYPE 0
#define NGLE_CMAP_OVERLAY_TYPE 3
/* typedef of LUT (Colormap) BLT Control Register */
typedef
union
/* Note assumption that fields are packed left-to-right */
{
u32
all
;
struct
{
unsigned
enable
:
1
;
unsigned
waitBlank
:
1
;
unsigned
reserved1
:
4
;
unsigned
lutOffset
:
10
;
/* Within destination LUT */
unsigned
lutType
:
2
;
/* Cursor, image, overlay */
unsigned
reserved2
:
4
;
unsigned
length
:
10
;
}
fields
;
}
NgleLutBltCtl
;
#if 0
static NgleLutBltCtl
setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
{
NgleLutBltCtl lutBltCtl;
/* set enable, zero reserved fields */
lutBltCtl.all = 0x80000000;
lutBltCtl.fields.length = length;
switch (fb->id)
{
case S9000_ID_A1439A: /* CRX24 */
if (fb->var.bits_per_pixel == 8) {
lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE;
lutBltCtl.fields.lutOffset = 0;
} else {
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0 * 256;
}
break;
case S9000_ID_ARTIST:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0 * 256;
break;
default:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0;
break;
}
/* Offset points to start of LUT. Adjust for within LUT */
lutBltCtl.fields.lutOffset += offsetWithinLut;
return lutBltCtl;
}
#endif
static
NgleLutBltCtl
setHyperLutBltCtl
(
struct
stifb_info
*
fb
,
int
offsetWithinLut
,
int
length
)
{
NgleLutBltCtl
lutBltCtl
;
/* set enable, zero reserved fields */
lutBltCtl
.
all
=
0x80000000
;
lutBltCtl
.
fields
.
length
=
length
;
lutBltCtl
.
fields
.
lutType
=
HYPER_CMAP_TYPE
;
/* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
if
(
fb
->
info
.
var
.
bits_per_pixel
==
8
)
lutBltCtl
.
fields
.
lutOffset
=
2
*
256
;
else
lutBltCtl
.
fields
.
lutOffset
=
0
*
256
;
/* Offset points to start of LUT. Adjust for within LUT */
lutBltCtl
.
fields
.
lutOffset
+=
offsetWithinLut
;
return
lutBltCtl
;
}
static
void
hyperUndoITE
(
struct
stifb_info
*
fb
)
{
int
nFreeFifoSlots
=
0
;
u32
fbAddr
;
NGLE_LOCK
(
fb
);
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
1
);
WRITE_WORD
(
0xffffffff
,
fb
,
REG_32
);
/* Write overlay transparency mask so only entry 255 is transparent */
/* Hardware setup for full-depth write to "magic" location */
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
7
);
NGLE_QUICK_SET_DST_BM_ACCESS
(
fb
,
BA
(
IndexedDcd
,
Otc04
,
Ots08
,
AddrLong
,
BAJustPoint
(
0
),
BINovly
,
BAIndexBase
(
0
)));
NGLE_QUICK_SET_IMAGE_BITMAP_OP
(
fb
,
IBOvals
(
RopSrc
,
MaskAddrOffset
(
0
),
BitmapExtent08
,
StaticReg
(
0
),
DataDynamic
,
MaskOtc
,
BGx
(
0
),
FGx
(
0
)));
/* Now prepare to write to the "magic" location */
fbAddr
=
NGLE_LONG_FB_ADDRESS
(
0
,
1532
,
0
);
NGLE_BINC_SET_DSTADDR
(
fb
,
fbAddr
);
NGLE_REALLY_SET_IMAGE_PLANEMASK
(
fb
,
0xffffff
);
NGLE_BINC_SET_DSTMASK
(
fb
,
0xffffffff
);
/* Finally, write a zero to clear the mask */
NGLE_BINC_WRITE32
(
fb
,
0
);
NGLE_UNLOCK
(
fb
);
}
static
void
ngleDepth8_ClearImagePlanes
(
struct
stifb_info
*
fb
)
{
/* FIXME! */
}
static
void
ngleDepth24_ClearImagePlanes
(
struct
stifb_info
*
fb
)
{
/* FIXME! */
}
static
void
sti_set_par
(
const
void
*
par
,
struct
fb_info_gen
*
info
)
ngleResetAttrPlanes
(
struct
stifb_info
*
fb
,
unsigned
int
ctlPlaneReg
)
{
int
nFreeFifoSlots
=
0
;
u32
packed_dst
;
u32
packed_len
;
NGLE_LOCK
(
fb
);
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
4
);
NGLE_QUICK_SET_DST_BM_ACCESS
(
fb
,
BA
(
IndexedDcd
,
Otc32
,
OtsIndirect
,
AddrLong
,
BAJustPoint
(
0
),
BINattr
,
BAIndexBase
(
0
)));
NGLE_QUICK_SET_CTL_PLN_REG
(
fb
,
ctlPlaneReg
);
NGLE_SET_TRANSFERDATA
(
fb
,
0xffffffff
);
NGLE_QUICK_SET_IMAGE_BITMAP_OP
(
fb
,
IBOvals
(
RopSrc
,
MaskAddrOffset
(
0
),
BitmapExtent08
,
StaticReg
(
1
),
DataDynamic
,
MaskOtc
,
BGx
(
0
),
FGx
(
0
)));
packed_dst
=
0
;
packed_len
=
(
fb
->
info
.
var
.
xres
<<
16
)
|
fb
->
info
.
var
.
yres
;
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
2
);
NGLE_SET_DSTXY
(
fb
,
packed_dst
);
SET_LENXY_START_RECFILL
(
fb
,
packed_len
);
/*
* In order to work around an ELK hardware problem (Buffy doesn't
* always flush it's buffers when writing to the attribute
* planes), at least 4 pixels must be written to the attribute
* planes starting at (X == 1280) and (Y != to the last Y written
* by BIF):
*/
if
(
fb
->
id
==
S9000_ID_A1659A
)
{
/* ELK_DEVICE_ID */
/* It's safe to use scanline zero: */
packed_dst
=
(
1280
<<
16
);
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
2
);
NGLE_SET_DSTXY
(
fb
,
packed_dst
);
packed_len
=
(
4
<<
16
)
|
1
;
SET_LENXY_START_RECFILL
(
fb
,
packed_len
);
}
/* ELK Hardware Kludge */
/**** Finally, set the Control Plane Register back to zero: ****/
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
1
);
NGLE_QUICK_SET_CTL_PLN_REG
(
fb
,
0
);
NGLE_UNLOCK
(
fb
);
}
static
void
ngleClearOverlayPlanes
(
struct
stifb_info
*
fb
,
int
mask
,
int
data
)
{
int
nFreeFifoSlots
=
0
;
u32
packed_dst
;
u32
packed_len
;
NGLE_LOCK
(
fb
);
/* Hardware setup */
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
8
);
NGLE_QUICK_SET_DST_BM_ACCESS
(
fb
,
BA
(
IndexedDcd
,
Otc04
,
Ots08
,
AddrLong
,
BAJustPoint
(
0
),
BINovly
,
BAIndexBase
(
0
)));
NGLE_SET_TRANSFERDATA
(
fb
,
0xffffffff
);
/* Write foreground color */
NGLE_REALLY_SET_IMAGE_FG_COLOR
(
fb
,
data
);
NGLE_REALLY_SET_IMAGE_PLANEMASK
(
fb
,
mask
);
packed_dst
=
0
;
packed_len
=
(
fb
->
info
.
var
.
xres
<<
16
)
|
fb
->
info
.
var
.
yres
;
NGLE_SET_DSTXY
(
fb
,
packed_dst
);
/* Write zeroes to overlay planes */
NGLE_QUICK_SET_IMAGE_BITMAP_OP
(
fb
,
IBOvals
(
RopSrc
,
MaskAddrOffset
(
0
),
BitmapExtent08
,
StaticReg
(
0
),
DataDynamic
,
MaskOtc
,
BGx
(
0
),
FGx
(
0
)));
SET_LENXY_START_RECFILL
(
fb
,
packed_len
);
NGLE_UNLOCK
(
fb
);
}
static
void
hyperResetPlanes
(
struct
stifb_info
*
fb
,
int
enable
)
{
unsigned
int
controlPlaneReg
;
NGLE_LOCK
(
fb
);
if
(
IS_24_DEVICE
(
fb
))
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
controlPlaneReg
=
0x04000F00
;
else
controlPlaneReg
=
0x00000F00
;
/* 0x00000800 should be enought, but lets clear all 4 bits */
else
controlPlaneReg
=
0x00000F00
;
/* 0x00000100 should be enought, but lets clear all 4 bits */
switch
(
enable
)
{
case
1
:
/* ENABLE */
/* clear screen */
if
(
IS_24_DEVICE
(
fb
))
ngleDepth24_ClearImagePlanes
(
fb
);
else
ngleDepth8_ClearImagePlanes
(
fb
);
/* Paint attribute planes for default case.
* On Hyperdrive, this means all windows using overlay cmap 0. */
ngleResetAttrPlanes
(
fb
,
controlPlaneReg
);
/* clear overlay planes */
ngleClearOverlayPlanes
(
fb
,
0xff
,
255
);
/**************************************************
** Also need to counteract ITE settings
**************************************************/
hyperUndoITE
(
fb
);
break
;
case
0
:
/* DISABLE */
/* clear screen */
if
(
IS_24_DEVICE
(
fb
))
ngleDepth24_ClearImagePlanes
(
fb
);
else
ngleDepth8_ClearImagePlanes
(
fb
);
ngleResetAttrPlanes
(
fb
,
controlPlaneReg
);
ngleClearOverlayPlanes
(
fb
,
0xff
,
0
);
break
;
case
-
1
:
/* RESET */
hyperUndoITE
(
fb
);
ngleResetAttrPlanes
(
fb
,
controlPlaneReg
);
break
;
}
NGLE_UNLOCK
(
fb
);
}
/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
static
void
ngleGetDeviceRomData
(
struct
stifb_info
*
fb
)
{
#if 0
XXX: FIXME: !!!
int *pBytePerLongDevDepData;/* data byte == LSB */
int *pRomTable;
NgleDevRomData *pPackedDevRomData;
int sizePackedDevRomData = sizeof(*pPackedDevRomData);
char *pCard8;
int i;
char *mapOrigin = NULL;
int romTableIdx;
pPackedDevRomData = fb->ngle_rom;
SETUP_HW(fb);
if (fb->id == S9000_ID_ARTIST) {
pPackedDevRomData->cursor_pipeline_delay = 4;
pPackedDevRomData->video_interleaves = 4;
} else {
/* Get pointer to unpacked byte/long data in ROM */
pBytePerLongDevDepData = fb->sti->regions[NGLEDEVDEPROM_CRT_REGION];
/* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */
if (fb->id == S9000_ID_TOMCAT)
{
/* jump to the correct ROM table */
GET_ROMTABLE_INDEX(romTableIdx);
while (romTableIdx > 0)
{
pCard8 = (Card8 *) pPackedDevRomData;
pRomTable = pBytePerLongDevDepData;
/* Pack every fourth byte from ROM into structure */
for (i = 0; i < sizePackedDevRomData; i++)
{
*pCard8++ = (Card8) (*pRomTable++);
}
pBytePerLongDevDepData = (Card32 *)
((Card8 *) pBytePerLongDevDepData +
pPackedDevRomData->sizeof_ngle_data);
romTableIdx--;
}
}
pCard8 = (Card8 *) pPackedDevRomData;
/* Pack every fourth byte from ROM into structure */
for (i = 0; i < sizePackedDevRomData; i++)
{
*pCard8++ = (Card8) (*pBytePerLongDevDepData++);
}
}
SETUP_FB(fb);
#endif
}
#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES 4
#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE 8
#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE 10
#define HYPERBOWL_MODE2_8_24 15
/* HCRX specific boot-time initialization */
static
void
__init
SETUP_HCRX
(
struct
stifb_info
*
fb
)
{
int
hyperbowl
;
int
nFreeFifoSlots
=
0
;
if
(
fb
->
id
!=
S9000_ID_HCRX
)
return
;
/* Initialize Hyperbowl registers */
GET_FIFO_SLOTS
(
fb
,
nFreeFifoSlots
,
7
);
if
(
IS_24_DEVICE
(
fb
))
{
hyperbowl
=
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
?
HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE
:
HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE
;
/* First write to Hyperbowl must happen twice (bug) */
WRITE_WORD
(
hyperbowl
,
fb
,
REG_40
);
WRITE_WORD
(
hyperbowl
,
fb
,
REG_40
);
WRITE_WORD
(
HYPERBOWL_MODE2_8_24
,
fb
,
REG_39
);
WRITE_WORD
(
0x014c0148
,
fb
,
REG_42
);
/* Set lut 0 to be the direct color */
WRITE_WORD
(
0x404c4048
,
fb
,
REG_43
);
WRITE_WORD
(
0x034c0348
,
fb
,
REG_44
);
WRITE_WORD
(
0x444c4448
,
fb
,
REG_45
);
}
else
{
hyperbowl
=
HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES
;
/* First write to Hyperbowl must happen twice (bug) */
WRITE_WORD
(
hyperbowl
,
fb
,
REG_40
);
WRITE_WORD
(
hyperbowl
,
fb
,
REG_40
);
WRITE_WORD
(
0x00000000
,
fb
,
REG_42
);
WRITE_WORD
(
0x00000000
,
fb
,
REG_43
);
WRITE_WORD
(
0x00000000
,
fb
,
REG_44
);
WRITE_WORD
(
0x444c4048
,
fb
,
REG_45
);
}
}
/* ------------------- driver specific functions --------------------------- */
static
int
sti
_getcolreg
(
unsigned
regno
,
unsigned
*
red
,
unsigned
*
green
,
u
nsigned
*
blue
,
unsigned
*
transp
,
struct
fb_info
*
info
)
sti
fb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u
_int
blue
,
u_int
transp
,
struct
fb_info
*
info
)
{
struct
stifb_info
*
fb
=
(
struct
stifb_info
*
)
info
;
u32
color
;
if
(
regno
>=
256
)
/* no. of hw registers */
return
1
;
START_IMAGE_COLORMAP_ACCESS
(
fb
);
if
(
fb
->
info
.
var
.
grayscale
)
{
/* gray = 0.30*R + 0.59*G + 0.11*B */
color
=
((
red
*
77
)
+
(
green
*
151
)
+
(
blue
*
28
))
>>
8
;
}
else
{
color
=
((
red
<<
16
)
|
(
green
<<
8
)
|
(
blue
));
}
WRITE_IMAGE_COLOR
(
fb
,
regno
,
color
);
if
(
fb
->
id
==
S9000_ID_HCRX
)
{
NgleLutBltCtl
lutBltCtl
;
lutBltCtl
=
setHyperLutBltCtl
(
fb
,
0
,
/* Offset w/i LUT */
256
);
/* Load entire LUT */
NGLE_BINC_SET_SRCADDR
(
fb
,
NGLE_LONG_FB_ADDRESS
(
0
,
0x100
,
0
));
/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
START_COLORMAPLOAD
(
fb
,
lutBltCtl
.
all
);
SETUP_FB
(
fb
);
}
else
{
/* cleanup colormap hardware */
FINISH_IMAGE_COLORMAP_ACCESS
(
fb
);
}
return
0
;
}
#if 0
static void
sti_set_disp
(
const
void
*
par
,
struct
display
*
disp
,
struct
fb_info_gen
*
info
)
stifb_loadcmap(struct stifb_info *fb)
{
disp
->
dispsw
=
&
fbcon_sti
;
u32 color;
int i;
if (!fb->cmap_reload)
return;
START_IMAGE_COLORMAP_ACCESS(fb);
for (i = 0; i < 256; i++) {
if (fb->info.var.bits_per_pixel > 8) {
color = (i << 16) | (i << 8) | i;
} else {
if (fb->info.var.grayscale) {
/* gray = 0.30*R + 0.59*G + 0.11*B */
color = ((fb->palette[i].red * 77) +
(fb->palette[i].green * 151) +
(fb->palette[i].blue * 28)) >> 8;
} else {
color = ((fb->palette[i].red << 16) |
(fb->palette[i].green << 8) |
(fb->palette[i].blue));
}
}
WRITE_IMAGE_COLOR(fb, i, color);
}
if (fb->id == S9000_ID_HCRX) {
NgleLutBltCtl lutBltCtl;
lutBltCtl = setHyperLutBltCtl(fb,
0, /* Offset w/i LUT */
256); /* Load entire LUT */
NGLE_BINC_SET_SRCADDR(fb,
NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
START_COLORMAPLOAD(fb, lutBltCtl.all);
SETUP_FB(fb);
} else {
/* cleanup colormap hardware */
FINISH_IMAGE_COLORMAP_ACCESS(fb);
}
fb->cmap_reload = 0;
}
#endif
static
void
sti
_detect
(
void
)
static
int
sti
fb_blank
(
int
blank_mode
,
struct
fb_info
*
info
)
{
struct
stifb_info
*
fb
=
(
struct
stifb_info
*
)
info
;
int
enable
=
(
blank_mode
==
0
)
?
ENABLE
:
DISABLE
;
switch
(
fb
->
id
)
{
case
S9000_ID_A1439A
:
CRX24_ENABLE_DISABLE_DISPLAY
(
fb
,
enable
);
break
;
case
CRT_ID_VISUALIZE_EG
:
case
S9000_ID_ARTIST
:
ARTIST_ENABLE_DISABLE_DISPLAY
(
fb
,
enable
);
break
;
case
S9000_ID_HCRX
:
HYPER_ENABLE_DISABLE_DISPLAY
(
fb
,
enable
);
break
;
case
S9000_ID_A1659A
:;
/* fall through */
case
S9000_ID_TIMBER
:;
case
CRX24_OVERLAY_PLANES
:;
default:
ENABLE_DISABLE_DISPLAY
(
fb
,
enable
);
break
;
}
SETUP_FB
(
fb
);
return
0
;
}
static
void
__init
stifb_init_display
(
struct
stifb_info
*
fb
)
{
int
id
=
fb
->
id
;
SETUP_FB
(
fb
);
/* HCRX specific initialization */
SETUP_HCRX
(
fb
);
/*
if (id == S9000_ID_HCRX)
hyperInitSprite(fb);
else
ngleInitSprite(fb);
*/
/* Initialize the image planes. */
switch
(
id
)
{
case
S9000_ID_HCRX
:
hyperResetPlanes
(
fb
,
ENABLE
);
break
;
case
S9000_ID_A1439A
:
rattlerSetupPlanes
(
fb
);
break
;
case
S9000_ID_A1659A
:
case
S9000_ID_ARTIST
:
case
CRT_ID_VISUALIZE_EG
:
elkSetupPlanes
(
fb
);
break
;
}
/* Clear attribute planes on non HCRX devices. */
switch
(
id
)
{
case
S9000_ID_A1659A
:
case
S9000_ID_A1439A
:
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
ngleSetupAttrPlanes
(
fb
,
BUFF1_CMAP3
);
else
{
ngleSetupAttrPlanes
(
fb
,
BUFF1_CMAP0
);
}
if
(
id
==
S9000_ID_A1439A
)
ngleClearOverlayPlanes
(
fb
,
0xff
,
0
);
break
;
case
S9000_ID_ARTIST
:
case
CRT_ID_VISUALIZE_EG
:
if
(
fb
->
info
.
var
.
bits_per_pixel
==
32
)
ngleSetupAttrPlanes
(
fb
,
BUFF1_CMAP3
);
else
{
ngleSetupAttrPlanes
(
fb
,
ARTIST_CMAP0
);
}
break
;
}
stifb_blank
(
0
,
(
struct
fb_info
*
)
fb
);
/* 0=enable screen */
SETUP_FB
(
fb
);
}
/* ------------ Interfaces to hardware functions ------------ */
struct
fbgen_hwswitch
sti_switch
=
{
.
detect
=
sti_detect
,
.
encode_fix
=
sti_encode_fix
,
.
decode_var
=
sti_decode_var
,
.
encode_var
=
sti_encode_var
,
.
get_par
=
sti_get_par
,
.
set_par
=
sti_set_par
,
.
getcolreg
=
sti_getcolreg
,
.
set_disp
=
sti_set_disp
};
static
struct
fb_ops
stifb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_set_var
=
gen_set_var
,
.
fb_get_cmap
=
gen_get_cmap
,
.
fb_set_cmap
=
gen_set_cmap
,
.
fb_setcolreg
=
stifb_setcolreg
,
/* .fb_pan_display = stifb_pan_display, */
.
fb_blank
=
stifb_blank
,
/*
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
*/
};
/* ------------ Hardware Independent Functions ------------ */
/*
* Initialization
*/
int
__init
stifb_init
(
void
)
stifb_init
_fb
(
struct
sti_struct
*
sti
,
int
force_bpp
)
{
printk
(
"searching for word mode STI ROMs
\n
"
);
/* XXX: in the future this will return a list of ROMs */
if
((
fb_info
.
sti
=
sti_init_roms
())
==
NULL
)
return
-
ENXIO
;
fb_info
.
gen
.
info
.
node
=
NODEV
;
fb_info
.
gen
.
info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_info
.
gen
.
info
.
fbops
=
&
stifb_ops
;
fb_info
.
gen
.
info
.
disp
=
&
disp
;
fb_info
.
gen
.
info
.
changevar
=
NULL
;
fb_info
.
gen
.
info
.
switch_con
=
&
fbgen_switch
;
fb_info
.
gen
.
info
.
updatevar
=
&
fbgen_update_var
;
strcpy
(
fb_info
.
gen
.
info
.
modename
,
"STI Generic"
);
fb_info
.
gen
.
fbhw
=
&
sti_switch
;
fb_info
.
gen
.
fbhw
->
detect
();
fb_info
.
gen
.
info
.
screen_base
=
(
void
*
)
PTR_STI
(
fb_info
.
sti
->
glob_cfg
)
->
region_ptrs
[
1
];
/* This should give a reasonable default video mode */
fbgen_get_var
(
&
disp
.
var
,
-
1
,
&
fb_info
.
gen
.
info
);
fbgen_do_set_var
(
&
disp
.
var
,
1
,
&
fb_info
.
gen
);
fbgen_set_disp
(
-
1
,
&
fb_info
.
gen
);
do_install_cmap
(
0
,
&
fb_info
.
gen
);
pdc_console_die
();
if
(
register_framebuffer
(
&
fb_info
.
gen
.
info
)
<
0
)
return
-
EINVAL
;
printk
(
KERN_INFO
"fb%d: %s frame buffer device
\n
"
,
GET_FB_IDX
(
fb_info
.
gen
.
info
.
node
),
fb_info
.
gen
.
info
.
modename
);
struct
fb_fix_screeninfo
*
fix
;
struct
fb_var_screeninfo
*
var
;
struct
display
*
disp
;
struct
display_switch
*
dispsw
;
struct
stifb_info
*
fb
;
struct
fb_info
*
info
;
unsigned
long
sti_rom_address
;
char
*
dev_name
;
int
bpp
,
xres
,
yres
;
fb
=
kmalloc
(
sizeof
(
*
fb
),
GFP_ATOMIC
);
if
(
!
fb
)
{
printk
(
KERN_ERR
"stifb: Could not allocate stifb structure
\n
"
);
return
-
ENODEV
;
}
info
=
&
fb
->
info
;
/* set struct to a known state */
memset
(
fb
,
0
,
sizeof
(
*
fb
));
fix
=
&
info
->
fix
;
var
=
&
info
->
var
;
disp
=
&
fb
->
disp
;
info
->
disp
=
&
fb
->
disp
;
fb
->
sti
=
sti
;
/* store upper 32bits of the graphics id */
fb
->
id
=
fb
->
sti
->
graphics_id
[
0
];
/* only supported cards are allowed */
switch
(
fb
->
id
)
{
case
S9000_ID_ARTIST
:
case
S9000_ID_HCRX
:
case
S9000_ID_TIMBER
:
case
S9000_ID_A1659A
:
case
S9000_ID_A1439A
:
case
CRT_ID_VISUALIZE_EG
:
break
;
default:
printk
(
KERN_WARNING
"stifb: Unsupported gfx card id 0x%08x
\n
"
,
fb
->
id
);
goto
out_err1
;
}
/* default to 8 bpp on most graphic chips */
bpp
=
8
;
xres
=
sti_onscreen_x
(
fb
->
sti
);
yres
=
sti_onscreen_y
(
fb
->
sti
);
ngleGetDeviceRomData
(
fb
);
/* get (virtual) io region base addr */
fix
->
mmio_start
=
REGION_BASE
(
fb
,
2
);
fix
->
mmio_len
=
0x400000
;
/* Reject any device not in the NGLE family */
switch
(
fb
->
id
)
{
case
S9000_ID_A1659A
:
/* CRX/A1659A */
break
;
case
S9000_ID_ELM
:
/* GRX, grayscale but else same as A1659A */
var
->
grayscale
=
1
;
fb
->
id
=
S9000_ID_A1659A
;
break
;
case
S9000_ID_TIMBER
:
/* HP9000/710 Any (may be a grayscale device) */
dev_name
=
fb
->
sti
->
outptr
.
dev_name
;
if
(
strstr
(
dev_name
,
"GRAYSCALE"
)
||
strstr
(
dev_name
,
"Grayscale"
)
||
strstr
(
dev_name
,
"grayscale"
))
var
->
grayscale
=
1
;
break
;
case
S9000_ID_TOMCAT
:
/* Dual CRX, behaves else like a CRX */
/* FIXME: TomCat supports two heads:
* fb.iobase = REGION_BASE(fb_info,3);
* fb.screen_base = (void*) REGION_BASE(fb_info,2);
* for now we only support the left one ! */
xres
=
fb
->
ngle_rom
.
x_size_visible
;
yres
=
fb
->
ngle_rom
.
y_size_visible
;
fb
->
id
=
S9000_ID_A1659A
;
break
;
case
S9000_ID_A1439A
:
/* CRX24/A1439A */
bpp
=
32
;
break
;
case
S9000_ID_HCRX
:
/* Hyperdrive/HCRX */
memset
(
&
fb
->
ngle_rom
,
0
,
sizeof
(
fb
->
ngle_rom
));
if
((
fb
->
sti
->
regions_phys
[
0
]
&
0xfc000000
)
==
(
fb
->
sti
->
regions_phys
[
2
]
&
0xfc000000
))
sti_rom_address
=
fb
->
sti
->
regions_phys
[
0
];
else
sti_rom_address
=
fb
->
sti
->
regions_phys
[
1
];
#ifdef __LP64__
sti_rom_address
|=
0xffffffff00000000
;
#endif
fb
->
deviceSpecificConfig
=
__raw_readl
(
sti_rom_address
);
if
(
IS_24_DEVICE
(
fb
))
{
if
(
force_bpp
==
8
||
force_bpp
==
32
)
bpp
=
force_bpp
;
else
bpp
=
32
;
}
else
bpp
=
8
;
READ_WORD
(
fb
,
REG_15
);
SETUP_HW
(
fb
);
break
;
case
CRT_ID_VISUALIZE_EG
:
case
S9000_ID_ARTIST
:
/* Artist */
break
;
default:
#ifdef FALLBACK_TO_1BPP
printk
(
KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- now trying 1bpp mode instead
\n
"
,
fb
->
id
);
bpp
=
1
;
/* default to 1 bpp */
break
;
#else
printk
(
KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- skipping.
\n
"
,
fb
->
id
);
goto
out_err1
;
#endif
}
/* get framebuffer pysical and virtual base addr & len (64bit ready) */
fix
->
smem_start
=
fb
->
sti
->
regions_phys
[
1
]
|
0xffffffff00000000
;
fix
->
smem_len
=
fb
->
sti
->
regions
[
1
].
region_desc
.
length
*
4096
;
fix
->
line_length
=
(
fb
->
sti
->
glob_cfg
->
total_x
*
bpp
)
/
8
;
if
(
!
fix
->
line_length
)
fix
->
line_length
=
2048
;
/* default */
fix
->
accel
=
FB_ACCEL_NONE
;
switch
(
bpp
)
{
case
1
:
fix
->
type
=
FB_TYPE_PLANES
;
/* well, sort of */
fix
->
visual
=
FB_VISUAL_MONO10
;
dispsw
=
&
fbcon_sti
;
break
;
#ifdef FBCON_HAS_CFB8
case
8
:
fix
->
type
=
FB_TYPE_PACKED_PIXELS
;
fix
->
visual
=
FB_VISUAL_PSEUDOCOLOR
;
dispsw
=
&
fbcon_cfb8
;
var
->
red
.
length
=
var
->
green
.
length
=
var
->
blue
.
length
=
8
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
fix
->
type
=
FB_TYPE_PACKED_PIXELS
;
fix
->
visual
=
FB_VISUAL_TRUECOLOR
;
dispsw
=
&
fbcon_cfb32
;
var
->
red
.
length
=
var
->
green
.
length
=
var
->
blue
.
length
=
var
->
transp
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
green
.
offset
=
8
;
var
->
red
.
offset
=
16
;
var
->
transp
.
offset
=
24
;
break
;
#endif
default:
dispsw
=
&
fbcon_dummy
;
break
;
}
var
->
xres
=
var
->
xres_virtual
=
xres
;
var
->
yres
=
var
->
yres_virtual
=
yres
;
var
->
bits_per_pixel
=
bpp
;
strcpy
(
info
->
modename
,
"stifb"
);
info
->
node
=
NODEV
;
info
->
fbops
=
&
stifb_ops
;
info
->
screen_base
=
(
void
*
)
REGION_BASE
(
fb
,
1
);
info
->
disp
=
disp
;
info
->
changevar
=
NULL
;
info
->
switch_con
=
gen_switch
;
info
->
updatevar
=
&
gen_update_var
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
currcon
=
-
1
;
/* This has to been done !!! */
fb_alloc_cmap
(
&
info
->
cmap
,
256
,
0
);
stifb_init_display
(
fb
);
gen_set_disp
(
-
1
,
info
);
disp
->
dispsw
=
dispsw
;
if
(
!
request_mem_region
(
fix
->
smem_start
,
fix
->
smem_len
,
"stifb"
))
{
printk
(
KERN_ERR
"stifb: cannot reserve fb region 0x%04lx-0x%04lx
\n
"
,
fix
->
smem_start
,
fix
->
smem_start
+
fix
->
smem_len
);
goto
out_err1
;
}
if
(
!
request_mem_region
(
fix
->
mmio_start
,
fix
->
mmio_len
,
"stifb mmio"
))
{
printk
(
KERN_ERR
"stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx
\n
"
,
fix
->
mmio_start
,
fix
->
mmio_start
+
fix
->
mmio_len
);
goto
out_err2
;
}
if
(
register_framebuffer
(
&
fb
->
info
)
<
0
)
goto
out_err3
;
printk
(
KERN_INFO
"fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx
\n
"
,
GET_FB_IDX
(
fb
->
info
.
node
),
fb
->
info
.
modename
,
disp
->
var
.
xres
,
disp
->
var
.
yres
,
disp
->
var
.
bits_per_pixel
,
fb
->
id
,
fix
->
mmio_start
);
return
0
;
}
/*
* Cleanup
*/
out_err3:
release_mem_region
(
fix
->
mmio_start
,
fix
->
mmio_len
);
out_err2:
release_mem_region
(
fix
->
smem_start
,
fix
->
smem_len
);
out_err1:
kfree
(
fb
);
return
-
ENXIO
;
}
void
stifb_
cleanup
(
struct
fb_info
*
info
)
int
__init
stifb_
init
(
void
)
{
printk
(
"stifb_cleanup: you're on crack
\n
"
);
struct
sti_struct
*
sti
;
int
i
;
if
(
sti_init_roms
()
==
NULL
)
return
-
ENXIO
;
/* no STI cards available */
for
(
i
=
0
;
i
<
MAX_STI_ROMS
;
i
++
)
{
sti
=
sti_get_rom
(
i
);
if
(
sti
)
stifb_init_fb
(
sti
,
stifb_force_bpp
[
i
]);
else
break
;
}
return
0
;
}
/*
* Cleanup
*/
static
void
__exit
stifb_cleanup
(
void
)
{
// unregister_framebuffer();
}
int
__init
stifb_setup
(
char
*
options
)
{
/* XXX: we should take the resolution, bpp as command line arguments. */
int
i
;
if
(
!
options
||
!*
options
)
return
0
;
if
(
strncmp
(
options
,
"bpp"
,
3
)
==
0
)
{
options
+=
3
;
for
(
i
=
0
;
i
<
MAX_STI_ROMS
;
i
++
)
{
if
(
*
options
++
==
':'
)
stifb_force_bpp
[
i
]
=
simple_strtoul
(
options
,
&
options
,
10
);
else
break
;
}
}
return
0
;
}
__setup
(
"stifb="
,
stifb_setup
);
/* ------------------------------------------------------------------------- */
#ifdef MODULE
module_init
(
stifb_init
);
#endif
module_exit
(
stifb_cleanup
);
MODULE_AUTHOR
(
"Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>"
);
MODULE_DESCRIPTION
(
"Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
bpp
,
"i"
);
MODULE_PARM_DESC
(
mem
,
"Bits per pixel (default: 8)"
);
static
struct
fb_ops
stifb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_get_fix
=
fbgen_get_fix
,
.
fb_get_var
=
fbgen_get_var
,
.
fb_set_var
=
fbgen_set_var
,
.
fb_get_cmap
=
fbgen_get_cmap
,
.
fb_set_cmap
=
gen_set_cmap
,
.
fb_pan_display
=
fbgen_pan_display
,
.
fb_blank
=
fbgen_blank
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment