int nve0_ram_init(struct nouveau_object *object) { struct nouveau_fb *pfb = (void *)object->parent; struct nve0_ram *ram = (void *)object; struct nouveau_bios *bios = nouveau_bios(pfb); static const u8 train0[] = { 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, }; static const u32 train1[] = { 0x00000000, 0xffffffff, 0x55555555, 0xaaaaaaaa, 0x33333333, 0xcccccccc, 0xf0f0f0f0, 0x0f0f0f0f, 0x00ff00ff, 0xff00ff00, 0x0000ffff, 0xffff0000, }; u8 ver, hdr, cnt, len, snr, ssz; u32 data, save; int ret, i; ret = nouveau_ram_init(&ram->base); if (ret) return ret; /* run a bunch of tables from rammap table. there's actually * individual pointers for each rammap entry too, but, nvidia * seem to just run the last two entries' scripts early on in * their init, and never again.. we'll just run 'em all once * for now. * * i strongly suspect that each script is for a separate mode * (likely selected by 0x10f65c's lower bits?), and the * binary driver skips the one that's already been setup by * the init tables. */ data = nvbios_rammapTe(bios, &ver, &hdr, &cnt, &len, &snr, &ssz); if (!data || hdr < 0x15) return -EINVAL; cnt = nv_ro08(bios, data + 0x14); /* guess at count */ data = nv_ro32(bios, data + 0x10); /* guess u32... */ save = nv_rd32(pfb, 0x10f65c); for (i = 0; i < cnt; i++) { nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4); nvbios_exec(&(struct nvbios_init) { .subdev = nv_subdev(pfb), .bios = bios, .offset = nv_ro32(bios, data), /* guess u32 */ .execute = 1, }); data += 4; }
u32 nvbios_rammapEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { u8 snr, ssz; u16 rammap = nvbios_rammapTe(bios, ver, hdr, cnt, len, &snr, &ssz); if (rammap && idx < *cnt) { rammap = rammap + *hdr + (idx * (*len + (snr * ssz))); *hdr = *len; *cnt = snr; *len = ssz; return rammap; } return 0x0000; }