lkml.org 
[lkml]   [2002]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subjectpatch for aty128fb.c
This patch gets aty128fb.c to compile and work on my G4 powerbook.  I
have fixed the bug where the check_var routine would alter the par
structure, and I have fixed up the errors in the powerbook-specific
sleep/wakeup code.

Currently it can only put one rage 128 chip to sleep, but that is ok
for now since I've never seen a laptop with two rage 128 chips yet. :)
The generic device model will ultimately give us a better way to
handle sleep/wakeup.

Paul.

diff -urN linux-2.5/drivers/video/aty128fb.c pmac-2.5/drivers/video/aty128fb.c
--- linux-2.5/drivers/video/aty128fb.c 2002-12-10 15:20:32.000000000 +1100
+++ pmac-2.5/drivers/video/aty128fb.c 2002-12-11 22:41:38.000000000 +1100
@@ -65,10 +65,7 @@
#ifdef CONFIG_ALL_PPC
#include <asm/prom.h>
#include <asm/pci-bridge.h>
-#include <video/macmodes.h>
-#ifdef CONFIG_NVRAM
-#include <linux/nvram.h>
-#endif
+#include "macmodes.h"
#endif

#ifdef CONFIG_ADB_PMU
@@ -285,7 +282,6 @@

struct aty128_crtc {
u32 gen_cntl;
- u32 ext_cntl;
u32 h_total, h_sync_strt_wid;
u32 v_total, v_sync_strt_wid;
u32 pitch;
@@ -326,10 +322,13 @@
unsigned char *save_framebuffer;
int pm_reg;
int crt_on, lcd_on;
+ struct pci_dev *pdev;
+ struct fb_info *next;
#endif
- unsigned char red[64]; /* see comments in aty128fb_setcolreg */
- unsigned char green[64];
- unsigned char blue[64];
+ u8 red[32]; /* see aty128fb_setcolreg */
+ u8 green[64];
+ u8 blue[32];
+ u32 pseudo_palette[16]; /* used for TRUECOLOR */
};

#ifdef CONFIG_PMAC_PBOOK
@@ -337,6 +336,7 @@
static struct pmu_sleep_notifier aty128_sleep_notifier = {
aty128_sleep_notify, SLEEP_LEVEL_VIDEO,
};
+static struct fb_info *aty128_fb = NULL;
#endif

#define round_div(n, d) ((n+(d/2))/d)
@@ -1203,7 +1203,11 @@
{
struct aty128fb_par *par = info->par;
u32 config;
-
+ int err;
+
+ if ((err = aty128_decode_var(&info->var, par)) != 0)
+ return err;
+
if (par->blitter_may_be_busy)
wait_for_idle(par);

@@ -1271,15 +1275,22 @@
aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par)
{
int err;
+ struct aty128_crtc crtc;
+ struct aty128_pll pll;
+ struct aty128_ddafifo fifo_reg;

- if ((err = aty128_var_to_crtc(var, &par->crtc, par)))
+ if ((err = aty128_var_to_crtc(var, &crtc, par)))
return err;

- if ((err = aty128_var_to_pll(var->pixclock, &par->pll, par)))
+ if ((err = aty128_var_to_pll(var->pixclock, &pll, par)))
return err;

- if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.depth, par)))
+ if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par)))
return err;
+
+ par->crtc = crtc;
+ par->pll = pll;
+ par->fifo_reg = fifo_reg;
par->accel_flags = var->accel_flags;

return 0;
@@ -1312,12 +1323,13 @@
static int
aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct aty128fb_par *par = info->par;
+ struct aty128fb_par par;
int err;

- if ((err = aty128_decode_var(var, par)) != 0)
+ par = *(struct aty128fb_par *)info->par;
+ if ((err = aty128_decode_var(var, &par)) != 0)
return err;
- aty128_encode_var(var, par);
+ aty128_encode_var(var, &par);
return 0;
}

