static void handle_request( struct imt_rpc_req *req ) { DBG2("imt: req: id %4d cmd %X len %3d par %08X rsp %08X", req->id, req->cmd, req->len, req->par, req->rsp ); if( req->cmd == IMT_CONNECTED ) { DBG("imt: CONNECTED: %02X", req->rsp); // no need to reply return; } else if( req->cmd == IMT_TRACE ) { DBG2("imt: TRACE: %d", req->par); output_trace(req->data); // TRACE does not respond! // reply( req, IMT_TRACED, 16, req->par ); } else if( req->cmd == IMT_MALLOC ) { uint32_t data = 0; DBG2("imt: MALLOC: %d", req->par); #if defined(CONFIG_ION_OMAP) data = tiler_alloc( req->par ); #endif reply( req, IMT_MALLOCED, 16, data ); } else if( req->cmd == IMT_FREE ) { DBG2("imt: FREE: %08X", req->par); #if defined(CONFIG_ION_OMAP) tiler_free( req->par ); #endif reply( req, IMT_FREED, 16, req->par ); } else { // we dont know that command ERR("imt: CONFUSED!: %X", req->cmd); reply( req, IMT_CONFUSED, 16, req->par ); } }
/** * Alloc Tiler Buffer for HDMI */ int AllocTilerForHdmi(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_DEVINFO *psDevInfo) { unsigned long w, h; unsigned long line_length; int err; if ( psSwapChain->stHdmiTiler.alloc ) return 0; w = psDevInfo->sFBInfo.ulWidth; { struct fb_fix_screeninfo *fix = &psDevInfo->psLINFBInfo->fix; h = fix->smem_len / fix->line_length; } if ( psSwapChain->stHdmiTiler.overlay==NULL ) { ERROR_PRINTK("Get HDMI Overlay fail\n"); return -EINVAL; } if ( psDevInfo->sFBInfo.ePixelFormat!= PVRSRV_PIXEL_FORMAT_ARGB8888 ) { ERROR_PRINTK("Allocated Bufffer is Not ARG32\n"); return -EINVAL; } line_length = ALIGN(w*4, PAGE_SIZE); w = line_length / 4; //alloc tiler #ifdef CONFIG_HDMI_DMA_COPY err = tiler_alloc(TILFMT_32BIT, w, 800*3, (u32 *)&psSwapChain->stHdmiTiler.pAddr ); if ( err ) { ERROR_PRINTK("Allocation Tiler Memory Failed\n"); return -ENOMEM; } #else err = tiler_alloc(TILFMT_32BIT, w,h, (u32 *)&psSwapChain->stHdmiTiler.pAddr ); if ( err ) { ERROR_PRINTK("Allocation Tiler Memory Failed\n"); return -ENOMEM; } #endif psSwapChain->stHdmiTiler.vStride = line_length; psSwapChain->stHdmiTiler.pStride = tiler_stride( tiler_get_natural_addr((void*)psSwapChain->stHdmiTiler.pAddr) ); psSwapChain->stHdmiTiler.pSize = psSwapChain->stHdmiTiler.pStride * h; psSwapChain->stHdmiTiler.vAddr = __arm_multi_strided_ioremap(1, (unsigned long*)&psSwapChain->stHdmiTiler.pAddr, &psSwapChain->stHdmiTiler.pSize, &psSwapChain->stHdmiTiler.pStride, &psSwapChain->stHdmiTiler.vStride, MT_DEVICE_WC); if ( psSwapChain->stHdmiTiler.vAddr == NULL ) { ERROR_PRINTK("Tiler Memory remap Failed\n"); tiler_free(psSwapChain->stHdmiTiler.pAddr); return -ENOMEM; } psSwapChain->stHdmiTiler.alloc = true; DEBUG_PRINTK("Tiler Setup Success pAddr:0x%x, pStride:%d, pSize:%d, vAddr:0x%x, vStride:%d, h:%d\n", psSwapChain->stHdmiTiler.pAddr, psSwapChain->stHdmiTiler.pStride, psSwapChain->stHdmiTiler.pSize, psSwapChain->stHdmiTiler.vAddr, psSwapChain->stHdmiTiler.vStride, h); // { // //initial setup overlay info // struct omap_overlay *overlay; // struct omap_overlay_info info; // overlay = psSwapChain->stHdmiTiler.overlay; // overlay->get_overlay_info(overlay, &info); // // info.color_mode = OMAP_DSS_COLOR_ARGB32; // info.rotation_type = OMAP_DSS_ROT_TILER; // // info.paddr = psSwapChain->stHdmiTiler.pAddr; // info.vaddr = NULL; // // info.rotation = 0; // // info.width = psDevInfo->sFBInfo.ulWidth; // info.height = psDevInfo->sFBInfo.ulHeight; // // info.pos_x = 0; // info.pos_y = 0; // info.out_width = info.width; // info.out_height = info.height; // // if ( overlay->set_overlay_info(overlay, &info) ) // { // ERROR_PRINTK("Initial overlay1 setup failed\n"); // return; // } // } return 0; }
void tiler_alloc_packed(s32 *count, enum tiler_fmt fmt, u32 width, u32 height, void **sysptr, void **allocptr, s32 aligned) { int til_width, bpp, bpt, buf_width, alloc_width, map_width; int buf_map_width, n_per_m, m_per_a, i = 0, m, n; /* Check input parameters for correctness */ if (!width || !height || !sysptr || !allocptr || !count || *count <= 0 || fmt < TILFMT_8BIT || fmt > TILFMT_32BIT) { if (count) *count = 0; return; } /* tiler page width in pixels, bytes per pixel, tiler page in bytes */ til_width = fmt == TILFMT_32BIT ? 32 : 64; bpp = 1 << (fmt - TILFMT_8BIT); bpt = til_width * bpp; /* width of buffer in tiled pages */ buf_width = DIVIDE_UP(width, til_width); /* :TODO: for now tiler allocation width is 64-multiple */ alloc_width = ROUND_UP_2P(buf_width, 64); map_width = TILER_PAGE / bpt; /* ensure alignment if needed */ buf_map_width = ROUND_UP_2P(buf_width, map_width); /* number of buffers in a map window */ n_per_m = aligned ? 1 : (buf_map_width / buf_width); /* number of map windows per allocation */ m_per_a = alloc_width / buf_map_width; printk(KERN_INFO "packing %d*%d buffers into an allocation\n", n_per_m, m_per_a); while (i < *count) { /* allocate required width of a frame to fit remaining frames */ int n_alloc, m_alloc, tiles, res; void *base; n_alloc = MIN(*count - i, m_per_a * n_per_m); m_alloc = DIVIDE_UP(n_alloc, n_per_m); tiles = ((m_alloc - 1) * map_width + buf_width * (n_alloc - (m_alloc - 1) * n_per_m)); res = tiler_alloc(fmt, til_width * tiles, height, (u32 *)sysptr + i); if (res != 0) break; /* mark allocation */ base = allocptr[i] = sysptr[i]; i++; /* portion out remaining buffers */ for (m = 0; m < m_per_a; m++, base += bpt * buf_map_width) { for (n = 0; n < n_per_m; n++) { /* first buffer is already allocated */ if (n + m == 0) continue; /* stop if we are done */ if (i == *count) break; /* set buffer address */ sysptr[i] = base + bpt * n * buf_width; allocptr[i++] = NULL; } } } /* mark how many buffers we allocated */ *count = i; }
void tiler_alloc_packed_nv12(s32 *count, u32 width, u32 height, void **y_sysptr, void **uv_sysptr, void **y_allocptr, void **uv_allocptr, s32 aligned) { /* optimized packing table */ /* we read this table from beginning to end, and determine whether the optimization meets our requirement (e.g. allocating at least i buffers, with max w y-width, and alignment a. If not, we get to the next element. Otherwise we do the allocation. The table is constructed in such a way that if an interim tiler allocation fails, the next matching rule for the scenario will be able to use the buffers already allocated. */ #define MAX_BUFS_TO_PACK 3 void *buf[MAX_BUFS_TO_PACK]; int n_buf, buf_w[MAX_BUFS_TO_PACK]; char packing[] = { /* min(i), max(w), aligned, buffers to alloc */ 5, 16, 0, 2, /* buffer widths in a + b * w(y) + c * w(uv) */ 64, 0, 0, 64, 0, 0, /* tiler-page offsets in a + b * w(y) + c * w(uv) */ 0, 0, 0, 32, 0, 0, 16, 0, 0, 40, 0, 0, 64, 0, 0, 96, 0, 0, 80, 0, 0, 104, 0, 0, 112, 0, 0, 56, 0, 0, 2, 16, 0, 1, 32, 0, 2, 0, 0, 0, 32, 0, 0, 0, 0, 2, 32, 0, 1, 2, 20, 0, 1, 42, 1, 0, 0, 0, 0, 32, 0, 0, 42, 0, 0, 21, 0, 0, 3, 24, 0, 2, 48, 0, 1, 32, 1, 0, 0, 0, 0, 64, 0, 0, 24, 0, 0, 76, 0, 0, 96, 0, 0, 48, 0, 0, 4, 32, 0, 3, 48, 0, 1, 32, 1, 0, 32, 1, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 48, 0, 0, 64, 0, 0, 128, 0, 0, 160, 0, 0, 144, 0, 0, /* this is needed for soft landing if prior allocation fails after two buffers */ 2, 32, 1, 2, 32, 0, 1, 32, 0, 1, 0, 0, 0, 32, 0, 0, 64, 0, 0, 96, 0, 0, 1, 32, 1, 1, 32, 0, 1, 0, 0, 0, 32, 0, 0, 2, 64, 1, 3, 0, 1, 0, 32, 0, 1, 0, 1, 0, 0, 0, 0, 64, 0, 0, 128, 0, 0, 96, 0, 0, /* this is the basic NV12 allocation using 2 buffers */ 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0 }; int y_width, uv_width, i = 0; /* Check input parameters for correctness */ if (!width || !height || !y_sysptr || !y_allocptr || !count || !uv_sysptr || !uv_allocptr || *count <= 0) { if (count) *count = 0; return; } y_width = DIVIDE_UP(width, 64); uv_width = DIVIDE_UP(width >> 1, 64); while (i < *count) { int n_alloc = *count - i; char *p = packing; n_buf = 0; /* skip packings that do not apply */ while (*p) { /* see if this packing applies */ if (p[0] <= n_alloc && (!p[1] || p[1] >= y_width) && (!aligned || p[2])) { /* allocate buffers */ while (n_buf < p[3]) { buf_w[n_buf] = p[4 + 3 * n_buf] + y_width * p[5 + 3 * n_buf] + uv_width * p[6 + 3 * n_buf]; if (0 != tiler_alloc( TILFMT_8BIT, buf_w[n_buf] * 64, height, (u32 *)buf + n_buf)) break; n_buf++; } /* if successfully allocated buffers */ if (n_buf >= p[3]) { i = layout_packed_nv12(p + 4 + 3 * p[3], y_width, uv_width, buf, 2 * p[0], i, y_sysptr, uv_sysptr, y_allocptr, uv_allocptr); break; } } p += 4 + 3 * p[3] + 6 * p[0]; } /* if allocation failed free any outstanding buffers and stop */ if (!*p) { while (n_buf > 0) tiler_free((unsigned long)(buf[--n_buf])); break; } } /* mark how many buffers we allocated */ *count = i; }