#define MODULE_BIT 0x00080000
#include "nv_std.h"
static void nv_init_for_3D_dma(void);
static void nv_start_dma(void);
static status_t nv_acc_fifofree_dma(uint16 cmd_size);
static void nv_acc_cmd_dma(uint32 cmd, uint16 offset, uint16 size);
static void nv_acc_set_ch_dma(uint16 ch, uint32 handle);
static uint8 err;
status_t nv_acc_wait_idle_dma()
{
uint16 cnt = 0;
while ((NV_REG32(NVACC_FIFO + NV_GENERAL_DMAGET) != (si->engine.dma.put << 2)) &&
(cnt < 10000) && (err < 3))
{
snooze (100);
cnt++;
}
if (cnt == 10000)
{
if (err < 3) err++;
LOG(4,("ACC_DMA: wait_idle; DMA timeout #%d, engine trouble!\n", err));
}
while (ACCR(STATUS))
{
snooze (100);
}
return B_OK;
}
status_t nv_acc_init_dma()
{
uint32 cnt, tmp;
uint32 surf_depth, cmd_depth;
err = 0;
NV_REG32(NV32_PWRUPCTRL) = 0xffff00ff;
snooze(1000);
NV_REG32(NV32_PWRUPCTRL) = 0xffffffff;
if (si->ps.card_arch < NV20A)
{
for (cnt = 0x00400000; cnt < 0x00402000; cnt +=4)
{
NV_REG32(cnt) = 0x00000000;
}
}
LOG(4,("ACC_DMA: timer numerator $%08x, denominator $%08x\n", ACCR(PT_NUMERATOR), ACCR(PT_DENOMINATR)));
if (!ACCR(PT_NUMERATOR) || !ACCR(PT_DENOMINATR)) {
ACCW(PT_NUMERATOR, 0x00000008);
ACCW(PT_DENOMINATR, 0x00000003);
}
ACCW(PT_INTEN, 0x00000000);
ACCW(PT_INTSTAT, 0xffffffff);
if (si->ps.card_arch == NV04A)
{
NV_REG32(NV32_PFB_CONFIG_0) = 0x00001114;
}
else
{
if ((si->ps.card_type <= NV40) || (si->ps.card_type == NV45))
{
ACCW(NV10_FBTIL0AD, 0);
ACCW(NV10_FBTIL1AD, 0);
ACCW(NV10_FBTIL2AD, 0);
ACCW(NV10_FBTIL3AD, 0);
ACCW(NV10_FBTIL4AD, 0);
ACCW(NV10_FBTIL5AD, 0);
ACCW(NV10_FBTIL6AD, 0);
ACCW(NV10_FBTIL7AD, 0);
ACCW(NV10_FBTIL0ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL1ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL2ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL3ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL4ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL5ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL6ED, (si->ps.memory_size - 1));
ACCW(NV10_FBTIL7ED, (si->ps.memory_size - 1));
}
else
{
ACCW(NV41_FBTIL0AD, 0);
ACCW(NV41_FBTIL1AD, 0);
ACCW(NV41_FBTIL2AD, 0);
ACCW(NV41_FBTIL3AD, 0);
ACCW(NV41_FBTIL4AD, 0);
ACCW(NV41_FBTIL5AD, 0);
ACCW(NV41_FBTIL6AD, 0);
ACCW(NV41_FBTIL7AD, 0);
ACCW(NV41_FBTIL8AD, 0);
ACCW(NV41_FBTIL9AD, 0);
ACCW(NV41_FBTILAAD, 0);
ACCW(NV41_FBTILBAD, 0);
ACCW(NV41_FBTIL0ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL1ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL2ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL3ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL4ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL5ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL6ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL7ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL8ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTIL9ED, (si->ps.memory_size - 1));
ACCW(NV41_FBTILAED, (si->ps.memory_size - 1));
ACCW(NV41_FBTILBED, (si->ps.memory_size - 1));
if (si->ps.card_type >= G70)
{
ACCW(G70_FBTILCAD, 0);
ACCW(G70_FBTILDAD, 0);
ACCW(G70_FBTILEAD, 0);
ACCW(G70_FBTILCED, (si->ps.memory_size - 1));
ACCW(G70_FBTILDED, (si->ps.memory_size - 1));
ACCW(G70_FBTILEED, (si->ps.memory_size - 1));
}
}
}
for(cnt = 0; cnt < 0x0400; cnt++)
NV_REG32(NVACC_HT_HANDL_00 + (cnt << 2)) = 0;
if (si->ps.card_arch >= NV40A)
{
ACCW(HT_HANDL_00, (0x80000000 | NV10_CONTEXT_SURFACES_2D));
ACCW(HT_VALUE_00, 0x0010114c);
ACCW(HT_HANDL_01, (0x80000000 | NV_IMAGE_BLIT));
ACCW(HT_VALUE_01, 0x00101148);
ACCW(HT_HANDL_02, (0x80000000 | NV4_GDI_RECTANGLE_TEXT));
ACCW(HT_VALUE_02, 0x0010114a);
ACCW(HT_HANDL_10, (0x80000000 | NV_ROP5_SOLID));
ACCW(HT_VALUE_10, 0x00101142);
ACCW(HT_HANDL_11, (0x80000000 | NV_IMAGE_BLACK_RECTANGLE));
ACCW(HT_VALUE_11, 0x00101144);
ACCW(HT_HANDL_12, (0x80000000 | NV_IMAGE_PATTERN));
ACCW(HT_VALUE_12, 0x00101146);
ACCW(HT_HANDL_13, (0x80000000 | NV_SCALED_IMAGE_FROM_MEMORY));
ACCW(HT_VALUE_13, 0x0010114e);
}
else
{
ACCW(HT_HANDL_00, (0x80000000 | NV4_SURFACE));
ACCW(HT_VALUE_00, 0x80011145);
ACCW(HT_HANDL_01, (0x80000000 | NV_IMAGE_BLIT));
ACCW(HT_VALUE_01, 0x80011146);
ACCW(HT_HANDL_02, (0x80000000 | NV4_GDI_RECTANGLE_TEXT));
ACCW(HT_VALUE_02, 0x80011147);
ACCW(HT_HANDL_03, (0x80000000 | NV4_CONTEXT_SURFACES_ARGB_ZS));
ACCW(HT_VALUE_03, 0x80011148);
ACCW(HT_HANDL_04, (0x80000000 | NV4_DX5_TEXTURE_TRIANGLE));
ACCW(HT_VALUE_04, 0x80011149);
ACCW(HT_HANDL_05, (0x80000000 | NV4_DX6_MULTI_TEXTURE_TRIANGLE));
ACCW(HT_VALUE_05, 0x8001114a);
ACCW(HT_HANDL_06, (0x80000000 | NV1_RENDER_SOLID_LIN));
ACCW(HT_VALUE_06, 0x8001114c);
ACCW(HT_HANDL_10, (0x80000000 | NV_ROP5_SOLID));
ACCW(HT_VALUE_10, 0x80011142);
ACCW(HT_HANDL_11, (0x80000000 | NV_IMAGE_BLACK_RECTANGLE));
ACCW(HT_VALUE_11, 0x80011143);
ACCW(HT_HANDL_12, (0x80000000 | NV_IMAGE_PATTERN));
ACCW(HT_VALUE_12, 0x80011144);
ACCW(HT_HANDL_13, (0x80000000 | NV_SCALED_IMAGE_FROM_MEMORY));
ACCW(HT_VALUE_13, 0x8001114b);
if (si->ps.card_type == NV15)
{
ACCW(HT_HANDL_14, (0x80000000 | NV_TCL_PRIMITIVE_3D));
ACCW(HT_VALUE_14, 0x8001114d);
}
}
if (si->ps.card_arch >= NV40A)
{
ACCW(PR_CTX0_R, 0x00003000);
ACCW(PR_CTX1_R, (si->ps.memory_size - 1));
ACCW(PR_CTX2_R, ((0x00000000 & 0xfffff000) | 0x00000002));
ACCW(PR_CTX3_R, 0x00000002);
ACCW(PR_CTX0_0, 0x02080043);
ACCW(PR_CTX1_0, 0x00000000);
ACCW(PR_CTX2_0, 0x00000000);
ACCW(PR_CTX3_0, 0x00000000);
ACCW(PR_CTX0_1, 0x00000000);
ACCW(PR_CTX1_1, 0x00000000);
ACCW(PR_CTX0_2, 0x02080019);
ACCW(PR_CTX1_2, 0x00000000);
ACCW(PR_CTX2_2, 0x00000000);
ACCW(PR_CTX3_2, 0x00000000);
ACCW(PR_CTX0_3, 0x00000000);
ACCW(PR_CTX1_3, 0x00000000);
ACCW(PR_CTX0_4, 0x02080018);
ACCW(PR_CTX1_4, 0x02000000);
ACCW(PR_CTX2_4, 0x00000000);
ACCW(PR_CTX3_4, 0x00000000);
ACCW(PR_CTX0_5, 0x00000000);
ACCW(PR_CTX1_5, 0x00000000);
ACCW(PR_CTX0_6, 0x0208009f);
ACCW(PR_CTX1_6, 0x00000000);
ACCW(PR_CTX2_6, 0x00001140);
ACCW(PR_CTX3_6, 0x00001140);
ACCW(PR_CTX0_7, 0x00000000);
ACCW(PR_CTX1_7, 0x00000000);
ACCW(PR_CTX0_8, 0x0208004a);
ACCW(PR_CTX1_8, 0x02000000);
ACCW(PR_CTX2_8, 0x00000000);
ACCW(PR_CTX3_8, 0x00000000);
ACCW(PR_CTX0_9, 0x00000000);
ACCW(PR_CTX1_9, 0x00000000);
ACCW(PR_CTX0_A, 0x02080062);
ACCW(PR_CTX1_A, 0x00000000);
ACCW(PR_CTX2_A, 0x00001140);
ACCW(PR_CTX3_A, 0x00001140);
ACCW(PR_CTX0_B, 0x00000000);
ACCW(PR_CTX1_B, 0x00000000);
ACCW(PR_CTX0_C, 0x02080077);
ACCW(PR_CTX1_C, 0x00000000);
ACCW(PR_CTX2_C, 0x00001140);
ACCW(PR_CTX3_C, 0x00001140);
ACCW(PR_CTX0_D, 0x00000000);
ACCW(PR_CTX1_D, 0x00000000);
ACCW(PR_CTX0_E, 0x00003002);
ACCW(PR_CTX1_E, 0x00007fff);
ACCW(PR_CTX2_E, (((si->ps.memory_size - 1) & 0xffff8000) | 0x00000002));
}
else
{
ACCW(PR_CTX0_R, 0x00003000);
ACCW(PR_CTX1_R, (si->ps.memory_size - 1));
ACCW(PR_CTX2_R, ((0x00000000 & 0xfffff000) | 0x00000002));
ACCW(PR_CTX3_R, 0x00000002);
ACCW(PR_CTX0_0, 0x01008043);
ACCW(PR_CTX1_0, 0x00000000);
ACCW(PR_CTX2_0, 0x00000000);
ACCW(PR_CTX3_0, 0x00000000);
ACCW(PR_CTX0_1, 0x01008019);
ACCW(PR_CTX1_1, 0x00000000);
ACCW(PR_CTX2_1, 0x00000000);
ACCW(PR_CTX3_1, 0x00000000);
ACCW(PR_CTX0_2, 0x01008018);
ACCW(PR_CTX1_2, 0x00000002);
ACCW(PR_CTX2_2, 0x00000000);
ACCW(PR_CTX3_2, 0x00000000);
if(si->ps.card_arch >= NV10A)
{
ACCW(PR_CTX0_3, 0x01008062);
}
else
{
ACCW(PR_CTX0_3, 0x01008042);
}
ACCW(PR_CTX1_3, 0x00000000);
ACCW(PR_CTX2_3, 0x11401140);
ACCW(PR_CTX3_3, 0x00000000);
if (si->ps.card_type >= NV11)
{
ACCW(PR_CTX0_4, 0x0100809f);
}
else
{
ACCW(PR_CTX0_4, 0x0100805f);
}
ACCW(PR_CTX1_4, 0x00000000);
ACCW(PR_CTX2_4, 0x11401140);
ACCW(PR_CTX3_4, 0x00000000);
ACCW(PR_CTX0_5, 0x0100804a);
ACCW(PR_CTX1_5, 0x00000002);
ACCW(PR_CTX2_5, 0x00000000);
ACCW(PR_CTX3_5, 0x00000000);
if (si->ps.card_arch >= NV10A)
{
ACCW(PR_CTX0_6, 0x00000093);
}
else
{
ACCW(PR_CTX0_6, 0x00000053);
}
ACCW(PR_CTX1_6, 0x00000000);
ACCW(PR_CTX2_6, 0x11401140);
ACCW(PR_CTX3_6, 0x00000000);
if (si->ps.card_arch >= NV10A)
{
ACCW(PR_CTX0_7, 0x0300a094);
}
else
{
ACCW(PR_CTX0_7, 0x0300a054);
}
ACCW(PR_CTX1_7, 0x00000000);
ACCW(PR_CTX2_7, 0x11401140);
ACCW(PR_CTX3_7, 0x00000000);
if (si->ps.card_arch >= NV10A)
{
ACCW(PR_CTX0_8, 0x0300a095);
}
else
{
ACCW(PR_CTX0_8, 0x0300a055);
}
ACCW(PR_CTX1_8, 0x00000000);
ACCW(PR_CTX2_8, 0x11401140);
ACCW(PR_CTX3_8, 0x00000000);
ACCW(PR_CTX0_9, 0x01018077);
ACCW(PR_CTX1_9, 0x00000000);
ACCW(PR_CTX2_9, 0x11401140);
ACCW(PR_CTX3_9, 0x00000000);
ACCW(PR_CTX0_A, 0x0300a01c);
ACCW(PR_CTX1_A, 0x00000000);
ACCW(PR_CTX2_A, 0x11401140);
ACCW(PR_CTX3_A, 0x00000000);
if (si->ps.card_type == NV15)
{
ACCW(PR_CTX0_B, 0x0300a096);
ACCW(PR_CTX1_B, 0x00000000);
ACCW(PR_CTX2_B, 0x11401140);
ACCW(PR_CTX3_B, 0x00000000);
}
if (si->engine.agp_mode)
{
ACCW(PR_CTX0_C, 0x00033002);
}
else
{
ACCW(PR_CTX0_C, 0x00023002);
}
ACCW(PR_CTX1_C, 0x000fffff);
ACCW(PR_CTX2_C, (((uintptr_t)((uint8 *)(si->dma_buffer_pci))) | 0x00000002));
switch(si->dm.space)
{
case B_CMAP8:
if (si->ps.card_arch < NV30A)
ACCW(BPIXEL, 0x00000100);
else
ACCW(BPIXEL, 0x00000021);
break;
case B_RGB15_LITTLE:
if (si->ps.card_arch < NV30A)
ACCW(BPIXEL, 0x00000400);
else
ACCW(BPIXEL, 0x00000042);
break;
case B_RGB16_LITTLE:
if (si->ps.card_arch < NV30A)
ACCW(BPIXEL, 0x00000500);
else
ACCW(BPIXEL, 0x000000a5);
break;
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
if (si->ps.card_arch < NV30A)
ACCW(BPIXEL, 0x00000c00);
else
ACCW(BPIXEL, 0x000000e7);
break;
default:
LOG(8,("ACC: init, invalid bit depth\n"));
return B_ERROR;
}
}
if (si->ps.card_arch == NV04A)
{
ACCW(DEBUG0, 0x000001ff);
ACCW(DEBUG0, 0x1230c000);
ACCW(DEBUG1, 0x72191101);
ACCW(DEBUG2, 0x11d5f071);
ACCW(DEBUG3, 0x0004ff31);
ACCW(DEBUG3, 0x4004ff31);
ACCW(ACC_INTE, 0x00000000);
ACCW(ACC_INTS, 0xffffffff);
ACCW(NV04_CTX_CTRL, 0x10010100);
ACCW(NV04_ACC_STAT, 0xffffffff);
ACCW(FIFO_EN, 0x00000001);
ACCW(OFFSET0, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(OFFSET1, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(BLIMIT0, (si->ps.memory_size - 1));
ACCW(BLIMIT1, (si->ps.memory_size - 1));
ACCW(BETA_AND_VAL, 0xffffffff);
}
else
{
ACCW(DEBUG0, 0xffffffff);
ACCW(DEBUG0, 0x00000000);
ACCW(ACC_INTE, 0x00000000);
ACCW(ACC_INTS, 0xffffffff);
ACCW(NV10_CTX_CTRL, 0x10010100);
ACCW(NV10_ACC_STAT, 0xffffffff);
ACCW(FIFO_EN, 0x00000001);
ACCW(NV10_SURF_TYP, ((ACCR(NV10_SURF_TYP)) & 0x0007ff00));
ACCW(NV10_SURF_TYP, ((ACCR(NV10_SURF_TYP)) | 0x00020101));
}
if (si->ps.card_arch == NV10A)
{
ACCW(DEBUG1, 0x00118700);
ACCW(DEBUG2, 0x24fd2ad9);
ACCW(DEBUG3, 0x55de0030);
ACCW(NV10_DEBUG4, 0x0000c000);
for (cnt = 0; cnt < 32; cnt++)
{
NV_REG32(NVACC_NV10_TIL0AD + (cnt << 2)) =
NV_REG32(NVACC_NV10_FBTIL0AD + (cnt << 2));
}
ACCW(OFFSET0, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(OFFSET1, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(BLIMIT0, (si->ps.memory_size - 1));
ACCW(BLIMIT1, (si->ps.memory_size - 1));
ACCW(BETA_AND_VAL, 0xffffffff);
}
if (si->ps.card_arch >= NV20A)
{
switch (si->ps.card_arch)
{
case NV40A:
ACCW(DEBUG1, 0x401287c0);
ACCW(DEBUG3, 0x60de8051);
ACCW(NV10_DEBUG4, 0x00008000);
ACCW(NV25_WHAT0, 0x00be3c5f);
tmp = (NV_REG32(NV32_NV4X_WHAT0) & 0x000000ff);
for (cnt = 0; (tmp && !(tmp & 0x00000001)); tmp >>= 1, cnt++)
{
ACCW(NV4X_WHAT2, cnt);
}
switch (si->ps.card_type)
{
case NV40:
case NV45:
ACCW(NV40_WHAT0, 0x83280fff);
ACCW(NV40_WHAT1, 0x000000a0);
ACCW(NV40_WHAT2, 0x0078e366);
ACCW(NV40_WHAT3, 0x0000014c);
break;
case NV41:
ACCW(NV40P_WHAT0, 0x83280eff);
ACCW(NV40P_WHAT1, 0x000000a0);
ACCW(NV40P_WHAT2, 0x007596ff);
ACCW(NV40P_WHAT3, 0x00000108);
break;
case NV43:
ACCW(NV40P_WHAT0, 0x83280eff);
ACCW(NV40P_WHAT1, 0x000000a0);
ACCW(NV40P_WHAT2, 0x0072cb77);
ACCW(NV40P_WHAT3, 0x00000108);
break;
case NV44:
case G72:
ACCW(NV40P_WHAT0, 0x83280eff);
ACCW(NV40P_WHAT1, 0x000000a0);
NV_REG32(NV32_NV44_WHAT10) = NV_REG32(NV32_NV10STRAPINFO);
NV_REG32(NV32_NV44_WHAT11) = 0x00000000;
NV_REG32(NV32_NV44_WHAT12) = 0x00000000;
NV_REG32(NV32_NV44_WHAT13) = NV_REG32(NV32_NV10STRAPINFO);
ACCW(NV44_WHAT2, 0x00000000);
ACCW(NV44_WHAT3, 0x00000000);
break;
case G70:
case G71:
case G73:
ACCW(NV40P_WHAT0, 0x83280eff);
ACCW(NV40P_WHAT1, 0x000000a0);
ACCW(NV40P_WHAT2, 0x07830610);
ACCW(NV40P_WHAT3, 0x0000016a);
break;
default:
ACCW(NV40P_WHAT0, 0x83280eff);
ACCW(NV40P_WHAT1, 0x000000a0);
break;
}
ACCW(NV10_TIL3PT, 0x2ffff800);
ACCW(NV10_TIL3ST, 0x00006000);
ACCW(NV4X_WHAT1, 0x01000000);
ACCW(NV4X_DMA_SRC, 0x00001140);
break;
case NV30A:
ACCW(DEBUG1, 0x40108700);
ACCW(NV25_WHAT1, 0x00140000);
ACCW(DEBUG3, 0xf00e0431);
ACCW(NV10_DEBUG4, 0x00008000);
ACCW(NV25_WHAT0, 0xf04b1f36);
ACCW(NV20_WHAT3, 0x1002d888);
ACCW(NV25_WHAT2, 0x62ff007f);
break;
case NV20A:
ACCW(DEBUG1, 0x00118700);
ACCW(DEBUG3, 0xf20e0431);
ACCW(NV10_DEBUG4, 0x00000000);
ACCW(NV20_WHAT1, 0x00000040);
if (si->ps.card_type < NV25)
{
ACCW(NV20_WHAT2, 0x00080000);
ACCW(NV10_DEBUG5, 0x00000005);
ACCW(NV20_WHAT3, 0x45caa208);
ACCW(NV20_WHAT4, 0x24000000);
ACCW(NV20_WHAT5, 0x00000040);
ACCW(RDI_INDEX, 0x00e00038);
ACCW(RDI_DATA, 0x00000030);
ACCW(RDI_INDEX, 0x00e10038);
ACCW(RDI_DATA, 0x00000030);
}
else
{
ACCW(NV25_WHAT1, 0x00080000);
ACCW(NV25_WHAT0, 0x304b1fb6);
ACCW(NV20_WHAT3, 0x18b82880);
ACCW(NV20_WHAT4, 0x44000000);
ACCW(NV20_WHAT5, 0x40000080);
ACCW(NV25_WHAT2, 0x000000ff);
}
break;
}
if ((si->ps.card_type <= NV40) || (si->ps.card_type == NV45))
{
for (cnt = 0; cnt < 32; cnt++)
{
NV_REG32(NVACC_NV20_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV10_FBTIL0AD + (cnt << 2));
NV_REG32(NVACC_NV20_2_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV10_FBTIL0AD + (cnt << 2));
}
}
else
{
if (si->ps.card_type >= G70)
{
for (cnt = 0; cnt < 60; cnt++)
{
NV_REG32(NVACC_NV41_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV41_FBTIL0AD + (cnt << 2));
NV_REG32(NVACC_NV20_2_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV41_FBTIL0AD + (cnt << 2));
}
}
else
{
for (cnt = 0; cnt < 48; cnt++)
{
NV_REG32(NVACC_NV20_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV41_FBTIL0AD + (cnt << 2));
if (si->ps.card_type != NV44)
{
NV_REG32(NVACC_NV20_2_WHAT0 + (cnt << 2)) =
NV_REG32(NVACC_NV41_FBTIL0AD + (cnt << 2));
}
}
}
}
if (si->ps.card_arch >= NV40A)
{
if ((si->ps.card_type == NV40) || (si->ps.card_type == NV45))
{
ACCW(NV20_WHAT_T0, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(NV20_WHAT_T1, NV_REG32(NV32_PFB_CONFIG_1));
ACCW(NV40_WHAT_T2, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(NV40_WHAT_T3, NV_REG32(NV32_PFB_CONFIG_1));
ACCW(NV20_OFFSET0, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV20_OFFSET1, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV20_BLIMIT6, (si->ps.memory_size - 1));
ACCW(NV20_BLIMIT7, (si->ps.memory_size - 1));
}
else
{
if (si->ps.card_type >= G70)
{
ACCW(G70_WHAT_T0, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(G70_WHAT_T1, NV_REG32(NV32_PFB_CONFIG_1));
}
else
{
ACCW(NV40P_WHAT_T0, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(NV40P_WHAT_T1, NV_REG32(NV32_PFB_CONFIG_1));
}
ACCW(NV40P_WHAT_T2, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(NV40P_WHAT_T3, NV_REG32(NV32_PFB_CONFIG_1));
ACCW(NV40P_OFFSET0, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV40P_OFFSET1, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV40P_BLIMIT6, (si->ps.memory_size - 1));
ACCW(NV40P_BLIMIT7, (si->ps.memory_size - 1));
}
}
else
{
ACCW(NV20_WHAT_T0, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(NV20_WHAT_T1, NV_REG32(NV32_PFB_CONFIG_1));
ACCW(RDI_INDEX, 0x00ea0000);
ACCW(RDI_DATA, NV_REG32(NV32_PFB_CONFIG_0));
ACCW(RDI_INDEX, 0x00ea0004);
ACCW(RDI_DATA, NV_REG32(NV32_PFB_CONFIG_1));
ACCW(NV20_OFFSET0, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV20_OFFSET1, ((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer));
ACCW(NV20_BLIMIT6, (si->ps.memory_size - 1));
ACCW(NV20_BLIMIT7, (si->ps.memory_size - 1));
}
ACCW(NV10_TIL2AD, 0x00000000);
ACCW(NV10_TIL0ED, 0xffffffff);
}
ACCW(ABS_UCLP_XMIN, 0x00000000);
ACCW(ABS_UCLP_YMIN, 0x00000000);
ACCW(ABS_UCLP_XMAX, 0x00007fff);
ACCW(ABS_UCLP_YMAX, 0x00007fff);
if (si->ps.card_type >= NV11)
{
ACCW(NV11_CRTC_LO, si->dm.timing.v_display - 1);
ACCW(NV11_CRTC_HI, si->dm.timing.v_display + 1);
}
ACCW(PF_CACHES, 0x00000000);
ACCW(PF_MODE, 0x00000001);
ACCW(PF_CACH1_PSH0, 0x00000000);
ACCW(PF_CACH1_PUL0, 0x00000000);
if (si->ps.card_arch >= NV40A)
ACCW(PF_CACH1_PSH1, 0x00010000);
else
ACCW(PF_CACH1_PSH1, 0x00000100);
ACCW(PF_CACH1_DMAP, 0x00000000);
ACCW(PF_CACH1_DMAG, 0x00000000);
if (si->ps.card_arch >= NV40A)
ACCW(PF_CACH1_DMAI, 0x00001150);
else
ACCW(PF_CACH1_DMAI, 0x0000114e);
ACCW(PF_CACH0_PSH0, 0x00000000);
ACCW(PF_CACH0_PUL0, 0x00000000);
ACCW(PF_RAMHT, 0x03000100);
ACCW(PF_RAMFC, 0x00000110);
ACCW(PF_RAMRO, 0x00000112);
ACCW(PF_SIZE, 0x0000ffff);
ACCW(PF_CACH1_HASH, 0x0000ffff);
ACCW(PF_INTEN, 0x00000000);
ACCW(PF_INTSTAT, 0xffffffff);
ACCW(PF_CACH0_PUL1, 0x00000001);
ACCW(PF_CACH1_DMAC, 0x00000000);
ACCW(PF_CACH1_ENG, 0x00000000);
ACCW(PF_CACH1_DMAF, 0x000f0078);
ACCW(PF_CACH1_DMAS, 0x00000001);
ACCW(PF_CACH1_PSH0, 0x00000001);
ACCW(PF_CACH1_PUL0, 0x00000001);
ACCW(PF_CACH1_PUL1, 0x00000001);
ACCW(PF_CACHES, 0x00000001);
nv_init_for_3D_dma();
si->engine.fifo.handle[0] = NV_ROP5_SOLID;
si->engine.fifo.handle[1] = NV_IMAGE_BLACK_RECTANGLE;
si->engine.fifo.handle[2] = NV_IMAGE_PATTERN;
si->engine.fifo.handle[3] = NV4_SURFACE;
si->engine.fifo.handle[4] = NV_IMAGE_BLIT;
si->engine.fifo.handle[5] = NV4_GDI_RECTANGLE_TEXT;
si->engine.fifo.handle[6] = NV4_CONTEXT_SURFACES_ARGB_ZS;
si->engine.fifo.handle[7] = NV4_DX5_TEXTURE_TRIANGLE;
for (cnt = 0; cnt < 0x20; cnt++)
{
si->engine.fifo.ch_ptr[cnt] = 0;
}
for (cnt = 0; cnt < 0x08; cnt++)
{
si->engine.fifo.ch_ptr[(si->engine.fifo.handle[cnt])]
= (0x00000001 + (cnt * 0x00002000));
}
if (si->ps.card_arch >= NV40A)
{
si->dma_buffer = (void *)((char *)si->framebuffer
+ ((si->ps.memory_size - 1) & 0xffff8000));
}
LOG(4, ("ACC_DMA: command buffer is at adress $%p\n", si->dma_buffer));
si->engine.dma.put = 0;
si->engine.dma.current = 0;
if (si->ps.card_arch < NV40A)
si->engine.dma.max = ((1 * 1024 * 1024) >> 2) - 1;
else
si->engine.dma.max = 8192 - 1;
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
if (si->ps.card_arch >= NV40A)
{
if (nv_acc_fifofree_dma(12) != B_OK) return B_ERROR;
} else {
if (nv_acc_fifofree_dma(16) != B_OK) return B_ERROR;
}
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH0, si->engine.fifo.handle[0]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH1, si->engine.fifo.handle[1]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH2, si->engine.fifo.handle[2]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH3, si->engine.fifo.handle[3]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH4, si->engine.fifo.handle[4]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH5, si->engine.fifo.handle[5]);
if (si->ps.card_arch < NV40A)
{
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH6, si->engine.fifo.handle[6]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH7, si->engine.fifo.handle[7]);
}
switch(si->dm.space)
{
case B_CMAP8:
surf_depth = 0x00000001;
cmd_depth = 0x00000003;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
surf_depth = 0x00000004;
cmd_depth = 0x00000001;
break;
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
surf_depth = 0x00000006;
cmd_depth = 0x00000003;
break;
default:
LOG(8,("ACC_DMA: init, invalid bit depth\n"));
return B_ERROR;
}
if (nv_acc_fifofree_dma(5) != B_OK) return B_ERROR;
nv_acc_cmd_dma(NV4_SURFACE, NV4_SURFACE_FORMAT, 4);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = surf_depth;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((si->fbc.bytes_per_row & 0x0000ffff) | (si->fbc.bytes_per_row << 16));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer);
if (nv_acc_fifofree_dma(2) != B_OK) return B_ERROR;
nv_acc_cmd_dma(NV_IMAGE_PATTERN, NV_IMAGE_PATTERN_SETCOLORFORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
if (nv_acc_fifofree_dma(2) != B_OK) return B_ERROR;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_SETCOLORFORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
if (nv_acc_fifofree_dma(7) != B_OK) return B_ERROR;
nv_acc_cmd_dma(NV_IMAGE_PATTERN, NV_IMAGE_PATTERN_SETSHAPE, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000000;
nv_acc_cmd_dma(NV_IMAGE_PATTERN, NV_IMAGE_PATTERN_SETCOLOR0, 4);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xffffffff;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xffffffff;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xffffffff;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xffffffff;
nv_start_dma();
return B_OK;
}
static void nv_init_for_3D_dma(void)
{
if (si->ps.card_arch >= NV10A)
{
ACCW(PGWHAT_00, 0x00000000);
ACCW(PGWHAT_01, 0x00000000);
ACCW(PGWHAT_02, 0x00000000);
ACCW(PGWHAT_03, 0x00000000);
ACCW(PGWHAT_04, 0x00001000);
ACCW(PGWHAT_05, 0x00001000);
ACCW(PGWHAT_06, 0x4003ff80);
ACCW(PGWHAT_07, 0x00000000);
ACCW(PGWHAT_08, 0x00000000);
ACCW(PGWHAT_09, 0x00000000);
ACCW(PGWHAT_0A, 0x00000000);
ACCW(PGWHAT_0B, 0x00000000);
ACCW(PGWHAT_0C, 0x00080008);
ACCW(PGWHAT_0D, 0x00080008);
ACCW(PGWHAT_0E, 0x00000000);
ACCW(PGWHAT_0F, 0x00000000);
ACCW(PGWHAT_10, 0x00000000);
ACCW(PGWHAT_11, 0x00000000);
ACCW(PGWHAT_12, 0x00000000);
ACCW(PGWHAT_13, 0x00000000);
ACCW(PGWHAT_14, 0x00000000);
ACCW(PGWHAT_15, 0x00000000);
ACCW(PGWHAT_16, 0x00000000);
ACCW(PGWHAT_17, 0x00000000);
ACCW(PGWHAT_18, 0x00000000);
ACCW(PGWHAT_19, 0x10000000);
ACCW(PGWHAT_1A, 0x00000000);
ACCW(PGWHAT_1B, 0x00000000);
ACCW(PGWHAT_1C, 0x00000000);
ACCW(PGWHAT_1D, 0x00000000);
ACCW(PGWHAT_1E, 0x00000000);
ACCW(PGWHAT_1F, 0x00000000);
ACCW(PGWHAT_20, 0x00000000);
ACCW(PGWHAT_21, 0x00000000);
ACCW(PGWHAT_22, 0x08000000);
ACCW(PGWHAT_23, 0x00000000);
ACCW(PGWHAT_24, 0x00000000);
ACCW(PGWHAT_25, 0x00000000);
ACCW(PGWHAT_26, 0x00000000);
ACCW(PGWHAT_27, 0x4b7fffff);
ACCW(PGWHAT_28, 0x00000000);
ACCW(PGWHAT_29, 0x00000000);
ACCW(PGWHAT_2A, 0x00000000);
ACCW(WINCLIP_H_0, 0x07ff0800);
ACCW(WINCLIP_H_1, 0x07ff0800);
ACCW(WINCLIP_H_2, 0x07ff0800);
ACCW(WINCLIP_H_3, 0x07ff0800);
ACCW(WINCLIP_H_4, 0x07ff0800);
ACCW(WINCLIP_H_5, 0x07ff0800);
ACCW(WINCLIP_H_6, 0x07ff0800);
ACCW(WINCLIP_H_7, 0x07ff0800);
ACCW(WINCLIP_V_0, 0x07ff0800);
ACCW(WINCLIP_V_1, 0x07ff0800);
ACCW(WINCLIP_V_2, 0x07ff0800);
ACCW(WINCLIP_V_3, 0x07ff0800);
ACCW(WINCLIP_V_4, 0x07ff0800);
ACCW(WINCLIP_V_5, 0x07ff0800);
ACCW(WINCLIP_V_6, 0x07ff0800);
ACCW(WINCLIP_V_7, 0x07ff0800);
ACCW(NV10_XFMOD0, 0x10000000);
ACCW(NV10_XFMOD1, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006740);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEADR, 0x00006750);
ACCW(NV10_PIPEDAT, 0x40000000);
ACCW(NV10_PIPEDAT, 0x40000000);
ACCW(NV10_PIPEDAT, 0x40000000);
ACCW(NV10_PIPEDAT, 0x40000000);
ACCW(NV10_PIPEADR, 0x00006760);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006770);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006780);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x000067a0);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEADR, 0x00006ab0);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEADR, 0x00006ac0);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006c10);
ACCW(NV10_PIPEDAT, 0xbf800000);
ACCW(NV10_PIPEADR, 0x00007030);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007040);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007050);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007060);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007070);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007080);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00007090);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x000070a0);
ACCW(NV10_PIPEDAT, 0x7149f2ca);
ACCW(NV10_PIPEADR, 0x00006a80);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEADR, 0x00006aa0);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00000040);
ACCW(NV10_PIPEDAT, 0x00000005);
ACCW(NV10_PIPEADR, 0x00006400);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x4b7fffff);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006410);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006420);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x00006430);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x000064c0);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEDAT, 0x477fffff);
ACCW(NV10_PIPEDAT, 0x3f800000);
ACCW(NV10_PIPEADR, 0x000064d0);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0xc5000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x000064e0);
ACCW(NV10_PIPEDAT, 0xc4fff000);
ACCW(NV10_PIPEDAT, 0xc4fff000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEADR, 0x000064f0);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_PIPEDAT, 0x00000000);
ACCW(NV10_XFMOD0, 0x30000000);
ACCW(NV10_XFMOD1, 0x00000004);
ACCW(GLOB_STAT_0, 0x10000000);
ACCW(GLOB_STAT_1, 0x00000000);
}
}
static void nv_start_dma(void)
{
uint32 dummy;
if (si->engine.dma.current != si->engine.dma.put)
{
si->engine.dma.put = si->engine.dma.current;
if (si->ps.card_arch < NV40A)
{
__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
dummy = ACCR(STATUS);
}
else
{
dummy = *((volatile uint32 *)(si->framebuffer));
}
NV_REG32(NVACC_FIFO + NV_GENERAL_DMAPUT) = (si->engine.dma.put << 2);
}
}
static status_t nv_acc_fifofree_dma(uint16 cmd_size)
{
uint32 dmaget;
uint16 cnt = 0;
while ((si->engine.dma.free < cmd_size) && (cnt < 10000) && (err < 3))
{
dmaget = ((NV_REG32(NVACC_FIFO + NV_GENERAL_DMAGET)) >> 2);
cnt++;
if (si->engine.dma.put >= dmaget)
{
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
if (si->engine.dma.free < cmd_size)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x20000000;
si->engine.dma.current = 0;
nv_start_dma();
si->engine.dma.free = dmaget - si->engine.dma.current;
if (si->engine.dma.free < 256)
si->engine.dma.free = 0;
else
si->engine.dma.free -= 256;
}
}
else
{
si->engine.dma.free = dmaget - si->engine.dma.current;
if (si->engine.dma.free < 256)
si->engine.dma.free = 0;
else
si->engine.dma.free -= 256;
}
}
if (cnt == 10000)
{
if (err < 3) err++;
LOG(4,("ACC_DMA: fifofree; DMA timeout #%d, engine trouble!\n", err));
}
if (err >= 3) return B_ERROR;
return B_OK;
}
static void nv_acc_cmd_dma(uint32 cmd, uint16 offset, uint16 size)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = ((size << 18) |
((si->engine.fifo.ch_ptr[cmd] + offset) & 0x0000fffc));
si->engine.dma.free -= (size + 1);
}
static void nv_acc_set_ch_dma(uint16 ch, uint32 handle)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = ((1 << 18) | ch);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = (0x80000000 | handle);
si->engine.dma.free -= 2;
}
void nv_acc_assert_fifo_dma(void)
{
if (!si->engine.fifo.ch_ptr[NV_ROP5_SOLID] ||
!si->engine.fifo.ch_ptr[NV_IMAGE_BLACK_RECTANGLE] ||
!si->engine.fifo.ch_ptr[NV_IMAGE_PATTERN] ||
!si->engine.fifo.ch_ptr[NV4_SURFACE] ||
!si->engine.fifo.ch_ptr[NV_IMAGE_BLIT] ||
!si->engine.fifo.ch_ptr[NV4_GDI_RECTANGLE_TEXT] ||
!si->engine.fifo.ch_ptr[NV_SCALED_IMAGE_FROM_MEMORY])
{
uint16 cnt;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[0]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[1]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[2]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[3]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[4]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[5]] = 0;
si->engine.fifo.ch_ptr[si->engine.fifo.handle[6]] = 0;
si->engine.fifo.handle[0] = NV_ROP5_SOLID;
si->engine.fifo.handle[1] = NV_IMAGE_BLACK_RECTANGLE;
si->engine.fifo.handle[2] = NV_IMAGE_PATTERN;
si->engine.fifo.handle[3] = NV4_SURFACE;
si->engine.fifo.handle[4] = NV_IMAGE_BLIT;
si->engine.fifo.handle[5] = NV4_GDI_RECTANGLE_TEXT;
si->engine.fifo.handle[6] = NV_SCALED_IMAGE_FROM_MEMORY;
for (cnt = 0; cnt < 0x08; cnt++)
{
si->engine.fifo.ch_ptr[(si->engine.fifo.handle[cnt])] =
(0x00000001 + (cnt * 0x00002000));
}
if (nv_acc_fifofree_dma(14) != B_OK) return;
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH0, si->engine.fifo.handle[0]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH1, si->engine.fifo.handle[1]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH2, si->engine.fifo.handle[2]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH3, si->engine.fifo.handle[3]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH4, si->engine.fifo.handle[4]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH5, si->engine.fifo.handle[5]);
nv_acc_set_ch_dma(NV_GENERAL_FIFO_CH6, si->engine.fifo.handle[6]);
nv_start_dma();
}
}
void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count)
{
uint32 i = 0;
uint16 subcnt;
if (nv_acc_fifofree_dma(2) != B_OK) return;
nv_acc_cmd_dma(NV_ROP5_SOLID, NV_ROP5_SOLID_SETROP5, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xcc;
while (count)
{
subcnt = 32;
if (count < 32) subcnt = count;
count -= subcnt;
if (nv_acc_fifofree_dma(4 * subcnt) != B_OK) return;
while (subcnt--)
{
nv_acc_cmd_dma(NV_IMAGE_BLIT, NV_IMAGE_BLIT_SOURCEORG, 3);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_top) << 16) | (list[i].src_left));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].dest_top) << 16) | (list[i].dest_left));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((((list[i].height) + 1) << 16) | ((list[i].width) + 1));
i++;
}
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}
void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT_DMA(engine_token *et, scaled_blit_params *list, uint32 count)
{
uint32 i = 0;
uint16 subcnt;
uint32 cmd_depth;
uint8 bpp;
switch(si->dm.space)
{
case B_RGB15_LITTLE:
cmd_depth = 0x00000002;
bpp = 2;
break;
case B_RGB16_LITTLE:
cmd_depth = 0x00000007;
bpp = 2;
break;
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
cmd_depth = 0x00000004;
bpp = 4;
break;
case B_YCbCr422:
cmd_depth = 0x00000005;
bpp = 2;
break;
case B_YUV422:
cmd_depth = 0x00000006;
bpp = 2;
break;
default:
LOG(8,("ACC_DMA: scaled_filtered_blit, invalid bit depth\n"));
return;
}
if (si->dm.space == B_RGB15_LITTLE)
{
if (nv_acc_fifofree_dma(2) != B_OK) return;
nv_acc_cmd_dma(NV4_SURFACE, NV4_SURFACE_FORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000002;
}
if (si->ps.card_type != NV04)
{
if (nv_acc_fifofree_dma(5) != B_OK) return;
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 2);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000003;
}
else
{
if (nv_acc_fifofree_dma(4) != B_OK) return;
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
}
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000000;
while (count)
{
subcnt = 16;
if (count < 16) subcnt = count;
count -= subcnt;
if (nv_acc_fifofree_dma(12 * subcnt) != B_OK) return;
while (subcnt--)
{
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCEORG, 6);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].dest_height + 1) << 16) | (list[i].dest_width + 1));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].dest_top) << 16) | (list[i].dest_left));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].dest_height + 1) << 16) | (list[i].dest_width + 1));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_width + 1) << 20) / (list[i].dest_width + 1));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_height + 1) << 20) / (list[i].dest_height + 1));
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCESIZE, 4);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_height + 1) << 16) |
(((list[i].src_width + 1) + 0x0001) & ~0x0001));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(si->fbc.bytes_per_row | (1 << 16) | (1 << 24));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((uint32)((uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer)) +
(list[i].src_top * si->fbc.bytes_per_row) + (list[i].src_left * bpp);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
0;
i++;
}
nv_start_dma();
}
if (si->dm.space == B_RGB15_LITTLE)
{
if (nv_acc_fifofree_dma(2) != B_OK) return;
nv_acc_cmd_dma(NV4_SURFACE, NV4_SURFACE_FORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000004;
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}
void OFFSCREEN_TO_SCREEN_SCALED_FILTERED_BLIT_DMA(
engine_token *et, offscreen_buffer_config *config, clipped_scaled_blit_params *list, uint32 count)
{
uint32 i = 0;
uint32 cmd_depth;
uint8 bpp;
LOG(4, ("ACC_DMA: offscreen src buffer location $%p\n",
(uint8*)(config->buffer)));
switch (config->space)
{
case B_RGB15_LITTLE:
cmd_depth = 0x00000002;
bpp = 2;
break;
case B_RGB16_LITTLE:
cmd_depth = 0x00000007;
bpp = 2;
break;
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
cmd_depth = 0x00000004;
bpp = 4;
break;
case B_YCbCr422:
cmd_depth = 0x00000005;
bpp = 2;
break;
case B_YUV422:
cmd_depth = 0x00000006;
bpp = 2;
break;
default:
LOG(8,("ACC_DMA: scaled_filtered_blit, invalid bit depth\n"));
return;
}
if (si->dm.space == B_RGB15_LITTLE)
{
if (nv_acc_fifofree_dma(2) != B_OK) return;
nv_acc_cmd_dma(NV4_SURFACE, NV4_SURFACE_FORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000002;
}
if (si->ps.card_type != NV04)
{
if (nv_acc_fifofree_dma(5) != B_OK) return;
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 2);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000003;
}
else
{
if (nv_acc_fifofree_dma(4) != B_OK) return;
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth;
}
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000000;
while (count--)
{
uint32 j = 0;
uint16 clipcnt = list[i].dest_clipcount;
LOG(4,("ACC_DMA: offscreen src left %d, top %d\n", list[i].src_left, list[i].src_top));
LOG(4,("ACC_DMA: offscreen src width %d, height %d\n", list[i].src_width + 1, list[i].src_height + 1));
LOG(4,("ACC_DMA: offscreen dest left %d, top %d\n", list[i].dest_left, list[i].dest_top));
LOG(4,("ACC_DMA: offscreen dest width %d, height %d\n", list[i].dest_width + 1, list[i].dest_height + 1));
if (nv_acc_fifofree_dma(9 + (5 * clipcnt)) != B_OK) return;
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCEORG + 8, 4);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((list[i].dest_top << 16) | list[i].dest_left);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].dest_height + 1) << 16) | (list[i].dest_width + 1));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_width + 1) << 20) / (list[i].dest_width + 1));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_height + 1) << 20) / (list[i].dest_height + 1));
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCESIZE, 3);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].src_height + 1) << 16) |
(((list[i].src_width + 1) + 0x0001) & ~0x0001));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(config->bytes_per_row | (1 << 16) | (1 << 24));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(uint32)((uint8*)config->buffer - (uint8*)si->framebuffer +
(list[i].src_top * config->bytes_per_row) + (list[i].src_left * bpp));
while (clipcnt--)
{
LOG(4,("ACC_DMA: offscreen clip left %d, top %d\n",
list[i].dest_cliplist[j].left, list[i].dest_cliplist[j].top));
LOG(4,("ACC_DMA: offscreen clip width %d, height %d\n",
list[i].dest_cliplist[j].width + 1, list[i].dest_cliplist[j].height + 1));
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCEORG, 2);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(list[i].dest_cliplist[j].top << 16) | list[i].dest_cliplist[j].left;
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((list[i].dest_cliplist[j].height + 1) << 16) | (list[i].dest_cliplist[j].width + 1);
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SOURCESIZE + 12, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
0;
j++;
}
i++;
}
nv_start_dma();
if (si->dm.space == B_RGB15_LITTLE)
{
if (nv_acc_fifofree_dma(2) != B_OK) return;
nv_acc_cmd_dma(NV4_SURFACE, NV4_SURFACE_FORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000004;
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}
void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
{
uint32 i = 0;
uint16 subcnt;
if (nv_acc_fifofree_dma(4) != B_OK) return;
nv_acc_cmd_dma(NV_ROP5_SOLID, NV_ROP5_SOLID_SETROP5, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xcc;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = colorIndex;
while (count)
{
subcnt = 32;
if (count < 32) subcnt = count;
count -= subcnt;
if (nv_acc_fifofree_dma(1 + (2 * subcnt)) != B_OK) return;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_UCR0_LEFTTOP, (2 * subcnt));
while (subcnt--)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].left) << 16) | ((list[i].top) & 0x0000ffff));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((((list[i].right)+1) - (list[i].left)) << 16) |
(((list[i].bottom-list[i].top)+1) & 0x0000ffff));
i++;
}
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}
void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
uint32 i = 0;
uint16 subcnt;
if (nv_acc_fifofree_dma(4) != B_OK) return;
nv_acc_cmd_dma(NV_ROP5_SOLID, NV_ROP5_SOLID_SETROP5, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0xcc;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = colorIndex;
while (count)
{
subcnt = 32;
if (count < 32) subcnt = count;
count -= subcnt;
if (nv_acc_fifofree_dma(1 + (2 * subcnt)) != B_OK) return;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_UCR0_LEFTTOP, (2 * subcnt));
while (subcnt--)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i+1]) << 16) | ((list[i]) & 0x0000ffff));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
((((list[i+2]+1) - (list[i+1])) << 16) | 0x00000001);
i+=3;
}
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}
void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count)
{
uint32 i = 0;
uint16 subcnt;
if (nv_acc_fifofree_dma(4) != B_OK) return;
nv_acc_cmd_dma(NV_ROP5_SOLID, NV_ROP5_SOLID_SETROP5, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x55;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000000;
while (count)
{
subcnt = 32;
if (count < 32) subcnt = count;
count -= subcnt;
if (nv_acc_fifofree_dma(1 + (2 * subcnt)) != B_OK) return;
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_UCR0_LEFTTOP, (2 * subcnt));
while (subcnt--)
{
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((list[i].left) << 16) | ((list[i].top) & 0x0000ffff));
((uint32*)(si->dma_buffer))[si->engine.dma.current++] =
(((((list[i].right)+1) - (list[i].left)) << 16) |
(((list[i].bottom-list[i].top)+1) & 0x0000ffff));
i++;
}
nv_start_dma();
}
si->engine.threeD.reload = 0xffffffff;
}