void FreeTilerForHdmi(OMAPLFB_SWAPCHAIN *psSwapChain) { if(psSwapChain->stHdmiTiler.alloc != true) return; //disable HDMI Layer first { struct omap_overlay_info info; struct omap_overlay *hdmi; struct omap_overlay_manager *manager; hdmi = psSwapChain->stHdmiTiler.overlay; manager = hdmi->manager; hdmi->get_overlay_info(hdmi, &info); if ( info.enabled ) { info.enabled = false; info.paddr = 0; info.vaddr = NULL; //no need hdmi_video_prepare_change(psSwapChain, 0, false, "Free HDMI Tiler Memory"); if ( hdmi->set_overlay_info(hdmi, &info) ) ERROR_PRINTK("Set HDMI Overlay setting failed"); if (manager) { manager->apply(manager); } hdmi_video_commit_change(psSwapChain); mdelay(100); // WaitForVsyncOfHDMI } } //unmap if ( psSwapChain->stHdmiTiler.vAddr!=NULL ) { iounmap(psSwapChain->stHdmiTiler.vAddr); psSwapChain->stHdmiTiler.vAddr= NULL; } //tiler free if ( psSwapChain->stHdmiTiler.pAddr!=0 ) { tiler_free(psSwapChain->stHdmiTiler.pAddr); psSwapChain->stHdmiTiler.pAddr = 0; } psSwapChain->stHdmiTiler.alloc = false; }
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_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; }