@@ -1415,7 +1427,7 @@
}
#endif
#ifdef CONFIG_ALL_PPC
- /* vmode and cmode depreciated */
+ /* vmode and cmode deprecated */
if (!strncmp(this_opt, "vmode:", 6)) {
unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
@@ -1602,7 +1614,12 @@
#endif /* CONFIG_PMAC_BACKLIGHT */
#ifdef CONFIG_PMAC_PBOOK
par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
- pmu_register_sleep_notifier(&aty128_sleep_notifier);
+ if (aty128_fb == NULL) {
+ /* XXX can only put one chip to sleep */
+ aty128_fb = info;
+ } else
+ printk(KERN_WARNING "aty128fb: can only sleep one Rage 128\n");
+ par->pdev = pdev;
#endif

printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
@@ -1647,8 +1664,7 @@
}

/* We have the resources. Now virtualize them */
- size = sizeof(struct fb_info) + sizeof(struct aty128fb_par) +
- sizeof(u32)*16;
+ size = sizeof(struct fb_info) + sizeof(struct aty128fb_par);
if (!(info = kmalloc(size, GFP_ATOMIC))) {
printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
goto err_unmap_out;
@@ -1656,9 +1672,7 @@
memset(info, 0, size);

par = (struct aty128fb_par *)(info + 1);
- info->pseudo_palette = (void *) (par + 1);
-
- memset(info, 0, sizeof(struct fb_info));
+ info->pseudo_palette = par->pseudo_palette;

info->par = par;
info->fix = aty128fb_fix;
@@ -1758,6 +1772,10 @@
pci_resource_len(pdev, 1));
release_mem_region(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2));
+#ifdef CONFIG_PMAC_PBOOK
+ if (info == aty128_fb)
+ aty128_fb = NULL;
+#endif
kfree(info);
}
#endif /* CONFIG_PCI */
@@ -2008,7 +2026,7 @@
}
}

- if (par->crtc.depth == 16) {
+ if (par->crtc.depth == 16 && regno > 0) {
/*
* With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
* have 32 slots for R and B values but 64 slots for G values.
@@ -2016,12 +2034,13 @@
* goes in a different slot, and we have to avoid disturbing
* the other fields in the slots we touch.
*/
- par->red[regno] = red;
par->green[regno] = green;
- par->blue[regno] = blue;
- if (regno > 0 && regno < 32)
+ if (regno < 32) {
+ par->red[regno] = red;
+ par->blue[regno] = blue;
aty128_st_pal(regno * 8, red, par->green[regno*2],
blue, par);
+ }
red = par->red[regno/2];
blue = par->blue[regno/2];
regno <<= 2;
@@ -2213,6 +2232,7 @@
{
u32 pmgt;
u16 pwr_command;
+ struct pci_dev *pdev = par->pdev;

if (!par->pm_reg)
return;
@@ -2237,17 +2257,16 @@
aty_st_le32(BUS_CNTL1, 0x00000010);
aty_st_le32(MEM_POWER_MISC, 0x0c830000);
mdelay(100);
- pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
/* Switch PCI power management to D2 */
- pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL,
+ pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
- pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
} else {
/* Switch back PCI power management to D0 */
mdelay(100);
- pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, 0);
- mdelay(100);
- pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+ pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
+ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
mdelay(100);
}
}
@@ -2259,10 +2278,13 @@
int
aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
- int result = PBOOK_SLEEP_OK, nb;
- struct fb_info *info = info; /* FIXME!!! How do find which framebuffer */
- struct aty128fb_par *par = info->par;
+ int nb;
+ struct fb_info *info = aty128_fb;
+ struct aty128fb_par *par;

+ if (info == NULL)
+ return PBOOK_SLEEP_OK;
+ par = info->par;
nb = info->var.yres * info->fix.line_length;

switch (when) {
@@ -2311,17 +2333,23 @@
aty128fb_blank(0, info);
break;
}
- return result;
+ return PBOOK_SLEEP_OK;
}
#endif /* CONFIG_PMAC_PBOOK */

int __init aty128fb_init(void)
{
+#ifdef CONFIG_PMAC_PBOOK
+ pmu_register_sleep_notifier(&aty128_sleep_notifier);
+#endif
return pci_module_init(&aty128fb_driver);
}

static void __exit aty128fb_exit(void)
{
+#ifdef CONFIG_PMAC_PBOOK
+ pmu_unregister_sleep_notifier(&aty128_sleep_notifier);
+#endif
pci_unregister_driver(&aty128fb_driver);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:31    [from the cache]
©2003-2011 Jasper Spaans