void rgz_profile_hwc(hwc_display_contents_1_t* list, int dispw, int disph) { if (!list) /* A NULL composition list can occur */ return; #ifndef RGZ_TEST_INTEGRATION static char regiondump2[PROPERTY_VALUE_MAX] = ""; char regiondump[PROPERTY_VALUE_MAX]; property_get("debug.2dhwc.region", regiondump, "0"); int dumpregions = strncmp(regiondump, regiondump2, PROPERTY_VALUE_MAX); if (dumpregions) strncpy(regiondump2, regiondump, PROPERTY_VALUE_MAX); else { dumpregions = !strncmp(regiondump, "all", PROPERTY_VALUE_MAX) && (list->flags & HWC_GEOMETRY_CHANGED); static int iteration = 0; if (dumpregions) sprintf(regiondump, "iteration %d", iteration++); } char dumplayerdata[PROPERTY_VALUE_MAX]; /* 0 - off, 1 - human readable, 2 - CSV */ property_get("debug.2dhwc.dumplayers", dumplayerdata, "0"); int dumplayers = atoi(dumplayerdata); #else char regiondump[] = ""; int dumplayers = 1; int dumpregions = 0; #endif if (dumplayers && (list->flags & HWC_GEOMETRY_CHANGED)) { OUTP("<!-- BEGUN-LAYER-DUMP: %d -->", list->numHwLayers); rgz_print_layers(list, dumplayers == 1 ? 0 : 1); OUTP("<!-- ENDED-LAYER-DUMP -->"); } if(!dumpregions) return; rgz_t rgz; rgz_in_params_t ip = { .data = { .hwc = { .layers = list->hwLayers, .layerno = list->numHwLayers } } }; ip.op = RGZ_IN_HWCCHK; if (rgz_in(&ip, &rgz) == RGZ_ALL) { ip.op = RGZ_IN_HWC; if (rgz_in(&ip, &rgz) == RGZ_ALL) { OUTP("<!-- BEGUN-SVG-DUMP: %s -->", regiondump); OUTP("<b>%s</b>", regiondump); rgz_out_params_t op = { .op = RGZ_OUT_SVG, .data = { .svg = { .dispw = dispw, .disph = disph, .htmlw = 450, .htmlh = 800 } }, }; rgz_out(&rgz, &op); OUTP("<!-- ENDED-SVG-DUMP -->"); }
static void show_heading(int16_t *heading) { if (heading) { OUTP("%d ", *heading); OUTP("[%d %d %d]", (int16_t)mag_uT[0], (int16_t)mag_uT[1], (int16_t)mag_uT[2]); } else { OUT("error"); } OUT("\r\n"); }
static void svgout_rect(blit_rect_t *r, char *color, char *text) { OUTP("<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"%s\" " "fill-opacity=\"%f\" stroke=\"black\" stroke-width=\"1\" />", r->left, r->top, r->right - r->left, r->bottom - r->top, color, 1.0f); if (!text) return; OUTP("<text x=\"%d\" y=\"%d\" style=\"font-size:30\" fill=\"black\">%s" "</text>", r->left, r->top + 40, text); }
static void svgout_header(int htmlw, int htmlh, int coordw, int coordh) { OUTP("<svg xmlns=\"http://www.w3.org/2000/svg\"" "width=\"%d\" height=\"%d\"" "viewBox=\"0 0 %d %d\">", htmlw, htmlh, coordw, coordh); }
static void print_routes(route_matrix_t *routes) { node_id_t src, dest; OUT("routes: \r\n"); OUT(" "); /* column width of source label */ for (dest = 0; dest < MAX_NODES; ++dest) OUTP("%d ", dest); OUT("\r\n"); for (src = 0; src < MAX_NODES; ++src) { OUTP("%d: ", src); for (dest = 0; dest < MAX_NODES; ++dest) OUTP("%d ", (*routes)[src][dest]); OUT("\r\n"); } }
static int loadbltsville(void) { void *hndl = dlopen(BLTSVILLELIB, RTLD_LOCAL | RTLD_LAZY); if (!hndl) { OUTE("Loading bltsville failed"); return -1; } bv_map = (BVFN_MAP)dlsym(hndl, "bv_map"); bv_blt = (BVFN_BLT)dlsym(hndl, "bv_blt"); bv_unmap = (BVFN_UNMAP)dlsym(hndl, "bv_unmap"); if(!bv_blt || !bv_map || !bv_unmap) { OUTE("Missing bltsville fn %p %p %p", bv_map, bv_blt, bv_unmap); return -1; } OUTP("Loaded %s", BLTSVILLELIB); #ifndef RGZ_TEST_INTEGRATION hw_module_t const* module; int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); if (err != 0) { OUTE("Loading gralloc failed"); return -1; } gralloc = (gralloc_module_t const *)module; #endif return 0; }
void Initialize_m(void) { /* * Make sure we have enough available FIFO entries * to initialize the card. */ CheckFIFOSpace_m(SIXTEEN_WORDS); /* * On the 68800, set the memory boundary to shared VGA memory. * On all cards, set the screen and drawing engine to start * at the beginning of accelerator memory and MEM_CNTL * to linear. */ if (phwDeviceExtension->ModelNumber == MACH32_ULTRA) OUTP (MEM_BNDRY,0); OUTPW(CRT_OFFSET_LO, 0); OUTPW(GE_OFFSET_LO, 0); OUTPW(CRT_OFFSET_HI, 0); OUTPW(GE_OFFSET_HI, 0); OUTPW(MEM_CNTL,0x5006); /* * Reset the engine and FIFO, then return to normal operation. */ OUTPW(SUBSYS_CNTL,0x9000); OUTPW(SUBSYS_CNTL,0x5000); /* * The hardware cursor is available only for Mach 32 cards. * disable the cursor and initialize it to display quadrant I - 0 */ if (phwDeviceExtension->ModelNumber == MACH32_ULTRA) { OUTPW(CURSOR_OFFSET_HI,0); OUTPW(HORZ_CURSOR_OFFSET,0); OUTP(VERT_CURSOR_OFFSET,0); OUTPW(CURSOR_COLOR_0, 0x0FF00); /* Colour 0 black, colour 1 white */ OUTPW(EXT_CURSOR_COLOR_0,0); // black OUTPW(EXT_CURSOR_COLOR_1,0xffff); // white } return; } /* Initialize_m() */
int8_t cmd_head(uint8_t argc, char **argv) { int16_t heading; int8_t rc = NRK_OK, rc_node = NRK_OK; #if ENABLE_COMPASS_RPC node_id_t node; uint8_t i; #endif if (!(argc == 1 || argc >= 2)) { OUT("usage: head [<node>...]\r\n"); return NRK_ERROR; } if (have_compass) { rc_node = get_heading(&heading); if (rc_node != NRK_OK) rc = rc_node; } OUT("node: heading [x y z] (uT)\r\n"); if (have_compass) { OUTP("%d: ", this_node_id); show_heading(rc == NRK_OK ? &heading : NULL); } if (argc >= 2) { #if ENABLE_COMPASS_RPC for (i = 1; i < argc; ++i) { node = atoi(argv[i]); rc_node = rpc_heading(node, &heading); if (rc_node != NRK_OK) rc = rc_node; OUTP("%d: ", node); show_heading(rc == NRK_OK ? &heading : NULL); } #else OUT("ERROR: COMPASS_RPC not linked in\r\n"); return NRK_ERROR; #endif } return rc; }
int8_t cmd_cnvtime(uint8_t argc, char **argv) { nrk_time_t time; uint32_t ms; char to_unit; char *sec, *nsec; if (argc != 3) { OUT("usage: cnvtime t|m <value>\r\n"); return NRK_ERROR; } to_unit = argv[1][0]; switch (to_unit) { case 't': ms = atol(argv[2]); MS_TO_TIME(time, ms); OUTP("%lu = ", ms); OUTP("%lu:%lu\r\n", time.secs, time.nano_secs); break; case 'm': sec = argv[2]; nsec = strchr(sec, ':'); if (nsec == NULL) { OUT("invalid time value: expecting s:ns\r\n"); return; } *nsec = '\0'; nsec++; time.secs = atol(sec); time.nano_secs = atol(nsec); ms = TIME_TO_MS(time); OUTP("%lu:%lu = ", time.secs, time.nano_secs); OUTP("%lu ms\r\n", ms); break; default: OUT("unknown unit\r\n"); return NRK_ERROR; } return NRK_OK; }
Byte Processor::execInstruction() { #ifdef R_UM_OPT_ENABLE_LOGGING #ifdef R_UM_OPT_PRC_DEBUG ic_ ++; #endif #endif Word instr = (*mm_)(0, pc_ ++); switch (decodeInstruction(instr)) { case IC_CNDMOV: return CNDMOV(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_ARRIDX: return ARRIDX(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_ARRAMD: return ARRAMD(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_ADD: return ADD(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_MUL: return MUL(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_DIV: return DIV(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_NOTAND: return NOTAND(decodeAreg(instr), decodeBreg(instr), decodeCreg(instr)); case IC_HLT: return HLT(); case IC_ALLOC: return ALLOC(decodeBreg(instr), decodeCreg(instr)); case IC_ABAND: return ABAND(decodeCreg(instr)); case IC_OUTP: return OUTP(decodeCreg(instr)); case IC_INP: return INP(decodeCreg(instr)); case IC_LDPRG: return LDPRG(decodeBreg(instr), decodeCreg(instr)); case IC_ORTHO: return ORTHO(decodeOreg(instr), decodeVal(instr)); default: assert(false); return HLT(); } }
static void print_locations() { node_id_t node; location_t *loc; OUT("locations:\r\n"); for (node = 0; node < MAX_NODES; ++node) { loc = &locations[node]; if (loc->valid) OUTP("%u: (%d,%d)\r\n", node, loc->pt.x, loc->pt.y); } print_loc_graph(&ir_graph, locations); }
int8_t cmd_mapdim(uint8_t argc, char **argv) { if (!(argc == 1 || argc == 3)) { OUT("usage: mapdim [<x> <y>]\r\n"); return NRK_ERROR; } if (argc == 3) { /* set */ map_dim.x = atoi(argv[1]); map_dim.y = atoi(argv[2]); } else { OUTP("%d %d\r\n", map_dim.x, map_dim.y); } return NRK_OK; }
VOID vReleaseCrtc(PDEV* ppdev) { // 80x/805i/928 and 928PCI chips have a bug where if I/O registers // are left unlocked after accessing them, writes to memory with // similar addresses can cause writes to I/O registers. The problem // registers are 0x40, 0x58, 0x59 and 0x5c. We will simply always // leave the index set to an innocuous register (namely, the text // mode cursor start scan line): OUTP(ppdev->pjIoBase, CRTC_INDEX, 0xa); if (!gbCrtcCriticalSection) RIP("Hadn't yet acquired Critical Section"); gbCrtcCriticalSection = FALSE; EngReleaseSemaphore(ppdev->csCrtc); }
static void rgz_out_svg(rgz_t *rgz, rgz_out_params_t *params) { if (!rgz || !(rgz->state & RGZ_REGION_DATA)) { OUTE("rgz_out_svg invoked with bad state"); return; } blit_hregion_t *hregions = rgz->hregions; svgout_header(params->data.svg.htmlw, params->data.svg.htmlh, params->data.svg.dispw, params->data.svg.disph); int i; for (i = 0; i < rgz->nhregions; i++) { OUTP("<!-- hregion %d (subcount %d)-->", i, hregions[i].nsubregions); svgout_hregion(&hregions[i], params->data.svg.dispw, params->data.svg.disph); } svgout_footer(); }
int8_t cmd_rcmd(uint8_t argc, char **argv) { uint8_t i; node_id_t node; uint8_t len = 0, arg_len; int8_t rc = NRK_OK; uint8_t cmd_args_idx = 0; bool args_valid = false; if (argc >= 4) { for (i = 2; i < argc; i++) { if (argv[i][0] == '-') { cmd_args_idx = i + 1; break; } } if (cmd_args_idx > 2 && cmd_args_idx < argc) args_valid = true; } if (!args_valid) { OUT("usage: rcmd <node>... - <cmd> [<arg>...]\r\n"); return NRK_ERROR; } for (i = cmd_args_idx; i < argc; ++i) { arg_len = strlen(argv[i]); memcpy(cmd_buf + len, argv[i], arg_len); len += arg_len; cmd_buf[len++] = ' '; } cmd_buf[len] = '\0'; for (i = 1; i < cmd_args_idx - 1; ++i) { node = atoi(argv[i]); rc = rpc_rcmd(node, cmd_buf); if (rc != NRK_OK) { OUT("ERROR: rcmd rpc failed to: "); OUTP("%u\r\n", node); /* continue */ } } return rc; }
void ResetDevice_m(void) { /* * If we are using the VGA aperture on a Mach 32, put its * VGA controller into planar mode. */ if (phwDeviceExtension->FrameLength == 0x10000) { OUTPW(reg1CE, SavedExtRegs[0]); OUTPW(reg1CE, SavedExtRegs[1]); OUTPW(reg1CE, SavedExtRegs[2]); OUTP(reg1CE, 0xBE); OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE)); } UninitTiDac_m(); Passth8514_m(SHOW_VGA); } /* ResetDevice_m() */
void khyt1331_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned short adr, i; unsigned char status, enclam; /* figure out which crate caused interrupt */ for (i = 0; i < 4; i++) { adr = io_base + (i << 4); status = INP(adr + 6); if (status != 0xFF && (status & (1 << 3))) { enclam = (INP(adr + 8) & 0x1F); // mask upper 3 bits interrupt_info = (i << 16) | enclam; printk(KERN_INFO "khyt1331: interrupt crate %d, station %d\n", i, enclam); /* disable interrupts */ OUTP(adr + 10, 40); /* increment interrupt counter */ interrupt_count++; /* wake user process */ wake_up_interruptible(&wq); /* send signal to user process */ kill_fasync(&async_queue, SIGIO, POLL_IN); } } /* signal raw interrupt response time adr = io_base; OUTP(adr, 0xFF); OUTP(adr+8, 1); OUTP(adr+6, 1); OUTP(adr+10, 16); OUTP(adr, 0); OUTP(adr+10, 16); */ }
int8_t cmd_twi(uint8_t argc, char **argv) { int8_t rc; char op; uint8_t addr, reg, val; if (!(argc == 4 || argc == 5)) { OUT("usage: twi r|w <addr> <reg> [<val>]\r\n"); return NRK_ERROR; } op = argv[1][0]; addr = strtol(argv[2], NULL, 0); reg = strtol(argv[3], NULL, 0); switch (op) { case 'r': /* read */ rc = twi_read(addr, reg, &val); if (rc == NRK_OK) { OUTP("0x%x ", val); OUT("\r\n"); } break; case 'w': if (argc != 5) { OUT("invalid cmd args\r\n"); return NRK_ERROR; } val = strtol(argv[4], NULL, 0); rc = twi_write(addr, reg, val); break; default: OUT("ERROR: invalid op\r\n"); return NRK_ERROR; } return rc; }
void SetCurrentMode_m(struct query_structure *QueryPtr, struct st_mode_table *CrtTable) { WORD MiscOptions; /* Contents of MISC_OPTIONS register */ USHORT Scratch; /* Temporary variable */ /* * Put the DAC in a known state before we start. */ UninitTiDac_m(); Passth8514_m(SHOW_ACCEL); // turn vga pass through off /* * On cards with the "MISC_OPTIONS doesn't report video memory size * correctly" bug, reset MISC_OPTIONS to show the true amount of * video memory. This is done here rather than when we determine * how much memory is present in order to avoid trashing the "blue * screen" (no adverse effects on operation, but would generate * large numbers of user complaints). */ if (((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX)) && (QueryPtr->q_VGA_type == 1) && ((QueryPtr->q_memory_type == VMEM_DRAM_256Kx4) || (QueryPtr->q_memory_type == VMEM_DRAM_256Kx16) || (QueryPtr->q_memory_type == VMEM_DRAM_256Kx4_GRAP))) { MiscOptions = INPW(MISC_OPTIONS) & MEM_SIZE_STRIPPED; switch (QueryPtr->q_memory_size) { case VRAM_512k: MiscOptions |= MEM_SIZE_512K; break; case VRAM_1mb: MiscOptions |= MEM_SIZE_1M; break; case VRAM_2mb: MiscOptions |= MEM_SIZE_2M; break; case VRAM_4mb: MiscOptions |= MEM_SIZE_4M; break; } OUTPW(MISC_OPTIONS, MiscOptions); } setmode_m(CrtTable, (ULONG) &(phwDeviceExtension->RomBaseRange), (ULONG) phwDeviceExtension->ModelNumber); /* * On a Mach 8 card, 1280x1024 can only be done in split * pixel mode. If we are running on a Mach 8, and this * resolution was selected, go into split pixel mode. * * Bit 4 of EXT_GE_CONFIG is set for split pixel mode and * clear for normal mode. Bit 3 must be set, since clearing * it accesses EEPROM read/write mode. */ if ((phwDeviceExtension->ModelNumber == _8514_ULTRA) || (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA)) { if (QueryPtr->q_desire_x == 1280) OUTPW(EXT_GE_CONFIG, 0x0018); else OUTPW(EXT_GE_CONFIG, 0x0008); } /* * Default to 8 bits per pixel. Modes which require a different * setting will change this in the init_ti_<depth>_m() function. */ OUTP(DAC_MASK, 0xff); if (phwDeviceExtension->ModelNumber == MACH32_ULTRA) { switch (CrtTable->m_pixel_depth) // program the DAC for the { // other resolutions case 4: case 8: InitTi_8_m((WORD)(CrtTable->ColourDepthInfo | 0x0a)); break; case 16: InitTi_16_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG) &(phwDeviceExtension->RomBaseRange)); /* 16 bit 565 */ break; case 24: case 32: /* * RGB/BGR and 24/32 bit mode information is * stored in CrtTable->ColourDepthInfo. */ InitTi_24_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG) &(phwDeviceExtension->RomBaseRange)); break; } } /* * If we are going to be using the VGA aperture on a Mach 32, * initialize the bank manager by saving the ATI extended register * values and putting the VGA controller into packed pixel mode. * * We can't identify this case by looking at * phwDeviceExtension->FrameLength because it is set to 0x10000 * when the VGA aperture is being used in the * IOCTL_VIDEO_MAP_VIDEO_MEMORY packet which may or may not * have been called by the time we reach this point. */ if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) && (QueryPtr->q_aperture_cfg == 0) && (QueryPtr->q_VGA_type == 1)) { for (Scratch = 0; Scratch <= 2; Scratch++) { OUTP(reg1CE, (BYTE)(SavedExtRegs[Scratch] & 0x00FF)); SavedExtRegs[Scratch] = (SavedExtRegs[Scratch] & 0x00FF) | (INP(reg1CF) << 8); } OUTPW(HI_SEQ_ADDR, 0x0F02); OUTPW(HI_SEQ_ADDR, 0x0A04); OUTPW(reg3CE, 0x1000); OUTPW(reg3CE, 0x0001); OUTPW(reg3CE, 0x0002); OUTPW(reg3CE, 0x0003); OUTPW(reg3CE, 0x0004); OUTPW(reg3CE, 0x0005); OUTPW(reg3CE, 0x0506); OUTPW(reg3CE, 0x0F07); OUTPW(reg3CE, 0xFF08); OUTPW(reg1CE, 0x28B0); /* Enable 256 colour, 1M video RAM */ OUTPW(reg1CE, 0x04B6); /* Select linear addressing */ OUTP(reg1CE, 0xBE); OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE)); } /* * phwDeviceExtension->ReInitializing becomes TRUE in * IOCTL_VIDEO_SET_COLOR_REGISTERS packet of ATIMPStartIO(). * * If this is not the first time we are switching into graphics * mode, set the palette to the last set of colours that was * selected while in graphics mode. */ if (phwDeviceExtension->ReInitializing) { SetPalette_m(phwDeviceExtension->Clut, phwDeviceExtension->FirstEntry, phwDeviceExtension->NumEntries); } /* * Clear visible screen. * * 24 and 32 BPP would require a q_desire_y value beyond the * maximum allowable clipping value (1535) if we clear the screen * using a normal blit. Since these pixel depths are only supported * up to 800x600, we can fake it by doing a 16BPP blit of double the * screen height, clipping the special case of 640x480 24BPP on * a 1M card (this is the only true colour mode that will fit in * 1M, so if we hit this case on a 1M card, we know which mode * we're dealing with) to avoid running off the end of video memory. */ if (CrtTable->m_pixel_depth >= 24) { /* * Save the colour depth configuration and switch into 16BPP */ Scratch = INPW(R_EXT_GE_CONFIG); OUTPD(EXT_GE_CONFIG, (Scratch & 0xFFCF) | PIX_WIDTH_16BPP); CheckFIFOSpace_m(SIXTEEN_WORDS); OUTPW(DP_CONFIG, 0x2011); OUTPW(ALU_FG_FN, 0x7); // Paint OUTPW(FRGD_COLOR, 0); // Black OUTPW(CUR_X, 0); OUTPW(CUR_Y, 0); OUTPW(DEST_X_START, 0); OUTPW(DEST_X_END, QueryPtr->q_desire_x); if (QueryPtr->q_memory_size == VRAM_1mb) OUTPW(DEST_Y_END, 720); /* Only 640x480 24BPP will fit in 1M */ else OUTPW(DEST_Y_END, (WORD)(2*(QueryPtr->q_desire_y))); /* * Let the blit finish then restore the colour depth configuration */ WaitForIdle_m(); OUTPD(EXT_GE_CONFIG, Scratch); } else{ /* * Other colour depths can be handled by a normal blit, and the * LFB may not be available, so use a blit to clear the screen. */ CheckFIFOSpace_m(SIXTEEN_WORDS); OUTPW(DP_CONFIG, 0x2011); OUTPW(ALU_FG_FN, 0x7); // Paint OUTPW(FRGD_COLOR, 0); // Black OUTPW(CUR_X, 0); OUTPW(CUR_Y, 0); OUTPW(DEST_X_START, 0); OUTPW(DEST_X_END, QueryPtr->q_desire_x); OUTPW(DEST_Y_END, QueryPtr->q_desire_y); } #if 0 /* * In 800x600 24BPP, set the offset to start 1 pixel into video * memory to avoid screen tearing. The MAP_VIDEO_MEMORY packet * must adjust the framebuffer base to compensate for this. */ if ((QueryPtr->q_desire_x == 800) && (QueryPtr->q_pix_depth == 24)) { OUTPW(CRT_OFFSET_LO, 3); } else { OUTPW(CRT_OFFSET_HI, 0); } #endif WaitForIdle_m(); return; } /* SetCurrentMode_m() */
static int rgz_hwc_layer_blit( hwc_layer_1_t *l, struct bvbuffdesc *scrdesc, struct bvsurfgeom *scrgeom, int noblend, int buff_idx) { IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle; if (!handle || l->flags & HWC_SKIP_LAYER || l->compositionType != HWC_OVERLAY) { /* * This shouldn't happen regionizer should reject compositions w/ skip * layers */ OUTP("Cannot handle skip layers\n"); return -1; } static int loaded = 0; if (!loaded) loaded = loadbltsville() ? : 1; /* attempt load once */ struct rgz_blt_entry* e; e = rgz_blts_get(&blts); struct bvbuffdesc *src1desc = &e->src1desc; src1desc->structsize = sizeof(struct bvbuffdesc); src1desc->length = handle->iHeight * HANDLE_TO_STRIDE(handle); /* * The virtaddr isn't going to be used in the final 2D h/w integration * because we will be handling buffers differently */ src1desc->virtaddr = buff_idx == -1 ? HANDLE_TO_BUFFER(handle) : (void*)buff_idx; /* FIXME: revisit this later */ struct bvsurfgeom *src1geom = &e->src1geom; src1geom->structsize = sizeof(struct bvsurfgeom); src1geom->format = hal_to_ocd(handle->iFormat); src1geom->width = handle->iWidth; src1geom->height = handle->iHeight; src1geom->orientation = l->transform & HWC_TRANSFORM_ROT_90 ? 90 : l->transform & HWC_TRANSFORM_ROT_180 ? 180 : l->transform & HWC_TRANSFORM_ROT_270 ? 270 : 0; src1geom->virtstride = HANDLE_TO_STRIDE(handle); struct bvsurfgeom *dstgeom = &e->dstgeom; dstgeom->structsize = sizeof(struct bvsurfgeom); dstgeom->format = scrgeom->format; dstgeom->width = scrgeom->width; dstgeom->height = scrgeom->height; dstgeom->orientation = 0; /* TODO */ dstgeom->virtstride = DSTSTRIDE(scrgeom); struct bvbltparams *bp = &e->bp; bp->structsize = sizeof(struct bvbltparams); bp->dstdesc = scrdesc; bp->dstgeom = dstgeom; bp->dstrect.left = l->displayFrame.left; bp->dstrect.top = l->displayFrame.top; bp->dstrect.width = WIDTH(l->displayFrame); bp->dstrect.height = HEIGHT(l->displayFrame); bp->src1.desc = src1desc; bp->src1geom = src1geom; bp->src1rect.left = l->sourceCrop.left; bp->src1rect.top = l->sourceCrop.top; bp->src1rect.width = WIDTH(l->sourceCrop); bp->src1rect.height = HEIGHT(l->sourceCrop); bp->cliprect.left = bp->cliprect.top = 0; bp->cliprect.width = scrgeom->width; bp->cliprect.height = scrgeom->height; unsigned long bpflags = BVFLAG_CLIP; if (!noblend && l->blending == HWC_BLENDING_PREMULT) { struct bvsurfgeom *src2geom = &e->src2geom; struct bvbuffdesc *src2desc = &e->src2desc; *src2geom = *dstgeom; src2desc->structsize = sizeof(struct bvbuffdesc); src2desc->virtaddr = 0; /* FB index */ bpflags |= BVFLAG_BLEND; bp->op.blend = BVBLEND_SRC1OVER; bp->src2.desc = scrdesc; bp->src2geom = dstgeom; bp->src2rect.left = l->displayFrame.left; bp->src2rect.top = l->displayFrame.top; bp->src2rect.width = WIDTH(l->displayFrame); bp->src2rect.height = HEIGHT(l->displayFrame); } else { bpflags |= BVFLAG_ROP; bp->op.rop = 0xCCCC; /* SRCCOPY */ if((src1geom->format == OCDFMT_BGR124) || (src1geom->format == OCDFMT_RGB124) || (src1geom->format == OCDFMT_RGB16)) dstgeom->format = OCDFMT_BGR124; } /* TODO regionizer won't permit transforms yet */ if (l->transform & HWC_TRANSFORM_FLIP_H) bpflags |= BVFLAG_HORZ_FLIP_SRC1; if (l->transform & HWC_TRANSFORM_FLIP_V) bpflags |= BVFLAG_VERT_FLIP_SRC1; bp->flags = bpflags; return 0; }
/***************************************************************************** * DrvMovePointer - ****************************************************************************/ VOID DrvMovePointer( SURFOBJ* pso, LONG x, LONG y, RECTL* prcl) { PPDEV ppdev; INT xx, yy; ppdev = (PPDEV) pso->dhpdev; // If x is -1 then take down the cursor. if (x == -1) { DISABLE_SPRITE(ppdev); return; } // Adjust the actual pointer position depending upon // the hot spot. x -= ppdev->W32SpriteData.ptlHot.x; y -= ppdev->W32SpriteData.ptlHot.y; if (ppdev->ulChipID == ET6000) { char xPreset = 0; char yPreset = 0; if (x < 0) { xPreset = (CHAR)~x; x = 0; } if (y < 0) { yPreset = (CHAR)~y; y = 0; } ET6K_HORZ_PRESET(ppdev, xPreset); ET6K_VERT_PRESET(ppdev, yPreset); ET6K_SPRITE_HORZ_POSITION(ppdev, x); ET6K_SPRITE_VERT_POSITION(ppdev, y); return; } else { // // Adjust pointer x position for color depth // x *= ppdev->cBpp; // Yet another bug. // If the cursor is moved entirely off the screen, it could cause // the screen to shake. So, we have to disable the cursor if it // is moved entirely off the screen. if ((x < - ((LONG) (ppdev->W32SpriteData.szlPointer.cx))) || (x > ((LONG) (ppdev->cxScreen * ppdev->cBpp))) || (y < - ((LONG) (ppdev->W32SpriteData.szlPointer.cy))) || (y > ((LONG) (ppdev->cyScreen)))) { ppdev->W32SpriteData.fl |= POINTER_DISABLED; DISABLE_SPRITE(ppdev); return; } // We may have disabled the sprite if it went off the screen. // So, now have to detect if we did and re-enable it if necessary. // (remembering to keep track of the state). if (ppdev->W32SpriteData.fl & POINTER_DISABLED) { ppdev->W32SpriteData.fl &= ~POINTER_DISABLED; ENABLE_SPRITE(ppdev); } // The W32 non-rev-B has a problem with a vertical offset of 0x3f. // All the other W32's have a problem with the last nibble being // 0x0F for both the horizontal and the verical. // Never set the bad presets on the chips in question. if (x <= 0) { if ((ppdev->ulChipID == W32) && (ppdev->ulRevLevel != REV_B)) { xx = -x; if ((xx & 0x0F) == 0x0F) xx &= ~0x01; SET_HORZ_PRESET(xx); } else { SET_HORZ_PRESET(-x); } x = 0; } else { SET_HORZ_PRESET(0); } if (y <= 0) { if (ppdev->ulChipID == W32) { yy = -y; if (ppdev->ulRevLevel != REV_B) { if (yy == 0x3F) yy = 0x3E; } else { if ((yy & 0x0F) == 0x0F) yy &= ~0x01; } SET_VERT_PRESET(yy); } else { SET_VERT_PRESET(-y); } y = 0; } else { SET_VERT_PRESET(0); } // You guessed it. Another bug. // On the W32 Rev B you can not put the cursor on the bottom line // of the display. And if were in interlaced mode you can't put it // on the bottom two lines. if ((ppdev->ulChipID == W32) && (ppdev->ulRevLevel == REV_B)) { INT i; if (y > (i = ppdev->cyScreen - 2)) { OUTP(0x3D4, 0x35); if (INP(0x3D5) & 0x80) y = i; } else if (y > (i+1)) { y = i+1; } } ////////////////////////////////////////////////////// // Set the position of the sprite. if ((ppdev->ulChipID == W32I) || (ppdev->ulChipID == W32P)) { // You bet, one more bug, and this one is a lulu. // First we have to set the vertical position before the horz // position. Why you ask, because, if this is a W32 Rev B or later // we may have to toggle a bit in a test register to really set the // vertical position, but of course we don't want to set anything // else at this point. BYTE status, byte; // Wait for horz display interval. while ( (INP(0x3DA) & 0x02)); while (!((status = INP(0x3DA)) & 0x02)); SET_VERT_POSITION(y); // Check if the sprite is being displayed at this very moment. // And if it is then skip the test bit stuff. if (!(status & 0x04)) { // Looks like we will have to toggle the test bit to // really set the vertical position. ENABLE_KEY(ppdev); OUTP(0x3D4, 0x37); byte = INP(0x3D5); byte |= 0x40; OUTP(0x3D5, byte); byte &= ~0x40; OUTP(0x3D5, byte); DISABLE_KEY(ppdev); } SET_HORZ_POSITION(x); } else { // For consistency sake, we're going to set the vertical first // even for non-W32 Rev B chips. SET_VERT_POSITION(y); SET_HORZ_POSITION(x); } return; } }
/* * generate a human readable description of the layer * * idx, flags, fmt, type, sleft, stop, sright, sbot, dleft, dtop, \ * dright, dbot, rot, flip, blending, scalew, scaleh, visrects * */ static void rgz_print_layer(hwc_layer_1_t *l, int idx, int csv) { char big_log[1024]; int e = sizeof(big_log); char *end = big_log + e; e -= snprintf(end - e, e, "<!-- LAYER-DAT: %d", idx); e -= snprintf(end - e, e, "%s %p", csv ? "," : " hndl:", l->handle ? l->handle : NULL); e -= snprintf(end - e, e, "%s %s", csv ? "," : " flags:", l->flags & HWC_SKIP_LAYER ? "skip" : "none"); IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle; if (handle) { e -= snprintf(end - e, e, "%s", csv ? ", " : " fmt: "); switch(handle->iFormat) { case HAL_PIXEL_FORMAT_BGRA_8888: e -= snprintf(end - e, e, "bgra"); break; case HAL_PIXEL_FORMAT_RGB_565: e -= snprintf(end - e, e, "rgb565"); break; case HAL_PIXEL_FORMAT_BGRX_8888: e -= snprintf(end - e, e, "bgrx"); break; case HAL_PIXEL_FORMAT_RGBX_8888: e -= snprintf(end - e, e, "rgbx"); break; case HAL_PIXEL_FORMAT_RGBA_8888: e -= snprintf(end - e, e, "rgba"); break; case HAL_PIXEL_FORMAT_TI_NV12: case HAL_PIXEL_FORMAT_TI_NV12_PADDED: e -= snprintf(end - e, e, "nv12"); break; default: e -= snprintf(end - e, e, "unknown"); } e -= snprintf(end - e, e, "%s", csv ? ", " : " type: "); if (handle->usage & GRALLOC_USAGE_HW_RENDER) e -= snprintf(end - e, e, "hw"); else if (handle->usage & GRALLOC_USAGE_SW_READ_MASK || handle->usage & GRALLOC_USAGE_SW_WRITE_MASK) e -= snprintf(end - e, e, "sw"); else e -= snprintf(end - e, e, "unknown"); } else { e -= snprintf(end - e, e, csv ? ", unknown" : " fmt: unknown"); e -= snprintf(end - e, e, csv ? ", na" : " type: na"); } e -= snprintf(end - e, e, csv ? ", %d, %d, %d, %d" : " src: %d %d %d %d", l->sourceCrop.left, l->sourceCrop.top, l->sourceCrop.right, l->sourceCrop.bottom); e -= snprintf(end - e, e, csv ? ", %d, %d, %d, %d" : " disp: %d %d %d %d", l->displayFrame.left, l->displayFrame.top, l->displayFrame.right, l->displayFrame.bottom); e -= snprintf(end - e, e, "%s %s", csv ? "," : " rot:", l->transform & HWC_TRANSFORM_ROT_90 ? "90" : l->transform & HWC_TRANSFORM_ROT_180 ? "180" : l->transform & HWC_TRANSFORM_ROT_270 ? "270" : "none"); char flip[5] = ""; strcat(flip, l->transform & HWC_TRANSFORM_FLIP_H ? "H" : ""); strcat(flip, l->transform & HWC_TRANSFORM_FLIP_V ? "V" : ""); if (!(l->transform & (HWC_TRANSFORM_FLIP_V|HWC_TRANSFORM_FLIP_H))) strcpy(flip, "none"); e -= snprintf(end - e, e, "%s %s", csv ? "," : " flip:", flip); e -= snprintf(end - e, e, "%s %s", csv ? "," : " blending:", l->blending == HWC_BLENDING_NONE ? "none" : l->blending == HWC_BLENDING_PREMULT ? "premult" : l->blending == HWC_BLENDING_COVERAGE ? "coverage" : "invalid"); e -= snprintf(end - e, e, "%s %1.3f", csv ? "," : " scalew:", getscalew(l)); e -= snprintf(end - e, e, "%s %1.3f", csv ? "," : " scaleh:", getscaleh(l)); e -= snprintf(end - e, e, "%s %d", csv ? "," : " visrect:", l->visibleRegionScreen.numRects); if (!csv) { e -= snprintf(end - e, e, " -->"); OUTP("%s", big_log); size_t i = 0; for (; i < l->visibleRegionScreen.numRects; i++) { hwc_rect_t const *r = &l->visibleRegionScreen.rects[i]; OUTP("<!-- LAYER-VIS: %d: rect: %d %d %d %d -->", i, r->left, r->top, r->right, r->bottom); } } else { size_t i = 0; for (; i < l->visibleRegionScreen.numRects; i++) { hwc_rect_t const *r = &l->visibleRegionScreen.rects[i]; e -= snprintf(end - e, e, ", %d, %d, %d, %d", r->left, r->top, r->right, r->bottom); } e -= snprintf(end - e, e, " -->"); OUTP("%s", big_log); } }
VOID vAssertModePointer( PDEV* ppdev, BOOL bEnable) { BYTE* pjBase; ULONG ulPhysicalAddr; INT i, j, nBytesPerBank, njSpriteBuffer, n8kBanks, nRemainingBytes; if (ppdev->flCaps & CAPS_SW_POINTER) { // With a software pointer, we don't have to do anything. } else { DISPDBG((1,"vAssertModePointer: cxMemory = %d", ppdev->cxMemory)); DISPDBG((1,"vAssertModePointer: cyMemory = %d", ppdev->cyMemory)); DISPDBG((1,"vAssertModePointer: cxScreen = %d", ppdev->cxScreen)); DISPDBG((1,"vAssertModePointer: cyScreen = %d", ppdev->cyScreen)); pjBase = ppdev->pjBase; // Take care of the init for the Sprite. if (ppdev->ulChipID == ET6000) { BYTE * pjDst = ppdev->pjScreen + ppdev->cjPointerOffset; ET6K_SPRITE_HORZ_POSITION(ppdev, ppdev->cxScreen / 2); // Center it. ET6K_SPRITE_VERT_POSITION(ppdev, ppdev->cyScreen / 2); // Center it. ET6K_HORZ_PRESET(ppdev, 0); ET6K_VERT_PRESET(ppdev, 0); ET6K_SPRITE_START_ADDR(ppdev, ppdev->cjPointerOffset); ET6K_SPRITE_COLOR(ppdev, 0xFF00); for (i = 0; i < 1024; i++) { *pjDst++ = 0xaa; } } else { SET_HORZ_POSITION(ppdev->cxScreen * ppdev->cBpp / 2); SET_VERT_POSITION(ppdev->cyScreen / 2); SET_HORZ_PRESET(0); SET_VERT_PRESET(0); SET_SPRITE_START_ADDR(ppdev->cjPointerOffset); SET_SPRITE_ROW_OFFSET; // Set the CRTCB pixel pan register to 0. OUTP(CRTCB_SPRITE_INDEX, CRTCB_PIXEL_PANNING); OUTP(CRTCB_SPRITE_DATA, 0); // Set the pixel depth to 2 bits per pixel. // (even though the doc says this is only for the CRTCB mode and not // the sprite mode, the doesn't work unless these values are 0. OUTP(CRTCB_SPRITE_INDEX, CRTCB_COLOR_DEPTH); OUTP(CRTCB_SPRITE_DATA, 0x01); // Set the CRTCB/Sprite control to a 64 X 64 Sprite in overlay mode. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_CONTROL); OUTP(CRTCB_SPRITE_DATA, 0x02); // Fill the sprite buffer and the next 17 lines with a transparent // pattern. This is to get around one of the sprite bugs. njSpriteBuffer = SPRITE_BUFFER_SIZE; nBytesPerBank = 0x2000; n8kBanks = njSpriteBuffer / nBytesPerBank; nRemainingBytes = njSpriteBuffer % nBytesPerBank; for (j = 0; j < n8kBanks; j++) { // First set Aperture 0 to the sprite buffer address. CP_MMU_BP0(ppdev, pjBase, (ppdev->cjPointerOffset + (j * nBytesPerBank))); // Reset the linear address to the beginning of this 8K segment for (i = 0; i < nBytesPerBank; i++) { //*pjSpriteBuffer++ = 0xAA; CP_WRITE_MMU_BYTE(ppdev, 0, i, 0xAA); } } // Set Aperture 0 to the sprite buffer address. CP_MMU_BP0(ppdev, pjBase, (ppdev->cjPointerOffset + (j * nBytesPerBank))); // Reset the linear address to the beginning of this 8K segment for (i = 0; i < nRemainingBytes; i++) { //*pjSpriteBuffer++ = 0xAA; CP_WRITE_MMU_BYTE(ppdev, 0, i, 0xAA); } } ENABLE_SPRITE(ppdev); } }
static void svgout_footer(void) { OUTP("</svg>"); }
static int khyt1331_ioctl(struct inode *inode, struct file *file, unsigned int opcode, unsigned long param) { int i, j; int c, n, a, f, data_size, write_flag, read_flag; unsigned char status; unsigned short adr = 0; unsigned int lam; CNAF_BUF cnaf_buf; void *buf; // printk(KERN_INFO "khyt1331: ioctl %d, param %lX\n", opcode, param); switch (opcode) { /*---- initialization functions --------------------------------*/ case OP_CRATE_ZINIT: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 34); break; case OP_CRATE_CLEAR: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 36); break; case OP_CRATE_CHECK: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); /* dummy clear inhibit operation */ OUTP(adr + 8, 1); OUTP(adr + 6, 2); OUTP(adr + 10, 32); /* readback n, a, f */ a = INP(adr + 10); n = INP(adr + 10); f = INP(adr + 10); if (n != 1 || a != 2 || f != 32) return 0; return 1; /*---- normal CAMAC functions ----------------------------------*/ case OP_CNAF8: case OP_CNAF16: case OP_CNAF24: /* printk(KERN_INFO "khyt1331: CNAF: %d %d %d %d %d\n", cnaf_buf.c, cnaf_buf.n, cnaf_buf.a, cnaf_buf.f, cnaf_buf.d); */ if (copy_from_user(&cnaf_buf, (void *) param, sizeof(cnaf_buf)) > 0) return -EFAULT; if (cnaf_buf.c > 3 || cnaf_buf.c < 0) return -EINVAL; adr = io_base + (cnaf_buf.c << 4); OUTP(adr + 8, cnaf_buf.n); if (cnaf_buf.f >= 8) { /* write operation */ OUTP(adr, (unsigned char) cnaf_buf.d); if (opcode != OP_CNAF8) { OUTP(adr + 2, *(((unsigned char *) &cnaf_buf.d) + 1)); if (opcode == OP_CNAF24) OUTP(adr + 4, *(((unsigned char *) &cnaf_buf.d) + 2)); } } OUTP(adr + 6, cnaf_buf.a); OUTP(adr + 10, cnaf_buf.f); status = (unsigned char) INP(adr + 6); cnaf_buf.q = status & 1; cnaf_buf.x = status >> 7; if (cnaf_buf.f < 8) { cnaf_buf.d = 0; /* read operation */ *((unsigned char *) &cnaf_buf.d) = INP(adr); if (opcode != OP_CNAF8) { *(((unsigned char *) &cnaf_buf.d) + 1) = INP(adr + 2); if (opcode == OP_CNAF24) *(((unsigned char *) &cnaf_buf.d) + 2) = INP(adr + 4); } } if (copy_to_user((void *) param, &cnaf_buf, sizeof(cnaf_buf)) > 0) return -EFAULT; break; /*---- repeat CAMAC functions ----------------------------------*/ case OP_CNAF8R: case OP_CNAF16R: case OP_CNAF24R: data_size = opcode == OP_CNAF8R ? 1 : opcode == OP_CNAF16R ? 2 : 4; if (copy_from_user(&cnaf_buf, (void *) param, sizeof(cnaf_buf)) > 0) return -EFAULT; printk(KERN_INFO "khyt1331: CNAFR: %d %d %d %d %lX %d %d\n", cnaf_buf.c, cnaf_buf.n, cnaf_buf.a, cnaf_buf.f, cnaf_buf.d, cnaf_buf.r, cnaf_buf.m); /* check for valid crate parameter */ if (cnaf_buf.c > 3 || cnaf_buf.c < 0) return -EINVAL; /* check for valid repeat count, allow 1M max. size */ if (cnaf_buf.r < 0 || cnaf_buf.r > 1024 * 1024) return -EINVAL; /* check for valid repeat mode */ if (cnaf_buf.m < RM_COUNT || cnaf_buf.m > RM_NSCAN) return -EINVAL; /* allocate local data buffer */ buf = kmalloc(cnaf_buf.r * data_size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; read_flag = (cnaf_buf.f < 8); write_flag = (cnaf_buf.f >= 16 && cnaf_buf.f <= 23); if (write_flag) { /* copy data buffer */ if (copy_from_user(buf, (void *) cnaf_buf.d, cnaf_buf.r * data_size) > 0) { kfree(buf); return -EFAULT; } } /* Turn on the Q-mode for repeat until Q=1 in the INPW(adr+12) */ if (cnaf_buf.m == RM_QMODE) OUTP(adr + 1, 0x10); adr = io_base + (cnaf_buf.c << 4); OUTP(adr + 8, cnaf_buf.n); OUTP(adr + 6, cnaf_buf.a); if (write_flag) { if (data_size == 1) { OUTP(adr, *((unsigned char *) buf)); } else if (data_size == 2) { //printk("OUT0: %d\n", *((unsigned short *) buf)); OUTP(adr, *((unsigned char *) buf)); OUTP(adr + 2, *((unsigned char *) buf + 1)); } else if (data_size == 4) { OUTP(adr, *((unsigned char *) buf)); OUTP(adr + 2, *((unsigned char *) buf + 1)); OUTP(adr + 4, *((unsigned char *) buf + 2)); } } /* trigger first cycle */ OUTP(adr + 10, cnaf_buf.f); if (read_flag) { if (data_size == 1) { *((unsigned char *) buf) = INP(adr); } else if (data_size == 2) { *((unsigned char *) buf) = INP(adr); *((unsigned char *) buf + 1) = INP(adr + 2); } else if (data_size == 4) { *((unsigned char *) buf) = INP(adr); *((unsigned char *) buf + 1) = INP(adr + 2); *((unsigned char *) buf + 1) = INP(adr + 4); } /* trigger first cycle */ INPW(adr + 12); INP(adr + 6); /* some delay */ } /* repeat cycles */ for (i = 1; i < cnaf_buf.r; i++) { if (write_flag) { if (data_size == 1) { OUTPW(adr + 12, *((unsigned char *) buf + i)); } else if (data_size == 2) { //printk("OUT%d: %d\n", i, *((unsigned short *) buf+i)); OUTPW(adr + 12, *((unsigned short *) buf + i)); } else if (data_size == 4) { /* write high byte */ OUTP(adr + 4, *((unsigned char *) buf + 4 * i + 2)); /* write low and middle bytes to repeat register */ OUTPW(adr + 12, *((unsigned short *) buf + 2 * i)); } } if (read_flag) { if (data_size == 1) { *((unsigned char *) buf + i) = (unsigned char) INPW(adr + 12); } else if (data_size == 2) { *((unsigned short *) buf + i) = INPW(adr + 12); } else if (data_size == 4) { /* read high byte */ *((unsigned char *) buf + 4 * i + 2) = INP(adr + 4); /* read low and middle bytes from repeat register */ *((unsigned short *) buf + i) = INPW(adr + 12); } } if (cnaf_buf.m == RM_QMODE) { /* in Q mode, test FAIL bit in status register */ status = (unsigned char) INP(adr + 6); if ((status & (1 << 5)) > 0) break; } if (cnaf_buf.m == RM_ASCAN) OUTP(adr + 6, ++cnaf_buf.a); if (cnaf_buf.m == RM_NSCAN) OUTP(adr + 8, ++cnaf_buf.n); for (j = 0; j < 1000; j++) udelay(1000); } /* Turn off the Q-mode */ if (cnaf_buf.m == RM_QMODE) OUTP(adr + 1, 0); if (read_flag) if (copy_to_user((void *) cnaf_buf.d, buf, i * data_size) > 0) { kfree(buf); return -EFAULT; } kfree(buf); break; case OP_INHIBIT_SET: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 33); break; case OP_INHIBIT_CLEAR: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 32); break; case OP_INHIBIT_TEST: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); status = INP(adr + 6); return (status & (1 << 1)) > 0; case OP_LAM_ENABLE: c = param >> 16; n = param & 0xFF; if (c > 3 || c < 0 || n > 24 || n < 0) return -EINVAL; adr = io_base + (c << 4); OUTP(adr + 10, 64 + n); break; case OP_LAM_DISABLE: c = param >> 16; n = param & 0xFF; if (c > 3 || c < 0 || n > 24 || n < 0) return -EINVAL; adr = io_base + (c << 4); OUTP(adr + 10, 128 + n); break; case OP_LAM_READ: /* return a BITWISE coded station NOT the station number i.e.: n = 5 ==> lam = 0x10 */ if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); status = INP(adr + 6); if (status & (1 << 3)) { lam = (INP(adr + 8) & 0x1F); // mask upper 3 bits lam = 1 << (lam - 1); } else lam = 0; return lam; case OP_LAM_CLEAR: c = param >> 16; n = param & 0xFF; if (c > 3 || c < 0 || n > 24 || n < 0) return -EINVAL; adr = io_base + (c << 4); /* restart LAM scanner in controller */ INP(adr + 8); break; case OP_INTERRUPT_ENABLE: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 41); break; case OP_INTERRUPT_DISABLE: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); OUTP(adr + 10, 40); break; case OP_INTERRUPT_TEST: if (param > 3 || param < 0) return -EINVAL; adr = io_base + (param << 4); status = INP(adr + 6); return (status & (1 << 2)) > 0; } /* signal success */ return 1; }
VP_STATUS A8514SetColorLookup( PHW_DEVICE_EXTENSION hwDeviceExtension, PVIDEO_CLUT ClutBuffer, ULONG ClutBufferSize ) /*++ Routine Description: This routine sets a specified portion of the color lookup table settings. Arguments: hwDeviceExtension - Pointer to the miniport driver's device extension. ClutBufferSize - Length of the input buffer supplied by the user. ClutBuffer - Pointer to the structure containing the color lookup table. Return Value: None. --*/ { USHORT i; // // Check if the size of the data in the input buffer is large enough. // if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) || (ClutBufferSize < sizeof(VIDEO_CLUT) + (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) { return ERROR_INSUFFICIENT_BUFFER; } // // Check to see if the parameters are valid. // if ( (ClutBuffer->NumEntries == 0) || (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) || (ClutBuffer->FirstEntry + ClutBuffer->NumEntries > VIDEO_MAX_COLOR_REGISTER + 1) ) { return ERROR_INVALID_PARAMETER; } // // Set CLUT registers directly on the hardware // for (i = 0; i < ClutBuffer->NumEntries; i++) { OUTP(hwDeviceExtension, INDEX_DAC_W_INDEX, (ClutBuffer->FirstEntry + i)); OUTP(hwDeviceExtension, INDEX_DAC_DATA, ClutBuffer->LookupTable[i].RgbArray.Red); OUTP(hwDeviceExtension, INDEX_DAC_DATA, ClutBuffer->LookupTable[i].RgbArray.Green); OUTP(hwDeviceExtension, INDEX_DAC_DATA, ClutBuffer->LookupTable[i].RgbArray.Blue); } return NO_ERROR; } // end A8514SetColorLookup()
BOOLEAN A8514StartIO( PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket ) /*++ Routine Description: This routine is the main execution routine for the miniport driver. It accepts a Video Request Packet, performs the request, and then returns with the appropriate status. Arguments: HwDeviceExtension - Supplies a pointer to the miniport's device extension. RequestPacket - Pointer to the video request packet. This structure contains all the parameters passed to the VideoIoControl function. Return Value: --*/ { PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; VP_STATUS status; PVIDEO_MODE_INFORMATION modeInformation; PVIDEO_MEMORY_INFORMATION memoryInformation; PVIDEO_CLUT clutBuffer; ULONG modeNumber; VIDEO_MODE_INFORMATION A8514ModeInformation = { sizeof(VIDEO_MODE_INFORMATION), // Size of the mode informtion structure 0, // Mode index used in setting the mode 1024, // X Resolution, in pixels 768, // Y Resolution, in pixels 1024, // Screen stride, in bytes (distance // between the start point of two // consecutive scan lines, in bytes) 1, // Number of video memory planes 8, // Number of bits per plane 1, // Screen Frequency, in Hertz 320, // Horizontal size of screen in millimeters 240, // Vertical size of screen in millimeters 6, // Number Red pixels in DAC 6, // Number Green pixels in DAC 6, // Number Blue pixels in DAC 0x00000000, // Mask for Red Pixels in non-palette modes 0x00000000, // Mask for Green Pixels in non-palette modes 0x00000000, // Mask for Blue Pixels in non-palette modes VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE, // Mode description flags. 1024, // Video Memory Bitmap Width 1024 // Video Memory Bitmap Height }; // // Assume we'll succeed. // status = NO_ERROR; // // Switch on the IoContolCode in the RequestPacket. It indicates which // function must be performed by the driver. // switch (RequestPacket->IoControlCode) { case IOCTL_VIDEO_MAP_VIDEO_MEMORY: VideoDebugPrint((2, "A8514tartIO - MapVideoMemory\n")); if ( (RequestPacket->OutputBufferLength < (RequestPacket->StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION))) || (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } memoryInformation = RequestPacket->OutputBuffer; // // The only field we need to fill is VideoRamLength. With this // miniport, we support only one meg 8514/A's: // memoryInformation->VideoRamLength = 0x100000; memoryInformation->FrameBufferBase = NULL; memoryInformation->FrameBufferLength = 0; break; case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: break; case IOCTL_VIDEO_QUERY_AVAIL_MODES: VideoDebugPrint((2, "A8514StartIO - QueryAvailableModes\n")); if (RequestPacket->OutputBufferLength < (RequestPacket->StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION)) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { modeInformation = RequestPacket->OutputBuffer; *modeInformation = A8514ModeInformation; } break; case IOCTL_VIDEO_QUERY_CURRENT_MODE: VideoDebugPrint((2, "A8514StartIO - QueryCurrentModes\n")); if (RequestPacket->OutputBufferLength < (RequestPacket->StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION)) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) = A8514ModeInformation; } break; case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: VideoDebugPrint((2, "A8514StartIO - QueryNumAvailableModes\n")); // // Find out the size of the data to be put in the the buffer and // return that in the status information (whether or not the // information is there). If the buffer passed in is not large // enough return an appropriate error code. // if (RequestPacket->OutputBufferLength < (RequestPacket->StatusBlock->Information = sizeof(VIDEO_NUM_MODES)) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = 1; ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION); } break; case IOCTL_VIDEO_SET_CURRENT_MODE: VideoDebugPrint((2, "A8514StartIO - SetCurrentMode\n")); // // Check if the size of the data in the input buffer is large enough. // if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) { status = ERROR_INSUFFICIENT_BUFFER; break; } // // Check to see if we are requesting a valid mode // modeNumber = ((PVIDEO_MODE) RequestPacket->InputBuffer)->RequestedMode; if (modeNumber >= 1) { status = ERROR_INVALID_PARAMETER; break; } // // Reset the draw engine. // OUTPW(hwDeviceExtension, INDEX_SUBSYS_CNTL, 0x9000); OUTPW(hwDeviceExtension, INDEX_SUBSYS_CNTL, 0x5000); // // Mode setting courtesy of p. 2-2, "Programmer's Guide to the // Mach-8 Extended Registers Supplement, Technical Reference // Manuals," ATI Technologies Inc., 1992 and pp 276-278, "Graphics // Programming for the 8514/A," Jake Richter and Bud Smith, M & T // Publishing, 1990. // OUTPW(hwDeviceExtension, INDEX_DISP_CNTL, 0x0053); OUTPW(hwDeviceExtension, INDEX_H_TOTAL, 0x009d); OUTPW(hwDeviceExtension, INDEX_H_DISP, 0x007f); OUTPW(hwDeviceExtension, INDEX_H_SYNC_STRT, 0x0081); OUTPW(hwDeviceExtension, INDEX_H_SYNC_WID, 0x0016); OUTPW(hwDeviceExtension, INDEX_V_TOTAL, 0x0660); OUTPW(hwDeviceExtension, INDEX_V_DISP, 0x05fb); OUTPW(hwDeviceExtension, INDEX_V_SYNC_STRT, 0x0600); OUTPW(hwDeviceExtension, INDEX_V_SYNC_WID, 0x0008); OUTPW(hwDeviceExtension, INDEX_ADVFUNC_CNTL, 0x0007); OUTPW(hwDeviceExtension, INDEX_DISP_CNTL, 0x0033); OUTPW(hwDeviceExtension, INDEX_MEM_CNTL, 0x500c); OUTP(hwDeviceExtension, INDEX_DAC_MASK, 0xff); // // Initialize some drawing registers. // while (INPW(hwDeviceExtension, INDEX_GE_STAT) & FIFO_6_EMPTY) ; OUTPW(hwDeviceExtension, INDEX_PIX_CNTL, 0x5006); OUTPW(hwDeviceExtension, INDEX_SCISSORS_T, 0x1000); OUTPW(hwDeviceExtension, INDEX_SCISSORS_L, 0x2000); OUTPW(hwDeviceExtension, INDEX_SCISSORS_B, 0x35ff); OUTPW(hwDeviceExtension, INDEX_SCISSORS_R, 0x45ff); OUTPW(hwDeviceExtension, INDEX_WRT_MASK, 0xff); // // Black out the screen so that we don't display garbage until the // display driver has a chance to clear everything. // while (INPW(hwDeviceExtension, INDEX_GE_STAT) & FIFO_7_EMPTY) ; OUTPW(hwDeviceExtension, INDEX_PIX_CNTL, 0xa000); // ALL_ONES OUTPW(hwDeviceExtension, INDEX_FRGD_MIX, 0x0001); // LOGICAL_0 OUTPW(hwDeviceExtension, INDEX_CUR_X, 0); OUTPW(hwDeviceExtension, INDEX_CUR_Y, 0); OUTPW(hwDeviceExtension, INDEX_MAJ_AXIS_PCNT, 0x05ff); OUTPW(hwDeviceExtension, INDEX_MIN_AXIS_PCNT, 0x05ff); OUTPW(hwDeviceExtension, INDEX_CMD, 0x40b3); // ( RECTANGLE_FILL | DRAWING_DIR_TBLRXM | DRAW | // MULTIPLE_PIXELS | WRITE ) break; case IOCTL_VIDEO_SET_COLOR_REGISTERS: VideoDebugPrint((2, "A8514StartIO - SetColorRegs\n")); clutBuffer = RequestPacket->InputBuffer; status = A8514SetColorLookup(HwDeviceExtension, (PVIDEO_CLUT) RequestPacket->InputBuffer, RequestPacket->InputBufferLength); break; case IOCTL_VIDEO_RESET_DEVICE: VideoDebugPrint((2, "A8514StartIO - RESET_DEVICE\n")); // // Wait for the 8514/A graphics engine to become idle. // while (INPW(hwDeviceExtension, INDEX_GE_STAT) & 0x0200); // // Enable VGA pass-through. // OUTPW(hwDeviceExtension, INDEX_ADVFUNC_CNTL, 0x0006); break; // // if we get here, an invalid IoControlCode was specified. // default: VideoDebugPrint((1, "Fell through A8514 startIO routine - invalid command\n")); status = ERROR_INVALID_FUNCTION; break; } VideoDebugPrint((2, "Leaving A8514 startIO routine\n")); RequestPacket->StatusBlock->Status = status; return TRUE; } // end A8514StartIO()
VP_STATUS SetPowerManagement_m(struct query_structure *QueryPtr, DWORD DpmsState) { struct st_mode_table *CrtTable; /* Mode table, used to obtain sync values */ /* * Only accept valid states. */ if ((DpmsState < VideoPowerOn) || (DpmsState > VideoPowerOff)) return ERROR_INVALID_PARAMETER; /* * Set CrtTable to point to the mode table associated with the * selected mode. * * When a pointer to a structure is incremented by an integer, * the integer represents the number of structure-sized blocks * to skip over, not the number of bytes to skip over. */ CrtTable = (struct st_mode_table *)QueryPtr; ((struct query_structure *)CrtTable)++; CrtTable += phwDeviceExtension->ModeIndex; /* * Mach 32 rev. 6 and later supports turning the sync signals on and off * through the HORZ_OVERSCAN registers, but some chips that report as * rev. 6 don't have this implemented. Also, Mach 32 rev. 3 and Mach 8 * don't support this mechanism. * * Disabling the sync by setting it to start after the total will work * for all chips. Most chips will de-synchronize if the sync is set * to 1 more than the total, but some need higher values. To be sure * of de-synchronizing, set the disabled sync signal to start at * the highest possible value. */ switch (DpmsState) { case VideoPowerOn: OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt); OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt); break; case VideoPowerStandBy: OUTP(H_SYNC_STRT, 0xFF); OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt); break; case VideoPowerSuspend: OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt); OUTPW(V_SYNC_STRT, 0x0FFF); break; case VideoPowerOff: OUTP(H_SYNC_STRT, 0xFF); OUTPW(V_SYNC_STRT, 0x0FFF); break; /* * This case should never happen, because the initial * acceptance of only valid states should have already * rejected anything that will appear here. */ default: break; } return NO_ERROR; } /* SetPowerManagement_m() */