r500/pci/main.c

522 lines
22 KiB
C

#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/aperture.h>
#include "3d_registers.h"
#include "undocumented_3d_registers.h"
#define R500 "r500"
static struct pci_device_id r500_id_table[] = {
{ PCI_DEVICE(0x1002, 0x71c1) },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, r500_id_table);
static int r500_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void r500_remove(struct pci_dev *pdev);
static struct pci_driver r500 = {
.name = R500,
.id_table = r500_id_table,
.probe = r500_probe,
.remove = r500_remove
};
struct r500_priv {
volatile u32 __iomem *hwmem;
};
/* */
static int __init r500_module_init(void)
{
return pci_register_driver(&r500);
}
static void __exit r500_module_exit(void)
{
pci_unregister_driver(&r500);
}
void release_device(struct pci_dev *pdev);
void release_device(struct pci_dev *pdev)
{
/* Free memory region */
pci_release_region(pdev, pci_select_bars(pdev, IORESOURCE_MEM));
/* And disable device */
pci_disable_device(pdev);
}
static inline void wreg(void __iomem * rmmio, uint32_t reg, uint32_t v)
{
writel(v, ((void __iomem *)rmmio) + reg);
}
static inline uint32_t rreg(void __iomem * rmmio, uint32_t reg)
{
return readl(((void __iomem *)rmmio) + reg);
}
#define bswap32 __builtin_bswap32
static const uint8_t _cp_data[] __attribute__((aligned (4))) = {
0x00,0x00,0x00,0x00,0x42,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xe0,0x00,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x99,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x9d,
0x00,0x00,0x00,0x00,0x4a,0x55,0x4b,0x4a,0x00,0x00,0x00,0x00,0x4a,0x4a,0x44,0x67,
0x00,0x00,0x00,0x00,0x55,0x52,0x6f,0x75,0x00,0x00,0x00,0x00,0x4a,0x7e,0x7d,0x65,
0x00,0x00,0x00,0x00,0xe0,0xda,0xe6,0xf6,0x00,0x00,0x00,0x00,0x4a,0xc5,0x4a,0x4a,
0x00,0x00,0x00,0x00,0xc8,0x82,0x82,0x82,0x00,0x00,0x00,0x00,0xbf,0x4a,0xcf,0xc1,
0x00,0x00,0x00,0x00,0x87,0xb0,0x4a,0xd5,0x00,0x00,0x00,0x00,0xb5,0x83,0x83,0x83,
0x00,0x00,0x00,0x00,0x4a,0x0f,0x85,0xba,0x00,0x00,0x00,0x04,0x00,0x0c,0xa0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x12,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0xb4,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0xb6,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x16,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x54,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x55,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x1a,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x56,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x1c,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x57,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x1e,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x24,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x25,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x22,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x30,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0xf0,0xc0,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x26,0x00,0x00,0x00,0x04,0x00,0x00,0xf0,0xc1,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x28,0x00,0x00,0x00,0x04,0x00,0x00,0xe0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x2a,0x00,0x00,0x00,0x04,0x00,0x00,0xe0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x2c,0x00,0x00,0x00,0x04,0x00,0x00,0xe0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x2e,0x00,0x00,0x00,0x04,0x00,0x00,0xe0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0xe0,0x00,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x32,0x00,0x00,0x00,0x04,0x00,0x00,0xf1,0x80,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x34,0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0x93,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x36,0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0x8a,
0x00,0x00,0x00,0x38,0x00,0x0d,0x00,0x38,0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0x8e,
0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x21,0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x04,0x00,0xcc,0xe8,0x00,
0x00,0x00,0x00,0x04,0x00,0x1b,0x00,0x01,0x00,0x00,0x00,0x04,0x08,0x00,0x48,0x00,
0x00,0x00,0x00,0x04,0x00,0x1b,0x00,0x01,0x00,0x00,0x00,0x04,0x08,0x00,0x48,0x00,
0x00,0x00,0x00,0x04,0x00,0x1b,0x00,0x01,0x00,0x00,0x00,0x04,0x08,0x00,0x48,0x00,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,
0x00,0x00,0x00,0x04,0x20,0x00,0x45,0x1d,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x80,
0x00,0x00,0x00,0x04,0x00,0x0c,0xe5,0x81,0x00,0x00,0x00,0x04,0x08,0x00,0x45,0x80,
0x00,0x00,0x00,0x04,0x00,0x0c,0xe5,0x81,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x47,
0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x04,0x00,0x0c,0x20,0x00,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x0e,0x00,0x00,0x00,0x04,0x00,0x03,0x20,0x00,
0x00,0x00,0x00,0x28,0x00,0x02,0x20,0x51,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x51,
0x00,0x00,0x00,0x04,0x08,0x00,0x45,0x0f,0x00,0x00,0x00,0x08,0x00,0x00,0xa0,0x4b,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x65,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x66,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x04,0x03,0xcc,0xa5,0xb4,
0x00,0x00,0x00,0x04,0x05,0x43,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x20,0x00,
0x00,0x00,0x00,0x30,0x4c,0xcc,0xe0,0x5e,0x00,0x00,0x00,0x04,0x08,0x27,0x45,0x65,
0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x04,0x08,0x00,0x45,0x64,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x66,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x55,
0x00,0x00,0x00,0x10,0x00,0x80,0x20,0x61,0x00,0x00,0x00,0x04,0x00,0x20,0x20,0x00,
0x00,0x00,0x00,0x04,0x00,0x1b,0x00,0xff,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x64,
0x00,0x00,0x00,0x04,0x00,0x1f,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x1c,0x00,0xff,
0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x72,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x76,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x77,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x0e,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x0f,0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0xc2,0x00,0xc0,0xe5,0xf9,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x04,0x00,0x14,0xe5,0x0e,
0x00,0x00,0x00,0x04,0x00,0x40,0xe5,0x0f,0x00,0x00,0x00,0x08,0x00,0xc0,0x00,0x6c,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x70,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x71,
0x00,0x00,0x00,0x0c,0x00,0x00,0xe5,0x72,0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,
0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0x68,
0x00,0x00,0x00,0x04,0x00,0x0c,0x20,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x76,
0x00,0x00,0x00,0x04,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x04,0x18,0xc0,0xe5,0x62,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x08,0x00,0xc0,0x00,0x77,
0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xc7,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x80,
0x00,0x00,0x00,0x04,0x00,0x00,0xe5,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0xe5,0xbc,
0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x21,
0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0x21,
0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x2e,0x00,0x00,0x00,0x04,0x02,0xcc,0xa0,0x00,
0x00,0x00,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0c,0xe1,0xcc,
0x00,0x00,0x00,0x04,0x05,0x0d,0xe1,0xcd,0x00,0x00,0x00,0x04,0x00,0x40,0x00,0x00,
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x8f,0x00,0x00,0x00,0x04,0x00,0xc0,0xa0,0x00,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x8c,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x91,
0x00,0x00,0x00,0x00,0x42,0x00,0xe0,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x98,
0x00,0x00,0x00,0x04,0x00,0x0c,0xa0,0x00,0x00,0x00,0x00,0x04,0x00,0x14,0x00,0x00,
0x00,0x00,0x00,0x04,0x00,0x0c,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x16,0x00,0x00,
0x00,0x00,0x00,0x04,0x70,0x0c,0xe0,0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x94,
0x00,0x00,0x00,0x00,0x40,0x00,0xe0,0x00,0x00,0x00,0x00,0x04,0x02,0x40,0x00,0x00,
0x00,0x00,0x00,0x04,0x40,0x0e,0xe0,0x00,0x00,0x00,0x00,0x04,0x02,0x40,0x00,0x00,
0x00,0x00,0x00,0x00,0x40,0x00,0xe0,0x00,0x00,0x00,0x00,0x04,0x00,0x0c,0x20,0x00,
0x00,0x00,0x00,0x04,0x02,0x40,0xe5,0x1b,0x00,0x00,0x00,0x05,0x00,0x80,0xe5,0x0a,
0x00,0x00,0x00,0x05,0x00,0x80,0xe5,0x0b,0x00,0x00,0x00,0x04,0x00,0x22,0x00,0x00,
0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xc7,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xa4,
0x00,0x00,0x00,0x05,0x00,0x80,0xe5,0xbd,0x00,0x00,0x00,0x05,0x00,0x00,0xe5,0xbb,
0x00,0x00,0x00,0x05,0x00,0x80,0xe5,0xbc,0x00,0x00,0x00,0x04,0x00,0x21,0x00,0x00,
0x00,0x00,0x00,0x04,0x02,0x80,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xc0,0x00,0xab,
0x00,0x00,0x00,0x40,0x41,0x80,0xe0,0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0xad,
0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x00,0xe5,0x1d,
0x00,0x00,0x00,0x04,0x00,0x00,0x45,0xbb,0x00,0x00,0x00,0x08,0x00,0x00,0x80,0xa7,
0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0xce,0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,
0x00,0x00,0x00,0x04,0x00,0xcc,0x20,0x00,0x00,0x00,0x00,0x40,0x08,0xc0,0x53,0xcf,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0xd2,
0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,0x00,0x00,0x00,0x04,0x00,0xcc,0x20,0x00,
0x00,0x00,0x00,0x40,0x08,0xc0,0x53,0xd3,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,
0x00,0x00,0x00,0x04,0x00,0x00,0xf3,0x9d,0x00,0x00,0x00,0x04,0x01,0x40,0xa0,0x00,
0x00,0x00,0x00,0x04,0x00,0xcc,0x20,0x00,0x00,0x00,0x00,0x40,0x08,0xc0,0x53,0x9e,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x04,0x03,0xc0,0x08,0x30,
0x00,0x00,0x00,0x00,0x42,0x00,0xe0,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,
0x00,0x00,0x00,0x04,0x20,0x00,0x45,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xe5,0xe1,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xc4,
0x00,0x00,0x00,0x00,0x08,0x00,0xe3,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0xc4,0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0xc5,
0x00,0x00,0x00,0x04,0x00,0x00,0xe8,0xc6,0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x28,
0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x29,0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x2a,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x28,
0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x29,0x00,0x00,0x00,0x04,0x00,0x00,0xe9,0x2a,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xcf,0x00,0x00,0x00,0x00,0xde,0xad,0xbe,0xef,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x16,0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xd3,
0x00,0x00,0x00,0x04,0x08,0x00,0x50,0xe7,0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xd4,
0x00,0x00,0x00,0x04,0x08,0x00,0x40,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x1d,
0x00,0x00,0x00,0x04,0x02,0xc0,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x00,
0x00,0x00,0x00,0x34,0x00,0x00,0x00,0xde,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xdb,
0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xe0,0x00,
0x00,0x00,0x00,0x04,0x00,0x00,0xe1,0xcc,0x00,0x00,0x00,0x04,0x05,0x00,0xe1,0xcd,
0x00,0x00,0x00,0x04,0x00,0x0c,0xa0,0x00,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0xe5,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,
0x00,0x00,0x00,0x04,0x00,0x19,0xe1,0xcc,0x00,0x00,0x00,0x04,0x00,0x1b,0x00,0x01,
0x00,0x00,0x00,0x04,0x05,0x00,0xa0,0x00,0x00,0x00,0x00,0x04,0x08,0x00,0x41,0xcd,
0x00,0x00,0x00,0x04,0x00,0x0c,0xa0,0x00,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0xfb,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x00,0x0c,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x1d,0x00,0x18,
0x00,0x00,0x00,0x04,0x00,0x1a,0x00,0x01,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0xfb,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x08,0x05,0x00,0xa0,0x4a,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/* This function is called by the kernel */
static int r500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
u16 vendor, device;
pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
pci_read_config_word(pdev, PCI_DEVICE_ID, &device);
printk(KERN_INFO "[r500] VENDOR_ID: %04x DEVICE_ID: %04x\n", vendor, device);
int ret;
ret = aperture_remove_conflicting_pci_devices(pdev, "R500");
if (ret)
return ret;
ret = pci_enable_device(pdev);
if (ret)
return ret;
if (!request_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0), "R500")) {
printk(KERN_INFO "[r500] !request_mem_region resource 0\n");
return -ENODEV;
}
if (!request_mem_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2), "R500")) {
printk(KERN_INFO "[r500] !request_mem_region resource 2\n");
return -ENODEV;
}
resource_size_t rmmio_base = pci_resource_start(pdev, 2);
resource_size_t rmmio_size = pci_resource_len(pdev, 2);
printk(KERN_INFO "[r500] rmmio base: %08x ; rmmio size: %08x\n", rmmio_base, rmmio_size);
void __iomem * rmmio = ioremap(rmmio_base, rmmio_size);
uint32_t value1 = rreg(rmmio, 0x6080);
printk(KERN_INFO "[r500] D1CRTC_CONTROL %08x\n", value1);
uint32_t value2 = rreg(rmmio, 0x6080 + 0x800);
printk(KERN_INFO "[r500] D2CRTC_CONTROL %08x\n", value2);
{
uint32_t value1 = rreg(rmmio, 0x6110);
printk(KERN_INFO "[r500] D1GRPH_PRIMARY_SURFACE_ADDRESS %08x\n", value1);
uint32_t value2 = rreg(rmmio, 0x6110 + 0x800);
printk(KERN_INFO "[r500] D2GRPH_PRIMARY_SURFACE_ADDRESS %08x\n", value2);
uint32_t value3 = rreg(rmmio, 0x6118);
printk(KERN_INFO "[r500] D1GRPH_SECONDARY_SURFACE_ADDRESS %08x\n", value3);
uint32_t value4 = rreg(rmmio, 0x6118 + 0x800);
printk(KERN_INFO "[r500] D2GRPH_SECONDARY_SURFACE_ADDRESS %08x\n", value4);
//wreg(rmmio, 0x6110, 0xe0100000);
//wreg(rmmio, 0x6110 + 0x800, 0xe0100000);
//wreg(rmmio, 0x6118, 0xe0100000);
//wreg(rmmio, 0x6118 + 0x800, 0xe0100000);
}
uint32_t memsize = rreg(rmmio, 0xf8);
printk(KERN_INFO "[r500] CONFIG_MEMSIZE %08x\n", memsize);
uint32_t config_cntl = rreg(rmmio, 0xe0);
printk(KERN_INFO "[r500] CONFIG_CNTL %08x\n", config_cntl);
config_cntl |= (1 << 9); // VGA DISABLE
wreg(rmmio, 0xe0, config_cntl);
// atombios_crtc.c avivo_crtc_do_set_base
uint32_t d1vga_control = rreg(rmmio, 0x330);
printk(KERN_INFO "[r500] D1VGA_CONTROL %08x\n", d1vga_control);
wreg(rmmio, 0x330, 0);
uint32_t d2vga_control = rreg(rmmio, 0x338);
printk(KERN_INFO "[r500] D2VGA_CONTROL %08x\n", d2vga_control);
wreg(rmmio, 0x338, 0);
uint32_t d1grph_x_start = rreg(rmmio, 0x612c);
printk(KERN_INFO "[r500] D1GRPH_X_START %08x\n", d1grph_x_start);
wreg(rmmio, 0x612c, 0);
uint32_t d1grph_y_start = rreg(rmmio, 0x6130);
printk(KERN_INFO "[r500] D1GRPH_Y_START %08x\n", d1grph_y_start);
wreg(rmmio, 0x6130, 0);
uint32_t d1grph_x_end = rreg(rmmio, 0x6134);
printk(KERN_INFO "[r500] D1GRPH_X_END %08x\n", d1grph_x_end);
wreg(rmmio, 0x6134, 1600);
uint32_t d1grph_y_end = rreg(rmmio, 0x6138);
printk(KERN_INFO "[r500] D1GRPH_Y_END %08x\n", d1grph_y_end);
wreg(rmmio, 0x6138, 1200);
uint32_t d1grph_pitch = rreg(rmmio, 0x6120);
printk(KERN_INFO "[r500] D1GRPH_PITCH %08x\n", d1grph_pitch);
wreg(rmmio, 0x6120, 1600);
uint32_t d1grph_enable = rreg(rmmio, 0x6100);
printk(KERN_INFO "[r500] D1GRPH_ENABLE %08x\n", d1grph_enable);
wreg(rmmio, 0x6100, 1);
void __iomem * fb;
{
resource_size_t fb_base = pci_resource_start(pdev, 0);
uint32_t fb_size = 64 * 1024 * 1024;
fb = ioremap(fb_base, fb_size);
if (!fb_base) {
printk(KERN_INFO "[r500] could not map fb\n");
return 0;
}
for (int y = 0; y < 1200; y++) {
for (int x = 0; x < 1600; x++) {
int red = x % 256;
int green = y % 256;
//wreg(fb, 0x00100000 + y * 1600 + x, red << 16 | green << 8);
wreg(fb, 0x00100000 + (y * 1600 + x) * 4, red << 16 | green << 8);
}
}
}
// r100.c r100_cp_init
wreg(rmmio, CP_ME_RAM_ADDR, 0);
const uint32_t * cp_data = (const uint32_t *)_cp_data;
for (int i = 0; i < (sizeof (_cp_data)) / (4 * 2); i++) {
wreg(rmmio, CP_ME_RAM_DATAH, bswap32(cp_data[i * 2 + 0]));
wreg(rmmio, CP_ME_RAM_DATAL, bswap32(cp_data[i * 2 + 1]));
}
mb();
mdelay(500);
// cp
// 1) Write CP_CSQ_CNTL and CP_CSQ_MODE to zero, effectively disabling the CP.
wreg(rmmio, CP_CSQ_CNTL, 0);
wreg(rmmio, CP_CSQ_MODE, 0);
// 2) Write to the proper RBBM register to assert and then de-assert the Soft Reset signal to the CP.
wreg(rmmio, RBBM_SOFT_RESET, RBBM_SOFT_RESET_CP);
rreg(rmmio, RBBM_SOFT_RESET);
mdelay(500);
wreg(rmmio, RBBM_SOFT_RESET, 0);
mdelay(1);
// 3) Set the RB_RPTR_WR_ENA bit to enable writing of the RPTR if desired not to start from the
// beginning of the buffer.
uint32_t tmp = rreg(rmmio, CP_RB_CNTL);
wreg(rmmio, CP_RB_CNTL, tmp | (1 << 31)); // RB_RPTR_WR_ENA
// 4) Write the CP_RB_RPTR_WR register if it is desired not to start at the beginning of the buffer.
wreg(rmmio, CP_RB_RPTR_WR, 0);
// 5) Write CP_RB_WPTR, to make it match the RPTR, causing the ring buffer to appear to be empty.
wreg(rmmio, CP_RB_WPTR, 0);
// 6) Clear the RB_RPTR_WR_ENA bit if no further writes of the RPTR are desired.
wreg(rmmio, CP_RB_CNTL, tmp);
// 7) Write CP_CSQ_CNTL or CP_CSQ_MODE to set the mode back to whatever you want.
wreg(rmmio, CP_CSQ_CNTL, 1 << 28); // Primary PIO, Indirect Disabled
wreg(rmmio, CP_CSQ_MODE, 0); // Primary PIO, Indirect Disabled
//pci_set_master(pdev);
uint32_t scratch;
scratch = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 0 %08x\n", scratch);
wreg(rmmio, SCRATCH_REG0, 0xEEAABBCC);
scratch = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 1 %08x\n", scratch);
#define PACKET_TYPE_0(base, count) \
(((base) >> 2) | ((count) << 16))
wreg(rmmio, 0x1000, PACKET_TYPE_0(SCRATCH_REG0, 0));
mb();
wreg(rmmio, 0x1000, 0xdeadbeef);
mb();
mdelay(1);
scratch = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 2 %08x\n", scratch);
if (0) {
wreg(rmmio, CP_CSQ_CNTL, 1); // Primary PIO, Indirect Disabled
wreg(rmmio, CP_CSQ_MODE, (1 << 30) | (1 << 31)); // Primary PIO, Indirect Disabled
///
wreg(rmmio, CP_RB_BASE, 0); // start of framebuffer memory
uint32_t cp_rb_cntl = ( (1 << 27) // RB_NO_UPDATE
);
wreg(rmmio, CP_RB_CNTL, cp_rb_cntl); // start of framebuffer memory
wreg(rmmio, CP_RB_RPTR_ADDR, 0);
udelay(10);
wreg(rmmio, CP_RB_WPTR_DELAY, 0);
wreg(rmmio, CP_CSQ_CNTL, 2 << 28);
volatile uint32_t * ring = (volatile uint32_t *)fb;
ring[0] = PACKET_TYPE_0(0x1724, 0); // ISYNC_CNTL
ring[1] = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5);
mb();
wreg(rmmio, CP_RB_WPTR, 2);
(void)rreg(rmmio, CP_RB_WPTR);
ring[2] = PACKET_TYPE_0(SCRATCH_REG0, 0);
ring[3] = 0xdeadbeef;
mb();
wreg(rmmio, CP_RB_WPTR, 4);
(void)rreg(rmmio, CP_RB_WPTR);
udelay(500);
}
uint32_t scratch_reg0_2 = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 2 %08x\n", scratch_reg0_2);
if (1) {
// GB_PIPE_SELECT
// GB_TILE_CONFIG
// GA_SOFT_RESET
uint32_t gb_pipe_select = rreg(rmmio, GB_PIPE_SELECT);
printk(KERN_INFO "[r500] GB_PIPE_SELECT %08x\n", gb_pipe_select);
uint32_t gb_tile_config = rreg(rmmio, GB_TILE_CONFIG);
printk(KERN_INFO "[r500] GB_TILE_CONFIG %08x\n", gb_tile_config);
uint32_t cp_csq_cntl = rreg(rmmio, CP_CSQ_CNTL);
printk(KERN_INFO "[r500] CP_CSQ_CNTL %08x\n", cp_csq_cntl);
uint32_t cp_csq_mode = rreg(rmmio, CP_CSQ_MODE);
printk(KERN_INFO "[r500] CP_CSQ_MODE %08x\n", cp_csq_mode);
uint32_t cp_csq_stat = rreg(rmmio, CP_CSQ_STAT);
printk(KERN_INFO "[r500] CP_CSQ_STAT %08x\n", cp_csq_stat);
uint32_t cp_csq2_stat = rreg(rmmio, CP_CSQ2_STAT);
printk(KERN_INFO "[r500] CP_CSQ2_STAT %08x\n", cp_csq2_stat);
uint32_t cp_csq_avail = rreg(rmmio, CP_CSQ_AVAIL);
printk(KERN_INFO "[r500] CP_CSQ_AVAIL %08x\n", cp_csq_avail);
uint32_t cp_rb_rptr = rreg(rmmio, CP_RB_RPTR);
printk(KERN_INFO "[r500] CP_RB_RPTR %08x\n", cp_rb_rptr);
uint32_t cp_rb_wptr = rreg(rmmio, CP_RB_WPTR);
printk(KERN_INFO "[r500] CP_RB_WPTR %08x\n", cp_rb_wptr);
}
if (0) {
wreg(rmmio, 0x1000, PACKET_TYPE_0(SCRATCH_REG0, 0));
wreg(rmmio, 0x1004, 0xdeadbeef);
for (int i = 0; i < 14; i++)
wreg(rmmio, 0x1008 + i * 4, 0x80000000);
mb();
mdelay(500);
uint32_t scratch_reg02 = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 2 %08x\n", scratch_reg02);
wreg(rmmio, CP_RB_WPTR, 16);
(void)rreg(rmmio, CP_RB_WPTR);
mdelay(500);
uint32_t scratch_reg03 = rreg(rmmio, SCRATCH_REG0);
printk(KERN_INFO "[r500] SCRATCH_REG0 3 %08x\n", scratch_reg03);
}
if (0) {
uint32_t tmp;
tmp = rreg(rmmio, 0xf8);
printk(KERN_INFO "CONFIG_MEMSIZE 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x4);
printk(KERN_INFO "MC_FB_LOCATION 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x4c);
printk(KERN_INFO "BUS_CNTL 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x5);
printk(KERN_INFO "MC_AGP_LOCATION 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x6);
printk(KERN_INFO "AGP_BASE 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x130);
printk(KERN_INFO "HOST_PATH_CNTL 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x1d0);
printk(KERN_INFO "AIC_CTRL 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x1dc);
printk(KERN_INFO "AIC_LO_ADDR 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x1e0);
printk(KERN_INFO "AIC_HI_ADDR 0x%08x\n", tmp);
tmp = rreg(rmmio, 0x01e4);
printk(KERN_INFO "AIC_TLB_ADDR 0x%08x\n", tmp);
}
// write packet0
// align to 16 dwords
// write wptr
// check reg0
iounmap(fb);
iounmap(rmmio);
release_mem_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
return 0;
}
/* Clean up */
static void r500_remove(struct pci_dev *pdev)
{
struct r500_priv *drv_priv = pci_get_drvdata(pdev);
if (drv_priv) {
if (drv_priv->hwmem) {
iounmap(drv_priv->hwmem);
}
kfree(drv_priv);
}
release_device(pdev);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Zachary Buhman <zack@buhman.org>");
MODULE_DESCRIPTION("R500 module");
MODULE_VERSION("0.1");
module_init(r500_module_init);
module_exit(r500_module_exit);