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

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

Merge "msm: kgsl: Finish up probe cleanups"

parents 816c0efa 0f9ebd55
Loading
Loading
Loading
Loading
+94 −130
Original line number Diff line number Diff line
@@ -653,37 +653,42 @@ static struct {
};

static struct device_node *
adreno_get_soc_hw_revision_node(struct adreno_device *adreno_dev,
	struct platform_device *pdev)
adreno_get_soc_hw_revision_node(struct platform_device *pdev, u32 hwrev)
{
	struct device_node *node, *child;
	unsigned int rev;

	node = of_find_node_by_name(pdev->dev.of_node, "qcom,soc-hw-revisions");
	if (node == NULL)
		return NULL;

	for_each_child_of_node(node, child) {
		u32 rev;

		if (of_property_read_u32(child, "qcom,soc-hw-revision", &rev))
			continue;

		if (rev == adreno_dev->soc_hw_rev)
		if (rev == hwrev) {
			of_node_put(node);
			return child;
		}
	}

	of_node_put(node);

	dev_warn(&pdev->dev, "No matching SOC HW revision found for efused HW rev=%u\n",
		hwrev);

	dev_warn(KGSL_DEVICE(adreno_dev)->dev,
		      "No matching SOC HW revision found for efused HW rev=%u\n",
		      adreno_dev->soc_hw_rev);
	return NULL;
}

static void adreno_update_soc_hw_revision_quirks(
		struct adreno_device *adreno_dev, struct platform_device *pdev)
static void
adreno_update_soc_hw_revision_quirks(struct adreno_device *adreno_dev,
		struct platform_device *pdev, u32 hwrev)
{
	struct device_node *node;
	int i;

