Beispiel #1
0
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 );
	}
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}