⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbus.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
			// Wait for MBUS interface			if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_R1_CMD)))				goto exit_mbus_read_dram;			gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_ADD, addr);			gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_CNT, mbus_size);			if (xfer_dma_size == mbus_size)				gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_CMD, MBUS_LINEAR_VOID);			else				gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_CMD, MBUS_LINEAR);							addr += mbus_size;			xfer_dma_size -= mbus_size;		}							offset = (offset + half_dma_size) & (dma_size - 1); // dma_size is a power of 2		dmacpy_read_data(pdmacpy, offset, data, old_read_size);		data += old_read_size;		// Wait for MBUS interface		if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_R1_CMD)))			goto exit_mbus_read_dram;				// Wait for PCI Master		if ((status = wait_for_pci(pgbus, REG_BASE_host_interface+WRITE_ENABLE, REG_BASE_host_interface+WRITE_COUNTER)))			goto exit_mbus_read_dram;	}	offset = (offset + half_dma_size) & (dma_size - 1); // dma_size is a power of 2	dmacpy_read_data(pdmacpy, offset, data, read_size); exit_mbus_read_dram:	dmacpy_close(pdmacpy);	gbus_close(pgbus);	return status;} RMint32 mbus_write_picture(struct llad *pllad, RMuint32 addr, RMuint8 *data, RMuint16 x, RMuint16 y, RMuint32 buffer_width, RMuint8 xfer_mode, RMuint32 max_pci_size){	RMuint32 pci_size, xfer_size = 0;    	RMuint32 dma_size, dma_bus_address, half_dma_size, offset;	RMuint32 skip;	RMint32 status = 0;	struct gbus *pgbus;	struct dmacpy *pdmacpy;	if (max_pci_size > 65532) {		RMDBGLOG((MBUSDBG, "bad value for max_pci_size %lu\n", max_pci_size));		return max_pci_size;	}	pgbus = gbus_open(pllad);	pdmacpy = dmacpy_open(pllad);	dmacpy_get_info(pdmacpy, &dma_size, &dma_bus_address);	half_dma_size = dma_size / 2;	offset = 0;	// Wait for MBUS interface	if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_W1_CMD)))		goto exit_mbus_write_picture;	// Wait for PCI Master	if ((status = wait_for_pci(pgbus, REG_BASE_host_interface+READ_ENABLE, REG_BASE_host_interface+READ_COUNTER)))		goto exit_mbus_write_picture;	// Program the switchbox	hostsbox_pcimaster_channel1(pgbus);	// Program endianness (0 on little-endian systems, 1 on big-endian systems)	gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_REVERSE, 0x0);	if (xfer_mode)		skip = ((buffer_width / 128) - 1) | 0x10000;	else		skip = buffer_width;	gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_W1_ADD, addr);	gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_W1_CNT, x + (y << 16));	gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_W1_SKIP, skip);	gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_W1_CMD, MBUS_RECTANGLE_VOID | xfer_mode);	pci_size = x * y;	while (pci_size > 0) {		if (xfer_size == 0) {			xfer_size = RMmin(max_pci_size, RMmin(half_dma_size, pci_size));			dmacpy_write_data(pdmacpy, offset, data, xfer_size);		}		// PCI Master side		status = get_pci_status(pgbus, REG_BASE_host_interface+READ_COUNTER);		if (status == 0) {			gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_ENABLE, 0);			gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_ADDRESS, dma_bus_address + offset);			gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_COUNTER, xfer_size);			gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_ENABLE, 1);			data += xfer_size;			pci_size -= xfer_size;			offset = (offset + half_dma_size) & (dma_size - 1); // dma_size is a power of 2			xfer_size = 0;		}		else if (status < 0)			goto exit_mbus_write_picture;			}	// Wait for the void command to be executed to ensure	// all the data has been written to DRAM.	if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_W1_CMD)))		goto exit_mbus_write_picture;	gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_W1_CMD, 0); // reset tiled mode	// Wait for PCI to finish	if ((status = wait_for_pci(pgbus, REG_BASE_host_interface+READ_ENABLE, REG_BASE_host_interface+READ_COUNTER)))		goto exit_mbus_write_picture; exit_mbus_write_picture:	dmacpy_close(pdmacpy);	gbus_close(pgbus);	return status;}RMint32 mbus_read_picture (struct llad *pllad, RMuint32 addr, RMuint8 *data, RMuint16 x, RMuint16 y, RMuint32 buffer_width, RMuint8 tiled_xfer, RMuint32 max_pci_size){	RMuint32 pci_size = 0;	RMuint32 line_read = 0;	RMuint32 dma_size, dma_bus_address, half_dma_size, offset;	RMuint32 skip;	RMuint16 x_xfer;	RMuint32 i, j;	RMint32 status = 0;	RMuint32 cur_address;	RMuint32 cur_y;	RMuint32 max_line_count;	struct gbus *pgbus;	struct dmacpy *pdmacpy;	RMuint32 base_addr;	if ((max_pci_size % 4) || (max_pci_size > 65532)) {		RMDBGLOG((MBUSDBG, "bad value for max_pci_size %lu\n", max_pci_size));		return max_pci_size;	}	if ((x == 0) || (y == 0))		return 1;		pgbus = gbus_open(pllad);	pdmacpy = dmacpy_open(pllad);	dmacpy_get_info(pdmacpy, &dma_size, &dma_bus_address);	half_dma_size = dma_size / 2;	offset = 0;#if (EM86XX_CHIP < EM86XX_CHIPID_TANGO15)	// read size must be a multiple of 4 on mambo/tango	x_xfer = (x + 3) & ~3;#else	x_xfer = x;#endif	max_pci_size = RMmin(max_pci_size,half_dma_size);	if (max_pci_size < x_xfer) {		RMDBGLOG((MBUSDBG, "max_pci_size [%lu] must be large enough to transfer one line of [%lu] bytes each\n", max_pci_size,x));		status = max_pci_size; 		goto exit_mbus_read_picture;	}	max_line_count = max_pci_size / x_xfer;	// Wait for MBUS interface	if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_R1_CMD)))		goto exit_mbus_read_picture;	// Wait for PCI Master	if ((status = wait_for_pci(pgbus, REG_BASE_host_interface+WRITE_ENABLE, REG_BASE_host_interface+WRITE_COUNTER)))		goto exit_mbus_read_picture;	// Program the switchbox	hostsbox_pcimaster_channel1(pgbus);	// Program endianness (0 on little-endian systems, 1 on big-endian systems)	gbus_write_uint32(pgbus, REG_BASE_host_interface+READ_REVERSE, 0x0);	if (tiled_xfer) 		skip = ((buffer_width / 128) - 1) | 0x10000;	else		skip = buffer_width;	j = y;	if (tiled_xfer) {		/* get the curt line in the tile and compute base_addr */		cur_y = (addr/128) % 32; 		base_addr = addr - (cur_y*128); 	} else {		cur_y = 0;		base_addr = addr;	}	while (j>0) {		RMuint32 line_count = RMmin(max_line_count, j);		if (tiled_xfer) {			cur_address = base_addr + (cur_y % 32) * 128 + (cur_y/32) * buffer_width * 32;		} else {			cur_address = base_addr + cur_y * buffer_width;		}		gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_ADD, cur_address);		gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_CNT, x_xfer + (line_count << 16));		gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_SKIP, skip);		gbus_write_uint32(pgbus, REG_BASE_host_interface+MIF_R1_CMD, MBUS_RECTANGLE_VOID | (tiled_xfer ? 0x8 : 0x0));				pci_size = x_xfer * line_count;				gbus_write_uint32(pgbus, REG_BASE_host_interface+WRITE_ENABLE, 0);		gbus_write_uint32(pgbus, REG_BASE_host_interface+WRITE_ADDRESS, dma_bus_address + offset);		gbus_write_uint32(pgbus, REG_BASE_host_interface+WRITE_COUNTER, pci_size);		gbus_write_uint32(pgbus, REG_BASE_host_interface+WRITE_ENABLE, 1);		RMDBGLOG((MBUSDBG, "MBUS 0x%08lx %ld %ld %ld %ld\n", cur_address, x_xfer, line_count, skip&~0x10000, pci_size));		offset = (offset + half_dma_size) & (dma_size - 1); // dma_size is a power of 2		for (i = 0; i < line_read; i++) {			dmacpy_read_data(pdmacpy, offset + i * x_xfer, data, x);			data += x;		}		line_read = line_count;		// Wait for MBUS interface		if ((status = wait_for_mbus(pgbus, REG_BASE_host_interface+MIF_R1_CMD)))			goto exit_mbus_read_picture;				// Wait for PCI Master		if ((status = wait_for_pci(pgbus, REG_BASE_host_interface+WRITE_ENABLE, REG_BASE_host_interface+WRITE_COUNTER)))			goto exit_mbus_read_picture;		j -= line_count;		cur_y += line_count;	}		offset = (offset + half_dma_size) & (dma_size - 1); // dma_size is a power of 2	for (i = 0; i < line_read; i ++) {		dmacpy_read_data(pdmacpy, offset + i * x_xfer, data + i * x, x);	} exit_mbus_read_picture:	dmacpy_close(pdmacpy);	gbus_close(pgbus);		return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -