* URGENT: status of atyfb
@ 2004-08-02 3:31 Benjamin Herrenschmidt
2004-08-02 5:21 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2004-08-02 3:31 UTC (permalink / raw)
To: fb-devel
Hi !
I'm having more and more pain with atyfb at this point. I really need
the changes that bring the pci_driver (and new PM callbacks) so I can
properly work on these.
However, bringing just that change from the fbdev tree to the main tree
is incredibly painful due to the major amount of changes that went into
this driver.
So can somebody show up and tell me what is the status of this driver as
it is currently in the fbdev-2.5 bk tree and if that stuff can actually
be sent upstream ASAP or not ?
I don't feel like re-doing just the pci_driver changes, did it once, was
painful enough, but on the other hand, this driver has been drifting
away from mainstream for ages, which is simply not acceptable.
Ben.
-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-02 3:31 URGENT: status of atyfb Benjamin Herrenschmidt
@ 2004-08-02 5:21 ` Benjamin Herrenschmidt
2004-08-03 20:57 ` Alexander Kern
0 siblings, 1 reply; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2004-08-02 5:21 UTC (permalink / raw)
To: fb-devel
Ok, I built an upstream tree with just the new atyfb in, and it breaks
on the wallstreet powerbook (LT-G) here. I'm not sure what is wrong at
this point, I'd say the clock stuff is incorrectly calculated.
On PPC, you do not have access to BIOS tables. So driver starts with
blowing up since the code for retreiving that from BIOS is unconditional
(it should be X86 only).
I disabled that, but then, the default values (which are the same as the old
driver afaik) don't seem to be enough anymore to produce a correct output.
Ben.
-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-02 5:21 ` Benjamin Herrenschmidt
@ 2004-08-03 20:57 ` Alexander Kern
2004-08-03 21:25 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 7+ messages in thread
From: Alexander Kern @ 2004-08-03 20:57 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: Benjamin Herrenschmidt, Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 882 bytes --]
Am Montag, 2. August 2004 07:21 schrieb Benjamin Herrenschmidt:
> Ok, I built an upstream tree with just the new atyfb in, and it breaks
> on the wallstreet powerbook (LT-G) here. I'm not sure what is wrong at
> this point, I'd say the clock stuff is incorrectly calculated.
>
> On PPC, you do not have access to BIOS tables. So driver starts with
> blowing up since the code for retreiving that from BIOS is unconditional
> (it should be X86 only).
>
> I disabled that, but then, the default values (which are the same as the
> old driver afaik) don't seem to be enough anymore to produce a correct
> output.
>
> Ben.
Hi, I do not have any information or hardware about PPC. Should it own
something like OpenFirmware? In this case it is possible to read clock
information from this.
I found, that we change a little behaviour. Please give a try for this
patch...
Regards Alex
[-- Attachment #2: atyfb_base_difference.patch --]
[-- Type: text/x-diff, Size: 505 bytes --]
--- atyfb_base.c 2004-08-01 00:23:53.000000000 +0200
+++ atyfb_base.c.ppc 2004-08-03 22:54:17.211890752 +0200
@@ -336,7 +336,7 @@
#define ATI_CHIP_264GTB (ATI_MODERN_SET)
/*#define ATI_CHIP_264GTDVD ?*/
-#define ATI_CHIP_264LTG (ATI_MODERN_SET)
+#define ATI_CHIP_264LTG (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
#define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_HW_TRIPLE)
#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-03 20:57 ` Alexander Kern
@ 2004-08-03 21:25 ` Benjamin Herrenschmidt
2004-08-03 22:05 ` Ville Syrjälä
2004-08-06 6:09 ` Alexander Kern
0 siblings, 2 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2004-08-03 21:25 UTC (permalink / raw)
To: Alexander Kern; +Cc: Linux Fbdev development list, Ville Syrjälä
> Hi, I do not have any information or hardware about PPC. Should it own
> something like OpenFirmware? In this case it is possible to read clock
> information from this.
On some models, yes, on some no. Older machines have a firmware that
won't tell you anything, the MacOS driver back then was hard coding the
values.
Anyway, the clocks are ok, apparently (maybe not the engine one though,
see later), the problem was that the DLL magic was reverted for the
LT-G, plus some minor issues with the driver blowing up on non-BIOS
machines that I can fix.
The engine tends to lockup quickly though, I'll do experiments.
> I found, that we change a little behaviour. Please give a try for this
> patch...
Your patch seem to address the DLL issue, I did that too, fixes the display,
I'll toy around and let you know.
Also, when just dropping the existing driver into the current linus tree, the
cursor code is blowing up, I don't know why yet, I suppose some changes to the
common code in the fbdev tree. I'll have a look.
I really want this new driver to be sent upstream ASAP. What I may do is once
I get it working well enough, I'll send it to andrew for the -mm tree and
leave it there for a while to get it properly tested.
Ben.
-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-03 21:25 ` Benjamin Herrenschmidt
@ 2004-08-03 22:05 ` Ville Syrjälä
2004-08-06 6:09 ` Alexander Kern
1 sibling, 0 replies; 7+ messages in thread
From: Ville Syrjälä @ 2004-08-03 22:05 UTC (permalink / raw)
To: Linux Fbdev development list
On Wed, Aug 04, 2004 at 07:25:40AM +1000, Benjamin Herrenschmidt wrote:
>
> Also, when just dropping the existing driver into the current linus tree, the
> cursor code is blowing up, I don't know why yet, I suppose some changes to the
> common code in the fbdev tree. I'll have a look.
I had (probably) the same oops when using the driver from bk on 2.6.5-mm6.
Alex's latest patch fixed it for me.
On a somewhat related note...
I'd like to know if my LT LCD register access patch works correctly. It
should allow the generic LCD code to work on LT. It's included in Alex's
latest patch. But since parsing the BIOS is out of the question you'd have
to hardcode the LCD parameters. Could you test it?
--
Ville Syrjälä
syrjala@sci.fi
http://www.sci.fi/~syrjala/
-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-03 21:25 ` Benjamin Herrenschmidt
2004-08-03 22:05 ` Ville Syrjälä
@ 2004-08-06 6:09 ` Alexander Kern
2004-08-06 8:10 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 7+ messages in thread
From: Alexander Kern @ 2004-08-06 6:09 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: Benjamin Herrenschmidt, Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 1519 bytes --]
Am Dienstag, 3. August 2004 23:25 schrieb Benjamin Herrenschmidt:
> > Hi, I do not have any information or hardware about PPC. Should it own
> > something like OpenFirmware? In this case it is possible to read clock
> > information from this.
>
> On some models, yes, on some no. Older machines have a firmware that
> won't tell you anything, the MacOS driver back then was hard coding the
> values.
>
> Anyway, the clocks are ok, apparently (maybe not the engine one though,
> see later), the problem was that the DLL magic was reverted for the
> LT-G, plus some minor issues with the driver blowing up on non-BIOS
> machines that I can fix.
>
> The engine tends to lockup quickly though, I'll do experiments.
>
> > I found, that we change a little behaviour. Please give a try for this
> > patch...
>
> Your patch seem to address the DLL issue, I did that too, fixes the
> display, I'll toy around and let you know.
>
> Also, when just dropping the existing driver into the current linus tree,
> the cursor code is blowing up, I don't know why yet, I suppose some changes
> to the common code in the fbdev tree. I'll have a look.
>
> I really want this new driver to be sent upstream ASAP. What I may do is
> once I get it working well enough, I'll send it to andrew for the -mm tree
> and leave it there for a while to get it properly tested.
>
> Ben.
Hi, here a snapshot from my tree over 2.6.7 + js3
Changes:
revert SDRAM_MAGIC_PLL to old behaviour
do a "from BIOS" initialisation only by __i386__
Regards
Alex
[-- Attachment #2: mach64-js3-ak6a.diff --]
[-- Type: text/x-diff, Size: 78050 bytes --]
diff -ur -X patches/exclude linux-2.6.7.js3/drivers/video/aty/atyfb.h linux-2.6.7.ak/drivers/video/aty/atyfb.h
--- linux-2.6.7.js3/drivers/video/aty/atyfb.h 2004-06-27 01:35:27.000000000 +0200
+++ linux-2.6.7.ak/drivers/video/aty/atyfb.h 2004-08-04 22:25:21.000000000 +0200
@@ -3,6 +3,8 @@
*/
#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
/*
* Elements of the hardware specific atyfb_par structure
*/
@@ -30,9 +32,18 @@
u32 shadow_h_sync_strt_wid;
u32 shadow_v_tot_disp;
u32 shadow_v_sync_strt_wid;
+ u32 lcd_gen_cntl;
+ u32 lcd_config_panel;
+ u32 lcd_index;
#endif
};
+struct aty_interrupt {
+ wait_queue_head_t wait;
+ unsigned int count;
+ int pan_display;
+};
+
struct pll_info {
int pll_max;
int pll_min;
@@ -116,6 +127,7 @@
struct atyfb_par {
struct aty_cmap_regs *aty_cmap_regs;
+ struct { u8 red, green, blue; } palette[256];
const struct aty_dac_ops *dac_ops;
const struct aty_pll_ops *pll_ops;
unsigned long ati_regbase;
@@ -141,8 +153,8 @@
#ifdef __sparc__
struct pci_mmap_map *mmap_map;
u8 mmaped;
- int open;
#endif
+ int open;
#ifdef CONFIG_FB_ATY_GENERIC_LCD
unsigned long bios_base_phys;
unsigned long bios_base;
@@ -165,6 +177,10 @@
#endif
unsigned long aux_start; /* auxiliary aperture */
unsigned long aux_size;
+ struct aty_interrupt vblank;
+ unsigned long irq_flags;
+ unsigned int irq;
+ spinlock_t int_lock;
};
/*
@@ -177,7 +193,7 @@
#define M64F_MAGIC_FIFO 0x00000002
#define M64F_GTB_DSP 0x00000004
#define M64F_FIFO_32 0x00000008
-#define M64F_NO_EXT_PLL 0x00000010
+#define M64F_SDRAM_MAGIC_PLL 0x00000010
#define M64F_MAGIC_POSTDIV 0x00000020
#define M64F_INTEGRATED 0x00000040
#define M64F_CT_BUS 0x00000080
@@ -191,7 +207,7 @@
#define M64F_G3_PB_1_1 0x00008000
#define M64F_G3_PB_1024x768 0x00010000
#define M64F_EXTRA_BRIGHT 0x00020000
-#define M64F_LT_SLEEP 0x00040000
+#define M64F_LT_LCD_REGS 0x00040000
#define M64F_XL_DLL 0x00080000
#define M64F_MFB_FORCE_4 0x00100000
#define M64F_HW_TRIPLE 0x00200000
@@ -251,6 +267,11 @@
#endif
}
+#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
+extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par);
+extern u32 aty_ld_lcd(int index, const struct atyfb_par *par);
+#endif
+
/*
* DAC operations
*/
@@ -275,6 +296,7 @@
int (*var_to_pll) (const struct fb_info * info, u32 vclk_per, u32 bpp, union aty_pll * pll);
u32 (*pll_to_var) (const struct fb_info * info, const union aty_pll * pll);
void (*set_pll) (const struct fb_info * info, const union aty_pll * pll);
+ void (*get_pll) (const struct fb_info *info, union aty_pll * pll);
int (*init_pll) (const struct fb_info * info, union aty_pll * pll);
};
diff -ur -X patches/exclude linux-2.6.7.js3/drivers/video/aty/atyfb_base.c linux-2.6.7.ak/drivers/video/aty/atyfb_base.c
--- linux-2.6.7.js3/drivers/video/aty/atyfb_base.c 2004-06-27 01:35:27.000000000 +0200
+++ linux-2.6.7.ak/drivers/video/aty/atyfb_base.c 2004-08-04 22:57:50.000000000 +0200
@@ -26,6 +26,7 @@
* Anthony Tong <atong@uiuc.edu>
*
* Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
+ * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
*
* 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
@@ -41,15 +42,16 @@
- cursor support on all cards and all ramdacs.
- cursor parameters controlable via ioctl()s.
- guess PLL and MCLK based on the original PLL register values initialized
- by the BIOS or Open Firmware (if they are initialized).
+ by Open Firmware (if they are initialized). BIOS is done
- (Anyone to help with this?)
+ (Anyone with Mac to help with this?)
******************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -61,6 +63,9 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -101,33 +106,63 @@
#define GUI_RESERVE (1 * PAGE_SIZE)
/* FIXME: remove the FAIL definition */
-#define FAIL(msg) do { printk(KERN_CRIT msg "\n"); return -EINVAL; } while (0)
-#define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0)
+#define FAIL(msg) do { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0)
+#define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0)
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
+#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
-static void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
+static const u32 lt_lcd_regs[] = {
+ CONFIG_PANEL_LG,
+ LCD_GEN_CNTL_LG,
+ DSTN_CONTROL_LG,
+ HFB_PITCH_ADDR_LG,
+ HORZ_STRETCHING_LG,
+ VERT_STRETCHING_LG,
+ 0, /* EXT_VERT_STRETCH */
+ LT_GIO_LG,
+ POWER_MANAGEMENT_LG
+};
+
+void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
{
- unsigned long temp;
+ if (M64_HAS(LT_LCD_REGS)) {
+ aty_st_le32(lt_lcd_regs[index], val, par);
+ } else {
+ unsigned long temp;
- /* write addr byte */
- temp = aty_ld_le32(LCD_INDEX, par);
- aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
- /* write the register value */
- aty_st_le32(LCD_DATA, val, par);
+ /* write addr byte */
+ temp = aty_ld_le32(LCD_INDEX, par);
+ aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
+ /* write the register value */
+ aty_st_le32(LCD_DATA, val, par);
+ }
}
-static u32 aty_ld_lcd(int index, const struct atyfb_par *par)
+u32 aty_ld_lcd(int index, const struct atyfb_par *par)
{
- unsigned long temp;
+ if (M64_HAS(LT_LCD_REGS)) {
+ return aty_ld_le32(lt_lcd_regs[index], par);
+ } else {
+ unsigned long temp;
- /* write addr byte */
- temp = aty_ld_le32(LCD_INDEX, par);
- aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
- /* read the register value */
- return aty_ld_le32(LCD_DATA, par);
+ /* write addr byte */
+ temp = aty_ld_le32(LCD_INDEX, par);
+ aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
+ /* read the register value */
+ return aty_ld_le32(LCD_DATA, par);
+ }
}
#endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
+#ifdef CONFIG_FB_ATY_GENERIC_LCD
/*
* ATIReduceRatio --
*
@@ -150,7 +185,7 @@
*Numerator /= Divider;
*Denominator /= Divider;
}
-
+#endif
/*
* The Hardware parameters for each card
*/
@@ -209,11 +244,11 @@
#ifdef CONFIG_ATARI
static int store_video_par(char *videopar, unsigned char m64_num);
#endif
-#if 0
+
static struct crtc saved_crtc;
static union aty_pll saved_pll;
static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
-#endif
+
static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
@@ -254,22 +289,19 @@
.fb_fillrect = atyfb_fillrect,
.fb_copyarea = atyfb_copyarea,
.fb_imageblit = atyfb_imageblit,
- .fb_cursor = atyfb_cursor,
+ .fb_cursor = soft_cursor,
#ifdef __sparc__
.fb_mmap = atyfb_mmap,
#endif
.fb_sync = atyfb_sync,
};
-static char noaccel __initdata = 0;
-static u32 default_vram __initdata = 0;
-static int default_pll __initdata = 0;
-static int default_mclk __initdata = 0;
-static int default_xclk __initdata = 0;
-
-#ifndef MODULE
-static char *mode_option __initdata = NULL;
-#endif
+static int noaccel;
+static int vram;
+static int pll;
+static int mclk;
+static int xclk;
+static char *mode;
#ifdef CONFIG_PPC
static int default_vmode __initdata = VMODE_CHOOSE;
@@ -294,20 +326,20 @@
#define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
#define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
-#define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
-#define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_NO_EXT_PLL)
+#define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
+#define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
-#define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_NO_EXT_PLL)
+#define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
/* make sets shorter */
-#define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_NO_EXT_PLL)
+#define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
-#define ATI_CHIP_264GTB (ATI_MODERN_SET)
+#define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
/*#define ATI_CHIP_264GTDVD ?*/
-#define ATI_CHIP_264LTG (ATI_MODERN_SET)
+#define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
-#define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_HW_TRIPLE)
-#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
+#define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
+#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
#define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
@@ -336,7 +368,7 @@
{ PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT },
/* FIXME chipset maybe ATI_CHIP_264LTPRO ? */
- { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
+ { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
{ PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 },
@@ -365,19 +397,20 @@
{ PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
{ PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
- { PCI_CHIP_MACH64LN, "3D RAGE Mobility (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
- { PCI_CHIP_MACH64LR, "3D RAGE Mobility (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
- { PCI_CHIP_MACH64LS, "3D RAGE Mobility (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
+ { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
+ { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
+ { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
#endif /* CONFIG_FB_ATY_CT */
};
+/* can not fail */
static int __devinit correct_chipset(struct atyfb_par *par)
{
- const char *name;
- int i, err = 0;
- u32 chip_id;
- u16 type;
u8 rev;
+ u16 type;
+ u32 chip_id;
+ const char *name;
+ int i;
for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
if (par->pci_id == aty_chips[i].pci_id)
@@ -396,12 +429,12 @@
switch(par->pci_id) {
#ifdef CONFIG_FB_ATY_GX
case PCI_CHIP_MACH64GX:
- if (type != 0x00d7)
- err = -ENXIO;
+ if(type != 0x00d7);
+ return -ENODEV;
break;
case PCI_CHIP_MACH64CX:
- if (type == 0x0057)
- err = -ENXIO;
+ if(type != 0x0057);
+ return -ENODEV;
break;
#endif
#ifdef CONFIG_FB_ATY_CT
@@ -443,11 +476,9 @@
break;
#endif
}
- if (!err)
- printk("atyfb: %s [0x%04x rev 0x%02x]\n", name, type, rev);
- else
- printk(KERN_INFO "atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev);
- return err;
+
+ PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
+ return 0;
}
static char ram_dram[] __initdata = "DRAM";
@@ -457,9 +488,9 @@
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
static char ram_edo[] __initdata = "EDO";
-static char ram_sdram[] __initdata = "SDRAM";
-static char ram_sgram[] __initdata = "SGRAM";
-static char ram_wram[] __initdata = "WRAM";
+static char ram_sdram[] __initdata = "SDRAM (1:1)";
+static char ram_sgram[] __initdata = "SGRAM (1:1)";
+static char ram_sdram32[] __initdata = "SDRAM (2:1) (32-bit)";
static char ram_off[] __initdata = "OFF";
#endif /* CONFIG_FB_ATY_CT */
@@ -476,7 +507,7 @@
#ifdef CONFIG_FB_ATY_CT
static char *aty_ct_ram[8] __initdata = {
ram_off, ram_dram, ram_edo, ram_edo,
- ram_sdram, ram_sgram, ram_wram, ram_resv
+ ram_sdram, ram_sgram, ram_sdram32, ram_resv
};
#endif /* CONFIG_FB_ATY_CT */
@@ -543,9 +574,30 @@
/*
* CRTC programming
*/
-#if 0
+
static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
{
+#ifdef CONFIG_FB_ATY_GENERIC_LCD
+ if (par->lcd_table != 0) {
+ if(!M64_HAS(LT_LCD_REGS)) {
+ crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
+ aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
+ }
+ crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
+ crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
+
+
+ /* switch to non shadow registers */
+ aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
+ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
+
+ /* save stretching */
+ crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
+ crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
+ if (!M64_HAS(LT_LCD_REGS))
+ crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
+ }
+#endif
crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
@@ -555,51 +607,34 @@
crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
#ifdef CONFIG_FB_ATY_GENERIC_LCD
-
if (par->lcd_table != 0) {
/* switch to shadow registers */
- u32 temp = aty_ld_lcd(LCD_GEN_CNTL, par);
- aty_st_lcd(LCD_GEN_CNTL, temp | SHADOW_EN | SHADOW_RW_EN, par);
+ aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
+ SHADOW_EN | SHADOW_RW_EN, par);
- /* get shadow registers */
crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
- aty_st_le32(LCD_GEN_CNTL, temp & ~(SHADOW_EN | SHADOW_RW_EN), par);
-
- /* get stretching */
- crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
- crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
- crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
+ aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
}
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
}
-#endif
+
static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
{
#ifdef CONFIG_FB_ATY_GENERIC_LCD
- u32 temp;
-
- /* Load LCD registers */
if (par->lcd_table != 0) {
- // Set the CRTC to primary, and make the registers writeable
- temp = aty_ld_lcd(LCD_GEN_CNTL, par);
- temp &= LCD_SET_PRIMARY_MASK;
- temp |= DONT_SHADOW_VPAR;
- aty_st_lcd(LCD_GEN_CNTL, temp, par);
-#if 0
- /* Stop CRTC */
- aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl &
- ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
+ /* stop CRTC */
+ aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
- /* Update non-shadow registers first */
- /*aty_st_lcd(LCD_CONFIG_PANEL, pATIHW->config_panel);*/
+ /* update non-shadow registers first */
+ aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
-#endif
- /* Temporarily disable stretching */
+
+ /* temporarily disable stretching */
aty_st_lcd(HORZ_STRETCHING,
crtc->horz_stretching &
~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
@@ -609,55 +644,72 @@
VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
}
#endif
+ /* turn off CRT */
aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
+
+ DPRINTK("setting up CRTC\n");
+ PRINTKI("set primary CRT to %ix%i %c%c composite %c\n",
+ ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
+ (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
+ (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
+
+ DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
+ DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
+ DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
+ DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
+ DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
+ DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
+ DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
+
aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
- aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
+ aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
+
aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
-#ifdef DEBUG
- printk(KERN_INFO "setting up CRTC\n");
- printk(KERN_INFO "CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
- printk(KERN_INFO "CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
- printk(KERN_INFO "CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
- printk(KERN_INFO "CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
- printk(KERN_INFO "CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
+#if 0
+ FIXME
+ if (par->accel_flags & FB_ACCELF_TEXT)
+ aty_init_engine(par, info);
#endif
#ifdef CONFIG_FB_ATY_GENERIC_LCD
- /* After setting the CRTC registers we should set the LCD
- * registers.
- */
+ /* after setting the CRTC registers we should set the LCD registers. */
if (par->lcd_table != 0) {
/* switch to shadow registers */
- temp = aty_ld_lcd(LCD_GEN_CNTL, par);
- aty_st_lcd(LCD_GEN_CNTL, temp | SHADOW_EN | SHADOW_RW_EN, par);
+ aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
+ (SHADOW_EN | SHADOW_RW_EN), par);
+
+ PRINTKI("set secondary CRT to %ix%i %c%c\n",
+ ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
+ (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
+
+ DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
+ DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
+ DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
+ DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
- /* set shadow registers */
aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
- aty_st_lcd(LCD_GEN_CNTL, temp & ~(SHADOW_EN | SHADOW_RW_EN), par);
+ /* restore CRTC selection & shadow state and enable stretching */
+ DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
+ DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
+ DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
+ if(!M64_HAS(LT_LCD_REGS))
+ DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
-#ifdef DEBUG
- printk(KERN_INFO "LCD_GEN_CNTL: %x\n", temp);
- printk(KERN_INFO "HORZ_STRETCHING: %x\n", crtc->horz_stretching);
- printk(KERN_INFO "VERT_STRETCHING: %x\n", crtc->vert_stretching);
- printk(KERN_INFO "EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
-#endif
- /* Restore CRTC selection & shadow state */
- /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
-
- /* Enable/disable stretching */
+ aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
- aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
- /*
- outr(LCD_INDEX, pATIHW->lcd_index);
- */
+ if(!M64_HAS(LT_LCD_REGS)) {
+ aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
+ aty_ld_le32(LCD_INDEX, par);
+ aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
+ }
}
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
}
@@ -667,14 +719,11 @@
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
- u32 sync, vmode;
+ u32 sync, vmode, vdisplay;
u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
u32 pix_width, dp_pix_width, dp_chain_mask;
-#ifdef CONFIG_FB_ATY_GENERIC_LCD
- int VScan = 1;
- u32 lcd_on_off = 0;
-#endif
+
/* input */
xres = var->xres;
yres = var->yres;
@@ -683,6 +732,8 @@
xoffset = var->xoffset;
yoffset = var->yoffset;
bpp = var->bits_per_pixel;
+ if (bpp == 16)
+ bpp = (var->green.length == 5) ? 15 : 16;
sync = var->sync;
vmode = var->vmode;
@@ -702,12 +753,18 @@
HOST_8BPP | SRC_8BPP | DST_8BPP |
BYTE_ORDER_LSB_TO_MSB;
dp_chain_mask = DP_CHAIN_8BPP;
- } else if (bpp <= 16) {
+ } else if (bpp <= 15) {
bpp = 16;
pix_width = CRTC_PIX_WIDTH_15BPP;
dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
BYTE_ORDER_LSB_TO_MSB;
dp_chain_mask = DP_CHAIN_15BPP;
+ } else if (bpp <= 16) {
+ bpp = 16;
+ pix_width = CRTC_PIX_WIDTH_16BPP;
+ dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
+ BYTE_ORDER_LSB_TO_MSB;
+ dp_chain_mask = DP_CHAIN_16BPP;
} else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
bpp = 24;
pix_width = CRTC_PIX_WIDTH_24BPP;
@@ -730,30 +787,59 @@
h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+ if((xres > 1600) || (yres > 1200)) {
+ FAIL("MACH64 chips are designed for max 1600x1200\n"
+ "select anoter resolution.");
+ }
+ h_sync_strt = h_disp + var->right_margin;
+ h_sync_end = h_sync_strt + var->hsync_len;
+ h_sync_dly = var->right_margin & 7;
+ h_total = h_sync_end + h_sync_dly + var->left_margin;
+
+ v_sync_strt = v_disp + var->lower_margin;
+ v_sync_end = v_sync_strt + var->vsync_len;
+ v_total = v_sync_end + var->upper_margin;
+
#ifdef CONFIG_FB_ATY_GENERIC_LCD
if (par->lcd_table != 0) {
- u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
- lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
+ if(!M64_HAS(LT_LCD_REGS)) {
+ u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
+ crtc->lcd_index = lcd_index &
+ ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
+ aty_st_le32(LCD_INDEX, lcd_index, par);
+ }
+
+ if (!M64_HAS(MOBIL_BUS))
+ crtc->lcd_index |= CRTC2_DISPLAY_DIS;
- if((lcd_on_off & LCD_ON) &&
+ crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
+ crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
+
+ crtc->lcd_gen_cntl &=
+ ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
+ /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
+ USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
+ crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
+
+ if((crtc->lcd_gen_cntl & LCD_ON) &&
((xres > par->lcd_width) || (yres > par->lcd_height))) {
/* We cannot display the mode on the LCD. If the CRT is enabled
we can turn off the LCD.
If the CRT is off, it isn't a good idea to switch it on; we don't
know if one is connected. So it's better to fail then.
*/
- if (lcd_on_off & CRT_ON) {
- printk(KERN_INFO "Disable lcd panel, because video mode does not fit.\n");
- lcd_on_off &= ~LCD_ON;
- aty_st_lcd(LCD_GEN_CNTL, lcd_on_off, par);
+ if (crtc->lcd_gen_cntl & CRT_ON) {
+ PRINTKI("Disable lcd panel, because video mode does not fit.\n");
+ crtc->lcd_gen_cntl &= ~LCD_ON;
+ /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
} else {
FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode.");
}
}
- aty_st_le32(LCD_INDEX, lcd_index, par);
}
- if ((par->lcd_table != 0) && (lcd_on_off & LCD_ON)) {
+ if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
+ int VScan = 1;
/* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */
@@ -784,24 +870,9 @@
v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
v_total = v_disp + par->lcd_vblank_len / VScan;
- } else {
+ }
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
- if((xres > 1600) || (yres > 1200)) {
- FAIL("MACH64 chips are designed for max 1600x1200\n"
- "select anoter resolution.");
- }
- h_sync_strt = h_disp + var->right_margin;
- h_sync_end = h_sync_strt + var->hsync_len;
- h_sync_dly = var->right_margin & 7;
- h_total = h_sync_end + h_sync_dly + var->left_margin;
-
- v_sync_strt = v_disp + var->lower_margin;
- v_sync_end = v_sync_strt + var->vsync_len;
- v_total = v_sync_end + var->upper_margin;
-#ifdef CONFIG_FB_ATY_GENERIC_LCD
- }
-#endif
h_disp = (h_disp >> 3) - 1;
h_sync_strt = (h_sync_strt >> 3) - 1;
h_sync_end = (h_sync_end >> 3) - 1;
@@ -810,7 +881,9 @@
FAIL_MAX("h_disp too large", h_disp, 0xff);
FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
- FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);
+ /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
+ if(h_sync_wid > 0x1f)
+ h_sync_wid = 0x1f;
FAIL_MAX("h_total too large", h_total, 0x1ff);
if (vmode & FB_VMODE_DOUBLE) {
@@ -820,26 +893,24 @@
v_total <<= 1;
}
- if(1) {
- int VDisplay = yres;
+ vdisplay = yres;
#ifdef CONFIG_FB_ATY_GENERIC_LCD
- if ((par->lcd_table != 0) && (lcd_on_off & LCD_ON))
- VDisplay = par->lcd_height;
+ if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
+ vdisplay = par->lcd_height;
#endif
- if(VDisplay < 400) {
- h_sync_pol = 1;
- v_sync_pol = 0;
- } else if(VDisplay < 480) {
- h_sync_pol = 0;
- v_sync_pol = 1;
- } else if(VDisplay < 768) {
- h_sync_pol = 0;
- v_sync_pol = 0;
- } else {
- h_sync_pol = 1;
- v_sync_pol = 1;
- }
+ if(vdisplay < 400) {
+ h_sync_pol = 1;
+ v_sync_pol = 0;
+ } else if(vdisplay < 480) {
+ h_sync_pol = 0;
+ v_sync_pol = 1;
+ } else if(vdisplay < 768) {
+ h_sync_pol = 0;
+ v_sync_pol = 0;
+ } else {
+ h_sync_pol = 1;
+ v_sync_pol = 1;
}
v_disp--;
@@ -850,7 +921,9 @@
FAIL_MAX("v_disp too large", v_disp, 0x7ff);
FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
- FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);
+ /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
+ if(v_sync_wid > 0x1f)
+ v_sync_wid = 0x1f;
FAIL_MAX("v_total too large", v_total, 0x7ff);
c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
@@ -881,12 +954,12 @@
if (vmode & FB_VMODE_INTERLACED)
crtc->gen_cntl |= CRTC_INTERLACE_EN;
#ifdef CONFIG_FB_ATY_GENERIC_LCD
- if ((par->lcd_table != 0) && (lcd_on_off & LCD_ON)) {
- int VDisplay = yres;
+ if (par->lcd_table != 0) {
+ vdisplay = yres;
if(vmode & FB_VMODE_DOUBLE)
- VDisplay <<= 1;
+ vdisplay <<= 1;
if(vmode & FB_VMODE_INTERLACED) {
- VDisplay >>= 1;
+ vdisplay >>= 1;
/* The prefered mode for the lcd is not interlaced, so disable it if
it was enabled. For doublescan there is no problem, because we can
@@ -896,14 +969,16 @@
/*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/
}
crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
-/*
- crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | SCLK_SEL | USE_SHADOWED_VEND | SHADOW_EN);
- crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR);
-*/
+ crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
+ /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
+ USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
+ crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
+
/* MOBILITY M1 tested, FIXME: LT */
crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
- crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
- ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
+ if (!M64_HAS(LT_LCD_REGS))
+ crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
+ ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
crtc->horz_stretching &=
~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
@@ -970,11 +1045,12 @@
} while (0);
}
- if (VDisplay < par->lcd_height) {
+ if (vdisplay < par->lcd_height) {
crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
- (((VDisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
+ (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
- if (xres <= (M64_HAS(MOBIL_BUS)?1024:800))
+ if (!M64_HAS(LT_LCD_REGS) &&
+ xres <= (M64_HAS(MOBIL_BUS)?1024:800))
crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
} else {
/*
@@ -983,13 +1059,12 @@
*/
crtc->vert_stretching = 0;
}
+ /* copy to shadow crtc */
+ crtc->shadow_h_tot_disp = crtc->h_tot_disp;
+ crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
+ crtc->shadow_v_tot_disp = crtc->v_tot_disp;
+ crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
}
-
- /* copy to shadow crtc */
- crtc->shadow_h_tot_disp = crtc->h_tot_disp;
- crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
- crtc->shadow_v_tot_disp = crtc->v_tot_disp;
- crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
if (M64_HAS(MAGIC_FIFO)) {
@@ -1078,7 +1153,6 @@
var->transp.offset = 0;
var->transp.length = 0;
break;
-#if 0
case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
bpp = 16;
var->red.offset = 11;
@@ -1090,7 +1164,6 @@
var->transp.offset = 0;
var->transp.length = 0;
break;
-#endif
case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
bpp = 24;
var->red.offset = 16;
@@ -1183,7 +1256,6 @@
wait_for_idle(par);
aty_set_crtc(par, &par->crtc);
-
par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
par->pll_ops->set_pll(info, &par->pll);
@@ -1194,7 +1266,7 @@
pixclock_in_ps = 0;
if(0 == pixclock_in_ps) {
- printk(KERN_CRIT "ALERT ops->pll_to_var get 0\n");
+ PRINTKE("ALERT ops->pll_to_var get 0\n");
pixclock_in_ps = pixclock;
}
@@ -1220,23 +1292,23 @@
if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
vRefresh /= 2;
- printk("atyfb: atyfb_set_par\n");
- printk(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
- printk(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
+ DPRINTK("atyfb_set_par\n");
+ DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
+ DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
- printk(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps);
- printk(" Horizontal sync: %i kHz\n", hSync);
- printk(" Vertical refresh: %i Hz\n", vRefresh);
- printk(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
+ DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps);
+ DPRINTK(" Horizontal sync: %i kHz\n", hSync);
+ DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
+ DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
h_disp, h_sync_strt, h_sync_end, h_total,
v_disp, v_sync_strt, v_sync_end, v_total);
- printk( " fb style:%i %i %i %i %i %i %i %i %i\n",
+ DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
pixclock_in_ps,
debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
}
-#endif
+#endif /* DEBUG */
if (!M64_HAS(INTEGRATED)) {
/* Don't forget MEM_CNTL */
@@ -1315,9 +1387,9 @@
/* CRTC registers */
base = 0x2000;
- printk("Mach64 non-shadow register values:");
+ printk("debug atyfb: Mach64 non-shadow register values:");
for (i = 0; i < 256; i = i+4) {
- if(i%16 == 0) printk("\n0x%04X: ", base + i);
+ if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
printk(" %08X", aty_ld_le32(i, par));
}
printk("\n\n");
@@ -1325,9 +1397,9 @@
#ifdef CONFIG_FB_ATY_CT
/* PLL registers */
base = 0x00;
- printk("Mach64 PLL register values:");
+ printk("debug atyfb: Mach64 PLL register values:");
for (i = 0; i < 64; i++) {
- if(i%16 == 0) printk("\n0x%02X: ", base + i);
+ if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
if(i%4 == 0) printk(" ");
printk("%02X", aty_ld_pll_ct(i, par));
}
@@ -1338,10 +1410,20 @@
if (par->lcd_table != 0) {
/* LCD registers */
base = 0x00;
- printk("LCD register values:");
- for (i = 0; i < 64; i++) {
- if(i%4 == 0) printk("\n0x%02X: ", base + i);
+ printk("debug atyfb: LCD register values:");
+ if(M64_HAS(LT_LCD_REGS)) {
+ for(i = 0; i <= POWER_MANAGEMENT; i++) {
+ if(i == EXT_VERT_STRETCH)
+ continue;
+ printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
+ printk(" %08X", aty_ld_lcd(i, par));
+ }
+
+ } else {
+ for (i = 0; i < 64; i++) {
+ if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
printk(" %08X", aty_ld_lcd(i, par));
+ }
}
printk("\n\n");
}
@@ -1395,7 +1477,6 @@
u32 bpp = info->var.bits_per_pixel;
par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
- aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
}
@@ -1405,26 +1486,103 @@
static int atyfb_open(struct fb_info *info, int user)
{
-#ifdef __sparc__
struct atyfb_par *par = (struct atyfb_par *) info->par;
if (user) {
par->open++;
+#ifdef __sparc__
par->mmaped = 0;
- }
#endif
+ }
return (0);
}
+static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp)
+{
+ struct atyfb_par *par = dev_id;
+ int handled = 0;
+ u32 int_cntl;
+
+ spin_lock(&par->int_lock);
+
+ int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
+
+ if (int_cntl & CRTC_VBLANK_INT) {
+ /* clear interrupt */
+ aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
+ par->vblank.count++;
+ if (par->vblank.pan_display) {
+ par->vblank.pan_display = 0;
+ aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
+ }
+ wake_up_interruptible(&par->vblank.wait);
+ handled = 1;
+ }
+
+ spin_unlock(&par->int_lock);
+
+ return IRQ_RETVAL(handled);
+}
+
+static int aty_enable_irq(struct atyfb_par *par, int reenable)
+{
+ u32 int_cntl;
+
+ if (!test_and_set_bit(0, &par->irq_flags)) {
+ if (request_irq(par->irq, aty_irq, SA_SHIRQ, "atyfb", par)) {
+ clear_bit(0, &par->irq_flags);
+ return -EINVAL;
+ }
+ spin_lock_irq(&par->int_lock);
+ int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
+ /* clear interrupt */
+ aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
+ /* enable interrupt */
+ aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
+ spin_unlock_irq(&par->int_lock);
+ } else if (reenable) {
+ spin_lock_irq(&par->int_lock);
+ int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
+ if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
+ printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
+ /* re-enable interrupt */
+ aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
+ }
+ spin_unlock_irq(&par->int_lock);
+ }
+
+ return 0;
+}
+
+static int aty_disable_irq(struct atyfb_par *par)
+{
+ u32 int_cntl;
+
+ if (test_and_clear_bit(0, &par->irq_flags)) {
+ if (par->vblank.pan_display) {
+ par->vblank.pan_display = 0;
+ aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
+ }
+ spin_lock_irq(&par->int_lock);
+ int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
+ /* disable interrupt */
+ aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
+ spin_unlock_irq(&par->int_lock);
+ free_irq(par->irq, par);
+ }
+
+ return 0;
+}
+
static int atyfb_release(struct fb_info *info, int user)
{
-#ifdef __sparc__
struct atyfb_par *par = (struct atyfb_par *) info->par;
if (user) {
par->open--;
mdelay(1);
wait_for_idle(par);
if (!par->open) {
+#ifdef __sparc__
int was_mmaped = par->mmaped;
par->mmaped = 0;
@@ -1443,15 +1601,16 @@
else
var.accel_flags |= FB_ACCELF_TEXT;
if (var.yres == var.yres_virtual) {
- u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
- var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
+ u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
+ var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
if (var.yres_virtual < var.yres)
var.yres_virtual = var.yres;
}
}
+#endif
+ aty_disable_irq(par);
}
}
-#endif
return (0);
}
@@ -1478,10 +1637,50 @@
info->var.yoffset = yoffset;
if (par->asleep)
return 0;
+
set_off_pitch(par, info);
+ if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
+ par->vblank.pan_display = 1;
+ } else {
+ par->vblank.pan_display = 0;
+ aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
+ }
+
return 0;
}
+static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
+{
+ struct aty_interrupt *vbl;
+ unsigned int count;
+ int ret;
+
+ switch (crtc) {
+ case 0:
+ vbl = &par->vblank;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ret = aty_enable_irq(par, 0);
+ if (ret)
+ return ret;
+
+ count = vbl->count;
+ ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
+ if (ret < 0) {
+ return ret;
+ }
+ if (ret == 0) {
+ aty_enable_irq(par, 1);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+
#ifdef DEBUG
#define ATYIO_CLKR 0x41545900 /* ATY\00 */
#define ATYIO_CLKW 0x41545901 /* ATY\01 */
@@ -1506,12 +1705,14 @@
#define ATYIO_FEATW 0x41545903 /* ATY\03 */
#endif
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#endif
+
static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, struct fb_info *info)
{
-#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
struct atyfb_par *par = (struct atyfb_par *) info->par;
-#endif /* __sparc__ || DEBUG */
#ifdef __sparc__
struct fbtype fbtyp;
#endif
@@ -1529,6 +1730,18 @@
return -EFAULT;
break;
#endif /* __sparc__ */
+
+ case FBIO_WAITFORVSYNC:
+ {
+ u32 crtc;
+
+ if (get_user(crtc, (__u32 *) arg))
+ return -EFAULT;
+
+ return aty_waitforvblank(par, crtc);
+ }
+ break;
+
#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
case ATYIO_CLKR:
if (M64_HAS(INTEGRATED)) {
@@ -1725,6 +1938,7 @@
info->var.yoffset = atyfb_save.yoffset;
set_off_pitch(par, info);
}
+ aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
break;
}
}
@@ -1736,69 +1950,10 @@
#if defined(CONFIG_PM) && defined(CONFIG_PCI)
/* Power management routines. Those are used for PowerBook sleep.
- *
- * It appears that Rage LT and Rage LT Pro have different power
- * management registers. There's is some confusion about which
- * chipID is a Rage LT or LT pro :(
*/
-static int aty_power_mgmt_LT(int sleep, struct atyfb_par *par)
-{
- unsigned int pm;
- int timeout;
-
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
-
- timeout = 200000;
- if (sleep) {
- /* Sleep */
- pm &= ~PWR_MGT_ON;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- pm &= ~(PWR_BLON | AUTO_PWR_UP);
- pm |= SUSPEND_NOW;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- pm |= PWR_MGT_ON;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- do {
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- if ((--timeout) == 0)
- break;
- } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
- } else {
- /* Wakeup */
- pm &= ~PWR_MGT_ON;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- pm |= (PWR_BLON | AUTO_PWR_UP);
- pm &= ~SUSPEND_NOW;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- pm |= PWR_MGT_ON;
- aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
- do {
- pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
- udelay(10);
- if ((--timeout) == 0)
- break;
- } while ((pm & PWR_MGT_STATUS_MASK) != 0);
- }
- mdelay(500);
-
- return timeout ? -1 : 0;
-}
-
-static int aty_power_mgmt_LTPro(int sleep, struct atyfb_par *par)
+static int aty_power_mgmt(int sleep, struct atyfb_par *par)
{
- unsigned int pm;
+ u32 pm;
int timeout;
pm = aty_ld_lcd(POWER_MANAGEMENT, par);
@@ -1806,7 +1961,7 @@
aty_st_lcd(POWER_MANAGEMENT, pm, par);
pm = aty_ld_lcd(POWER_MANAGEMENT, par);
- timeout = 200;
+ timeout = 2000;
if (sleep) {
/* Sleep */
pm &= ~PWR_MGT_ON;
@@ -1846,16 +2001,11 @@
break;
} while ((pm & PWR_MGT_STATUS_MASK) != 0);
}
+ mdelay(500);
return timeout ? -1 : 0;
}
-static int aty_power_mgmt(int sleep, struct atyfb_par *par)
-{
- return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, par)
- : aty_power_mgmt_LTPro(sleep, par);
-}
-
static int atyfb_pci_suspend(struct pci_dev *pdev, u32 state)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -1990,7 +2140,7 @@
const int *refresh_tbl;
int i, size;
- if (IS_XL(par->pci_id)) {
+ if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
refresh_tbl = ragexl_tbl;
size = sizeof(ragexl_tbl)/sizeof(int);
} else {
@@ -2023,15 +2173,18 @@
int sense;
#endif
+ init_waitqueue_head(&par->vblank.wait);
+ spin_lock_init(&par->int_lock);
+
par->aty_cmap_regs =
(struct aty_cmap_regs *) (par->ati_regbase + 0xc0);
- if (default_pll)
- par->pll_limits.pll_max = default_pll;
- if (default_mclk)
- par->pll_limits.mclk = default_mclk;
- if (default_xclk)
- par->pll_limits.xclk = default_xclk;
+ if (pll)
+ par->pll_limits.pll_max = pll;
+ if (mclk)
+ par->pll_limits.mclk = mclk;
+ if (xclk)
+ par->pll_limits.xclk = xclk;
aty_calc_mem_refresh(par, par->pll_limits.xclk);
par->pll_per = 1000000/par->pll_limits.pll_max;
@@ -2076,7 +2229,7 @@
par->dac_ops = &aty_dac_att21c498;
break;
default:
- printk(" aty_init: DAC type not implemented yet!\n");
+ PRINTKI("aty_init: DAC type not implemented yet!\n");
par->dac_ops = &aty_dac_unsupported;
break;
}
@@ -2097,7 +2250,7 @@
par->pll_ops = &aty_pll_ibm514;
break;
default:
- printk(" aty_init: CLK type not implemented yet!");
+ PRINTKI("aty_init: CLK type not implemented yet!");
par->pll_ops = &aty_pll_unsupported;
break;
}
@@ -2131,11 +2284,12 @@
}
}
#endif /* CONFIG_FB_ATY_CT */
-#if 0
+
+ /* save previous video mode */
aty_get_crtc(par, &saved_crtc);
if(par->pll_ops->get_pll)
par->pll_ops->get_pll(info, &saved_pll);
-#endif
+
i = aty_ld_le32(MEM_CNTL, par);
gtb_memsize = M64_HAS(GTB_DSP);
if (gtb_memsize)
@@ -2189,8 +2343,8 @@
info->fix.smem_len += 0x400000;
}
- if (default_vram) {
- info->fix.smem_len = default_vram * 1024;
+ if (vram) {
+ info->fix.smem_len = vram * 1024;
i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
if (info->fix.smem_len <= 0x80000)
i |= MEM_SIZE_512K;
@@ -2218,16 +2372,16 @@
info->fix.mmio_len = 0x400;
info->fix.accel = FB_ACCEL_ATI_MACH64CT;
} else if (M64_HAS(VT)) {
- info->fix.mmio_start = -0x400;
+ info->fix.mmio_start -= 0x400;
info->fix.mmio_len = 0x800;
info->fix.accel = FB_ACCEL_ATI_MACH64VT;
} else {/* GT */
- info->fix.mmio_start = -0x400;
+ info->fix.mmio_start -= 0x400;
info->fix.mmio_len = 0x800;
info->fix.accel = FB_ACCEL_ATI_MACH64GT;
}
- printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
+ PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
par->pll_limits.mclk, par->pll_limits.xclk);
@@ -2235,10 +2389,10 @@
#if defined(DEBUG) && defined(CONFIG_ATY_CT)
if (M64_HAS(INTEGRATED)) {
int i;
- printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
+ printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
"DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
- "%08x %08x %08x %08x %08x %08x %08x %08x\n"
- "PLL",
+ "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n"
+ "debug atyfb: PLL",
aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
@@ -2292,8 +2446,8 @@
* FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
* applies to all Mac video cards
*/
- if (mode_option) {
- if (!mac_find_mode(&var, info, mode_option, 8))
+ if (mode) {
+ if (!mac_find_mode(&var, info, mode, 8))
var = default_var;
} else {
if (default_vmode == VMODE_CHOOSE) {
@@ -2309,7 +2463,7 @@
else
default_vmode = VMODE_640_480_67;
sense = read_aty_sense(par);
- printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n",
+ PRINTKI("monitor sense=%x, mode %d\n",
sense, mac_map_monitor_sense(sense));
}
if (default_vmode <= 0 || default_vmode > VMODE_MAX)
@@ -2321,7 +2475,7 @@
}
} else
#endif /* !CONFIG_PPC */
- if (!fb_find_mode(&var, info, mode_option, NULL, 0, &defmode, 8))
+ if (!fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
var = default_var;
if (noaccel)
@@ -2330,15 +2484,15 @@
var.accel_flags |= FB_ACCELF_TEXT;
if (var.yres == var.yres_virtual) {
- u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
- var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
+ u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
+ var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
if (var.yres_virtual < var.yres)
var.yres_virtual = var.yres;
}
if (atyfb_check_var(&var, info)) {
- printk(KERN_CRIT "atyfb: can't set default video mode\n");
- return 0;
+ PRINTKE("can't set default video mode\n");
+ goto aty_init_exit;
}
#ifdef __sparc__
@@ -2346,7 +2500,7 @@
#endif
#ifdef CONFIG_FB_ATY_CT
- if (M64_HAS(INTEGRATED))
+ if (!noaccel && M64_HAS(INTEGRATED))
aty_init_cursor(info);
#endif /* CONFIG_FB_ATY_CT */
info->var = var;
@@ -2354,85 +2508,21 @@
fb_alloc_cmap(&info->cmap, 256, 0);
if (register_framebuffer(info) < 0)
- return 0;
+ goto aty_init_exit;
fb_list = info;
- printk("fb%d: %s frame buffer device on %s\n",
+ PRINTKI("fb%d: %s frame buffer device on %s\n",
info->node, info->fix.id, name);
return 1;
-}
-
-#ifndef MODULE
-int __init atyfb_setup(char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return 0;
+
+aty_init_exit:
+ /* restore video mode */
+ aty_set_crtc(par, &saved_crtc);
+ par->pll_ops->set_pll(info, &saved_pll);
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!strncmp(this_opt, "noaccel", 7)) {
- noaccel = 1;
- } else if (!strncmp(this_opt, "vram:", 5))
- default_vram =
- simple_strtoul(this_opt + 5, NULL, 0);
- else if (!strncmp(this_opt, "pll:", 4))
- default_pll =
- simple_strtoul(this_opt + 4, NULL, 0);
- else if (!strncmp(this_opt, "mclk:", 5))
- default_mclk =
- simple_strtoul(this_opt + 5, NULL, 0);
- else if (!strncmp(this_opt, "xclk:", 5))
- default_xclk =
- simple_strtoul(this_opt+5, NULL, 0);
-#ifdef CONFIG_PPC
- else if (!strncmp(this_opt, "vmode:", 6)) {
- unsigned 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)) {
- unsigned int cmode =
- simple_strtoul(this_opt + 6, NULL, 0);
- switch (cmode) {
- case 0:
- 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;
- }
- }
-#endif
-#ifdef CONFIG_ATARI
- /*
- * Why do we need this silly Mach64 argument?
- * We are already here because of mach64= so its redundant.
- */
- else if (MACH_IS_ATARI
- && (!strncmp(this_opt, "Mach64:", 7))) {
- static unsigned char m64_num;
- static char mach64_str[80];
- strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
- if (!store_video_par(mach64_str, m64_num)) {
- m64_num++;
- mach64_count = m64_num;
- }
- }
-#endif
- else
- mode_option = this_opt;
- }
return 0;
}
-#endif /* !MODULE */
#ifdef CONFIG_ATARI
static int __init store_video_par(char *video_str, unsigned char m64_num)
@@ -2440,7 +2530,7 @@
char *p;
unsigned long vmembase, size, guiregbase;
- printk("store_video_par() '%s' \n", video_str);
+ PRINTKI("store_video_par() '%s' \n", video_str);
if (!(p = strsep(&video_str, ";")) || !*p)
goto mach64_invalid;
@@ -2455,7 +2545,7 @@
phys_vmembase[m64_num] = vmembase;
phys_size[m64_num] = size;
phys_guiregbase[m64_num] = guiregbase;
- printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
+ PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
guiregbase);
return 0;
@@ -2480,7 +2570,14 @@
#ifdef CONFIG_PMAC_BACKLIGHT
if ((_machine == _MACH_Pmac) && blank)
set_backlight_enable(0);
-#endif /* CONFIG_PMAC_BACKLIGHT */
+#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
+ if (par->lcd_table && blank &&
+ (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+ u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
+ pm &= ~PWR_BLON;
+ aty_st_lcd(POWER_MANAGEMENT, pm, par);
+ }
+#endif
gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
if (blank > 0)
@@ -2504,52 +2601,76 @@
#ifdef CONFIG_PMAC_BACKLIGHT
if ((_machine == _MACH_Pmac) && !blank)
set_backlight_enable(1);
-#endif /* CONFIG_PMAC_BACKLIGHT */
+#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
+ if (par->lcd_table && !blank &&
+ (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+ u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
+ pm |= PWR_BLON;
+ aty_st_lcd(POWER_MANAGEMENT, pm, par);
+ }
+#endif
+
return 0;
}
+static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
+ const struct atyfb_par *par)
+{
+#ifdef CONFIG_ATARI
+ out_8(&par->aty_cmap_regs->windex, regno);
+ out_8(&par->aty_cmap_regs->lut, red);
+ out_8(&par->aty_cmap_regs->lut, green);
+ out_8(&par->aty_cmap_regs->lut, blue);
+#else
+ writeb(regno, &par->aty_cmap_regs->windex);
+ writeb(red, &par->aty_cmap_regs->lut);
+ writeb(green, &par->aty_cmap_regs->lut);
+ writeb(blue, &par->aty_cmap_regs->lut);
+#endif
+}
+
/*
* Set a single color register. The values supplied are already
* rounded down to the hardware's capabilities (according to the
* entries in the var structure). Return != 0 for invalid regno.
+ * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
*/
static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
- int i, scale;
+ int i, depth;
u32 *pal = info->pseudo_palette;
+ depth = info->var.bits_per_pixel;
+ if (depth == 16)
+ depth = (info->var.green.length == 5) ? 15 : 16;
+
if (par->asleep)
return 0;
- if (regno > 255)
+
+ if (regno > 255 ||
+ (depth == 16 && regno > 63) ||
+ (depth == 15 && regno > 31))
return 1;
+
red >>= 8;
green >>= 8;
blue >>= 8;
- i = aty_ld_8(DAC_CNTL, par) & 0xfc;
- if (M64_HAS(EXTRA_BRIGHT))
- i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
- aty_st_8(DAC_CNTL, i, par);
- aty_st_8(DAC_MASK, 0xff, par);
- scale = (M64_HAS(INTEGRATED) && info->var.bits_per_pixel == 16) ? 3 : 0;
-#ifdef CONFIG_ATARI
- out_8(&par->aty_cmap_regs->windex, regno << scale);
- out_8(&par->aty_cmap_regs->lut, red);
- out_8(&par->aty_cmap_regs->lut, green);
- out_8(&par->aty_cmap_regs->lut, blue);
-#else
- writeb(regno << scale, &par->aty_cmap_regs->windex);
- writeb(red, &par->aty_cmap_regs->lut);
- writeb(green, &par->aty_cmap_regs->lut);
- writeb(blue, &par->aty_cmap_regs->lut);
-#endif
- if (regno < 16)
- switch (info->var.bits_per_pixel) {
- case 16:
+
+ par->palette[regno].red = red;
+ par->palette[regno].green = green;
+ par->palette[regno].blue = blue;
+
+ if (regno < 16) {
+ switch (depth) {
+ case 15:
pal[regno] = (regno << 10) | (regno << 5) | regno;
break;
+ case 16:
+ pal[regno] = (regno << 11) | (regno << 5) | regno;
+ break;
case 24:
pal[regno] = (regno << 16) | (regno << 8) | regno;
break;
@@ -2558,6 +2679,32 @@
pal[regno] = (i << 16) | i;
break;
}
+ }
+
+ i = aty_ld_8(DAC_CNTL, par) & 0xfc;
+ if (M64_HAS(EXTRA_BRIGHT))
+ i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
+ aty_st_8(DAC_CNTL, i, par);
+ aty_st_8(DAC_MASK, 0xff, par);
+
+ if (M64_HAS(INTEGRATED)) {
+ if (depth == 16) {
+ if (regno < 32)
+ aty_st_pal(regno << 3, red,
+ par->palette[regno<<1].green,
+ blue, par);
+ red = par->palette[regno>>1].red;
+ blue = par->palette[regno>>1].blue;
+ regno <<= 2;
+ } else if (depth == 15) {
+ regno <<= 3;
+ for(i = 0; i < 8; i++) {
+ aty_st_pal(regno + i, red, green, blue, par);
+ }
+ }
+ }
+ aty_st_pal(regno, red, green, blue, par);
+
return 0;
}
@@ -2573,7 +2720,7 @@
struct atyfb_par *par = info->par;
struct pcidev_cookie *pcp;
char prop[128];
- int node, len, i, j;
+ int node, len, i, j, ret;
u32 mem, chip_id;
/* Do not attach when we have a serial console. */
@@ -2602,7 +2749,7 @@
par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
if (!_par->mmap_map) {
- printk(KERN_ERR "atyfb_init: can't alloc mmap_map\n");
+ PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
return -ENOMEM;
}
memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
@@ -2661,7 +2808,8 @@
j++;
}
- correct_chipset(par);
+ if((ret = correct_chipset(par)))
+ return ret;
if (IS_XL(pdev->device)) {
/*
@@ -2735,7 +2883,7 @@
* Read the PLL to figure actual Refresh Rate.
*/
clock_cntl = aty_ld_8(CLOCK_CNTL, par);
- /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
+ /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
for (i = 0; i < 16; i++)
pll_regs[i] = aty_ld_pll_ct(i, par);
@@ -2783,6 +2931,7 @@
#else /* __sparc__ */
+#ifdef __i386__
#ifdef CONFIG_FB_ATY_GENERIC_LCD
void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
{
@@ -2805,7 +2954,7 @@
(sig == 0x544d5224) || /* Rage mobility */
(sig == 0x54435824) || /* Rage XC */
(sig == 0x544c5824)) { /* Rage XL */
- printk(KERN_INFO "atyfb: BIOS contains driver information table.\n");
+ PRINTKI("BIOS contains driver information table.\n");
lcd_ofs = (*(u16 *)(driv_inf_tab + 10));
par->lcd_table = 0;
if (lcd_ofs != 0) {
@@ -2904,8 +3053,10 @@
txtformat = "unkown format";
}
}
- printk(KERN_INFO "atyfb: %s%s %s monitor detected: %s\n id=%d, %dx%d pixels, %s\n",
- txtdual ,txtcolour, txtmonitor, model, id, width, height, txtformat);
+ PRINTKI("%s%s %s monitor detected: %s\n",
+ txtdual ,txtcolour, txtmonitor, model);
+ PRINTKI(" id=%d, %dx%d pixels, %s\n",
+ id, width, height, txtformat);
refresh_rates_buf[0] = 0;
refresh_rates = *(u16 *)(par->lcd_table+62);
m = 1;
@@ -2923,7 +3074,7 @@
m = m << 1;
}
default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
- printk(KERN_INFO " supports refresh rates [%s], default %d Hz\n",
+ PRINTKI(" supports refresh rates [%s], default %d Hz\n",
refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
/* We now need to determine the crtc parameters for the
@@ -2978,10 +3129,10 @@
lcdmodeptr++;
}
if (*lcdmodeptr == 0) {
- printk(KERN_WARNING "atyfb: LCD monitor CRTC parameters not found!!!\n");
+ PRINTKE("LCD monitor CRTC parameters not found!!!\n");
/* To do: Switch to CRT if possible. */
} else {
- printk(KERN_INFO " LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
+ PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
par->lcd_hdisp,
par->lcd_hdisp + par->lcd_right_margin,
@@ -2992,7 +3143,7 @@
par->lcd_vdisp + par->lcd_lower_margin,
par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
par->lcd_vtotal);
- printk(KERN_INFO " : %d %d %d %d %d %d %d %d %d\n",
+ PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
par->lcd_pixclock,
par->lcd_hblank_len - (par->lcd_right_margin +
par->lcd_hsync_dly + par->lcd_hsync_len),
@@ -3023,7 +3174,7 @@
u16 rom_table_offset, freq_table_offset;
PLL_BLOCK_MACH64 pll_block;
- printk(KERN_INFO "atyfb: Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
+ PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
/* check for frequncy table */
bios_ptr = (u8*)bios_base;
@@ -3031,11 +3182,11 @@
freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
- printk(KERN_INFO "atyfb: BIOS frequency table:\n");
- printk(KERN_INFO " PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
+ PRINTKI("BIOS frequency table:\n");
+ PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
pll_block.ref_freq, pll_block.ref_divider);
- printk(KERN_INFO " MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
+ PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
pll_block.XCLK_max_freq, pll_block.SCLK_freq);
@@ -3052,13 +3203,14 @@
#endif
ret = 0;
} else {
- printk(KERN_CRIT "atyfb: no BIOS frequency table found, use parameters\n");
+ PRINTKE("no BIOS frequency table found, use parameters\n");
ret = -ENXIO;
}
iounmap((void*)bios_base);
return ret;
}
+#endif /* __i386__ */
static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr)
{
@@ -3066,6 +3218,7 @@
u16 tmp;
unsigned long raddr;
struct resource *rrp;
+ int ret = 0;
raddr = addr + 0x7ff000UL;
rrp = &pdev->resource[2];
@@ -3073,7 +3226,7 @@
par->aux_start = rrp->start;
par->aux_size = rrp->end - rrp->start + 1;
raddr = rrp->start;
- printk(KERN_INFO "atyfb: using auxiliary register aperture\n");
+ PRINTKI("using auxiliary register aperture\n");
}
info->fix.mmio_start = raddr;
@@ -3102,16 +3255,16 @@
info->fix.smem_start = addr;
info->screen_base = (char *)ioremap(addr, 0x800000);
if (info->screen_base == NULL) {
- iounmap((void *)par->ati_regbase);
- par->ati_regbase = 0;
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto atyfb_setup_generic_fail;
}
- /* always succeeded ? */
- if (correct_chipset(par) < 0)
- return -ENXIO;
- init_from_bios(par);
-
+ if((ret = correct_chipset(par)))
+ goto atyfb_setup_generic_fail;
+#ifdef __i386__
+ if((ret = init_from_bios(par)))
+ goto atyfb_setup_generic_fail;
+#endif
if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
else
@@ -3121,16 +3274,21 @@
par->clk_wr_offset = 3;
return 0;
+
+atyfb_setup_generic_fail:
+ iounmap((void *)par->ati_regbase);
+ par->ati_regbase = 0;
+ return ret;
}
#endif /* !__sparc__ */
static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- unsigned long addr;
+ unsigned long addr, res_start, res_size;
struct fb_info *info;
struct resource *rp;
- struct atyfb_par *par = info->par;
+ struct atyfb_par *par;
int i, rc = -ENOMEM;
for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
@@ -3142,7 +3300,7 @@
/* Enable device in PCI config */
if (pci_enable_device(pdev)) {
- printk(KERN_ERR "atyfb: Cannot enable PCI device\n");
+ PRINTKE("Cannot enable PCI device\n");
return -ENXIO;
}
@@ -3154,23 +3312,24 @@
if (!addr)
return -ENXIO;
- /* Allocate framebuffer */
+ /* Reserve space */
+ res_start = rp->start;
+ res_size = rp->end - rp->start + 1;
+ if (!request_mem_region (res_start, res_size, "atyfb"))
+ return -EBUSY;
+
+ /* Allocate framebuffer */
info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
if (!info) {
- printk(KERN_ERR "atyfb_init: can't alloc fb_info\n");
+ PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
return -ENOMEM;
}
par = info->par;
info->fix = atyfb_fix;
par->pci_id = aty_chips[i].pci_id;
-
- /* Reserve space */
- par->res_start = rp->start;
- par->res_size = rp->end - rp->start + 1;
- if (!request_mem_region (par->res_start, par->res_size, "atyfb")) {
- rc = -EBUSY;
- goto err_free;
- }
+ par->res_start = res_start;
+ par->res_size = res_size;
+ par->irq = pdev->irq;
/* Setup "info" structure */
#ifdef __sparc__
@@ -3224,7 +3383,6 @@
release_mem_region(par->aux_start, par->aux_size);
release_mem_region(par->res_start, par->res_size);
-err_free:
framebuffer_release(info);
return rc;
@@ -3244,19 +3402,21 @@
for (m64_num = 0; m64_num < mach64_count; m64_num++) {
if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
!phys_guiregbase[m64_num]) {
- printk(" phys_*[%d] parameters not set => returning early. \n", m64_num);
+ PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num);
continue;
}
info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
if (!info) {
- printk("atyfb_init: can't alloc fb_info\n");
+ PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
return -ENOMEM;
}
par = info->par;
info->fix = atyfb_fix;
+ par->irq = (unsigned int) -1; /* something invalid */
+
/*
* Map the video memory (physical address given) to somewhere in the
* kernel address space.
@@ -3298,6 +3458,10 @@
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
+ /* restore video mode */
+ aty_set_crtc(par, &saved_crtc);
+ par->pll_ops->set_pll(info, &saved_pll);
+
unregister_framebuffer(info);
#ifndef __sparc__
@@ -3375,4 +3539,93 @@
#endif
}
+int __init atyfb_setup(char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!strncmp(this_opt, "noaccel", 7)) {
+ noaccel = 1;
+ } else if (!strncmp(this_opt, "vram:", 5))
+ vram = simple_strtoul(this_opt + 5, NULL, 0);
+ else if (!strncmp(this_opt, "pll:", 4))
+ pll = simple_strtoul(this_opt + 4, NULL, 0);
+ else if (!strncmp(this_opt, "mclk:", 5))
+ mclk = simple_strtoul(this_opt + 5, NULL, 0);
+ else if (!strncmp(this_opt, "xclk:", 5))
+ xclk = simple_strtoul(this_opt+5, NULL, 0);
+#ifdef CONFIG_PPC
+ else if (!strncmp(this_opt, "vmode:", 6)) {
+ unsigned 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)) {
+ unsigned int cmode =
+ simple_strtoul(this_opt + 6, NULL, 0);
+ switch (cmode) {
+ case 0:
+ 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;
+ }
+ }
+#endif
+#ifdef CONFIG_ATARI
+ /*
+ * Why do we need this silly Mach64 argument?
+ * We are already here because of mach64= so its redundant.
+ */
+ else if (MACH_IS_ATARI
+ && (!strncmp(this_opt, "Mach64:", 7))) {
+ static unsigned char m64_num;
+ static char mach64_str[80];
+ strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
+ if (!store_video_par(mach64_str, m64_num)) {
+ m64_num++;
+ mach64_count = m64_num;
+ }
+ }
+#endif
+ else
+ mode = this_opt;
+ }
+ return 0;
+}
+
+#ifdef MODULE
+module_init(atyfb_init);
+module_exit(atyfb_exit);
+#endif
+
+MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
MODULE_LICENSE("GPL");
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
+module_param(vram, int, 0);
+MODULE_PARM_DESC(vram, "int: override size of video ram");
+module_param(pll, int, 0);
+MODULE_PARM_DESC(pll, "int: override video clock");
+module_param(mclk, int, 0);
+MODULE_PARM_DESC(mclk, "int: override memory clock");
+module_param(xclk, int, 0);
+MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
+#ifdef CONFIG_PPC
+module_param(vmode, int, 0);
+MODULE_PARM_DESC(vmode, "int: video mode for mac");
+module_param(cmode, int, 0);
+MODULE_PARM_DESC(cmode, "int: color mode for mac");
+#endif
+module_param(mode, charp, 0);
+MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
diff -ur -X patches/exclude linux-2.6.7.js3/drivers/video/aty/mach64_ct.c linux-2.6.7.ak/drivers/video/aty/mach64_ct.c
--- linux-2.6.7.js3/drivers/video/aty/mach64_ct.c 2004-06-27 01:35:27.000000000 +0200
+++ linux-2.6.7.ak/drivers/video/aty/mach64_ct.c 2004-08-04 22:32:10.000000000 +0200
@@ -115,7 +115,6 @@
static int aty_dsp_gt(const struct fb_info *info, u32 bpp, struct pll_ct *pll)
{
- struct atyfb_par *par = (struct atyfb_par *) info->par;
u32 dsp_off, dsp_on, dsp_xclks;
u32 multiplier, divider, ras_multiplier, ras_divider, tmp;
u8 vshift, xshift;
@@ -137,6 +136,8 @@
#ifdef CONFIG_FB_ATY_GENERIC_LCD
if (pll->xres != 0) {
+ struct atyfb_par *par = (struct atyfb_par *) info->par;
+
multiplier = multiplier * par->lcd_width;
divider = divider * pll->xres & ~7;
@@ -281,8 +282,8 @@
#ifdef CONFIG_FB_ATY_GENERIC_LCD
if (par->lcd_table != 0) {
/* turn off LCD */
- lcd_gen_cntrl = aty_ld_le32(LCD_GEN_CNTL, par);
- aty_st_le32(LCD_GEN_CNTL, lcd_gen_cntrl & ~LCD_ON, par);
+ lcd_gen_cntrl = aty_ld_lcd(LCD_GEN_CNTL, par);
+ aty_st_lcd(LCD_GEN_CNTL, lcd_gen_cntrl & ~LCD_ON, par);
}
#endif
aty_st_8(CLOCK_CNTL, par->clk_wr_offset | CLOCK_STROBE, par);
@@ -351,12 +352,12 @@
#ifdef CONFIG_FB_ATY_GENERIC_LCD
if (par->lcd_table != 0) {
/* restore LCD */
- aty_st_le32(LCD_GEN_CNTL, lcd_gen_cntrl, par);
+ aty_st_lcd(LCD_GEN_CNTL, lcd_gen_cntrl, par);
}
#endif
}
-#if 0
-void aty_get_pll_ct(const struct fb_info *info, union aty_pll *pll)
+
+void __init aty_get_pll_ct(const struct fb_info *info, union aty_pll *pll)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
u8 tmp, clock;
@@ -378,7 +379,7 @@
pll->ct.dsp_on_off = aty_ld_le32(DSP_ON_OFF, par);
}
}
-#endif
+
int __init aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) {
struct atyfb_par *par = (struct atyfb_par *) info->par;
u8 mpost_div, xpost_div, sclk_post_div_real, sclk_fb_div, spll_cntl2;
@@ -526,10 +527,10 @@
__FUNCTION__, pllmclk, pllmclk / pll->ct.xclk_post_div_real);
#endif
- pll->ct.pll_gen_cntl = OSC_EN;
-
- if (M64_HAS(NO_EXT_PLL))
- pll->ct.pll_gen_cntl |= (DLL_PWDN | FORCE_DCLK_TRI_STATE);
+ if (M64_HAS(SDRAM_MAGIC_PLL) && (par->ram_type >= SDRAM))
+ pll->ct.pll_gen_cntl = OSC_EN;
+ else
+ pll->ct.pll_gen_cntl = OSC_EN | DLL_PWDN /* | FORCE_DCLK_TRI_STATE */;
if (M64_HAS(MAGIC_POSTDIV))
pll->ct.pll_ext_cntl = 0;
@@ -608,5 +609,6 @@
.var_to_pll = aty_var_to_pll_ct,
.pll_to_var = aty_pll_to_var_ct,
.set_pll = aty_set_pll_ct,
+ .get_pll = aty_get_pll_ct,
.init_pll = aty_init_pll_ct
};
diff -ur -X patches/exclude linux-2.6.7.js3/drivers/video/aty/mach64_cursor.c linux-2.6.7.ak/drivers/video/aty/mach64_cursor.c
--- linux-2.6.7.js3/drivers/video/aty/mach64_cursor.c 2004-06-27 01:35:27.000000000 +0200
+++ linux-2.6.7.ak/drivers/video/aty/mach64_cursor.c 2004-07-23 23:51:53.000000000 +0200
@@ -71,26 +71,6 @@
0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
};
-void aty_set_cursor_shape(struct fb_info *info, u8 *dst, u8 *src, unsigned int width)
-{
- int i, j, offset = info->sprite.scan_align - width*2;
- u8 *mask = info->cursor.mask, m, b;
-
- for (i = 0; i < info->cursor.image.height; i++) {
- for (j = 0; j < width; j++) {
- b = *src++;
- m = *mask++;
- // Upper 4 bits of mask data
- fb_writeb(cursor_mask_lookup[m >> 4 ] |
- cursor_bits_lookup[(b & m) >> 4], dst++);
- // Lower 4 bits of mask
- fb_writeb(cursor_mask_lookup[m & 0x0f ] |
- cursor_bits_lookup[(b & m) & 0x0f], dst++);
- }
- dst += offset;
- }
-}
-
int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -176,9 +156,46 @@
}
if (cursor->set & FB_CUR_SETSHAPE) {
- // Clear cursor image with 1010101010...
- fb_memset(info->sprite.addr, 0xaa, 1024);
- fb_load_cursor_image(info);
+ u8 *src = (u8 *)cursor->image.data;
+ u8 *msk = (u8 *)info->cursor.mask;
+ u8 *dst = (u8 *)info->sprite.addr;
+ unsigned int width = (info->cursor.image.width + 7) >> 3;
+ unsigned int height = info->cursor.image.height;
+ unsigned int align = info->sprite.scan_align;
+
+ unsigned int i, j, offset;
+ u8 m, b;
+
+ // Clear cursor image with 1010101010...
+ fb_memset(dst, 0xaa, 1024);
+
+ offset = align - width*2;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ b = *src++;
+ m = *msk++;
+ switch (info->cursor.rop) {
+ case ROP_XOR:
+ // Upper 4 bits of mask data
+ fb_writeb(cursor_mask_lookup[m >> 4 ] |
+ cursor_bits_lookup[(b ^ m) >> 4], dst++);
+ // Lower 4 bits of mask
+ fb_writeb(cursor_mask_lookup[m & 0x0f ] |
+ cursor_bits_lookup[(b ^ m) & 0x0f], dst++);
+ break;
+ case ROP_COPY:
+ // Upper 4 bits of mask data
+ fb_writeb(cursor_mask_lookup[m >> 4 ] |
+ cursor_bits_lookup[(b & m) >> 4], dst++);
+ // Lower 4 bits of mask
+ fb_writeb(cursor_mask_lookup[m & 0x0f ] |
+ cursor_bits_lookup[(b & m) & 0x0f], dst++);
+ break;
+ }
+ }
+ dst += offset;
+ }
}
if (cursor->enable) {
@@ -210,10 +227,12 @@
if (!info->sprite.addr)
return -ENXIO;
info->sprite.size = PAGE_SIZE;
- info->sprite.scan_align = 16; // Scratch pad 64 bytes wide
- info->sprite.buf_align = 16; // *64; // and 64 lines tall.
+ info->sprite.scan_align = 16; /* Scratch pad 64 bytes wide */
+ info->sprite.buf_align = 16; /* and 64 lines tall. */
info->sprite.flags = FB_PIXMAP_IO;
- info->sprite.outbuf = aty_set_cursor_shape;
+
+ info->fbops->fb_cursor = atyfb_cursor;
+
return 0;
}
diff -ur -X patches/exclude linux-2.6.7.js3/drivers/video/modedb.c linux-2.6.7.ak/drivers/video/modedb.c
--- linux-2.6.7.js3/drivers/video/modedb.c 2004-06-16 07:19:22.000000000 +0200
+++ linux-2.6.7.ak/drivers/video/modedb.c 2004-07-21 22:05:06.000000000 +0200
@@ -16,12 +16,14 @@
#include <linux/fb.h>
#include <linux/sched.h>
-#undef DEBUG
+#define DEBUG
#define name_matches(v, s, l) \
((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l))
#define res_matches(v, x, y) \
((v).xres == (x) && (v).yres == (y))
+#define refresh_closest_to(v, x, y) \
+ ((!y || (abs((x)->refresh - (v)) < abs((y)->refresh - (v))))?x:y)
#ifdef DEBUG
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
@@ -126,16 +128,16 @@
0, FB_VMODE_NONINTERLACED
}, {
/* 1400x1050 @ 60Hz, 63.9 kHz hsync */
- NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
- 0, FB_VMODE_NONINTERLACED
+ NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
+ 0, FB_VMODE_NONINTERLACED
}, {
- /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
- NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ /* 1400x1050 @ 64 Hz, 68.8 kHz */
+ NULL, 64, 1400, 1050, 8197, 184, 28, 10, 2, 152, 12,
+ 0, FB_VMODE_NONINTERLACED
}, {
- /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
- NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ /* 1400x1050 @ 75 Hz, 81,3 kHz */
+ NULL, 75, 1400, 1050, 6418, 128, 64, 26, 2, 320, 12,
+ 0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 85 Hz, 70.24 kHz hsync */
NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
@@ -528,25 +530,44 @@
res_specified = 1;
}
done:
- for (i = refresh_specified; i >= 0; i--) {
- DPRINTK("Trying specified video mode%s\n",
- i ? "" : " (ignoring refresh rate)");
- for (j = 0; j < dbsize; j++)
- if ((name_matches(db[j], name, namelen) ||
- (res_specified && res_matches(db[j], xres, yres))) &&
- (!i || db[j].refresh == refresh) &&
- !fb_try_mode(var, info, &db[j], bpp))
- return 2-i;
+ {
+ if(refresh_specified) {
+ const struct fb_videomode *na = 0; /* nearest accepted with given refreshrate */
+
+ DPRINTK("Trying all video modes with refresh rate %i\n", refresh);
+
+ for(j = 0; j < dbsize; j++) {
+ if((name_matches(db[j], name, namelen) || (res_specified && res_matches(db[j], xres, yres)))) {
+ if(!fb_try_mode(var, info, &db[j], bpp)) {
+ na = refresh_closest_to(refresh, &db[j], na);
+ }
+ }
+ }
+ if(na) {
+ DPRINTK("Try the winner %ix%i@%i one more time\n", na->xres, na->yres, na->refresh);
+ if(!fb_try_mode(var, info, na, bpp))
+ return 1;
+ }
+ } else {
+ DPRINTK("Trying specified video mode(ignoring refresh rate), first win\n");
+ for(j = 0; j < dbsize; j++) {
+ if((name_matches(db[j], name, namelen) || (res_specified && res_matches(db[j], xres, yres)))) {
+ if(!fb_try_mode(var, info, &db[j], bpp)) {
+ return 2;
+ }
+ }
+ }
+ }
}
}
DPRINTK("Trying default video mode\n");
- if (!fb_try_mode(var, info, default_mode, default_bpp))
+ if(!fb_try_mode(var, info, default_mode, default_bpp))
return 3;
DPRINTK("Trying all modes\n");
- for (i = 0; i < dbsize; i++)
- if (!fb_try_mode(var, info, &db[i], default_bpp))
+ for(i = 0; i < dbsize; i++)
+ if(!fb_try_mode(var, info, &db[i], default_bpp))
return 4;
DPRINTK("No valid mode found\n");
[-- Attachment #3: mach64-js3-ak6b.diff --]
[-- Type: text/x-diff, Size: 6580 bytes --]
diff -ur -X patches/exclude linux-2.6.7.js3/include/video/mach64.h linux-2.6.7.ak/include/video/mach64.h
--- linux-2.6.7.js3/include/video/mach64.h 2004-06-27 01:35:27.000000000 +0200
+++ linux-2.6.7.ak/include/video/mach64.h 2004-07-28 21:55:35.000000000 +0200
@@ -68,6 +68,8 @@
#define I2C_CNTL_0 0x003C /* Dword offset 0_0F */
+#define DSTN_CONTROL_LG 0x003C /* Dword offset 0_0F (LG) */
+
/* Overscan */
#define OVR_CLR 0x0040 /* Dword offset 0_10 */
#define OVR2_CLR 0x0040 /* Dword offset 0_10 */
@@ -101,7 +103,7 @@
#define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */
#define CUR2_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */
-#define CONFIG_PANEL_LG 0x0074 /* Dword offset 0_1D */
+#define CONFIG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */
/* General I/O Control */
#define GP_IO 0x0078 /* Dword offset 0_1E */
@@ -153,6 +155,8 @@
#define LCD_INDEX 0x00A4 /* Dword offset 0_29 */
#define LCD_DATA 0x00A8 /* Dword offset 0_2A */
+#define HFB_PITCH_ADDR_LG 0x00A8 /* Dword offset 0_2A (LG) */
+
/* Memory Control */
#define EXT_MEM_CNTL 0x00AC /* Dword offset 0_2B */
#define MEM_CNTL 0x00B0 /* Dword offset 0_2C */
@@ -161,6 +165,8 @@
#define I2C_CNTL_1 0x00BC /* Dword offset 0_2F */
+#define LT_GIO_LG 0x00BC /* Dword offset 0_2F (LG) */
+
/* DAC Control */
#define DAC_REGS 0x00C0 /* Dword offset 0_30 */
#define DAC_W_INDEX 0x00C0 /* Dword offset 0_30 */
@@ -171,14 +177,16 @@
#define EXT_DAC_REGS 0x00C8 /* Dword offset 0_32 */
+#define HORZ_STRETCHING_LG 0x00C8 /* Dword offset 0_32 (LG) */
+#define VERT_STRETCHING_LG 0x00CC /* Dword offset 0_33 (LG) */
+
/* Test and Debug */
#define GEN_TEST_CNTL 0x00D0 /* Dword offset 0_34 */
/* Custom Macros */
#define CUSTOM_MACRO_CNTL 0x00D4 /* Dword offset 0_35 */
-#define LCD_GEN_CNTL_LG 0x00D4 /* Dword offset 0_35 */
-
+#define LCD_GEN_CNTL_LG 0x00D4 /* Dword offset 0_35 (LG) */
#define POWER_MANAGEMENT_LG 0x00D8 /* Dword offset 0_36 (LG) */
/* Configuration */
@@ -508,7 +516,7 @@
#define SCALER_BUF0_OFFSET_V 0x05D8 /* Dword offset 1_76 */
#define SCALER_BUF1_OFFSET_U 0x05DC /* Dword offset 1_77 */
#define SCALER_BUF1_OFFSET_V 0x05E0 /* Dword offset 1_78 */
-
+
/* Setup Engine */
#define VERTEX_1_S 0x0640 /* Dword offset 1_90 */
#define VERTEX_1_T 0x0644 /* Dword offset 1_91 */
@@ -622,10 +630,70 @@
#define CRTC_CUR_B_TEST 0x80000000
#define CRTC_CRNT_VLINE 0x07f00000
-#define CRTC_VBLANK 0x00000001
#define CRTC_PRESERVED_MASK 0x0001f000
+#define CRTC_VBLANK 0x00000001
+#define CRTC_VBLANK_INT_EN 0x00000002
+#define CRTC_VBLANK_INT 0x00000004
+#define CRTC_VBLANK_INT_AK CRTC_VBLANK_INT
+#define CRTC_VLINE_INT_EN 0x00000008
+#define CRTC_VLINE_INT 0x00000010
+#define CRTC_VLINE_INT_AK CRTC_VLINE_INT
+#define CRTC_VLINE_SYNC 0x00000020
+#define CRTC_FRAME 0x00000040
+#define SNAPSHOT_INT_EN 0x00000080
+#define SNAPSHOT_INT 0x00000100
+#define SNAPSHOT_INT_AK SNAPSHOT_INT
+#define I2C_INT_EN 0x00000200
+#define I2C_INT 0x00000400
+#define I2C_INT_AK I2C_INT
+#define CRTC2_VBLANK 0x00000800
+#define CRTC2_VBLANK_INT_EN 0x00001000
+#define CRTC2_VBLANK_INT 0x00002000
+#define CRTC2_VBLANK_INT_AK CRTC2_VBLANK_INT
+#define CRTC2_VLINE_INT_EN 0x00004000
+#define CRTC2_VLINE_INT 0x00008000
+#define CRTC2_VLINE_INT_AK CRTC2_VLINE_INT
+#define CAPBUF0_INT_EN 0x00010000
+#define CAPBUF0_INT 0x00020000
+#define CAPBUF0_INT_AK CAPBUF0_INT
+#define CAPBUF1_INT_EN 0x00040000
+#define CAPBUF1_INT 0x00080000
+#define CAPBUF1_INT_AK CAPBUF1_INT
+#define OVERLAY_EOF_INT_EN 0x00100000
+#define OVERLAY_EOF_INT 0x00200000
+#define OVERLAY_EOF_INT_AK OVERLAY_EOF_INT
+#define ONESHOT_CAP_INT_EN 0x00400000
+#define ONESHOT_CAP_INT 0x00800000
+#define ONESHOT_CAP_INT_AK ONESHOT_CAP_INT
+#define BUSMASTER_EOL_INT_EN 0x01000000
+#define BUSMASTER_EOL_INT 0x02000000
+#define BUSMASTER_EOL_INT_AK BUSMASTER_EOL_INT
+#define GP_INT_EN 0x04000000
+#define GP_INT 0x08000000
+#define GP_INT_AK GP_INT
+#define CRTC2_VLINE_SYNC 0x10000000
+#define SNAPSHOT2_INT_EN 0x20000000
+#define SNAPSHOT2_INT 0x40000000
+#define SNAPSHOT2_INT_AK SNAPSHOT2_INT
+#define VBLANK_BIT2_INT 0x80000000
+#define VBLANK_BIT2_INT_AK VBLANK_BIT2_INT
+
+#define CRTC_INT_EN_MASK (CRTC_VBLANK_INT_EN | \
+ CRTC_VLINE_INT_EN | \
+ SNAPSHOT_INT_EN | \
+ I2C_INT_EN | \
+ CRTC2_VBLANK_INT_EN | \
+ CRTC2_VLINE_INT_EN | \
+ CAPBUF0_INT_EN | \
+ CAPBUF1_INT_EN | \
+ OVERLAY_EOF_INT_EN | \
+ ONESHOT_CAP_INT_EN | \
+ BUSMASTER_EOL_INT_EN | \
+ GP_INT_EN | \
+ SNAPSHOT2_INT_EN)
+
/* DAC control values */
#define DAC_EXT_SEL_RS2 0x01
@@ -640,6 +708,24 @@
#define DAC_BLANK_ADJ_1 0x00000800
#define DAC_BLANK_ADJ_2 0x00001000
+/* DAC control values (my source XL/XC Register reference) */
+#define DAC_OUTPUT_MASK 0x00000001 /* 0 - PAL, 1 - NTSC */
+#define DAC_MISTERY_BIT 0x00000002 /* PS2 ? RS343 ?, EXTRA_BRIGHT for GT */
+#define DAC_BLANKING 0x00000004
+#define DAC_CMP_DISABLE 0x00000008
+#define DAC1_CLK_SEL 0x00000010
+#define PALETTE_ACCESS_CNTL 0x00000020
+#define PALETTE2_SNOOP_EN 0x00000040
+#define DAC_CMP_OUTPUT 0x00000080 /* read only */
+/* #define DAC_8BIT_EN is ok */
+#define CRT_SENSE 0x00000800 /* read only */
+#define CRT_DETECTION_ON 0x00001000
+#define DAC_VGA_ADR_EN 0x00002000
+#define DAC_FEA_CON_EN 0x00004000
+#define DAC_PDWN 0x00008000
+#define DAC_TYPE_MASK 0x00070000 /* read only */
+
+
/* Mix control values */
@@ -912,10 +998,14 @@
#define GI_CHIP_ID 0x4749 /* RAGE PRO, BGA, PCI33 only */
#define GP_CHIP_ID 0x4750 /* RAGE PRO, PQFP, PCI33, full 3D */
#define GQ_CHIP_ID 0x4751 /* RAGE PRO, PQFP, PCI33, limited 3D */
-#define LM_CHIP_ID 0x4c4d /* RAGE Mobility PCI */
-#define LN_CHIP_ID 0x4c4e /* RAGE Mobility AGP */
+#define LM_CHIP_ID 0x4c4d /* RAGE Mobility AGP, full function */
+#define LN_CHIP_ID 0x4c4e /* RAGE Mobility AGP */
+#define LR_CHIP_ID 0x4c52 /* RAGE Mobility PCI, full function */
+#define LS_CHIP_ID 0x4c53 /* RAGE Mobility PCI */
+#define IS_MOBILITY(id) ((id)==LM_CHIP_ID || (id)==LN_CHIP_ID || \
+ (id)==LR_CHIP_ID || (id)==LS_CHIP_ID)
/* Mach64 major ASIC revisions */
#define MACH64_ASIC_NEC_VT_A3 0x08
#define MACH64_ASIC_NEC_VT_A4 0x48
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: URGENT: status of atyfb
2004-08-06 6:09 ` Alexander Kern
@ 2004-08-06 8:10 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2004-08-06 8:10 UTC (permalink / raw)
To: Alexander Kern; +Cc: Linux Fbdev development list, Ville Syrjälä
On Fri, 2004-08-06 at 16:09, Alexander Kern wrote:
> Hi, here a snapshot from my tree over 2.6.7 + js3
Thanks, I'll have a look next week
Ben.
-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-08-06 8:13 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-02 3:31 URGENT: status of atyfb Benjamin Herrenschmidt
2004-08-02 5:21 ` Benjamin Herrenschmidt
2004-08-03 20:57 ` Alexander Kern
2004-08-03 21:25 ` Benjamin Herrenschmidt
2004-08-03 22:05 ` Ville Syrjälä
2004-08-06 6:09 ` Alexander Kern
2004-08-06 8:10 ` Benjamin Herrenschmidt
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).