|
|
1.1.1.2 ! root 1: /* $Id: sun-cgtwo.c,v 1.7 2007/03/03 15:36:15 fredette Exp $ */ 1.1 root 2: 3: /* machine/sun/sun-cgtwo.c - Sun cgtwo emulation: */ 4: 5: /* 6: * Copyright (c) 2003, 2004, 2005 Matt Fredette 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by Matt Fredette. 20: * 4. The name of the author may not be used to endorse or promote products 21: * derived from this software without specific prior written permission. 22: * 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33: * POSSIBILITY OF SUCH DAMAGE. 34: */ 35: 36: #include <tme/common.h> 1.1.1.2 ! root 37: _TME_RCSID("$Id: sun-cgtwo.c,v 1.7 2007/03/03 15:36:15 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include <tme/machine/sun.h> 41: #include <tme/generic/bus-device.h> 42: #include <tme/generic/fb.h> 43: #include "sun-fb.h" 44: 45: /* macros: */ 46: 47: /* cgtwo types: */ 48: #define TME_SUNCG2_TYPE_NULL (0) 49: #define TME_SUNCG2_TYPE_SUN3 (1) 50: 51: /* a cgtwo has eight planes: */ 52: #define TME_SUNCG2_PLANE_MAX (8) 53: 54: /* every rasterop unit has its alternate, prime registers: */ 55: #define TME_SUNCG2_ROPC_PRIME (9) 56: 57: /* every so many CSR reads, we fake a retrace: */ 58: #define TME_SUNCG2_CYCLE_RETRACE (10) 59: 60: /* this gives the index into the entire colormap of a pixel's 61: intensity for a given primary: */ 62: #define TME_SUNCG2_CMAP_INDEX(pixel, primary) ((((primary) - TME_SUNCG2_REG_CMAP_R) / sizeof(tme_uint16_t)) + (pixel)) 63: 64: /* this gives a pixel's intensity for a given primary: */ 65: #define TME_SUNCG2_CMAP_VALUE(suncg2, pixel, primary) \ 66: (tme_betoh_u16((suncg2)->tme_suncg2_cmap_raw[TME_SUNCG2_CMAP_INDEX(pixel, primary)]) & 0xff) 67: 68: /* a plane bitmap has one bit per pixel: */ 69: #define TME_SUNCG2_REG_BITMAP(x) (0x000000 + (TME_SUNCG2_SIZ_BITMAP * (x))) 70: #define TME_SUNCG2_SIZ_BITMAP ((1024 * 1024) / 8) 71: 72: /* the pixmap has one byte per pixel: */ 73: #define TME_SUNCG2_REG_PIXMAP (0x100000) 74: #define TME_SUNCG2_SIZ_PIXMAP (1024 * 1024) 75: 76: /* the raster op data: */ 77: #define TME_SUNCG2_REG_ROP_DATA (0x200000) 78: 79: /* register offsets and sizes. many registers are decoded at all 80: size-aligned addresses within a 4KB page: */ 81: #define TME_SUNCG2_SIZ_REG_PAGE (0x001000) 82: #define TME_SUNCG2_REG_ROPC_UNIT(x) (0x300000 + ((x) * TME_SUNCG2_SIZ_REG_PAGE)) 83: #define TME_SUNCG2_REG_ROPC_UNIT_PRIME(x) (TME_SUNCG2_REG_ROPC_UNIT(x) + 0x000800) 84: #define TME_SUNCG2_REG_CSR (0x309000) 85: #define TME_SUNCG2_REG_PLANE_MASK (0x30a000) 86: #define TME_SUNCG2_REG_SUN2_PAN_HI (0x30b000) 87: #define TME_SUNCG2_REG_SUN3_DOUBLE_BUF (0x30b000) 88: #define TME_SUNCG2_REG_SUN2_ZOOM (0x30c000) 89: #define TME_SUNCG2_REG_SUN3_DMA_BASE (0x30c000) 90: #define TME_SUNCG2_REG_SUN2_PAN_LO (0x30d000) 91: #define TME_SUNCG2_REG_SUN3_DMA_WIDTH (0x30d000) 92: #define TME_SUNCG2_REG_SUN2_ZOOM_VAR (0x30e000) 93: #define TME_SUNCG2_REG_SUN3_FRAME_COUNT (0x30e000) 94: #define TME_SUNCG2_REG_INTVEC (0x30f000) 95: #define TME_SUNCG2_REG_CMAP_R (0x310000) 96: #define TME_SUNCG2_REG_CMAP_G (0x310200) 97: #define TME_SUNCG2_REG_CMAP_B (0x310400) 98: #define TME_SUNCG2_SIZ_REGS (0x310600) 99: 100: /* the bits in the Control/Status register: */ 101: #define TME_SUNCG2_CSR_ENABLE_VIDEO (0x0001) 102: #define TME_SUNCG2_CSR_CMAP_UPDATE (0x0002) 103: #define TME_SUNCG2_CSR_INT_ENABLE (0x0004) 104: #define TME_SUNCG2_CSR_ROP_MODE_MASK (0x0038) 105: #define TME_SUNCG2_CSR_ROP_MODE_PRWWRD (0x0000) 106: #define TME_SUNCG2_CSR_ROP_MODE_SRWPIX (0x0008) 107: #define TME_SUNCG2_CSR_ROP_MODE_PWWWRD (0x0010) 108: #define TME_SUNCG2_CSR_ROP_MODE_SWWPIX (0x0018) 109: #define TME_SUNCG2_CSR_ROP_MODE_PRRWRD (0x0020) 110: #define TME_SUNCG2_CSR_ROP_MODE_PRWPIX (0x0028) 111: #define TME_SUNCG2_CSR_ROP_MODE_PWRWRD (0x0030) 112: #define TME_SUNCG2_CSR_ROP_MODE_PWWPIX (0x0038) 113: #define TME_SUNCG2_CSR_INT_ACTIVE (0x0040) 114: #define TME_SUNCG2_CSR_RETRACE (0x0080) 115: #define TME_SUNCG2_CSR_SIZE_MASK_SUN2 (0x0f00) 116: #define TME_SUNCG2_CSR_SIZE_MASK_SUN3 (0x0100) 117: #define TME_SUNCG2_CSR_SIZE_1152_900 (0x0000) 118: #define TME_SUNCG2_CSR_SIZE_1024_1024 (0x0100) 119: 120: /* the raster ops: */ 121: #define TME_SUNCG2_ROP_SRC (0xcc) 122: #define TME_SUNCG2_ROP_DST (0xaa) 123: #define TME_SUNCG2_ROP_NOT(x) ((x) ^ 0xff) 124: 125: /* the callout flags: */ 126: #define TME_SUNCG2_CALLOUT_CHECK (0) 127: #define TME_SUNCG2_CALLOUT_RUNNING TME_BIT(0) 128: #define TME_SUNCG2_CALLOUTS_MASK (-2) 129: #define TME_SUNCG2_CALLOUT_MODE_CHANGE TME_BIT(1) 130: #define TME_SUNCG2_CALLOUT_INT TME_BIT(2) 131: 132: /* state flags: */ 133: #define TME_SUNCG2_FLAG_INVALID_DISPLAYED TME_BIT(0) 134: #define TME_SUNCG2_FLAG_INVALID_PIXMAP TME_BIT(1) 135: #define TME_SUNCG2_FLAG_INVALID_BITMAPS TME_BIT(2) 136: #define TME_SUNCG2_FLAG_CALLOUT_THREAD_RUNNING TME_BIT(3) 137: 138: /* structures: */ 139: 140: /* the card: */ 141: struct tme_suncg2 { 142: 143: /* our simple bus device header: */ 144: struct tme_bus_device tme_suncg2_device; 145: #define tme_suncg2_element tme_suncg2_device.tme_bus_device_element 146: 147: /* the mutex protecting the card: */ 148: tme_mutex_t tme_suncg2_mutex; 149: 150: /* the rwlock protecting the card: */ 151: tme_rwlock_t tme_suncg2_rwlock; 152: 153: /* the framebuffer connection: */ 154: struct tme_fb_connection *tme_suncg2_fb_connection; 155: 156: /* the callout flags: */ 157: int tme_suncg2_callout_flags; 158: 159: /* the type of the cgtwo: */ 160: tme_uint32_t tme_suncg2_type; 161: 162: /* the size of the bwtwo: */ 163: tme_uint32_t tme_suncg2_size; 164: 165: /* the number of displayed pixels: */ 166: tme_uint32_t tme_suncg2_pixel_count; 167: 168: /* the raw memory: */ 169: tme_uint8_t *tme_suncg2_raw_memory; 170: 171: /* the displayed memory: */ 172: tme_uint8_t *tme_suncg2_displayed_memory; 173: 174: /* the rasterop registers: */ 175: struct { 176: tme_uint16_t tme_suncg2_ropc_dest; 177: tme_uint16_t tme_suncg2_ropc_source1; 178: tme_uint16_t tme_suncg2_ropc_source2; 179: tme_uint16_t tme_suncg2_ropc_pattern; 180: tme_uint16_t tme_suncg2_ropc_mask1; 181: tme_uint16_t tme_suncg2_ropc_mask2; 182: tme_uint16_t tme_suncg2_ropc_ena_shift; 183: tme_uint16_t tme_suncg2_ropc_op; 184: tme_uint16_t tme_suncg2_ropc_width; 185: tme_uint16_t tme_suncg2_ropc_opcount; 186: tme_uint16_t tme_suncg2_ropc_decoderout; 187: tme_uint16_t tme_suncg2_ropc_x11; 188: tme_uint16_t tme_suncg2_ropc_x12; 189: tme_uint16_t tme_suncg2_ropc_x13; 190: tme_uint16_t tme_suncg2_ropc_x14; 191: tme_uint16_t tme_suncg2_ropc_x15; 192: } tme_suncg2_ropc[TME_SUNCG2_ROPC_PRIME * 2]; 193: 194: /* our csr: */ 195: tme_uint16_t tme_suncg2_csr; 196: 197: /* our interrupt vector: */ 198: tme_uint16_t tme_suncg2_intvec; 199: 200: /* our plane mask: */ 201: tme_uint16_t tme_suncg2_plane_mask; 202: 203: /* the raw colormap: */ 204: tme_uint16_t tme_suncg2_cmap_raw[(1 << TME_SUNCG2_PLANE_MAX) * 3]; 205: 206: /* the cooked colormap: */ 207: tme_uint8_t tme_suncg2_cmap[(1 << TME_SUNCG2_PLANE_MAX) * 3]; 208: 209: /* if this is zero, the next CSR read will have the retrace bit set: */ 210: unsigned int tme_suncg2_cycle_retrace; 211: 212: /* if this is TME_SUNCG2_PLANE_MAX, we are displaying the pixmap, 213: else we are displaying this plane's bitmap: */ 214: unsigned int tme_suncg2_bitmap_mode_plane; 215: 216: /* state flags: */ 217: unsigned int tme_suncg2_flags; 218: 219: /* any outstanding TLBs: */ 220: struct tme_bus_tlb *tme_suncg2_tlbs[4]; 221: unsigned int tme_suncg2_tlb_head; 222: 223: /* a rasterop buffered SRC value: */ 224: tme_uint16_t tme_suncg2_rop_src_buffer; 225: }; 226: 227: /* globals: */ 228: 229: #ifndef TME_NO_LOG 230: static const char *_tme_suncg2_ropc_regs[] = 231: { "dest", 232: "source1", 233: "source2", 234: "pattern", 235: "mask1", 236: "mask2", 237: "ena_shift", 238: "op", 239: "width", 240: "opcount", 241: "decoderout", 242: "x11", 243: "x12", 244: "x13", 245: "x14", 246: "x15", 247: }; 248: #endif /* !TME_NO_LOG */ 249: 250: /* this invalidates any outstanding TLBs: */ 251: static void 252: _tme_suncg2_tlb_invalidate(struct tme_suncg2 *suncg2, struct tme_bus_tlb *tlb_valid) 253: { 254: unsigned int tlb_i; 255: struct tme_bus_tlb *tlb; 256: 257: if (tlb_valid != NULL) { 1.1.1.2 ! root 258: tlb_valid = tlb_valid->tme_bus_tlb_global; 1.1 root 259: } 260: 261: for (tlb_i = 0; tlb_i < TME_ARRAY_ELS(suncg2->tme_suncg2_tlbs); tlb_i++) { 262: tlb = suncg2->tme_suncg2_tlbs[tlb_i]; 263: suncg2->tme_suncg2_tlbs[tlb_i] = NULL; 264: if (tlb != NULL 265: && tlb != tlb_valid) { 266: tme_bus_tlb_invalidate(tlb); 267: } 268: } 269: } 270: 271: /* this adds an outstanding TLB: */ 272: static void 273: _tme_suncg2_tlb_add(struct tme_suncg2 *suncg2, struct tme_bus_tlb *tlb_valid) 274: { 275: struct tme_bus_tlb *tlb; 276: 1.1.1.2 ! root 277: tlb_valid = tlb_valid->tme_bus_tlb_global; 1.1 root 278: 279: tlb = suncg2->tme_suncg2_tlbs[suncg2->tme_suncg2_tlb_head % TME_ARRAY_ELS(suncg2->tme_suncg2_tlbs)]; 280: if (tlb != NULL 281: && tlb != tlb_valid) { 282: tme_bus_tlb_invalidate(tlb); 283: } 284: suncg2->tme_suncg2_tlbs[suncg2->tme_suncg2_tlb_head % TME_ARRAY_ELS(suncg2->tme_suncg2_tlbs)] = tlb_valid; 285: suncg2->tme_suncg2_tlb_head++; 286: } 287: 288: /* this validates the bitmaps: */ 289: static void 290: _tme_suncg2_validate_bitmaps(struct tme_suncg2 *suncg2, struct tme_bus_tlb *tlb) 291: { 292: const tme_uint32_t *pixmap_pointer; 293: tme_uint32_t pixmap; 294: tme_uint32_t pixmap_resid; 295: tme_uint32_t bitmaps_lo; 296: tme_uint32_t bitmaps_hi; 297: tme_uint8_t *bitmap_pointer; 298: 299: /* if the bitmaps are invalid: */ 300: if (suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_BITMAPS) { 301: 302: /* the pixmap must not be invalid: */ 303: assert (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_PIXMAP)); 304: 305: /* invalidate any outstanding TLBs: */ 306: _tme_suncg2_tlb_invalidate(suncg2, tlb); 307: 308: /* if we are displaying the pixmap: */ 309: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 310: 311: /* if the displayed memory is not invalid: */ 312: if (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED)) { 313: 314: /* copy the displayed memory back into the pixmap: */ 315: memcpy((suncg2->tme_suncg2_raw_memory 316: + TME_SUNCG2_REG_PIXMAP), 317: suncg2->tme_suncg2_displayed_memory, 318: TME_SUNCG2_SIZ_PIXMAP); 319: } 320: } 321: 322: /* otherwise, we're displaying a bitmap: */ 323: else { 324: 325: /* the displayed memory must be invalid: */ 326: assert (suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED); 327: } 328: 329: /* start in the pixmap: */ 1.1.1.2 ! root 330: pixmap_pointer = (tme_uint32_t *) (suncg2->tme_suncg2_raw_memory + TME_SUNCG2_REG_PIXMAP + TME_SUNCG2_SIZ_PIXMAP); 1.1 root 331: pixmap_resid = TME_SUNCG2_SIZ_PIXMAP; 332: pixmap = 0; 333: 334: /* start in the bitmaps: */ 1.1.1.2 ! root 335: bitmap_pointer = suncg2->tme_suncg2_raw_memory + TME_SUNCG2_REG_BITMAP(0) + TME_SUNCG2_SIZ_BITMAP; 1.1 root 336: bitmaps_lo = 0; 337: bitmaps_hi = 0; 338: 339: /* do the translation: */ 340: do { 341: 342: /* if the pixmap data is empty, reload it: */ 343: if (__tme_predict_false((pixmap_resid % sizeof(pixmap)) == 0)) { 1.1.1.2 ! root 344: pixmap = *(--pixmap_pointer); 1.1 root 345: pixmap = tme_betoh_u32(pixmap); 346: } 347: 348: /* translate another pixel's bits into the bitmaps: */ 349: bitmaps_lo >>= 1; 350: if (pixmap & TME_BIT(0)) bitmaps_lo |= 0x00000080; 351: if (pixmap & TME_BIT(1)) bitmaps_lo |= 0x00008000; 352: if (pixmap & TME_BIT(2)) bitmaps_lo |= 0x00800000; 353: if (pixmap & TME_BIT(3)) bitmaps_lo |= 0x80000000; 354: bitmaps_hi >>= 1; 355: if (pixmap & TME_BIT(4)) bitmaps_hi |= 0x00000080; 356: if (pixmap & TME_BIT(5)) bitmaps_hi |= 0x00008000; 357: if (pixmap & TME_BIT(6)) bitmaps_hi |= 0x00800000; 358: if (pixmap & TME_BIT(7)) bitmaps_hi |= 0x80000000; 359: 360: /* we have translated another pixel: */ 361: pixmap >>= 8; 362: pixmap_resid--; 363: 364: /* after every eight pixels, we have another eight bytes of bitmap 365: data to write out: */ 366: if (__tme_predict_false((pixmap_resid % 8) == 0)) { 1.1.1.2 ! root 367: bitmap_pointer--; 1.1 root 368: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 0] = TME_FIELD_MASK_EXTRACTU(bitmaps_lo, 0x000000ff); 369: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 1] = TME_FIELD_MASK_EXTRACTU(bitmaps_lo, 0x0000ff00); 370: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 2] = TME_FIELD_MASK_EXTRACTU(bitmaps_lo, 0x00ff0000); 371: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 3] = TME_FIELD_MASK_EXTRACTU(bitmaps_lo, 0xff000000); 372: bitmaps_lo = 0; 373: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 4] = TME_FIELD_MASK_EXTRACTU(bitmaps_hi, 0x000000ff); 374: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 5] = TME_FIELD_MASK_EXTRACTU(bitmaps_hi, 0x0000ff00); 375: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 6] = TME_FIELD_MASK_EXTRACTU(bitmaps_hi, 0x00ff0000); 376: bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 7] = TME_FIELD_MASK_EXTRACTU(bitmaps_hi, 0xff000000); 377: bitmaps_hi = 0; 378: } 379: 380: /* loop while we have pixmap bytes remaining: */ 381: } while (pixmap_resid > 0); 382: 383: /* the bitmaps are no longer invalid: */ 384: suncg2->tme_suncg2_flags &= ~TME_SUNCG2_FLAG_INVALID_BITMAPS; 385: } 386: 387: /* otherwise, the bitmaps are valid: */ 388: else { 389: 390: /* if our caller needs the actual raw bitmap memory valid 391: (indicated by tlb == NULL): */ 392: if (tlb == NULL) { 393: 394: /* invalidate any outstanding TLBs: */ 395: _tme_suncg2_tlb_invalidate(suncg2, NULL); 396: 397: /* if we're displaying a bitmap: */ 398: if (suncg2->tme_suncg2_bitmap_mode_plane != TME_SUNCG2_PLANE_MAX) { 399: 400: /* if the displayed memory is not invalid: */ 401: if (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED)) { 402: 403: /* copy the displayed memory back into the bitmap: */ 404: memcpy((suncg2->tme_suncg2_raw_memory 405: + TME_SUNCG2_REG_BITMAP(suncg2->tme_suncg2_bitmap_mode_plane)), 406: suncg2->tme_suncg2_displayed_memory, 407: TME_SUNCG2_SIZ_BITMAP); 408: } 409: } 410: } 411: } 412: } 413: 414: /* this validates the pixmap: */ 415: static void 416: _tme_suncg2_validate_pixmap(struct tme_suncg2 *suncg2, struct tme_bus_tlb *tlb) 417: { 418: tme_uint32_t *pixmap_pointer; 419: tme_uint32_t pixmap; 420: tme_uint32_t pixmap_resid; 421: tme_uint32_t bitmaps_lo; 422: tme_uint32_t bitmaps_hi; 423: const tme_uint8_t *bitmap_pointer; 424: 425: /* if the pixmap is invalid: */ 426: if (suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_PIXMAP) { 427: 428: /* the bitmaps must not be invalid: */ 429: assert (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_BITMAPS)); 430: 431: /* invalidate any outstanding TLBs: */ 432: _tme_suncg2_tlb_invalidate(suncg2, tlb); 433: 434: /* if we are displaying a bitmap: */ 435: if (suncg2->tme_suncg2_bitmap_mode_plane != TME_SUNCG2_PLANE_MAX) { 436: 437: /* if the displayed memory is not invalid: */ 438: if (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED)) { 439: 440: /* copy the displayed memory back into the bitmap: */ 441: memcpy((suncg2->tme_suncg2_raw_memory 442: + TME_SUNCG2_REG_BITMAP(suncg2->tme_suncg2_bitmap_mode_plane)), 443: suncg2->tme_suncg2_displayed_memory, 444: TME_SUNCG2_SIZ_BITMAP); 445: } 446: } 447: 448: /* otherwise, we're displaying the pixmap: */ 449: else { 450: 451: /* the displayed memory must be invalid: */ 452: assert (suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED); 453: } 454: 455: /* start in the pixmap: */ 456: pixmap_pointer = (tme_uint32_t *) (suncg2->tme_suncg2_raw_memory + TME_SUNCG2_REG_PIXMAP); 457: pixmap_resid = TME_SUNCG2_SIZ_PIXMAP; 458: pixmap = 0; 459: 460: /* start in the bitmaps: */ 461: bitmap_pointer = suncg2->tme_suncg2_raw_memory + TME_SUNCG2_REG_BITMAP(0); 462: bitmaps_lo = 0; 463: bitmaps_hi = 0; 464: 465: /* do the translation: */ 466: do { 467: 468: /* if the bitmap data is empty, reload it: */ 469: if (__tme_predict_false((pixmap_resid % 8) == 0)) { 470: bitmaps_lo 471: = ((((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 0]) << 0) 472: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 1]) << 8) 473: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 2]) << 16) 474: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 3]) << 24)); 475: bitmaps_hi 476: = ((((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 4]) << 0) 477: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 5]) << 8) 478: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 6]) << 16) 479: | (((tme_uint32_t) bitmap_pointer[TME_SUNCG2_SIZ_BITMAP * 7]) << 24)); 480: bitmap_pointer++; 481: } 482: 483: /* we are about to translate another pixel: */ 484: pixmap <<= 8; 485: pixmap_resid--; 486: 487: /* translate another pixel's bits from the bitmaps: */ 488: if (bitmaps_lo & 0x00000080) pixmap |= TME_BIT(0); 489: if (bitmaps_lo & 0x00008000) pixmap |= TME_BIT(1); 490: if (bitmaps_lo & 0x00800000) pixmap |= TME_BIT(2); 491: if (bitmaps_lo & 0x80000000) pixmap |= TME_BIT(3); 492: bitmaps_lo <<= 1; 493: if (bitmaps_hi & 0x00000080) pixmap |= TME_BIT(4); 494: if (bitmaps_hi & 0x00008000) pixmap |= TME_BIT(5); 495: if (bitmaps_hi & 0x00800000) pixmap |= TME_BIT(6); 496: if (bitmaps_hi & 0x80000000) pixmap |= TME_BIT(7); 497: bitmaps_hi <<= 1; 498: 499: /* if the pixmap data is full, write it: */ 500: if (__tme_predict_false((pixmap_resid % sizeof(pixmap)) == 0)) { 501: *(pixmap_pointer++) = tme_htobe_u32(pixmap); 502: pixmap = 0; 503: } 504: 505: /* loop while we have pixmap bytes remaining: */ 506: } while (pixmap_resid > 0); 507: 508: /* the pixmap is no longer invalid, but the bitmaps are: */ 509: suncg2->tme_suncg2_flags &= ~TME_SUNCG2_FLAG_INVALID_PIXMAP; 510: } 511: 512: /* otherwise, the pixmap is valid: */ 513: else { 514: 515: /* if our caller needs the actual raw pixmap memory valid 516: (indicated by tlb == NULL): */ 517: if (tlb == NULL) { 518: 519: /* invalidate any outstanding TLBs: */ 520: _tme_suncg2_tlb_invalidate(suncg2, NULL); 521: 522: /* if we're displaying the pixmap: */ 523: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 524: 525: /* if the displayed memory is not invalid: */ 526: if (!(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED)) { 527: 528: /* copy the displayed memory back into the pixmap: */ 529: memcpy((suncg2->tme_suncg2_raw_memory 530: + TME_SUNCG2_REG_PIXMAP), 531: suncg2->tme_suncg2_displayed_memory, 532: TME_SUNCG2_SIZ_PIXMAP); 533: } 534: } 535: } 536: } 537: } 538: 539: /* this validates the displayed memory: */ 540: static void 541: _tme_suncg2_validate_displayed(struct tme_suncg2 *suncg2, struct tme_bus_tlb *tlb) 542: { 543: 544: /* if the displayed memory is invalid: */ 545: if (suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_INVALID_DISPLAYED) { 546: 547: /* if we're displaying the pixmap: */ 548: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 549: 550: /* validate the pixmap: */ 551: _tme_suncg2_validate_pixmap(suncg2, tlb); 552: 553: /* copy the pixmap into the displayed memory: */ 554: memcpy(suncg2->tme_suncg2_displayed_memory, 555: (suncg2->tme_suncg2_raw_memory 556: + TME_SUNCG2_REG_PIXMAP), 557: TME_SUNCG2_SIZ_PIXMAP); 558: } 559: 560: /* otherwise, we're displaying a bitmap: */ 561: else { 562: 563: /* validate the bitmaps: */ 564: _tme_suncg2_validate_bitmaps(suncg2, tlb); 565: 566: /* copy the bitmap into the displayed memory: */ 567: memcpy(suncg2->tme_suncg2_displayed_memory, 568: (suncg2->tme_suncg2_raw_memory 569: + TME_SUNCG2_REG_BITMAP(suncg2->tme_suncg2_bitmap_mode_plane)), 570: TME_SUNCG2_SIZ_BITMAP); 571: } 572: 573: /* the displayed memory is no longer invalid: */ 574: suncg2->tme_suncg2_flags &= ~TME_SUNCG2_FLAG_INVALID_DISPLAYED; 575: } 576: } 577: 578: /* this handles a mode change callout: */ 579: static int 580: _tme_suncg2_mode_change(struct tme_suncg2 *suncg2) 581: { 582: struct tme_fb_connection *conn_fb_other; 583: struct tme_fb_connection *conn_fb; 584: unsigned int pixel_i; 585: unsigned int mono_mask; 586: tme_uint32_t color0; 587: tme_uint32_t color1; 588: tme_uint32_t color; 589: unsigned int bitmap_mode_plane; 590: unsigned int color_i; 591: int rc; 592: 593: /* this makes a color for a pixel: */ 594: #define _TME_SUNCG2_PIXEL_COLOR(pixel) \ 595: ((TME_SUNCG2_CMAP_VALUE(suncg2, pixel, TME_SUNCG2_REG_CMAP_G) << 0) \ 596: | (TME_SUNCG2_CMAP_VALUE(suncg2, pixel, TME_SUNCG2_REG_CMAP_R) << 8) \ 597: | (TME_SUNCG2_CMAP_VALUE(suncg2, pixel, TME_SUNCG2_REG_CMAP_B) << 16)) 598: 599: /* if we are to display a bitmap, the color for pixmap pixel zero 600: must be the color for bitmap pixel zero, and the color for pixmap 601: pixel 255 must be the color for bitmap pixel one: */ 602: color0 = _TME_SUNCG2_PIXEL_COLOR(0); 603: color1 = _TME_SUNCG2_PIXEL_COLOR(255); 604: 605: /* we don't know what the monochrome mask is yet: */ 606: mono_mask = 0xff; 607: 608: /* loop over the other pixels: */ 609: for (pixel_i = 1; pixel_i < 255; pixel_i++) { 610: 611: /* get the color for this pixel: */ 612: color = _TME_SUNCG2_PIXEL_COLOR(pixel_i); 613: 614: /* if this matches color0: */ 615: if (color == color0) { 616: 617: /* any set bits in this pixel number can't be in the monochrome 618: mask: */ 619: mono_mask &= ~pixel_i; 620: } 621: 622: /* else, if this matches color1: */ 623: else if (color == color1) { 624: 625: /* any clear bits in this pixel number can't be in the 626: monochrome mask: */ 627: mono_mask &= pixel_i; 628: } 629: 630: /* otherwise, this is some other color: */ 631: else { 632: 633: /* we can't be in bitmap mode: */ 634: mono_mask = 0; 635: break; 636: } 637: } 638: 639: /* if the monochrome mask is zero, we must display the pixmap, else 640: we display the bitmap corresponding to the least significant set 641: bit in the monochrome mask: */ 1.1.1.2 ! root 642: if (mono_mask == 0 ! 643: || (mono_mask & (mono_mask - 1)) != 0) { 1.1 root 644: bitmap_mode_plane = TME_SUNCG2_PLANE_MAX; 645: } 646: else { 647: for (bitmap_mode_plane = 0; 648: (mono_mask & 1) == 0; 649: bitmap_mode_plane++, mono_mask >>= 1); 650: } 651: 652: #undef _TME_SUNCG2_PIXEL_COLOR 653: 654: /* get both sides of the framebuffer connection: */ 655: conn_fb_other = suncg2->tme_suncg2_fb_connection; 656: conn_fb = (struct tme_fb_connection *) conn_fb_other->tme_fb_connection.tme_connection_other; 657: 658: /* if we are displaying the pixmap: */ 659: if (bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 660: 661: /* the pixmap is eight bits deep: */ 662: conn_fb->tme_fb_connection_depth = TME_SUNCG2_PLANE_MAX; 663: conn_fb->tme_fb_connection_bits_per_pixel = TME_SUNCG2_PLANE_MAX; 664: 665: /* recook the colormap: */ 666: for (color_i = 0; 667: color_i < TME_ARRAY_ELS(suncg2->tme_suncg2_cmap_raw); 668: color_i++) { 669: suncg2->tme_suncg2_cmap[color_i] = tme_betoh_u16(suncg2->tme_suncg2_cmap_raw[color_i]); 670: } 671: } 672: 673: /* otherwise, we can display a bitmap: */ 674: else { 675: 676: /* a bitmap is one bit deep: */ 677: conn_fb->tme_fb_connection_depth = 1; 678: conn_fb->tme_fb_connection_bits_per_pixel = 1; 679: 680: /* cook the monochrome colormap: */ 681: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_G)] = TME_SUNCG2_CMAP_VALUE(suncg2, 0, TME_SUNCG2_REG_CMAP_G); 682: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_R)] = TME_SUNCG2_CMAP_VALUE(suncg2, 0, TME_SUNCG2_REG_CMAP_R); 683: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_B)] = TME_SUNCG2_CMAP_VALUE(suncg2, 0, TME_SUNCG2_REG_CMAP_B); 684: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(1, TME_SUNCG2_REG_CMAP_G)] = TME_SUNCG2_CMAP_VALUE(suncg2, 255, TME_SUNCG2_REG_CMAP_G); 685: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(1, TME_SUNCG2_REG_CMAP_R)] = TME_SUNCG2_CMAP_VALUE(suncg2, 255, TME_SUNCG2_REG_CMAP_R); 686: suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(1, TME_SUNCG2_REG_CMAP_B)] = TME_SUNCG2_CMAP_VALUE(suncg2, 255, TME_SUNCG2_REG_CMAP_B); 687: } 688: 689: /* if the display is changing: */ 690: if (bitmap_mode_plane != suncg2->tme_suncg2_bitmap_mode_plane) { 691: 692: /* log the change: */ 693: tme_log(&suncg2->tme_suncg2_element->tme_element_log_handle, 694: 100, TME_OK, 695: (&suncg2->tme_suncg2_element->tme_element_log_handle, 696: "display changing from plane %u to plane %u", 697: suncg2->tme_suncg2_bitmap_mode_plane, 698: bitmap_mode_plane)); 699: 700: /* if we were displaying the pixmap, validate the pixmap, else 701: validate the bitmaps, to copy the current displayed memory back 702: into the raw memory: */ 703: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 704: _tme_suncg2_validate_pixmap(suncg2, NULL); 705: } 706: else { 707: _tme_suncg2_validate_bitmaps(suncg2, NULL); 708: } 709: 710: /* invalidate any outstanding TLBs: */ 711: _tme_suncg2_tlb_invalidate(suncg2, NULL); 712: 713: /* set the display: */ 714: suncg2->tme_suncg2_bitmap_mode_plane = bitmap_mode_plane; 715: 716: /* free any previously allocated memory: */ 717: if (suncg2->tme_suncg2_displayed_memory != NULL) { 718: tme_free(suncg2->tme_suncg2_displayed_memory); 719: } 720: 721: /* allocate memory for our framebuffer connection: */ 722: rc = tme_fb_xlat_alloc_src(conn_fb); 723: assert (rc == TME_OK); 724: suncg2->tme_suncg2_displayed_memory = conn_fb->tme_fb_connection_buffer; 725: 726: /* the displayed memory is now invalid: */ 727: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_DISPLAYED; 728: } 729: 730: /* unlock the mutex: */ 731: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 732: 733: /* do the callout: */ 734: rc = (conn_fb_other != NULL 735: ? ((*conn_fb_other->tme_fb_connection_mode_change) 736: (conn_fb_other)) 737: : TME_OK); 738: 739: /* lock the mutex: */ 740: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 741: 742: return (rc); 743: } 744: 745: /* the suncg2 callout function. it must be called with the mutex locked: */ 746: static void 747: _tme_suncg2_callout(struct tme_suncg2 *suncg2, int new_callouts) 748: { 749: int callouts, later_callouts; 750: int rc; 751: 752: /* add in any new callouts: */ 753: suncg2->tme_suncg2_callout_flags |= new_callouts; 754: 755: /* if this function is already running in another thread, simply 756: return now. the other thread will do our work: */ 757: if (suncg2->tme_suncg2_callout_flags 758: & TME_SUNCG2_CALLOUT_RUNNING) { 759: return; 760: } 761: 762: /* callouts are now running: */ 763: suncg2->tme_suncg2_callout_flags 764: |= TME_SUNCG2_CALLOUT_RUNNING; 765: 766: /* assume that we won't need any later callouts: */ 767: later_callouts = 0; 768: 769: /* loop while callouts are needed: */ 770: for (; ((callouts 771: = suncg2->tme_suncg2_callout_flags) 772: & TME_SUNCG2_CALLOUTS_MASK); ) { 773: 774: /* clear the needed callouts: */ 775: suncg2->tme_suncg2_callout_flags 776: = (callouts 777: & ~TME_SUNCG2_CALLOUTS_MASK); 778: callouts 779: &= TME_SUNCG2_CALLOUTS_MASK; 780: 781: /* if we need a mode change: */ 1.1.1.2 ! root 782: if (callouts & TME_SUNCG2_CALLOUT_MODE_CHANGE) { 1.1 root 783: 784: /* call out the mode change: */ 785: rc = _tme_suncg2_mode_change(suncg2); 786: 787: /* if the callout failed: */ 788: if (rc != TME_OK) { 789: 790: /* remember that this callout should be attempted again at 791: some later time: */ 792: later_callouts |= TME_SUNCG2_CALLOUT_MODE_CHANGE; 793: } 794: } 795: } 796: 797: /* put in any later callouts, and clear that callouts are running: */ 798: suncg2->tme_suncg2_callout_flags = later_callouts; 799: } 800: 801: /* the callout thread: */ 802: static void 803: _tme_suncg2_callout_thread(void *_suncg2) 804: { 805: struct tme_suncg2 *suncg2; 806: 807: /* recover our data structure: */ 808: suncg2 = _suncg2; 809: 810: /* lock the mutex: */ 811: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 812: 813: /* the callout thread is no longer running: */ 814: suncg2->tme_suncg2_flags &= ~TME_SUNCG2_FLAG_CALLOUT_THREAD_RUNNING; 815: 816: /* make any callouts: */ 817: _tme_suncg2_callout(suncg2, 0); 818: 819: /* unlock the mutex: */ 820: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 821: } 822: 823: /* this is called before the framebuffer's display is updated: */ 824: static int 825: _tme_suncg2_update(struct tme_fb_connection *conn_fb) 826: { 827: struct tme_suncg2 *suncg2; 828: 829: /* recover our data structure: */ 830: suncg2 = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private; 831: 832: /* lock the mutex: */ 833: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 834: 835: /* validate the displayed memory: */ 836: _tme_suncg2_validate_displayed(suncg2, NULL); 837: 838: /* if we still need callouts, and the callout thread isn't running, 839: start it: */ 840: if ((suncg2->tme_suncg2_callout_flags & TME_SUNCG2_CALLOUTS_MASK) != 0 841: && !(suncg2->tme_suncg2_flags & TME_SUNCG2_FLAG_CALLOUT_THREAD_RUNNING)) { 842: tme_thread_create(_tme_suncg2_callout_thread, suncg2); 843: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_CALLOUT_THREAD_RUNNING; 844: } 845: 846: /* unlock the mutex: */ 847: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 848: 849: return (TME_OK); 850: } 851: 852: /* the suncg2 displayed memory bus cycle handler: */ 853: static int 854: _tme_suncg2_bus_cycle_displayed(void *_suncg2, struct tme_bus_cycle *cycle_init) 855: { 856: struct tme_suncg2 *suncg2; 857: unsigned int plane_i; 858: tme_bus_addr_t address_first; 859: tme_bus_addr_t address_last; 860: 861: /* recover our data structure: */ 862: suncg2 = (struct tme_suncg2 *) _suncg2; 863: 864: /* lock the mutex: */ 865: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 866: 867: /* if we're displaying the pixmap: */ 868: plane_i = suncg2->tme_suncg2_bitmap_mode_plane; 869: if (plane_i == TME_SUNCG2_PLANE_MAX) { 870: 871: /* the displayed memory is the pixmap memory: */ 872: address_first = TME_SUNCG2_REG_PIXMAP; 873: address_last = TME_SUNCG2_REG_PIXMAP + suncg2->tme_suncg2_pixel_count - 1; 874: } 875: 876: /* otherwise, we're in bitmap mode: */ 877: else { 878: 879: /* the displayed memory is the displayed bitmap memory: */ 880: address_first = TME_SUNCG2_REG_BITMAP(plane_i); 881: address_last = address_first + (suncg2->tme_suncg2_pixel_count / 8) - 1; 882: } 883: 884: /* run the cycle: */ 885: tme_bus_cycle_xfer_memory(cycle_init, 886: (suncg2->tme_suncg2_displayed_memory 887: - address_first), 888: address_last); 889: 890: /* unlock the mutex: */ 891: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 892: 893: /* no faults: */ 894: return (TME_OK); 895: } 896: 897: /* the suncg2 raw memory bus cycle handler: */ 898: static int 899: _tme_suncg2_bus_cycle_raw(void *_suncg2, struct tme_bus_cycle *cycle_init) 900: { 901: struct tme_suncg2 *suncg2; 902: 903: /* recover our data structure: */ 904: suncg2 = (struct tme_suncg2 *) _suncg2; 905: 906: /* lock the mutex: */ 907: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 908: 909: /* run the cycle: */ 910: tme_bus_cycle_xfer_memory(cycle_init, 911: (suncg2->tme_suncg2_raw_memory 912: - TME_SUNCG2_REG_BITMAP(0)), 913: (TME_SUNCG2_REG_PIXMAP 914: + TME_SUNCG2_SIZ_PIXMAP 915: - 1)); 916: 917: /* unlock the mutex: */ 918: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 919: 920: /* no faults: */ 921: return (TME_OK); 922: } 923: 924: /* this catches unsupported rasterop configurations: */ 925: static void 926: _tme_suncg2_rop_unsupported(struct tme_suncg2 *suncg2) 927: { 928: /* nothing */ 929: } 930: 931: /* this does a raster op: */ 932: static tme_uint16_t 933: _tme_suncg2_rop_op(struct tme_suncg2 *suncg2, 934: unsigned int ropc_unit, 935: tme_uint16_t src, 936: tme_uint16_t dst) 937: { 938: switch ((tme_uint8_t) suncg2->tme_suncg2_ropc[ropc_unit].tme_suncg2_ropc_op) { 939: default: 940: _tme_suncg2_rop_unsupported(suncg2); 941: /* FALLTHROUGH */ 942: case (TME_SUNCG2_ROP_SRC): return (src); 943: case (TME_SUNCG2_ROP_NOT(TME_SUNCG2_ROP_DST)): return (~dst); 944: } 945: } 946: 947: /* the bus cycle handler for the rasterop data: */ 948: static int 949: _tme_suncg2_bus_cycle_rop_data(void *_suncg2, struct tme_bus_cycle *cycle_init) 950: { 951: struct tme_suncg2 *suncg2; 952: tme_uint32_t address; 953: tme_uint32_t address_aligned; 954: tme_uint16_t data; 955: tme_uint8_t src; 956: tme_uint8_t dst; 957: tme_uint8_t pixel; 958: int supported; 959: 960: /* recover our data structure: */ 961: suncg2 = (struct tme_suncg2 *) _suncg2; 962: 963: /* decode the address: */ 964: address 965: = (cycle_init->tme_bus_cycle_address 966: - TME_SUNCG2_REG_ROP_DATA); 967: address_aligned 968: = (address & (((tme_uint32_t) 0) - sizeof(tme_uint16_t))); 969: 970: /* assume that this access is unsupported: */ 971: supported = FALSE; 972: 973: /* lock the mutex: */ 974: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 975: 976: /* if this is a read: */ 977: if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_READ) { 978: 979: /* dispatch on the rop mode: */ 980: switch (suncg2->tme_suncg2_csr & TME_SUNCG2_CSR_ROP_MODE_MASK) { 981: 982: default: 983: _tme_suncg2_rop_unsupported(suncg2); 984: data = 0; 985: break; 986: 987: /* the single pixel, LD_SRC write, LD_DST write, mode: */ 988: case TME_SUNCG2_CSR_ROP_MODE_SWWPIX: 989: 990: /* this mode has partial support: */ 991: supported = TRUE; 992: 993: /* XXX FIXME does a load reset the state? */ 994: 995: /* just load two pixels from the pixmap: */ 996: _tme_suncg2_validate_pixmap(suncg2, NULL); 997: data = (suncg2->tme_suncg2_raw_memory[TME_SUNCG2_REG_PIXMAP + address_aligned] 998: & ((tme_uint8_t) suncg2->tme_suncg2_plane_mask)); 999: data = ((data << 8) 1000: | (suncg2->tme_suncg2_raw_memory[TME_SUNCG2_REG_PIXMAP + address_aligned + 1] 1001: & ((tme_uint8_t) suncg2->tme_suncg2_plane_mask))); 1002: break; 1003: } 1004: } 1005: 1006: /* do the bus cycle: */ 1007: tme_bus_cycle_xfer_reg(cycle_init, 1008: &data, 1009: TME_BUS16_LOG2); 1010: 1011: /* get the data: */ 1012: data = (((cycle_init->tme_bus_cycle_size == sizeof(tme_uint16_t) 1013: || (address % sizeof(tme_uint16_t)) == 1) 1014: ? data 1015: : (data >> 8)) 1016: & (0xffff >> (sizeof(tme_uint16_t) - cycle_init->tme_bus_cycle_size))); 1017: 1018: /* log the cycle: */ 1019: tme_log(&suncg2->tme_suncg2_element->tme_element_log_handle, 1020: 100, TME_OK, 1021: (&suncg2->tme_suncg2_element->tme_element_log_handle, 1022: ((cycle_init->tme_bus_cycle_size == sizeof(tme_uint16_t)) 1023: ? "rop data offset 0x%05x size 16bits %s 0x%04x" 1024: : "rop data offset 0x%05x size 8bits %s 0x%02x"), 1025: address, 1026: ((cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) 1027: ? "<-" 1028: : "->"), 1029: data)); 1030: 1031: /* if this is a write: */ 1032: if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) { 1033: 1034: /* dispatch on the rop mode: */ 1035: switch (suncg2->tme_suncg2_csr & TME_SUNCG2_CSR_ROP_MODE_MASK) { 1036: 1037: default: 1038: _tme_suncg2_rop_unsupported(suncg2); 1039: break; 1040: 1041: /* the single pixel, LD_SRC write, LD_DST write, mode: */ 1042: case TME_SUNCG2_CSR_ROP_MODE_SWWPIX: 1043: 1044: /* this mode has partial support: */ 1045: supported = TRUE; 1046: 1047: /* validate the pixmap: */ 1048: _tme_suncg2_validate_pixmap(suncg2, NULL); 1049: 1050: /* the current pixel value is DST: */ 1051: dst = suncg2->tme_suncg2_raw_memory[TME_SUNCG2_REG_PIXMAP + address]; 1052: 1053: /* the current source buffer is SRC: */ 1054: src = suncg2->tme_suncg2_rop_src_buffer; 1055: 1056: /* make the new pixel value: */ 1057: pixel = _tme_suncg2_rop_op(suncg2, 1058: 8, 1059: src, 1060: dst); 1061: 1062: /* store the pixel: */ 1063: suncg2->tme_suncg2_raw_memory[TME_SUNCG2_REG_PIXMAP + address] 1064: = ((dst & ((tme_uint8_t) (~suncg2->tme_suncg2_plane_mask))) 1065: | (pixel & ((tme_uint8_t) suncg2->tme_suncg2_plane_mask))); 1066: 1067: /* the displayed memory is now invalid: */ 1068: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_DISPLAYED; 1069: 1070: /* load the source buffer: */ 1071: suncg2->tme_suncg2_rop_src_buffer = data; 1072: break; 1073: } 1074: } 1075: 1076: /* if this cycle was unsupported, abort: */ 1077: if (__tme_predict_false(!supported)) { 1078: _tme_suncg2_rop_unsupported(suncg2); 1079: } 1080: 1081: /* unlock the mutex: */ 1082: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 1083: 1084: /* no faults: */ 1085: return (TME_OK); 1086: } 1087: 1088: /* the bus cycle handler for the registers: */ 1089: static int 1090: _tme_suncg2_bus_cycle_regs(void *_suncg2, struct tme_bus_cycle *cycle_init) 1091: { 1092: struct tme_suncg2 *suncg2; 1093: tme_bus_addr_t address; 1094: tme_uint16_t *reg; 1095: tme_uint16_t reg_old, reg_new; 1096: tme_uint16_t junk; 1097: unsigned int ropc_unit; 1098: unsigned int ropc_unit_prime; 1099: unsigned int ropc_reg; 1100: int new_callouts; 1101: 1102: /* assume we won't need any new callouts: */ 1103: new_callouts = 0; 1104: 1105: /* recover our data structure: */ 1106: suncg2 = (struct tme_suncg2 *) _suncg2; 1107: 1108: /* coarsely decode the address: */ 1109: address 1110: = (cycle_init->tme_bus_cycle_address 1111: & (((tme_bus_addr_t) 0) 1112: - TME_SUNCG2_SIZ_REG_PAGE)); 1113: 1114: /* lock the mutex: */ 1115: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 1116: 1117: /* the rasterop registers go from [TME_SUNCG2_REG_ROPC_UNIT(0)..TME_SUNCG2_REG_CSR): */ 1118: assert (address >= TME_SUNCG2_REG_ROPC_UNIT(0)); 1119: if (address < TME_SUNCG2_REG_CSR) { 1120: 1121: /* get the rasterop unit number: */ 1122: ropc_unit = (address - TME_SUNCG2_REG_ROPC_UNIT(0)) / TME_SUNCG2_SIZ_REG_PAGE; 1123: 1124: /* see if this is the prime registers: */ 1125: ropc_unit_prime 1126: = ((cycle_init->tme_bus_cycle_address & (TME_SUNCG2_SIZ_REG_PAGE / 2)) 1127: ? TME_SUNCG2_ROPC_PRIME 1128: : 0); 1129: 1130: /* get the register number: */ 1131: ropc_reg 1132: = ((cycle_init->tme_bus_cycle_address 1133: % sizeof(suncg2->tme_suncg2_ropc[ropc_unit_prime + ropc_unit])) 1134: / sizeof(tme_uint16_t)); 1135: 1136: /* get a pointer to the single register: */ 1137: reg = (((tme_uint16_t *) &suncg2->tme_suncg2_ropc[ropc_unit_prime + ropc_unit]) + ropc_reg); 1138: 1139: /* do the bus cycle: */ 1140: tme_bus_cycle_xfer_reg(cycle_init, 1141: reg, 1142: TME_BUS16_LOG2); 1143: 1144: #ifndef TME_NO_LOG 1145: /* log the transfer: */ 1146: tme_log(&suncg2->tme_suncg2_element->tme_element_log_handle, 1147: 100, TME_OK, 1148: (&suncg2->tme_suncg2_element->tme_element_log_handle, 1149: "ropc unit %u%s reg %s %s 0x%04x", 1150: ropc_unit, 1151: (ropc_unit_prime 1152: ? " PRIME" 1153: : ""), 1154: _tme_suncg2_ropc_regs[ropc_reg], 1155: ((cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) 1156: ? "<-" 1157: : "->"), 1158: *reg)); 1159: #endif /* !TME_NO_LOG */ 1160: } 1161: 1162: /* the CSR is the entire page at TME_SUNCG2_REG_CSR: */ 1163: else if (address == TME_SUNCG2_REG_CSR) { 1164: 1165: /* if this is a read: */ 1166: if ((cycle_init->tme_bus_cycle_type & TME_BUS_CYCLE_READ) != 0) { 1167: 1168: /* if it's time to set the retrace bit, set it: */ 1169: if (suncg2->tme_suncg2_cycle_retrace-- == 0) { 1170: suncg2->tme_suncg2_csr |= TME_SUNCG2_CSR_RETRACE; 1171: suncg2->tme_suncg2_cycle_retrace = TME_SUNCG2_CYCLE_RETRACE; 1172: } 1173: 1174: /* otherwise, clear it: */ 1175: else { 1176: suncg2->tme_suncg2_csr &= ~TME_SUNCG2_CSR_RETRACE; 1177: } 1178: } 1179: 1180: /* do the bus cycle: */ 1181: reg_old = suncg2->tme_suncg2_csr; 1182: tme_bus_cycle_xfer_reg(cycle_init, 1183: &suncg2->tme_suncg2_csr, 1184: TME_BUS16_LOG2); 1185: reg_new = suncg2->tme_suncg2_csr; 1186: 1187: /* put back the unchanging bits: */ 1188: reg_new 1189: = ((reg_new 1190: & ~(TME_SUNCG2_CSR_INT_ACTIVE 1191: | TME_SUNCG2_CSR_RETRACE 1192: | 0xff00)) 1193: | (reg_old 1194: & (TME_SUNCG2_CSR_INT_ACTIVE 1195: | TME_SUNCG2_CSR_RETRACE 1196: | 0xff00))); 1197: suncg2->tme_suncg2_csr = reg_new; 1198: 1199: /* log the transfer: */ 1200: tme_log(&suncg2->tme_suncg2_element->tme_element_log_handle, 1201: 100, TME_OK, 1202: (&suncg2->tme_suncg2_element->tme_element_log_handle, 1203: "csr %s 0x%04x", 1204: ((cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) 1205: ? "<-" 1206: : "->"), 1207: reg_new)); 1208: 1209: /* we do not support these bits: */ 1210: if ((reg_new 1211: ^ reg_old) 1212: & TME_SUNCG2_CSR_INT_ENABLE) { 1213: abort(); 1214: } 1215: 1216: /* if the cmap update bit is transitioning from a zero to a one, 1217: we need a mode change: */ 1218: if ((reg_old & TME_SUNCG2_CSR_CMAP_UPDATE) == 0 1219: && (reg_new & TME_SUNCG2_CSR_CMAP_UPDATE) != 0) { 1220: new_callouts |= TME_SUNCG2_CALLOUT_MODE_CHANGE; 1221: } 1222: } 1223: 1224: /* if this is the interrupt vector: */ 1225: else if (address == TME_SUNCG2_REG_INTVEC) { 1226: tme_bus_cycle_xfer_reg(cycle_init, 1227: &suncg2->tme_suncg2_intvec, 1228: TME_BUS16_LOG2); 1229: } 1230: 1231: /* if this is the plane mask: */ 1232: else if (address == TME_SUNCG2_REG_PLANE_MASK) { 1233: 1234: /* do the bus cycle: */ 1235: tme_bus_cycle_xfer_reg(cycle_init, 1236: &suncg2->tme_suncg2_plane_mask, 1237: TME_BUS16_LOG2); 1238: 1239: /* log the transfer: */ 1240: tme_log(&suncg2->tme_suncg2_element->tme_element_log_handle, 1241: 100, TME_OK, 1242: (&suncg2->tme_suncg2_element->tme_element_log_handle, 1243: "plane mask %s 0x%04x", 1244: ((cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) 1245: ? "<-" 1246: : "->"), 1247: suncg2->tme_suncg2_plane_mask)); 1248: } 1249: 1250: /* XXX FIXME - the sun3 PROM zeroes the cg3 DMA base register, 1251: the cg3 double buffer register, the cg3 DMA width register, 1252: and the cg3 frame count registers: */ 1253: else if (address == TME_SUNCG2_REG_SUN3_DMA_BASE 1254: || address == TME_SUNCG2_REG_SUN3_DOUBLE_BUF 1255: || address == TME_SUNCG2_REG_SUN3_DMA_WIDTH 1256: || address == TME_SUNCG2_REG_SUN3_FRAME_COUNT) { 1257: tme_bus_cycle_xfer_reg(cycle_init, 1258: &junk, 1259: TME_BUS16_LOG2); 1260: } 1261: 1262: /* XXX FIXME - this is a partial implementation: */ 1263: else { 1264: abort(); 1265: } 1266: 1267: /* make any new callouts: */ 1268: _tme_suncg2_callout(suncg2, new_callouts); 1269: 1270: /* unlock the mutex: */ 1271: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 1272: 1273: /* no faults: */ 1274: return (TME_OK); 1275: } 1276: 1277: /* the bus cycle handler for the suncg2 colormap registers: */ 1278: static int 1279: _tme_suncg2_bus_cycle_cmap(void *_suncg2, struct tme_bus_cycle *cycle_init) 1280: { 1281: struct tme_suncg2 *suncg2; 1282: 1283: /* recover our data structure: */ 1284: suncg2 = (struct tme_suncg2 *) _suncg2; 1285: 1286: /* lock the mutex: */ 1287: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 1288: 1289: /* run the cycle: */ 1290: tme_bus_cycle_xfer_memory(cycle_init, 1291: (((tme_uint8_t *) suncg2->tme_suncg2_cmap_raw) 1292: - TME_SUNCG2_REG_CMAP_R), 1293: TME_SUNCG2_SIZ_REGS - 1); 1294: 1295: /* if this is a write and colormap updates are enabled, we need to 1296: call out a mode change. we don't make the callout now, assuming 1297: that more writes to the colormap are coming soon. we will 1298: eventually make the callout when the framebuffer updates: */ 1299: if ((cycle_init->tme_bus_cycle_type & TME_BUS_CYCLE_WRITE) 1300: && (suncg2->tme_suncg2_csr 1301: & TME_SUNCG2_CSR_CMAP_UPDATE)) { 1302: suncg2->tme_suncg2_callout_flags |= TME_SUNCG2_CALLOUT_MODE_CHANGE; 1303: } 1304: 1305: /* unlock the mutex: */ 1306: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 1307: 1308: /* no faults: */ 1309: return (TME_OK); 1310: } 1311: 1312: /* the suncg2 TLB filler: */ 1313: static int 1314: _tme_suncg2_tlb_fill(void *_suncg2, struct tme_bus_tlb *tlb, 1315: tme_bus_addr_t address, unsigned int cycles) 1316: { 1317: struct tme_suncg2 *suncg2; 1318: tme_uint8_t *memory; 1319: tme_bus_addr_t address_first; 1320: tme_bus_addr_t address_last; 1321: 1322: /* recover our data structure: */ 1323: suncg2 = (struct tme_suncg2 *) _suncg2; 1324: 1325: /* initialize the TLB entry: */ 1326: tme_bus_tlb_initialize(tlb); 1327: 1328: /* the fast reading and writing rwlock: */ 1329: tlb->tme_bus_tlb_rwlock = &suncg2->tme_suncg2_rwlock; 1330: 1331: /* allow reading and writing: */ 1332: tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE; 1333: 1334: /* our bus cycle handler private data: */ 1335: tlb->tme_bus_tlb_cycle_private = _suncg2; 1336: 1337: /* lock the mutex: */ 1338: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 1339: 1340: /* we require a connection: */ 1341: assert (suncg2->tme_suncg2_fb_connection != NULL); 1342: assert (suncg2->tme_suncg2_displayed_memory != NULL); 1343: 1344: /* if this address falls in a bitmap: */ 1345: if ((TME_SUNCG2_REG_BITMAP(0) 1346: <= address) 1347: && (address 1348: < TME_SUNCG2_REG_BITMAP(TME_SUNCG2_PLANE_MAX))) { 1349: 1350: /* the cycle handler: */ 1351: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_raw; 1352: 1353: /* if we're displaying the pixmap: */ 1354: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 1355: 1356: /* validate the bitmaps: */ 1357: _tme_suncg2_validate_bitmaps(suncg2, tlb); 1358: 1359: /* this TLB entry covers all of the bitmap memory: */ 1360: address_first = TME_SUNCG2_REG_BITMAP(0); 1361: address_last = TME_SUNCG2_REG_PIXMAP - 1; 1362: memory = suncg2->tme_suncg2_raw_memory + address_first; 1363: 1364: /* the displayed memory is now invalid: */ 1365: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_DISPLAYED; 1366: } 1367: 1368: /* otherwise, we're displaying a bitmap: */ 1369: else { 1370: 1371: /* calculate the first and last addresses of the displayed 1372: memory: */ 1373: address_first = TME_SUNCG2_REG_BITMAP(suncg2->tme_suncg2_bitmap_mode_plane); 1374: address_last = address_first + (suncg2->tme_suncg2_pixel_count / 8) - 1; 1375: 1376: /* if this address is before the displayed memory, this TLB 1377: entry covers from the beginning of the bitmap memory up to 1378: the displayed memory: */ 1379: if (address < address_first) { 1380: address_last = address_first - 1; 1381: address_first = TME_SUNCG2_REG_BITMAP(0); 1382: memory = suncg2->tme_suncg2_raw_memory + address_first; 1383: 1384: /* validate the bitmaps: */ 1385: _tme_suncg2_validate_bitmaps(suncg2, tlb); 1386: } 1387: 1388: /* otherwise, if this address is after the displayed memory, 1389: this TLB entry covers from right after the displayed memory 1390: to the end of the bitmap memory: */ 1391: else if (address > address_last) { 1392: address_first = address_last + 1; 1393: address_last = TME_SUNCG2_REG_PIXMAP - 1; 1394: memory = suncg2->tme_suncg2_raw_memory + address_first; 1395: 1396: /* validate the bitmaps: */ 1397: _tme_suncg2_validate_bitmaps(suncg2, tlb); 1398: } 1399: 1400: /* otherwise, this address is in the displayed memory: */ 1401: else { 1402: memory = suncg2->tme_suncg2_displayed_memory; 1403: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_displayed; 1404: 1405: /* validate the displayed memory: */ 1406: _tme_suncg2_validate_displayed(suncg2, tlb); 1407: } 1408: } 1409: 1410: /* the address range: */ 1.1.1.2 ! root 1411: tlb->tme_bus_tlb_addr_first = address_first; ! 1412: tlb->tme_bus_tlb_addr_last = address_last; 1.1 root 1413: 1414: /* this TLB entry allows fast reading and fast writing: */ 1415: tlb->tme_bus_tlb_emulator_off_read = memory - address_first; 1416: tlb->tme_bus_tlb_emulator_off_write = memory - address_first; 1417: 1418: /* add this TLB entry: */ 1419: _tme_suncg2_tlb_add(suncg2, tlb); 1420: 1421: /* the pixmap is now invalid: */ 1422: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_PIXMAP; 1423: } 1424: 1425: /* if this address falls in the pixmap: */ 1426: else if ((TME_SUNCG2_REG_PIXMAP 1427: <= address) 1428: && (address 1429: < (TME_SUNCG2_REG_PIXMAP + TME_SUNCG2_SIZ_PIXMAP))) { 1430: 1431: /* the cycle handler: */ 1432: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_raw; 1433: 1434: /* if we're displaying the pixmap: */ 1435: if (suncg2->tme_suncg2_bitmap_mode_plane == TME_SUNCG2_PLANE_MAX) { 1436: 1437: /* calculate the first and last addresses of the displayed memory: */ 1438: address_first = TME_SUNCG2_REG_PIXMAP; 1439: address_last = TME_SUNCG2_REG_PIXMAP + suncg2->tme_suncg2_pixel_count - 1; 1440: 1441: /* if this address is after the displayed memory, we're in the pad: */ 1442: if (address > address_last) { 1443: address_first = address_last + 1; 1444: address_last = TME_SUNCG2_REG_PIXMAP + TME_SUNCG2_SIZ_PIXMAP - 1; 1445: memory = suncg2->tme_suncg2_raw_memory + address_first; 1446: 1447: /* validate the pixmap: */ 1448: _tme_suncg2_validate_pixmap(suncg2, tlb); 1449: } 1450: 1451: /* otherwise, this address is in the displayed memory: */ 1452: else { 1453: memory = suncg2->tme_suncg2_displayed_memory; 1454: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_displayed; 1455: 1456: /* validate the displayed memory: */ 1457: _tme_suncg2_validate_displayed(suncg2, tlb); 1458: } 1459: } 1460: 1461: /* otherwise, we're displaying a bitmap: */ 1462: else { 1463: 1464: /* validate the pixmap: */ 1465: _tme_suncg2_validate_pixmap(suncg2, tlb); 1466: 1467: /* this TLB covers all of pixmap memory: */ 1468: address_first = TME_SUNCG2_REG_PIXMAP; 1469: address_last = TME_SUNCG2_REG_PIXMAP + TME_SUNCG2_SIZ_PIXMAP - 1; 1470: memory = suncg2->tme_suncg2_raw_memory + address_first; 1471: 1472: /* the displayed memory is now invalid: */ 1473: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_DISPLAYED; 1474: } 1475: 1476: /* the address range: */ 1.1.1.2 ! root 1477: tlb->tme_bus_tlb_addr_first = address_first; ! 1478: tlb->tme_bus_tlb_addr_last = address_last; 1.1 root 1479: 1480: /* this TLB entry allows fast reading and fast writing: */ 1481: tlb->tme_bus_tlb_emulator_off_read = memory - address_first; 1482: tlb->tme_bus_tlb_emulator_off_write = memory - address_first; 1483: 1484: /* add this TLB entry: */ 1485: _tme_suncg2_tlb_add(suncg2, tlb); 1486: 1487: /* the bitmaps are now invalid: */ 1488: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_BITMAPS; 1489: } 1490: 1491: /* if this address falls in the rasterop data: */ 1492: else if ((TME_SUNCG2_REG_ROP_DATA 1493: <= address) 1494: && (address 1495: < TME_SUNCG2_REG_ROPC_UNIT(0))) { 1496: 1497: /* the cycle handler: */ 1498: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_rop_data; 1499: 1500: /* this TLB entry covers this range: */ 1.1.1.2 ! root 1501: tlb->tme_bus_tlb_addr_first = TME_SUNCG2_REG_ROP_DATA; ! 1502: tlb->tme_bus_tlb_addr_last = (TME_SUNCG2_REG_ROPC_UNIT(0) - 1); 1.1 root 1503: 1504: /* this TLB entry cannot allow fast reading or fast writing, since 1505: this is the rasterop data: */ 1506: } 1507: 1508: /* if this address falls in the registers: */ 1509: else if ((TME_SUNCG2_REG_ROPC_UNIT(0) 1510: <= address) 1511: && (address 1512: < TME_SUNCG2_REG_CMAP_R)) { 1513: 1514: /* the cycle handler: */ 1515: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_regs; 1516: 1517: /* this TLB entry covers this range: */ 1.1.1.2 ! root 1518: tlb->tme_bus_tlb_addr_first = TME_SUNCG2_REG_ROPC_UNIT(0); ! 1519: tlb->tme_bus_tlb_addr_last = (TME_SUNCG2_REG_CMAP_R - 1); 1.1 root 1520: 1521: /* this TLB entry cannot allow fast reading or fast writing, since 1522: these are registers: */ 1523: } 1524: 1525: /* if this address falls in the colormap registers: */ 1526: else if ((TME_SUNCG2_REG_CMAP_R 1527: <= address) 1528: && (address 1529: <= (TME_SUNCG2_SIZ_REGS 1530: - 1))) { 1531: 1532: /* the cycle handler: */ 1533: tlb->tme_bus_tlb_cycle = _tme_suncg2_bus_cycle_cmap; 1534: 1535: /* this TLB entry covers this range: */ 1.1.1.2 ! root 1536: tlb->tme_bus_tlb_addr_first = TME_SUNCG2_REG_CMAP_R; ! 1537: tlb->tme_bus_tlb_addr_last = TME_SUNCG2_SIZ_REGS - 1; 1.1 root 1538: 1539: /* this TLB entry allows fast reading: */ 1540: tlb->tme_bus_tlb_emulator_off_read 1541: = (((tme_uint8_t *) suncg2->tme_suncg2_cmap_raw) 1542: - TME_SUNCG2_REG_CMAP_R); 1543: } 1544: 1545: /* XXX FIXME - this is a partial implementation: */ 1546: else { 1547: abort(); 1548: } 1549: 1550: /* unlock the mutex: */ 1551: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 1552: 1553: return (TME_OK); 1554: } 1555: 1556: /* this makes a new framebuffer connection: */ 1557: static int 1558: _tme_suncg2_connection_make(struct tme_connection *conn, unsigned int state) 1559: { 1560: struct tme_suncg2 *suncg2; 1561: struct tme_fb_connection *conn_fb; 1562: struct tme_fb_connection *conn_fb_other; 1563: int rc; 1564: 1565: /* recover our data structures: */ 1566: suncg2 = conn->tme_connection_element->tme_element_private; 1567: conn_fb = (struct tme_fb_connection *) conn; 1568: conn_fb_other = (struct tme_fb_connection *) conn->tme_connection_other; 1569: 1570: /* both sides must be framebuffer connections: */ 1571: assert(conn->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); 1572: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); 1573: 1574: /* lock our mutex: */ 1575: tme_mutex_lock(&suncg2->tme_suncg2_mutex); 1576: 1577: /* once the connection is made, we know whether or not the other 1578: side of the connection is supplying specific memory that it wants 1579: us to use, or if we should allocate memory ourselves: */ 1580: if (conn_fb->tme_fb_connection_buffer == NULL) { 1581: rc = tme_fb_xlat_alloc_src(conn_fb); 1582: assert (rc == TME_OK); 1583: } 1584: suncg2->tme_suncg2_displayed_memory = conn_fb->tme_fb_connection_buffer; 1585: 1586: /* invalidate any outstanding TLBs: */ 1587: _tme_suncg2_tlb_invalidate(suncg2, NULL); 1588: 1589: /* the displayed memory is now invalid: */ 1590: suncg2->tme_suncg2_flags |= TME_SUNCG2_FLAG_INVALID_DISPLAYED; 1591: 1592: /* we're always set up to answer calls across the connection, so we 1593: only have to do work when the connection has gone full, namely 1594: taking the other side of the connection: */ 1595: if (state == TME_CONNECTION_FULL) { 1596: 1597: /* save our connection: */ 1598: suncg2->tme_suncg2_fb_connection = conn_fb_other; 1599: } 1600: 1601: /* unlock our mutex: */ 1602: tme_mutex_unlock(&suncg2->tme_suncg2_mutex); 1603: 1604: return (TME_OK); 1605: } 1606: 1607: /* this breaks a connection: */ 1608: static int 1609: _tme_suncg2_connection_break(struct tme_connection *conn, unsigned int state) 1610: { 1611: abort(); 1612: } 1613: 1614: /* this makes a new connection side for a suncg2: */ 1615: static int 1616: _tme_suncg2_connections_new(struct tme_element *element, 1617: const char * const *args, 1618: struct tme_connection **_conns, 1619: char **_output) 1620: { 1621: struct tme_suncg2 *suncg2; 1622: struct tme_fb_connection *conn_fb; 1623: struct tme_connection *conn; 1624: int rc; 1625: 1626: /* recover our data structure: */ 1627: suncg2 = (struct tme_suncg2 *) element->tme_element_private; 1628: 1629: /* make the generic bus device connection side: */ 1630: rc = tme_bus_device_connections_new(element, args, _conns, _output); 1631: if (rc != TME_OK) { 1632: return (rc); 1633: } 1634: 1635: /* if we don't have a framebuffer connection, make one: */ 1636: if (suncg2->tme_suncg2_fb_connection == NULL) { 1637: 1638: /* allocate the new framebuffer connection: */ 1639: conn_fb = tme_new0(struct tme_fb_connection, 1); 1640: conn = &conn_fb->tme_fb_connection; 1641: 1642: /* fill in the generic connection: */ 1643: conn->tme_connection_next = *_conns; 1644: conn->tme_connection_type = TME_CONNECTION_FRAMEBUFFER; 1645: conn->tme_connection_score = tme_fb_connection_score; 1646: conn->tme_connection_make = _tme_suncg2_connection_make; 1647: conn->tme_connection_break = _tme_suncg2_connection_break; 1648: 1649: /* fill in the framebuffer connection: */ 1650: conn_fb->tme_fb_connection_mode_change = NULL; 1651: conn_fb->tme_fb_connection_update = _tme_suncg2_update; 1652: 1653: /* height and width: */ 1.1.1.2 ! root 1654: conn_fb->tme_fb_connection_width = tme_sunfb_size_width(suncg2->tme_suncg2_size); ! 1655: conn_fb->tme_fb_connection_height = tme_sunfb_size_height(suncg2->tme_suncg2_size); 1.1 root 1656: 1657: /* we are color: */ 1658: conn_fb->tme_fb_connection_class = TME_FB_XLAT_CLASS_COLOR; 1659: conn_fb->tme_fb_connection_depth = TME_SUNCG2_PLANE_MAX; 1660: conn_fb->tme_fb_connection_bits_per_pixel = TME_SUNCG2_PLANE_MAX; 1661: 1662: /* we skip no pixels at the start of the scanline: */ 1663: conn_fb->tme_fb_connection_skipx = 0; 1664: 1665: /* we pad to 32-bit boundaries: */ 1666: conn_fb->tme_fb_connection_scanline_pad = 32; 1667: 1668: /* we are big-endian: */ 1669: conn_fb->tme_fb_connection_order = TME_ENDIAN_BIG; 1670: 1671: /* we don't allocate memory until the connection is made, in case 1672: the other side of the connection wants to provide us with a 1673: specific memory region to use (maybe we're on a system with a 1674: real cgtwo and we can write directly to its buffer): */ 1675: conn_fb->tme_fb_connection_buffer = NULL; 1676: 1677: /* our pixels don't have subfields: */ 1678: conn_fb->tme_fb_connection_mask_g = 0; 1679: conn_fb->tme_fb_connection_mask_r = 0; 1680: conn_fb->tme_fb_connection_mask_b = 0; 1681: 1682: /* intensities are eight bits and index mapped: */ 1683: conn_fb->tme_fb_connection_map_bits = (8 * sizeof(suncg2->tme_suncg2_cmap[0])); 1684: conn_fb->tme_fb_connection_map_g = &suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_G)]; 1685: conn_fb->tme_fb_connection_map_r = &suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_R)]; 1686: conn_fb->tme_fb_connection_map_b = &suncg2->tme_suncg2_cmap[TME_SUNCG2_CMAP_INDEX(0, TME_SUNCG2_REG_CMAP_B)]; 1687: 1688: /* return the connection side possibility: */ 1689: *_conns = conn; 1690: } 1691: 1692: /* done: */ 1693: return (TME_OK); 1694: } 1695: 1696: /* the new sun cgtwo function: */ 1697: int 1698: tme_sun_cgtwo(struct tme_element *element, const char * const *args, char **_output) 1699: { 1700: struct tme_suncg2 *suncg2; 1701: tme_uint32_t cg2_type; 1702: tme_uint32_t cg2_size; 1703: int arg_i; 1704: int usage; 1705: 1706: /* check our arguments: */ 1707: usage = 0; 1708: cg2_type = TME_SUNCG2_TYPE_NULL; 1.1.1.2 ! root 1709: cg2_size = TME_SUNFB_SIZE_1152_900; 1.1 root 1710: arg_i = 1; 1711: for (;;) { 1712: 1713: /* the framebuffer type: */ 1714: if (TME_ARG_IS(args[arg_i + 0], "type")) { 1715: if (TME_ARG_IS(args[arg_i + 1], "sun3")) { 1716: cg2_type = TME_SUNCG2_TYPE_SUN3; 1717: } 1718: else { 1719: usage = TRUE; 1720: break; 1721: } 1722: arg_i += 2; 1723: } 1724: 1725: /* the framebuffer size: */ 1726: else if (TME_ARG_IS(args[arg_i + 0], "size")) { 1.1.1.2 ! root 1727: cg2_size = tme_sunfb_size(args[arg_i + 1]); ! 1728: if (cg2_size != TME_SUNFB_SIZE_1152_900 ! 1729: && cg2_size != TME_SUNFB_SIZE_1024_1024) { 1.1 root 1730: usage = TRUE; 1731: break; 1732: } 1733: arg_i += 2; 1734: } 1735: 1736: /* if we ran out of arguments: */ 1737: else if (args[arg_i] == NULL) { 1738: break; 1739: } 1740: 1741: /* otherwise this is a bad argument: */ 1742: else { 1743: tme_output_append_error(_output, 1744: "%s %s, ", 1745: args[arg_i], 1746: _("unexpected")); 1747: usage = TRUE; 1748: break; 1749: } 1750: } 1751: 1752: /* a cgtwo type must have been given: */ 1753: if (cg2_type == TME_SUNCG2_TYPE_NULL) { 1754: usage = TRUE; 1755: } 1756: 1757: if (usage) { 1758: tme_output_append_error(_output, 1759: "%s %s type sun3 [ size { 1152x900 | 1024x1024 } ]", 1760: _("usage:"), 1761: args[0]); 1762: return (EINVAL); 1763: } 1764: 1765: /* start the suncg2 structure: */ 1766: suncg2 = tme_new0(struct tme_suncg2, 1); 1767: suncg2->tme_suncg2_element = element; 1768: tme_mutex_init(&suncg2->tme_suncg2_mutex); 1769: tme_rwlock_init(&suncg2->tme_suncg2_rwlock); 1770: 1771: /* set the cgtwo type: */ 1772: suncg2->tme_suncg2_type = cg2_type; 1773: 1774: /* set the cgtwo size: */ 1775: suncg2->tme_suncg2_size = cg2_size; 1776: 1777: /* start displaying the pixmap: */ 1778: suncg2->tme_suncg2_bitmap_mode_plane = TME_SUNCG2_PLANE_MAX; 1779: 1780: /* set our initial CSR: */ 1781: suncg2->tme_suncg2_csr 1782: = (TME_SUNCG2_CSR_ENABLE_VIDEO 1.1.1.2 ! root 1783: | (cg2_size == TME_SUNFB_SIZE_1024_1024 1.1 root 1784: ? TME_SUNCG2_CSR_SIZE_1024_1024 1785: : TME_SUNCG2_CSR_SIZE_1152_900)); 1786: 1787: /* if this is a sun3 cgtwo: */ 1788: if (cg2_type == TME_SUNCG2_TYPE_SUN3) { 1789: /* nothing to do */ 1790: } 1791: 1792: /* calculate the pixel count: */ 1793: suncg2->tme_suncg2_pixel_count 1.1.1.2 ! root 1794: = (tme_sunfb_size_width(cg2_size) ! 1795: * tme_sunfb_size_height(cg2_size)); 1.1 root 1796: 1797: /* allocate the raw memory: */ 1798: suncg2->tme_suncg2_raw_memory 1799: = tme_new0(tme_uint8_t, TME_SUNCG2_REG_PIXMAP + TME_SUNCG2_SIZ_PIXMAP); 1800: 1801: /* initialize our simple bus device descriptor: */ 1802: suncg2->tme_suncg2_device.tme_bus_device_element = element; 1803: suncg2->tme_suncg2_device.tme_bus_device_tlb_fill = _tme_suncg2_tlb_fill; 1804: suncg2->tme_suncg2_device.tme_bus_device_address_last = TME_SUNCG2_SIZ_REGS - 1; 1805: 1806: /* fill the element: */ 1807: element->tme_element_private = suncg2; 1808: element->tme_element_connections_new = _tme_suncg2_connections_new; 1809: 1810: return (TME_OK); 1811: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.