Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80eeb91a authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Improve GMU firmware loading time"

parents ebc7d738 de365229
Loading
Loading
Loading
Loading
+3 −11
Original line number Diff line number Diff line
@@ -485,15 +485,12 @@ static int _load_legacy_gmu_fw(struct kgsl_device *device,
	struct gmu_device *gmu)
{
	const struct firmware *fw = gmu->fw_image;
	u32 *fwptr = (u32 *)fw->data;
	int i;

	if (fw->size > MAX_GMUFW_SIZE)
		return -EINVAL;

	for (i = 0; i < (fw->size >> 2); i++)
		gmu_core_regwrite(device,
			A6XX_GMU_CM3_ITCM_START + i, fwptr[i]);
	gmu_core_blkwrite(device, A6XX_GMU_CM3_ITCM_START, fw->data,
			fw->size);

	/* Proceed only after the FW is written */
	wmb();
@@ -504,7 +501,6 @@ static int load_gmu_fw(struct kgsl_device *device)
{
	struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
	uint8_t *fw = (uint8_t *)gmu->fw_image->data;
	int j;
	int tcm_addr;
	struct gmu_block_header *blk;
	struct gmu_memdesc *md;
@@ -530,8 +526,6 @@ static int load_gmu_fw(struct kgsl_device *device)
		}

		if (md->mem_type == GMU_ITCM || md->mem_type == GMU_DTCM) {
			uint32_t *fwptr = (uint32_t *)fw;

			tcm_addr = (blk->addr - (uint32_t)md->gmuaddr) /
				sizeof(uint32_t);

@@ -540,9 +534,7 @@ static int load_gmu_fw(struct kgsl_device *device)
			else
				tcm_addr += A6XX_GMU_CM3_DTCM_START;

			for (j = 0; j < blk->size / sizeof(uint32_t); j++)
				gmu_core_regwrite(device, tcm_addr + j,
					fwptr[j]);
			gmu_core_blkwrite(device, tcm_addr, fw, blk->size);
		} else {
			uint32_t offset = blk->addr - (uint32_t)md->gmuaddr;

+14 −0
Original line number Diff line number Diff line
@@ -231,6 +231,20 @@ void gmu_core_regwrite(struct kgsl_device *device, unsigned int offsetwords,
	__raw_writel(value, reg);
}

void gmu_core_blkwrite(struct kgsl_device *device, unsigned int offsetwords,
		const void *buffer, size_t size)
{
	void __iomem *base;

	if (WARN_ON(!gmu_core_is_register_offset(device, offsetwords)))
		return;

	offsetwords -= device->gmu_core.gmu2gpu_offset;
	base = device->gmu_core.reg_virt + (offsetwords << 2);

	memcpy_toio(base, buffer, size);
}

void gmu_core_regrmw(struct kgsl_device *device,
		unsigned int offsetwords,
		unsigned int mask, unsigned int bits)
+15 −0
Original line number Diff line number Diff line
@@ -194,6 +194,21 @@ void gmu_core_regread(struct kgsl_device *device, unsigned int offsetwords,
		unsigned int *value);
void gmu_core_regwrite(struct kgsl_device *device, unsigned int offsetwords,
		unsigned int value);

/**
 * gmu_core_blkwrite - Do a bulk I/O write to GMU
 * @device: Pointer to the kgsl device
 * @offsetwords: Destination dword offset
 * @buffer: Pointer to the source buffer
 * @size: Number of bytes to copy
 *
 * Write a series of GMU registers quickly without bothering to spend time
 * logging the register writes. The logging of these writes causes extra
 * delays that could allow IRQs arrive and be serviced before finishing
 * all the writes.
 */
void gmu_core_blkwrite(struct kgsl_device *device, unsigned int offsetwords,
		const void *buffer, size_t size);
void gmu_core_regrmw(struct kgsl_device *device, unsigned int offsetwords,
		unsigned int mask, unsigned int bits);
const char *gmu_core_oob_type_str(enum oob_request req);