* platinum video makes me cry...
@ 1999-07-08 12:04 Mark Abene
1999-07-08 18:29 ` Hollis R Blanchard
0 siblings, 1 reply; 7+ messages in thread
From: Mark Abene @ 1999-07-08 12:04 UTC (permalink / raw)
To: linuxppc-dev
The good news is that I finally got around to installing linuxppc-1999 (R5)
on my 7200. The BAD news is that much to my chagrin, the changes I made to
fix the platinum video driver in the newer kernels (which I submitted to the
code maintainer nearly a month ago, if not more) are NOT present in R5!
I was greeted by the sickly-looking psychedelic arch-nemesis of Tux the penguin.
Suffice to say, gnome came up looking like a bad acid trip.
Sooooo, I'm rebuilding my kernel to make things right, but I'm irritated that
all you proud 7200/8200/PT120 users out there were let down.
If anyone out there is using one of these wonderful machines and is still
plagued by the psychedic penguin syndrome in 16 or 32 bpp, let me know, and
I'll stick the repaired platinumfb.c file somewhere for ya, or just e-mail it.
Credit where credit is due: even though our good Mr. Herrenschmidt is busy
making life easier for so many with BootX, he still came through and obviously
made sure my fixes for the TurboMouse 5 trackball were committed. My mouse is
doing The Right Thing. (Thanks Ben! :)
I'll be the first one to admit that we all get busy with Real Life stuff, it
just made me sad to see the console colors still all mucked-up.
Anyway, it's 8am here in NYC, and I've been up all night.
If I've offended anyone with my rant, I apologize in advance.
Feel free to mentally replace this message with "mouse good, console bad".
Good night, all.
-Mark
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
1999-07-08 12:04 platinum video makes me cry Mark Abene
@ 1999-07-08 18:29 ` Hollis R Blanchard
1999-07-09 13:32 ` Tom Rini
[not found] ` <Pine.BSF.3.96.990709093050.70746F-100000@silver.teardrop.n et>
0 siblings, 2 replies; 7+ messages in thread
From: Hollis R Blanchard @ 1999-07-08 18:29 UTC (permalink / raw)
To: Mark Abene; +Cc: linuxppc-dev
On Thu, 8 Jul 1999, Mark Abene wrote:
>
> The good news is that I finally got around to installing linuxppc-1999 (R5)
> on my 7200. The BAD news is that much to my chagrin, the changes I made to
> fix the platinum video driver in the newer kernels (which I submitted to the
> code maintainer nearly a month ago, if not more) are NOT present in R5!
> I was greeted by the sickly-looking psychedelic arch-nemesis of Tux the
> penguin.
> Suffice to say, gnome came up looking like a bad acid trip.
Strangely enough, the kernel the installer uses was right. I was very
pleasently surprised to see Tux in the correct colors when I went to install.
Of course, the kernel the installer actually installs is screwed up in this
respect.
-Hollis
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
1999-07-08 18:29 ` Hollis R Blanchard
@ 1999-07-09 13:32 ` Tom Rini
1999-07-09 13:50 ` Mark Abene
[not found] ` <Pine.BSF.3.96.990709093050.70746F-100000@silver.teardrop.n et>
1 sibling, 1 reply; 7+ messages in thread
From: Tom Rini @ 1999-07-09 13:32 UTC (permalink / raw)
To: Hollis R Blanchard; +Cc: Mark Abene, linuxppc-dev
On Thu, 8 Jul 1999, Hollis R Blanchard wrote:
>
> On Thu, 8 Jul 1999, Mark Abene wrote:
> >
> > The good news is that I finally got around to installing linuxppc-1999 (R5)
> > on my 7200. The BAD news is that much to my chagrin, the changes I made to
> > fix the platinum video driver in the newer kernels (which I submitted to the
> > code maintainer nearly a month ago, if not more) are NOT present in R5!
> > I was greeted by the sickly-looking psychedelic arch-nemesis of Tux the
> > penguin.
> > Suffice to say, gnome came up looking like a bad acid trip.
>
> Strangely enough, the kernel the installer uses was right. I was very
> pleasently surprised to see Tux in the correct colors when I went to install.
> Of course, the kernel the installer actually installs is screwed up in this
> respect.
Well, 1) Did the installer endup using no video driver? (I still don't
have a CD pair, have to bug jeff again once i settle in) 2) iirc, about a
month ago Geert (the video maintainer) was working towards his PhD and
could have easily lost the mail. 3) Where is the patch anyhow, there'll no
doubt be a kernel upgrade "soon" :)
---
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
1999-07-09 13:32 ` Tom Rini
@ 1999-07-09 13:50 ` Mark Abene
1999-08-02 15:39 ` Jerry Quinn
0 siblings, 1 reply; 7+ messages in thread
From: Mark Abene @ 1999-07-09 13:50 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 645 bytes --]
I'll attach the "current" platinumfb.c file in its entirety. Although I've
just been informed (and I've verified) that 32bpp doesn't work. I didn't
originally notice because I normally use vmode 20 16, and hadn't checked
32bpp. So the changes only fix 16bpp (8 still works as before).
I'm looking into why 32bpp doesn't work. I'm still irritated at how much
abstraction was done to make the driver "FBDev-aware". It was so much simpler
in 2.1.24, when ALL recognized modes worked in ALL available bit-depths.
Now I'm playing catch-up since I was previously much too busy to know what
was going on with newer kernels and FBDev.
Ugh.
-Mark
[-- Attachment #2: platinumfb.c --]
[-- Type: text/plain, Size: 26264 bytes --]
/*
* platinumfb.c -- frame buffer device for the PowerMac 'platinum' display
*
* Copyright (C) 1998 Franz Sirl
*
* Frame buffer structure from:
* drivers/video/controlfb.c -- frame buffer device for
* Apple 'control' display chip.
* Copyright (C) 1998 Dan Jacobowitz
*
* Hardware information from:
* platinum.c: Console support for PowerMac "platinum" display adaptor.
* Copyright (C) 1996 Paul Mackerras and Mark Abene
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/selection.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/nvram.h>
#ifdef CONFIG_FB_COMPAT_XPMAC
#include <asm/vc_ioctl.h>
#endif
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pgtable.h>
#include <asm/adb.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#include <video/macmodes.h>
#include "platinumfb.h"
static char fontname[40] __initdata = { 0 };
static int currcon = 0;
static int default_vmode = VMODE_NVRAM;
static int default_cmode = CMODE_NVRAM;
struct fb_par_platinum {
int vmode, cmode;
int xres, yres;
int vxres, vyres;
int xoffset, yoffset;
};
struct fb_info_platinum {
struct fb_info fb_info;
struct display disp;
struct fb_par_platinum default_par;
struct fb_par_platinum current_par;
struct {
__u8 red, green, blue;
} palette[256];
volatile struct cmap_regs *cmap_regs;
unsigned long cmap_regs_phys;
volatile struct platinum_regs *platinum_regs;
unsigned long platinum_regs_phys;
__u8 *frame_buffer;
volatile __u8 *base_frame_buffer;
unsigned long frame_buffer_phys;
unsigned long total_vram;
int clktype;
int dactype;
union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
#endif
#ifdef FBCON_HAS_CFB32
u32 cfb32[16];
#endif
} fbcon_cmap;
};
/*
* Frame buffer device API
*/
static int platinum_open(struct fb_info *info, int user);
static int platinum_release(struct fb_info *info, int user);
static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *fb);
static int platinum_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *fb);
static int platinum_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *fb);
static int platinum_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *fb);
static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int platinum_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info);
/*
* Interface to the low level console driver
*/
static int platinum_switch(int con, struct fb_info *fb);
static int platinum_updatevar(int con, struct fb_info *fb);
static void platinum_blank(int blank, struct fb_info *fb);
/*
* internal functions
*/
static inline int platinum_vram_reqd(int video_mode, int color_mode);
static int read_platinum_sense(struct fb_info_platinum *info);
static void set_platinum_clock(struct fb_info_platinum *info);
static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_platinum *info);
static int platinum_par_to_var(struct fb_var_screeninfo *var,
const struct fb_par_platinum *par,
const struct fb_info_platinum *info);
static int platinum_var_to_par(const struct fb_var_screeninfo *var,
struct fb_par_platinum *par,
const struct fb_info_platinum *info);
static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
const struct fb_par_platinum *par,
const struct fb_info_platinum *info);
static int platinum_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *fb);
static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *fb);
static void do_install_cmap(int con, struct fb_info *info);
/*
* Interface used by the world
*/
void platinum_init(void);
#ifdef CONFIG_FB_OF
void platinum_of_init(struct device_node *dp);
#endif
void platinum_setup(char *options, int *ints);
static struct fb_ops platinumfb_ops = {
platinum_open,
platinum_release,
platinum_get_fix,
platinum_get_var,
platinum_set_var,
platinum_get_cmap,
platinum_set_cmap,
platinum_pan_display,
platinum_ioctl
};
__openfirmware
static int platinum_open(struct fb_info *info, int user)
{
MOD_INC_USE_COUNT;
return 0;
}
static int platinum_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return 0;
}
static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *fb)
{
const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
struct fb_par_platinum par;
if (con == -1)
par = info->default_par;
else
platinum_var_to_par(&fb_display[con].var, &par, info);
platinum_encode_fix(fix, &par, info);
return 0;
}
static int platinum_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *fb)
{
const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
if (con == -1)
platinum_par_to_var(var, &info->default_par, info);
else
*var = fb_display[con].var;
return 0;
}
static int platinum_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *fb)
{
struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
struct fb_par_platinum par;
struct display *display;
int oldxres, oldyres, oldvxres, oldvyres, oldbpp, err;
int activate = var->activate;
struct platinum_regvals *init;
display = (con >= 0) ? &fb_display[con] : fb->disp;
if((err = platinum_var_to_par(var, &par, info))) {
printk(KERN_ERR "platinum_set_var: error calling platinum_var_to_par: %d.\n", err);
return err;
}
platinum_par_to_var(var, &par, info);
if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
printk(KERN_INFO "platinum_set_var: Not activating.\n");
return 0;
}
init = platinum_reg_init[par.vmode-1];
oldxres = display->var.xres;
oldyres = display->var.yres;
oldvxres = display->var.xres_virtual;
oldvyres = display->var.yres_virtual;
oldbpp = display->var.bits_per_pixel;
display->var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual || oldyres != var->yres_virtual ||
oldbpp != var->bits_per_pixel) {
struct fb_fix_screeninfo fix;
platinum_encode_fix(&fix, &par, info);
/*display->screen_base = (char *) info->frame_buffer + 0x1000;*/
/*display->screen_base = (char *) fix.smem_start;*/
display->screen_base = (char *) info->frame_buffer + init->fb_offset + 0x20;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
display->ypanstep = fix.ypanstep;
display->ywrapstep = fix.ywrapstep;
display->line_length = fix.line_length;
display->can_soft_blank = 1;
display->inverse = 0;
switch(par.cmode) {
#ifdef FBCON_HAS_CFB8
case CMODE_8:
display->dispsw = &fbcon_cfb8;
break;
#endif
#ifdef FBCON_HAS_CFB16
case CMODE_16:
display->dispsw = &fbcon_cfb16;
display->dispsw_data = info->fbcon_cmap.cfb16;
break;
#endif
#ifdef FBCON_HAS_CFB32
case CMODE_32:
display->dispsw = &fbcon_cfb32;
display->dispsw_data = info->fbcon_cmap.cfb32;
break;
#endif
default:
display->dispsw = &fbcon_dummy;
break;
}
display->scrollmode = SCROLL_YREDRAW;
if (info->fb_info.changevar)
(*info->fb_info.changevar)(con);
}
if (con == currcon)
platinum_set_par(&par, info);
if (oldbpp != var->bits_per_pixel) {
if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
return err;
do_install_cmap(con, &info->fb_info);
}
return 0;
}
static int platinum_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
/*
* Pan (or wrap, depending on the `vmode' field) the display using the
* `xoffset' and `yoffset' fields of the `var' structure.
* If the values don't fit, return -EINVAL.
*/
if (var->xoffset != 0 || var->yoffset != 0)
return -EINVAL;
return 0;
}
static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
if (con == currcon) /* current console? */
return fb_get_cmap(cmap, kspc, platinum_getcolreg, info);
if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else {
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
}
return 0;
}
static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
int err;
if (!fb_display[con].cmap.len) {
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
err = fb_alloc_cmap(&fb_display[con].cmap, size, 0);
if (err)
return err;
}
if (con == currcon)
return fb_set_cmap(cmap, kspc, platinum_setcolreg, info);
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
}
static int platinum_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info)
{
printk(KERN_ERR "platinum_ioctl not yet implemented\n");
return -EINVAL;
}
static int platinum_switch(int con, struct fb_info *fb)
{
struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
struct fb_par_platinum par;
if (fb_display[currcon].cmap.len)
fb_get_cmap(&fb_display[currcon].cmap, 1, platinum_getcolreg,
fb);
currcon = con;
platinum_var_to_par(&fb_display[currcon].var, &par, info);
platinum_set_par(&par, info);
do_install_cmap(con, fb);
return 1;
}
static int platinum_updatevar(int con, struct fb_info *fb)
{
printk(KERN_ERR "platinum_updatevar is doing nothing yet.\n");
return 0;
}
static void platinum_blank(int blank, struct fb_info *fb)
{
/*
* Blank the screen if blank_mode != 0, else unblank. If blank == NULL
* then the caller blanks by setting the CLUT (Color Look Up Table) to all
* black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
* to e.g. a video mode which doesn't support it. Implements VESA suspend
* and powerdown modes on hardware that supports disabling hsync/vsync:
* blank_mode == 2: suspend vsync
* blank_mode == 3: suspend hsync
* blank_mode == 4: powerdown
*/
/* [danj] I think there's something fishy about those constants... */
/*
struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
int ctrl;
ctrl = ld_le32(&info->platinum_regs->ctrl.r) | 0x33;
if (blank)
--blank_mode;
if (blank & VESA_VSYNC_SUSPEND)
ctrl &= ~3;
if (blank & VESA_HSYNC_SUSPEND)
ctrl &= ~0x30;
out_le32(&info->platinum_regs->ctrl.r, ctrl);
*/
/* TODO: Figure out how the heck to powerdown this thing! */
return;
}
static int platinum_getcolreg(u_int regno, u_int *red, u_int *green,
u_int *blue, u_int *transp, struct fb_info *fb)
{
struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
if (regno > 255)
return 1;
*red = (info->palette[regno].red<<8) | info->palette[regno].red;
*green = (info->palette[regno].green<<8) | info->palette[regno].green;
*blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
*transp = 0;
return 0;
}
static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *fb)
{
struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
volatile struct cmap_regs *cmap_regs = info->cmap_regs;
/* int scale; */
if (regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
info->palette[regno].red = red;
info->palette[regno].green = green;
info->palette[regno].blue = blue;
/* scale = (info->current_par.cmode == CMODE_16) ? 3 : 0; */
out_8(&cmap_regs->addr, regno); /* tell clut what addr to fill */
out_8(&cmap_regs->lut, red); /* send one color channel at */
out_8(&cmap_regs->lut, green); /* a time... */
out_8(&cmap_regs->lut, blue);
if(regno < 16) {
#ifdef FBCON_HAS_CFB16
info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | (regno << 0);
#endif
#ifdef FBCON_HAS_CFB32
info->fbcon_cmap.cfb32[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
#endif
}
return 0;
}
static void do_install_cmap(int con, struct fb_info *info)
{
if (con != currcon)
return;
if (fb_display[con].cmap.len)
fb_set_cmap(&fb_display[con].cmap, 1, platinum_setcolreg,
info);
else {
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
fb_set_cmap(fb_default_cmap(size), 1, platinum_setcolreg,
info);
}
}
static inline int platinum_vram_reqd(int video_mode, int color_mode)
{
return vmode_attrs[video_mode-1].vres *
(vmode_attrs[video_mode-1].hres * (1<<color_mode) + 0x20) +0x1000;
}
#define STORE_D2(a, d) { \
out_8(&cmap_regs->addr, (a+32)); \
out_8(&cmap_regs->d2, (d)); \
}
static void set_platinum_clock(struct fb_info_platinum *info)
{
volatile struct cmap_regs *cmap_regs = info->cmap_regs;
struct platinum_regvals *init;
init = platinum_reg_init[info->current_par.vmode-1];
STORE_D2(6, 0xc6);
out_8(&cmap_regs->addr,3+32);
if (in_8(&cmap_regs->d2) == 2) {
STORE_D2(7, init->clock_params[info->clktype][0]);
STORE_D2(8, init->clock_params[info->clktype][1]);
STORE_D2(3, 3);
} else {
STORE_D2(4, init->clock_params[info->clktype][0]);
STORE_D2(5, init->clock_params[info->clktype][1]);
STORE_D2(3, 2);
}
__delay(5000);
STORE_D2(9, 0xa6);
}
/* Now how about actually saying, Make it so! */
/* Some things in here probably don't need to be done each time. */
static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_platinum *info)
{
volatile struct platinum_regs *platinum_regs = info->platinum_regs;
volatile struct cmap_regs *cmap_regs = info->cmap_regs;
struct platinum_regvals *init;
int i;
int vmode, cmode;
info->current_par = *par;
vmode = par->vmode;
cmode = par->cmode;
init = platinum_reg_init[vmode - 1];
/* Initialize display timing registers */
out_be32(&platinum_regs->reg[24].r, 7); /* turn display off */
for (i = 0; i < 26; ++i)
out_be32(&platinum_regs->reg[i+32].r, init->regs[i]);
out_be32(&platinum_regs->reg[26+32].r, (info->total_vram == 0x100000 ?
init->offset[cmode] + 4 - cmode :
init->offset[cmode]));
/*out_be32(&platinum_regs->reg[16].r, (unsigned) info->frame_buffer_phys + 0x1000 - 0x10);*/
out_be32(&platinum_regs->reg[16].r, (unsigned) info->frame_buffer_phys+init->fb_offset+0x10);
out_be32(&platinum_regs->reg[18].r, init->pitch[cmode]);
out_be32(&platinum_regs->reg[19].r, (info->total_vram == 0x100000 ?
init->mode[cmode+1] :
init->mode[cmode]));
out_be32(&platinum_regs->reg[20].r, (info->total_vram == 0x100000 ? 0x11 : 0x1011));
out_be32(&platinum_regs->reg[21].r, 0x100);
out_be32(&platinum_regs->reg[22].r, 1);
out_be32(&platinum_regs->reg[23].r, 1);
out_be32(&platinum_regs->reg[26].r, 0xc00);
out_be32(&platinum_regs->reg[27].r, 0x235);
/* out_be32(&platinum_regs->reg[27].r, 0x2aa); */
STORE_D2(0, (info->total_vram == 0x100000 ?
init->dacula_ctrl[cmode] & 0xf :
init->dacula_ctrl[cmode]));
STORE_D2(1, 4);
STORE_D2(2, 0);
set_platinum_clock(info);
out_be32(&platinum_regs->reg[24].r, 0); /* turn display on */
#ifdef CONFIG_FB_COMPAT_XPMAC
if (console_fb_info == &info->fb_info) {
display_info.height = par->yres;
display_info.width = par->xres;
display_info.depth = ( (cmode == CMODE_32) ? 32 :
((cmode == CMODE_16) ? 16 : 8));
display_info.pitch = vmode_attrs[vmode-1].hres * (1<<cmode) + 0x20;
display_info.mode = vmode;
strncpy(display_info.name, "platinum",
sizeof(display_info.name));
/*display_info.fb_address = info->frame_buffer_phys + 0x1000;*/
display_info.fb_address = info->frame_buffer_phys + init->fb_offset + 0x20;
display_info.cmap_adr_address = info->cmap_regs_phys;
display_info.cmap_data_address = info->cmap_regs_phys + 0x30;
display_info.disp_reg_address = info->platinum_regs_phys;
}
#endif /* CONFIG_FB_COMPAT_XPMAC */
}
__initfunc(static int init_platinum(struct fb_info_platinum *info))
{
struct fb_var_screeninfo var;
struct display *disp;
int sense;
int j,k;
sense = read_platinum_sense(info);
printk(KERN_INFO "Monitor sense value = 0x%x, ", sense);
if (default_vmode == VMODE_NVRAM) {
default_vmode = nvram_read_byte(NV_VMODE);
if (default_vmode <= 0 || default_vmode > VMODE_MAX ||
!platinum_reg_init[default_vmode-1])
default_vmode = VMODE_CHOOSE;
}
if (default_vmode == VMODE_CHOOSE) {
default_vmode = mac_map_monitor_sense(sense);
}
if (default_vmode <= 0 || default_vmode > VMODE_MAX)
default_vmode = VMODE_640_480_60;
if (default_cmode == CMODE_NVRAM)
default_cmode = nvram_read_byte(NV_CMODE);
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_cmode = CMODE_8;
/*
* Reduce the pixel size if we don't have enough VRAM.
*/
while(default_cmode > CMODE_8 && platinum_vram_reqd(default_vmode, default_cmode) > info->total_vram)
default_cmode--;
printk("using video mode %d and color mode %d.\n", default_vmode, default_cmode);
mac_vmode_to_var(default_vmode, default_cmode, &var);
if (platinum_var_to_par(&var, &info->default_par, info)) {
printk(KERN_ERR "platinumfb: can't set default video mode\n");
return 0;
}
disp = &info->disp;
strcpy(info->fb_info.modename, "platinum");
info->fb_info.node = -1;
info->fb_info.fbops = &platinumfb_ops;
info->fb_info.disp = disp;
strcpy(info->fb_info.fontname, fontname);
info->fb_info.changevar = NULL;
info->fb_info.switch_con = &platinum_switch;
info->fb_info.updatevar = &platinum_updatevar;
info->fb_info.blank = &platinum_blank;
info->fb_info.flags = FBINFO_FLAG_DEFAULT;
for (j = 0; j < 16; j++) {
k = color_table[j];
info->palette[j].red = default_red[k];
info->palette[j].green = default_grn[k];
info->palette[j].blue = default_blu[k];
}
platinum_set_var(&var, -1, &info->fb_info);
if (register_framebuffer(&info->fb_info) < 0)
return 0;
printk(KERN_INFO "fb%d: platinum frame buffer device\n",
GET_FB_IDX(info->fb_info.node));
return 1;
}
__initfunc(void platinum_init(void))
{
#ifndef CONFIG_FB_OF
struct device_node *dp;
dp = find_devices("platinum");
if (dp != 0)
platinum_of_init(dp);
#endif /* CONFIG_FB_OF */
}
#ifdef __powerpc__
#define invalidate_cache(addr) \
asm volatile("eieio; dcbf 0,%1" \
: "=m" (*(addr)) : "r" (addr) : "memory");
#else
#define invalidate_cache(addr)
#endif
__initfunc(void platinum_of_init(struct device_node *dp))
{
struct fb_info_platinum *info;
unsigned long addr, size;
int i, bank0, bank1, bank2, bank3;
if(dp->n_addrs != 2)
panic("expecting 2 address for platinum (got %d)", dp->n_addrs);
info = kmalloc(sizeof(*info), GFP_ATOMIC);
if (info == 0)
return;
memset(info, 0, sizeof(*info));
/* Map in frame buffer and registers */
for (i = 0; i < dp->n_addrs; ++i) {
addr = dp->addrs[i].address;
size = dp->addrs[i].size;
if (size >= 0x400000) {
/* frame buffer - map only 4MB */
info->frame_buffer_phys = addr;
info->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU);
info->base_frame_buffer = info->frame_buffer;
} else {
/* registers */
info->platinum_regs_phys = addr;
info->platinum_regs = ioremap(addr, size);
}
}
info->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
info->cmap_regs = ioremap(info->cmap_regs_phys, 0x1000);
/* Grok total video ram */
out_be32(&info->platinum_regs->reg[16].r, (unsigned)info->frame_buffer_phys);
out_be32(&info->platinum_regs->reg[20].r, 0x1011); /* select max vram */
out_be32(&info->platinum_regs->reg[24].r, 0); /* switch in vram */
info->base_frame_buffer[0x100000] = 0x34;
info->base_frame_buffer[0x100008] = 0x0;
invalidate_cache(&info->base_frame_buffer[0x100000]);
info->base_frame_buffer[0x200000] = 0x56;
info->base_frame_buffer[0x200008] = 0x0;
invalidate_cache(&info->base_frame_buffer[0x200000]);
info->base_frame_buffer[0x300000] = 0x78;
info->base_frame_buffer[0x300008] = 0x0;
invalidate_cache(&info->base_frame_buffer[0x300000]);
bank0 = 1; /* builtin 1MB vram, always there */
bank1 = info->base_frame_buffer[0x100000] == 0x34;
bank2 = info->base_frame_buffer[0x200000] == 0x56;
bank3 = info->base_frame_buffer[0x300000] == 0x78;
info->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000;
printk(KERN_INFO "Total VRAM = %dMB %d%d%d%d\n", (int) (info->total_vram / 1024 / 1024), bank3, bank2, bank1, bank0);
/*
* Try to determine whether we have an old or a new DACula.
*/
out_8(&info->cmap_regs->addr, 0x40);
info->dactype = in_8(&info->cmap_regs->d2);
switch (info->dactype) {
case 0x3c:
info->clktype = 1;
break;
case 0x84:
info->clktype = 0;
break;
default:
info->clktype = 0;
printk(KERN_INFO "Unknown DACula type: %x\n", info->dactype);
break;
}
if (!init_platinum(info)) {
kfree(info);
return;
}
#ifdef CONFIG_FB_COMPAT_XPMAC
if (!console_fb_info)
console_fb_info = &info->fb_info;
#endif
}
/*
* Get the monitor sense value.
* Note that this can be called before calibrate_delay,
* so we can't use udelay.
*/
static int read_platinum_sense(struct fb_info_platinum *info)
{
volatile struct platinum_regs *platinum_regs = info->platinum_regs;
int sense;
out_be32(&platinum_regs->reg[23].r, 7); /* turn off drivers */
__delay(2000);
sense = (~in_be32(&platinum_regs->reg[23].r) & 7) << 8;
/* drive each sense line low in turn and collect the other 2 */
out_be32(&platinum_regs->reg[23].r, 3); /* drive A low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 3) << 4;
out_be32(&platinum_regs->reg[23].r, 5); /* drive B low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 4) << 1;
sense |= (~in_be32(&platinum_regs->reg[23].r) & 1) << 2;
out_be32(&platinum_regs->reg[23].r, 6); /* drive C low */
__delay(2000);
sense |= (~in_be32(&platinum_regs->reg[23].r) & 6) >> 1;
out_be32(&platinum_regs->reg[23].r, 7); /* turn off drivers */
return sense;
}
/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
static int platinum_var_to_par(const struct fb_var_screeninfo *var,
struct fb_par_platinum *par,
const struct fb_info_platinum *info)
{
if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0) {
printk(KERN_ERR "platinum_var_to_par: mac_var_to_vmode unsuccessful.\n");
printk(KERN_ERR "platinum_var_to_par: var->xres = %d\n", var->xres);
printk(KERN_ERR "platinum_var_to_par: var->yres = %d\n", var->yres);
printk(KERN_ERR "platinum_var_to_par: var->xres_virtual = %d\n", var->xres_virtual);
printk(KERN_ERR "platinum_var_to_par: var->yres_virtual = %d\n", var->yres_virtual);
printk(KERN_ERR "platinum_var_to_par: var->bits_per_pixel = %d\n", var->bits_per_pixel);
printk(KERN_ERR "platinum_var_to_par: var->pixclock = %d\n", var->pixclock);
printk(KERN_ERR "platinum_var_to_par: var->vmode = %d\n", var->vmode);
return -EINVAL;
}
if(!platinum_reg_init[par->vmode-1]) {
printk(KERN_ERR "platinum_var_to_par, vmode %d not valid.\n", par->vmode);
return -EINVAL;
}
if (platinum_vram_reqd(par->vmode, par->cmode) > info->total_vram) {
printk(KERN_ERR "platinum_var_to_par, not enough ram for vmode %d, cmode %d.\n", par->vmode, par->cmode);
return -EINVAL;
}
par->xres = vmode_attrs[par->vmode-1].hres;
par->yres = vmode_attrs[par->vmode-1].vres;
par->xoffset = 0;
par->yoffset = 0;
par->vxres = par->xres;
par->vyres = par->yres;
return 0;
}
static int platinum_par_to_var(struct fb_var_screeninfo *var,
const struct fb_par_platinum *par,
const struct fb_info_platinum *info)
{
return mac_vmode_to_var(par->vmode, par->cmode, var);
}
static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
const struct fb_par_platinum *par,
const struct fb_info_platinum *info)
{
struct platinum_regvals *init;
init = platinum_reg_init[par->vmode-1];
memset(fix, 0, sizeof(*fix));
strcpy(fix->id, "platinum");
/*fix->smem_start = (void *) (info->frame_buffer_phys + 0x1000);*/
fix->smem_start = (void *) (info->frame_buffer_phys) + init->fb_offset + 0x20;
/*fix->smem_len = (u32) info->total_vram - 0x1000;*/
fix->smem_len = (u32) info->total_vram;
/*
fix->mmio_start = (char *) (info->platinum_regs_phys);
fix->mmio_len = 0x1000;
*/
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
fix->ywrapstep = 0;
fix->xpanstep = 0;
fix->ypanstep = 0;
fix->visual = (par->cmode == CMODE_8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
fix->line_length = vmode_attrs[par->vmode-1].hres * (1<<par->cmode) + 0x20;
return 0;
}
/*
* Parse user speficied options (`video=platinumfb:')
*/
__initfunc(void platinum_setup(char *options, int *ints))
{
char *this_opt;
if (!options || !*options)
return;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
if (!strncmp(this_opt, "font:", 5)) {
char *p;
int i;
p = this_opt + 5;
for (i = 0; i < sizeof(fontname) - 1; i++)
if (!*p || *p == ' ' || *p == ',')
break;
memcpy(fontname, this_opt + 5, i);
fontname[i] = 0;
}
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
default_vmode = vmode;
} else if (!strncmp(this_opt, "cmode:", 6)) {
int depth = simple_strtoul(this_opt+6, NULL, 0);
switch (depth) {
case 8:
default_cmode = CMODE_8;
break;
case 15:
case 16:
default_cmode = CMODE_16;
break;
case 24:
case 32:
default_cmode = CMODE_32;
break;
}
}
}
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
[not found] ` <Pine.BSF.3.96.990709093050.70746F-100000@silver.teardrop.n et>
@ 1999-07-09 15:43 ` Franz Sirl
1999-07-11 11:24 ` Geert Uytterhoeven
0 siblings, 1 reply; 7+ messages in thread
From: Franz Sirl @ 1999-07-09 15:43 UTC (permalink / raw)
To: Tom Rini; +Cc: Hollis R Blanchard, Mark Abene, linuxppc-dev
At 15:32 09.07.99 , Tom Rini wrote:
>On Thu, 8 Jul 1999, Hollis R Blanchard wrote:
>
> >
> > On Thu, 8 Jul 1999, Mark Abene wrote:
> > >
> > > The good news is that I finally got around to installing
> linuxppc-1999 (R5)
> > > on my 7200. The BAD news is that much to my chagrin, the changes I
> made to
> > > fix the platinum video driver in the newer kernels (which I submitted
> to the
> > > code maintainer nearly a month ago, if not more) are NOT present in R5!
> > > I was greeted by the sickly-looking psychedelic arch-nemesis of Tux the
> > > penguin.
> > > Suffice to say, gnome came up looking like a bad acid trip.
> >
> > Strangely enough, the kernel the installer uses was right. I was very
> > pleasently surprised to see Tux in the correct colors when I went to
> install.
> > Of course, the kernel the installer actually installs is screwed up in this
> > respect.
>
>Well, 1) Did the installer endup using no video driver? (I still don't
>have a CD pair, have to bug jeff again once i settle in) 2) iirc, about a
>month ago Geert (the video maintainer) was working towards his PhD and
>could have easily lost the mail. 3) Where is the patch anyhow, there'll no
>doubt be a kernel upgrade "soon" :)
The fix is in 2.2.10vger (and was in later 2.2.9vger as well). Geert
accepted it nearly immediately, but probably feeding it to 2.2.10linus
didn't happen in time.
Franz.
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
1999-07-09 15:43 ` Franz Sirl
@ 1999-07-11 11:24 ` Geert Uytterhoeven
0 siblings, 0 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 1999-07-11 11:24 UTC (permalink / raw)
To: Franz Sirl; +Cc: Tom Rini, Hollis R Blanchard, Mark Abene, linuxppc-dev
On Fri, 9 Jul 1999, Franz Sirl wrote:
> At 15:32 09.07.99 , Tom Rini wrote:
> >Well, 1) Did the installer endup using no video driver? (I still don't
> >have a CD pair, have to bug jeff again once i settle in) 2) iirc, about a
> >month ago Geert (the video maintainer) was working towards his PhD and
> >could have easily lost the mail. 3) Where is the patch anyhow, there'll no
> >doubt be a kernel upgrade "soon" :)
>
> The fix is in 2.2.10vger (and was in later 2.2.9vger as well). Geert
> accepted it nearly immediately, but probably feeding it to 2.2.10linus
> didn't happen in time.
I have to admit I haven't sent any single patch to Linus during the last few
months. Sorry, I'm trying to get in sync again. Being about 2 weeks abroad
is a terrible thing...
Greetings,
Geert
--
Geert Uytterhoeven Geert.Uytterhoeven@cs.kuleuven.ac.be
Wavelets, Linux/{m68k~Amiga,PPC~CHRP} http://www.cs.kuleuven.ac.be/~geert/
Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: platinum video makes me cry...
1999-07-09 13:50 ` Mark Abene
@ 1999-08-02 15:39 ` Jerry Quinn
0 siblings, 0 replies; 7+ messages in thread
From: Jerry Quinn @ 1999-08-02 15:39 UTC (permalink / raw)
To: Mark Abene; +Cc: Tom Rini, linuxppc-dev
>> "Mark" == Mark Abene <phiber@radicalmedia.com> writes:
Mark> I'll attach the "current" platinumfb.c file in its entirety. Although
Mark> I've just been informed (and I've verified) that 32bpp doesn't work. I
Mark> didn't originally notice because I normally use vmode 20 16, and hadn't
Mark> checked 32bpp. So the changes only fix 16bpp (8 still works as
Mark> before). I'm looking into why 32bpp doesn't work. I'm still irritated
Mark> at how much abstraction was done to make the driver "FBDev-aware". It
Mark> was so much simpler in 2.1.24, when ALL recognized modes worked in ALL
Mark> available bit-depths. Now I'm playing catch-up since I was previously
Mark> much too busy to know what was going on with newer kernels and FBDev.
I just tried out your revised platinumfb file. Kudos - I don't have to use
the OFfb anymore, the video driver works right. I don't have enough VRAM to
check out the 32bpp mode.
A couple of things I noticed, but don't know if they are directly due to the
driver or a more generic part. First, at the console, the block cursor is
invisible. The only way to tell where it is is because it is blinking (also
different) when over a character. Second, when I switch VT's, I get a resynch
disturbance. I'm running an Apple 21" fixed-freq monitor, so there shouldn't
be any attempt to change frequencies. This resync doesn't happen with 'no
video driver' checked.
I'm running a stock Linus 2.2.10.
As an aside, how do I get XF68_fbdev to work? It demands a config file.
I tried running Xconfigurator (vague memory since I haven't been following
those discussions), but it only detects 1M of VRAM instead of 2.
And more generally, why does Xpmac do the right thing and XF68_fpdev not?
There seems to be a lot of questions of the form "How do I get X set up
right?". I guess the question I have is why it's so seamless on the MacOS
side but hairy on the Linux side. What magic is Apple pulling and how do we
go about wrapping it up so that things work cleanly for Linux too?
Thanks
Jerry
--
Jerry Quinn Tel: (514) 761-8737
jquinn@nortelnetworks.com Fax: (514) 761-8505
Speech Recognition Research
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~1999-08-02 15:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
1999-07-08 12:04 platinum video makes me cry Mark Abene
1999-07-08 18:29 ` Hollis R Blanchard
1999-07-09 13:32 ` Tom Rini
1999-07-09 13:50 ` Mark Abene
1999-08-02 15:39 ` Jerry Quinn
[not found] ` <Pine.BSF.3.96.990709093050.70746F-100000@silver.teardrop.n et>
1999-07-09 15:43 ` Franz Sirl
1999-07-11 11:24 ` Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).