	node = adreno_get_soc_hw_revision_node(adreno_dev, pdev);
	node = adreno_get_soc_hw_revision_node(pdev, hwrev);
	if (node == NULL)
		node = pdev->dev.of_node;

@@ -691,8 +696,7 @@ static void adreno_update_soc_hw_revision_quirks(
	if (of_property_read_u32(node, "qcom,chipid", &adreno_dev->chipid)) {
		if (of_property_read_u32(pdev->dev.of_node,
				"qcom,chipid", &adreno_dev->chipid)) {
			dev_crit(KGSL_DEVICE(adreno_dev)->dev,
				"No GPU chip ID was specified\n");
			dev_crit(&pdev->dev, "No GPU chip ID was specified\n");
			BUG();
			return;
		}
@@ -709,6 +713,9 @@ static void adreno_update_soc_hw_revision_quirks(
		kgsl_mmu_set_feature(KGSL_DEVICE(adreno_dev),
			KGSL_MMU_SECURE_CB_ALT);


	if (node != pdev->dev.of_node)
		of_node_put(node);
}

static int adreno_identify_gpu(struct adreno_device *adreno_dev)
@@ -769,58 +776,6 @@ static const struct of_device_id adreno_match_table[] = {
	{}
};

static void adreno_of_get_ca_target_pwrlevel(struct adreno_device *adreno_dev,
		struct device_node *node)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	unsigned int ca_target_pwrlevel = 1;

	of_property_read_u32(node, "qcom,ca-target-pwrlevel",
		&ca_target_pwrlevel);

	if (ca_target_pwrlevel >= device->pwrctrl.num_pwrlevels)
		ca_target_pwrlevel = 1;

	device->pwrscale.ctxt_aware_target_pwrlevel = ca_target_pwrlevel;
}

static void adreno_of_get_ca_aware_properties(struct adreno_device *adreno_dev,
		struct device_node *parent)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct kgsl_pwrscale *pwrscale = &device->pwrscale;
	struct device_node *node, *child;
	unsigned int bin = 0;

	pwrscale->ctxt_aware_enable =
		of_property_read_bool(parent, "qcom,enable-ca-jump");

	if (pwrscale->ctxt_aware_enable) {
		if (of_property_read_u32(parent, "qcom,ca-busy-penalty",
			&pwrscale->ctxt_aware_busy_penalty))
			pwrscale->ctxt_aware_busy_penalty = 12000;

		node = of_find_node_by_name(parent, "qcom,gpu-pwrlevel-bins");
		if (node == NULL) {
			adreno_of_get_ca_target_pwrlevel(adreno_dev, parent);
			return;
		}

		for_each_child_of_node(node, child) {
			if (of_property_read_u32(child, "qcom,speed-bin", &bin))
				continue;

			if (bin == adreno_dev->speed_bin) {
				adreno_of_get_ca_target_pwrlevel(adreno_dev,
					child);
				return;
			}
		}

		pwrscale->ctxt_aware_target_pwrlevel = 1;
	}
}

/* Dynamically build the OPP table for the GPU device */
static void adreno_build_opp_table(struct device *dev, struct kgsl_pwrctrl *pwr)
{
@@ -953,11 +908,9 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
	return ret;
}

static void adreno_of_get_initial_pwrlevel(struct adreno_device *adreno_dev,
static void adreno_of_get_initial_pwrlevel(struct kgsl_pwrctrl *pwr,
		struct device_node *node)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	int init_level = 1;

	of_property_read_u32(node, "qcom,initial-pwrlevel", &init_level);
@@ -991,31 +944,33 @@ static void adreno_of_get_limits(struct adreno_device *adreno_dev,
static int adreno_of_get_legacy_pwrlevels(struct adreno_device *adreno_dev,
		struct device_node *parent)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct device_node *node;
	int ret;

	node = of_find_node_by_name(parent, "qcom,gpu-pwrlevels");

	if (node == NULL) {
		dev_err(KGSL_DEVICE(adreno_dev)->dev,
		dev_err(&device->pdev->dev,
			"Unable to find 'qcom,gpu-pwrlevels'\n");
		return -EINVAL;
	}

	ret = adreno_of_parse_pwrlevels(adreno_dev, node);
	if (ret)
		return ret;

	adreno_of_get_initial_pwrlevel(adreno_dev, parent);

	if (!ret) {
		adreno_of_get_initial_pwrlevel(&device->pwrctrl, parent);
		adreno_of_get_limits(adreno_dev, parent);
	}

	return 0;
	of_node_put(node);
	return ret;
}

static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
		struct device_node *parent)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct device_node *node, *child;
	unsigned int bin = 0;

@@ -1028,14 +983,16 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
		if (of_property_read_u32(child, "qcom,speed-bin", &bin))
			continue;

		if (bin == adreno_dev->speed_bin) {
		if (bin == device->speed_bin) {
			int ret;

			ret = adreno_of_parse_pwrlevels(adreno_dev, child);
			if (ret)
			if (ret) {
				of_node_put(child);
				return ret;
			}

			adreno_of_get_initial_pwrlevel(adreno_dev, child);
			adreno_of_get_initial_pwrlevel(&device->pwrctrl, child);

			/*
			 * Check for global throttle-pwrlevel first and override
@@ -1044,13 +1001,14 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
			adreno_of_get_limits(adreno_dev, parent);
			adreno_of_get_limits(adreno_dev, child);

			of_node_put(child);
			return 0;
		}
	}

	dev_err(KGSL_DEVICE(adreno_dev)->dev,
	dev_err(&device->pdev->dev,
		"GPU speed_bin:%d mismatch for efused bin:%d\n",
		adreno_dev->speed_bin, bin);
		device->speed_bin, bin);
	return -ENODEV;
}

@@ -1075,26 +1033,23 @@ l3_pwrlevel_probe(struct kgsl_device *device, struct device_node *node)
		if (index >= device->num_l3_pwrlevels)
			device->num_l3_pwrlevels = index + 1;

		if (of_property_read_u32(child, "qcom,l3-freq",
				&device->l3_freq[index]))
			continue;
		of_property_read_u32(child, "qcom,l3-freq",
				&device->l3_freq[index]);
	}

	device->l3_clk = devm_clk_get(&device->pdev->dev, "l3_vote");

	if (IS_ERR_OR_NULL(device->l3_clk)) {
	if (IS_ERR_OR_NULL(device->l3_clk))
		dev_err(&device->pdev->dev,
			"Unable to get the l3_vote clock\n");
		device->l3_clk = NULL;
	}
}

static int adreno_of_get_power(struct adreno_device *adreno_dev,
		struct platform_device *pdev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct device_node *node = pdev->dev.of_node;
	struct resource *res;
	int ret;

	/* Get starting physical address of device registers */
	res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
@@ -1114,13 +1069,11 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
	device->reg_phys = res->start;
	device->reg_len = resource_size(res);

	if (adreno_of_get_pwrlevels(adreno_dev, node))
		return -EINVAL;

	/* Get context aware DCVS properties */
	adreno_of_get_ca_aware_properties(adreno_dev, node);
	ret = adreno_of_get_pwrlevels(adreno_dev, pdev->dev.of_node);
	if (ret)
		return ret;

	l3_pwrlevel_probe(device, node);
	l3_pwrlevel_probe(device, pdev->dev.of_node);

	/* Default timeout is 80 ms across all targets */
	device->pwrctrl.interval_timeout = msecs_to_jiffies(80);
@@ -1128,7 +1081,8 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
	/* Set default bus control to true on all targets */
	device->pwrctrl.bus_control = true;

	device->pwrctrl.input_disable = of_property_read_bool(node,
	device->pwrctrl.input_disable =
		of_property_read_bool(pdev->dev.of_node,
			"qcom,disable-wake-on-touch");

	return 0;
@@ -1147,7 +1101,7 @@ static void adreno_cx_dbgc_probe(struct kgsl_device *device)

	adreno_dev->cx_dbgc_base = res->start - device->reg_phys;
	adreno_dev->cx_dbgc_len = resource_size(res);
	adreno_dev->cx_dbgc_virt = devm_ioremap(device->dev,
	adreno_dev->cx_dbgc_virt = devm_ioremap(&device->pdev->dev,
					device->reg_phys +
						adreno_dev->cx_dbgc_base,
					adreno_dev->cx_dbgc_len);
@@ -1168,7 +1122,7 @@ static void adreno_cx_misc_probe(struct kgsl_device *device)
		return;

	adreno_dev->cx_misc_len = resource_size(res);
	adreno_dev->cx_misc_virt = devm_ioremap(device->dev,
	adreno_dev->cx_misc_virt = devm_ioremap(&device->pdev->dev,
					res->start, adreno_dev->cx_misc_len);
}

@@ -1185,7 +1139,7 @@ static void adreno_rscc_probe(struct kgsl_device *device)

	adreno_dev->rscc_base = res->start - device->reg_phys;
	adreno_dev->rscc_len = resource_size(res);
	adreno_dev->rscc_virt = devm_ioremap(device->dev, res->start,
	adreno_dev->rscc_virt = devm_ioremap(&device->pdev->dev, res->start,
						adreno_dev->rscc_len);
	if (adreno_dev->rscc_virt == NULL)
		dev_warn(device->dev, "rscc ioremap failed\n");
@@ -1203,41 +1157,39 @@ static void adreno_isense_probe(struct kgsl_device *device)

	adreno_dev->isense_base = res->start - device->reg_phys;
	adreno_dev->isense_len = resource_size(res);
	adreno_dev->isense_virt = devm_ioremap(device->dev, res->start,
	adreno_dev->isense_virt = devm_ioremap(&device->pdev->dev, res->start,
					adreno_dev->isense_len);
	if (adreno_dev->isense_virt == NULL)
		dev_warn(device->dev, "isense ioremap failed\n");
}

static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev)
static u32 adreno_efuse_read_soc_hw_rev(struct platform_device *pdev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	unsigned int val;
	unsigned int soc_hw_rev[3];
	int ret;

	if (of_property_read_u32_array(
		device->pdev->dev.of_node,
	if (of_property_read_u32_array(pdev->dev.of_node,
		"qcom,soc-hw-rev-efuse", soc_hw_rev, 3))
		return;
		return 0;

	ret = adreno_efuse_map(device->pdev);
	ret = adreno_efuse_map(pdev);
	if (ret) {
		dev_err(device->dev,
		dev_err(&pdev->dev,
			"Unable to map hardware revision fuse: ret=%d\n", ret);
		return;
		return 0;
	}

	ret = adreno_efuse_read_u32(soc_hw_rev[0], &val);
	adreno_efuse_unmap();

	if (ret) {
		dev_err(device->dev,
		dev_err(&pdev->dev,
			"Unable to read hardware revision fuse: ret=%d\n", ret);
		return;
		return 0;
	}

	adreno_dev->soc_hw_rev = (val >> soc_hw_rev[1]) & soc_hw_rev[2];
	return (val >> soc_hw_rev[1]) & soc_hw_rev[2];
}

static bool adreno_is_gpu_disabled(struct adreno_device *adreno_dev)
@@ -1315,7 +1267,7 @@ static int adreno_read_speed_bin(struct platform_device *pdev)
	return val;
}

static void adreno_probe_llcc(struct adreno_device *adreno_dev,
static int adreno_probe_llcc(struct adreno_device *adreno_dev,
		struct platform_device *pdev)
{
	int ret;
@@ -1323,16 +1275,32 @@ static void adreno_probe_llcc(struct adreno_device *adreno_dev,
	/* Get the system cache slice descriptor for GPU */
	adreno_dev->gpu_llc_slice = llcc_slice_getd(LLCC_GPU);
	ret = PTR_ERR_OR_ZERO(adreno_dev->gpu_llc_slice);
	if (ret && ret != -ENOENT)
		dev_warn(&pdev->dev, "Unable to get the GPU LLC slice: %d\n",
			ret);

	if (ret) {
		/* Propagate EPROBE_DEFER back to the probe function */
		if (ret == -EPROBE_DEFER)
			return ret;

		if (ret != -ENOENT)
			dev_warn(&pdev->dev,
				"Unable to get the GPU LLC slice: %d\n", ret);
	}

	/* Get the system cache slice descriptor for GPU pagetables */
	adreno_dev->gpuhtw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
	ret = PTR_ERR_OR_ZERO(adreno_dev->gpuhtw_llc_slice);
	if (ret && ret != -ENOENT)
		dev_warn(&pdev->dev, "Unable to get GPU HTW LLC slice: %d\n",
			ret);
	if (ret) {
		if (ret == -EPROBE_DEFER) {
			llcc_slice_putd(adreno_dev->gpu_llc_slice);
			return ret;
		}

		if (ret != -ENOENT)
			dev_warn(&pdev->dev,
				"Unable to get GPU HTW LLC slice: %d\n", ret);
	}

	return 0;
}

static const struct kgsl_functable adreno_functable;
@@ -1366,10 +1334,6 @@ static void adreno_setup_device(struct adreno_device *adreno_dev)
	INIT_LIST_HEAD(&adreno_dev->active_list);
	spin_lock_init(&adreno_dev->active_list_lock);

	/* Enable use of the LLC slices where applicable */
	adreno_dev->gpu_llc_slice_enable = true;
	adreno_dev->gpuhtw_llc_slice_enable = true;

	for (i = 0; i < ARRAY_SIZE(adreno_dev->ringbuffers); i++) {
		struct adreno_ringbuffer *rb = &adreno_dev->ringbuffers[i];

@@ -1385,7 +1349,7 @@ static int adreno_bind(struct device *dev)
	struct kgsl_device *device;
	int status;
	unsigned int priv = 0;
	u32 size;
	u32 size, hwrev;

	of_id = of_match_device(adreno_match_table, &pdev->dev);
	if (!of_id)
@@ -1408,25 +1372,23 @@ static int adreno_bind(struct device *dev)
	}

	/* Identify SOC hardware revision to be used */
	adreno_efuse_read_soc_hw_rev(adreno_dev);
	hwrev = adreno_efuse_read_soc_hw_rev(pdev);

	adreno_update_soc_hw_revision_quirks(adreno_dev, pdev);
	adreno_update_soc_hw_revision_quirks(adreno_dev, pdev, hwrev);

	status = adreno_read_speed_bin(pdev);
	if (status < 0)
		return status;

	adreno_dev->speed_bin = status;
	device->speed_bin = status;

	/* Get the chip ID from the DT and set up target specific parameters */
	if (adreno_identify_gpu(adreno_dev))
		return -ENODEV;

	status = adreno_of_get_power(adreno_dev, pdev);
	if (status) {
		device->pdev = NULL;
	if (status)
		return status;
	}

	status = kgsl_bus_init(device, pdev);
	if (status)
@@ -1455,8 +1417,10 @@ static int adreno_bind(struct device *dev)
	device->mmu.secured = (IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) &&
		ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION));

	/* Probe the LLCC */
	adreno_probe_llcc(adreno_dev, pdev);
	/* Probe the LLCC - this could return -EPROBE_DEFER */
	status = adreno_probe_llcc(adreno_dev, pdev);
	if (status)
		goto err;

	/*
	 * IF the GPU HTW slice was successsful set the MMU feature so the
@@ -2505,7 +2469,7 @@ static int adreno_prop_u32(struct kgsl_device *device,
	else if (param->type == KGSL_PROP_DEVICE_BITNESS)
		val = adreno_support_64bit(adreno_dev) ? 48 : 32;
	else if (param->type == KGSL_PROP_SPEED_BIN)
		val = adreno_dev->speed_bin;
		val = device->speed_bin;

	return copy_prop(param, &val, sizeof(val));
}
+0 −4
Original line number Diff line number Diff line
@@ -416,7 +416,6 @@ struct adreno_gpu_core {
 * @lm_threshold_count: register value for counter for lm threshold breakin
 * @lm_threshold_cross: number of current peaks exceeding threshold
 * @ifpc_count: Number of times the GPU went into IFPC
 * @speed_bin: Indicate which power level set to use
 * @highest_bank_bit: Value of the highest bank bit
 * @csdev: Pointer to a coresight device (if applicable)
 * @gpmu_throttle_counters - counteers for number of throttled clocks
@@ -428,7 +427,6 @@ struct adreno_gpu_core {
 * @gpuhtw_llc_slice: GPU pagetables system cache slice descriptor
 * @gpuhtw_llc_slice_enable: To enable the GPUHTW system cache slice or not
 * @zap_loaded: Used to track if zap was successfully loaded or not
 * @soc_hw_rev: Indicate which SOC hardware revision to use
 */
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -499,7 +497,6 @@ struct adreno_device {
	uint32_t lm_threshold_cross;
	uint32_t ifpc_count;

	unsigned int speed_bin;
	unsigned int highest_bank_bit;
	unsigned int quirks;

@@ -515,7 +512,6 @@ struct adreno_device {
	void *gpuhtw_llc_slice;
	bool gpuhtw_llc_slice_enable;
	unsigned int zap_loaded;
	unsigned int soc_hw_rev;
	/**
	 * @critpkts: Memory descriptor for 5xx critical packets if applicable
	 */
+2 −2
Original line number Diff line number Diff line
@@ -1233,10 +1233,10 @@ static int _load_firmware(struct kgsl_device *device, const char *fwfile,
	const struct firmware *fw = NULL;
	int ret;

	ret = request_firmware(&fw, fwfile, device->dev);
	ret = request_firmware(&fw, fwfile, &device->pdev->dev);

	if (ret) {
		dev_err(device->dev, "request_firmware(%s) failed: %d\n",
		dev_err(&device->pdev->dev, "request_firmware(%s) failed: %d\n",
			     fwfile, ret);
		return ret;
	}
+6 −5
Original line number Diff line number Diff line
@@ -563,9 +563,10 @@ static int _load_gpmu_firmware(struct adreno_device *adreno_dev)
	if (a5xx_core->gpmufw_name == NULL)
		return 0;

	ret = request_firmware(&fw, a5xx_core->gpmufw_name, device->dev);
	ret = request_firmware(&fw, a5xx_core->gpmufw_name, &device->pdev->dev);
	if (ret || fw == NULL) {
		dev_err(device->dev, "request_firmware (%s) failed: %d\n",
		dev_err(&device->pdev->dev,
			"request_firmware (%s) failed: %d\n",
			a5xx_core->gpmufw_name, ret);
		return ret;
	}
@@ -804,9 +805,9 @@ static void _load_regfile(struct adreno_device *adreno_dev)
	if (!a5xx_core->regfw_name)
		return;

	ret = request_firmware(&fw, a5xx_core->regfw_name, device->dev);
	ret = request_firmware(&fw, a5xx_core->regfw_name, &device->pdev->dev);
	if (ret) {
		dev_err(device->dev, "request firmware failed %d, %s\n",
		dev_err(&device->pdev->dev, "request firmware failed %d, %s\n",
				ret, a5xx_core->regfw_name);
		return;
	}
+3 −0
Original line number Diff line number Diff line
@@ -2286,6 +2286,9 @@ static void a6xx_platform_setup(struct adreno_device *adreno_dev)
	adreno_dev->preempt.skipsaverestore = true;
	adreno_dev->preempt.usesgmem = true;

	adreno_dev->gpu_llc_slice_enable = true;
	adreno_dev->gpuhtw_llc_slice_enable = true;

	if (adreno_has_gbif(adreno_dev)) {
		a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].regs =
				a6xx_perfcounters_gbif;
Loading