Commit 9ecccaf9 authored by Rob Clark's avatar Rob Clark
Browse files

Merge tag 'drm-msm-fixes-2021-04-02' into msm-next

Pull in fixes from previous cycle
parents 1e28eed1 12aca1ce
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1386,8 +1386,8 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)

static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
{
	*value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO,
		REG_A5XX_RBBM_PERFCTR_CP_0_HI);
	*value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO,
		REG_A5XX_RBBM_ALWAYSON_COUNTER_HI);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu)
	/* Set up the limits management */
	if (adreno_is_a530(adreno_gpu))
		a530_lm_setup(gpu);
	else
	else if (adreno_is_a540(adreno_gpu))
		a540_lm_setup(gpu);

	/* Set up SP/TP power collpase */
+1 −1
Original line number Diff line number Diff line
@@ -339,7 +339,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
	else
		bit = a6xx_gmu_oob_bits[state].ack_new;

	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, bit);
	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);
}

/* Enable CPU control of SPTP power power collapse */
+75 −33
Original line number Diff line number Diff line
@@ -522,28 +522,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu)
	return a6xx_idle(gpu, ring) ? 0 : -EINVAL;
}

static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
/*
 * Check that the microcode version is new enough to include several key
 * security fixes. Return true if the ucode is safe.
 */
static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
		struct drm_gem_object *obj)
{
	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
	struct msm_gpu *gpu = &adreno_gpu->base;
	u32 *buf = msm_gem_get_vaddr(obj);
	bool ret = false;

	if (IS_ERR(buf))
		return;
		return false;

	/*
	 * If the lowest nibble is 0xa that is an indication that this microcode
	 * has been patched. The actual version is in dword [3] but we only care
	 * about the patchlevel which is the lowest nibble of dword [3]
	 * Targets up to a640 (a618, a630 and a640) need to check for a
	 * microcode version that is patched to support the whereami opcode or
	 * one that is new enough to include it by default.
	 */
	if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) ||
		adreno_is_a640(adreno_gpu)) {
		/*
		 * If the lowest nibble is 0xa that is an indication that this
		 * microcode has been patched. The actual version is in dword
		 * [3] but we only care about the patchlevel which is the lowest
		 * nibble of dword [3]
		 *
	 * Otherwise check that the firmware is greater than or equal to 1.90
	 * which was the first version that had this fix built in
		 * Otherwise check that the firmware is greater than or equal
		 * to 1.90 which was the first version that had this fix built
		 * in
		 */
	if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1)
		a6xx_gpu->has_whereami = true;
	else if ((buf[0] & 0xfff) > 0x190)
		if ((((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) ||
			(buf[0] & 0xfff) >= 0x190) {
			a6xx_gpu->has_whereami = true;
			ret = true;
			goto out;
		}

		DRM_DEV_ERROR(&gpu->pdev->dev,
			"a630 SQE ucode is too old. Have version %x need at least %x\n",
			buf[0] & 0xfff, 0x190);
	}  else {
		/*
		 * a650 tier targets don't need whereami but still need to be
		 * equal to or newer than 0.95 for other security fixes
		 */
		if (adreno_is_a650(adreno_gpu)) {
			if ((buf[0] & 0xfff) >= 0x095) {
				ret = true;
				goto out;
			}

			DRM_DEV_ERROR(&gpu->pdev->dev,
				"a650 SQE ucode is too old. Have version %x need at least %x\n",
				buf[0] & 0xfff, 0x095);
		}

		/*
		 * When a660 is added those targets should return true here
		 * since those have all the critical security fixes built in
		 * from the start
		 */
	}
out:
	msm_gem_put_vaddr(obj);
	return ret;
}

static int a6xx_ucode_init(struct msm_gpu *gpu)
@@ -566,7 +611,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu)
		}

		msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw");
		a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo);
		if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) {
			msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
			drm_gem_object_put(a6xx_gpu->sqe_bo);

			a6xx_gpu->sqe_bo = NULL;
			return -EPERM;
		}
	}

	gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO,
@@ -1177,8 +1228,8 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
	/* Force the GPU power on so we can read this register */
	a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);

	*value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
		REG_A6XX_RBBM_PERFCTR_CP_0_HI);
	*value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
		REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);

	a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
	mutex_unlock(&perfcounter_oob);
@@ -1350,35 +1401,26 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu,
		u32 revn)
{
	struct opp_table *opp_table;
	struct nvmem_cell *cell;
	u32 supp_hw = UINT_MAX;
	void *buf;
	u16 speedbin;
	int ret;

	cell = nvmem_cell_get(dev, "speed_bin");
	ret = nvmem_cell_read_u16(dev, "speed_bin", &speedbin);
	/*
	 * -ENOENT means that the platform doesn't support speedbin which is
	 * fine
	 */
	if (PTR_ERR(cell) == -ENOENT)
	if (ret == -ENOENT) {
		return 0;
	else if (IS_ERR(cell)) {
	} else if (ret) {
		DRM_DEV_ERROR(dev,
				"failed to read speed-bin. Some OPPs may not be supported by hardware");
			      "failed to read speed-bin (%d). Some OPPs may not be supported by hardware",
			      ret);
		goto done;
	}
	speedbin = le16_to_cpu(speedbin);

	buf = nvmem_cell_read(cell, NULL);
	if (IS_ERR(buf)) {
		nvmem_cell_put(cell);
		DRM_DEV_ERROR(dev,
				"failed to read speed-bin. Some OPPs may not be supported by hardware");
		goto done;
	}

	supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf));

	kfree(buf);
	nvmem_cell_put(cell);
	supp_hw = fuse_to_supp_hw(dev, revn, speedbin);

done:
	opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1);
+3 −1
Original line number Diff line number Diff line
@@ -496,7 +496,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,

	DPU_REG_WRITE(c, CTL_TOP, mode_sel);
	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
	DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0));
	if (cfg->merge_3d)
		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
			      BIT(cfg->merge_3d - MERGE_3D_0));
}

static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
Loading