Subject: agp_i810.c and i965
To: None <port-i386@NetBSD.org>
From: Mark Davies <mark@mcs.vuw.ac.nz>
List: tech-kern
Date: 02/17/2007 01:24:16
I'm trying to add support for the i965 to the agp driver.
I initially made the the obvious additions to treat the 965 like the
915 and 945 but that failed in agp_map_aperture() with
pci_mem_find: expected mem type 00000000, found 00000004
Changing the type used by pci_mapreg_info() (for the 965) to
PCI_MAPREG_MEM_TYPE_64BIT got past that but then it failed in the
pci_mapreg_map() for the AGP_I915_GTTADR.
Looking at the linux intel-agp.c which does have support for the 965 I
see that they do basically this for the 915:
pci_read_config_dword(intel_i830_private.i830_dev,
I915_MMADR,&temp);
pci_read_config_dword(intel_i830_private.i830_dev,
I915_GTTADR,&temp2);
intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
temp &= 0xfff80000;
intel_i830_private.registers = ioremap(temp,128 * 4096);
temp = readl(intel_i830_private.registers+I810_PGTBL_CTL) &
0xfffff000;
global_cache_flush();
pci_read_config_word(agp_bridge->dev,I830_GCC1,&gmch_ctrl);
size = agp_bridge->driver->fetch_size() + 4;
gtt_entries = MB(XX) - KB(size);
while for the 965 they do:
pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADR,
&temp);
temp &= 0xfff00000;
intel_i830_private.gtt =
ioremap((temp + (512 * 1024)) , 512 * 1024);
intel_i830_private.registers = ioremap(temp,128 * 4096);
temp = readl(intel_i830_private.registers+I810_PGTBL_CTL) &
0xfffff000;
global_cache_flush();
pci_read_config_word(agp_bridge->dev,I830_GCC1,&gmch_ctrl);
pci_read_config_dword(agp_bridge->dev, I810_PGTBL_CTL,
&pgetbl_ctl);
/* The 965 has a field telling us the size of the GTT,
* which may be larger than what is necessary to map the
* aperture.
*/
switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
case I965_PGETBL_SIZE_128KB:
size = 128;
break;
case I965_PGETBL_SIZE_256KB:
size = 256;
break;
case I965_PGETBL_SIZE_512KB:
size = 512;
break;
default:
printk(KERN_INFO PFX "Unknown page table size, "
"assuming 512KB\n");
size = 512;
}
size += 4; /* add in BIOS popup space */
gtt_entries = MB(XX) - KB(size);
So among other things they don't use the GTTADR registers at all.
Now the NetBSD agp does this for 915:
error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR,
PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, NULL, NULL);
error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR,
PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh,
NULL, NULL);
isc->initial_aperture = AGP_GET_APERTURE(sc);
gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
where get_aperture for i915 is
reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC);
msac = (u_int16_t)(reg >> 16);
if (msac & AGP_I915_MSAC_APER_128M)
return 128 * 1024 * 1024;
else
return 256 * 1024 * 1024;
and at various points calls WRITEGTT() which is defined as
#define WRITEGTT(off, v) \
do { \
if (isc->chiptype == CHIP_I915) { \
bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, \
(u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \
(v)); \
} else { \
WRITE4(AGP_I810_GTT + \
(u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \
(v)); \
} \
} while (0)
Being an absolute beginner at agp, pci and bus_space I need some help
to map the differences in the linux handling of 915/965 to our
driver.
So for the 965 the call to pci_mapreg_map(..,AGP_I915_GTTADR,..) goes
away and the WRITEGTT() becomes a WRITE4() but what base offset?
And I'm not sure ag_entries is set right. What else?
cheers
mark