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

Commit 11d1626c authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Remove struct kgsl_device_platform_data



The platform data is from a pre DT era and adds an additional global
header that we don't need to deal with. Put it out to pasture.

Change-Id: Ic0dedbad1bbda06380dfa5f6193a4445b3caf24c
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent bc407b4f
Loading
Loading
Loading
Loading
+60 −94
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ static struct adreno_device device_3d0 = {
		.name = DEVICE_3D0_NAME,
		.id = KGSL_DEVICE_3D0,
		.pwrctrl = {
			.irq_name = KGSL_3D0_IRQ,
			.irq_name = "kgsl_3d0_irq",
		},
		.iomemname = KGSL_3D0_REG_MEMORY,
		.shadermemname = KGSL_3D0_SHADER_MEMORY,
		.iomemname = "kgsl_3d0_reg_memory",
		.shadermemname = "kgsl_3d0_shader_memory",
		.ftbl = &adreno_functable,
		.cmd_log = KGSL_LOG_LEVEL_DEFAULT,
		.ctxt_log = KGSL_LOG_LEVEL_DEFAULT,
@@ -844,20 +844,21 @@ static const struct of_device_id adreno_match_table[] = {
	{}
};

static int adreno_of_parse_pwrlevels(struct device_node *node,
	struct kgsl_device_platform_data *pdata)
static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
		struct device_node *node)
{
	struct kgsl_device *device = &adreno_dev->dev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct device_node *child;
	int ret = -EINVAL;

	pdata->num_levels = 0;
	pwr->num_pwrlevels = 0;

	for_each_child_of_node(node, child) {
		unsigned int index;
		struct kgsl_pwrlevel *level;

		if (adreno_of_read_property(child, "reg", &index))
			goto done;
			return -EINVAL;

		if (index >= KGSL_MAX_PWRLEVELS) {
			KGSL_CORE_ERR("Pwrlevel index %d is out of range\n",
@@ -865,18 +866,18 @@ static int adreno_of_parse_pwrlevels(struct device_node *node,
			continue;
		}

		if (index >= pdata->num_levels)
			pdata->num_levels = index + 1;
		if (index >= pwr->num_pwrlevels)
			pwr->num_pwrlevels = index + 1;

		level = &pdata->pwrlevel[index];
		level = &pwr->pwrlevels[index];

		if (adreno_of_read_property(child, "qcom,gpu-freq",
			&level->gpu_freq))
			goto done;
			return -EINVAL;

		if (adreno_of_read_property(child, "qcom,bus-freq",
			&level->bus_freq))
			goto done;
			return -EINVAL;

		if (of_property_read_u32(child, "qcom,bus-min",
			&level->bus_min))
@@ -887,14 +888,11 @@ static int adreno_of_parse_pwrlevels(struct device_node *node,
			level->bus_max = level->bus_freq;
	}


	ret = 0;
done:
	return ret;

	return 0;
}
static int adreno_of_get_legacy_pwrlevels(struct device_node *parent,
	struct kgsl_device_platform_data *pdata)

static int adreno_of_get_legacy_pwrlevels(struct adreno_device *adreno_dev,
		struct device_node *parent)
{
	struct device_node *node;

@@ -905,18 +903,17 @@ static int adreno_of_get_legacy_pwrlevels(struct device_node *parent,
		return -EINVAL;
	}

	return adreno_of_parse_pwrlevels(node, pdata);
	return adreno_of_parse_pwrlevels(adreno_dev, node);
}

static int adreno_of_get_pwrlevels(struct device_node *parent,
		struct adreno_device *adreno_dev,
		struct kgsl_device_platform_data *pdata)
static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
		struct device_node *parent)
{
	struct device_node *node, *child;

	node = of_find_node_by_name(parent, "qcom,gpu-pwrlevel-bins");
	if (node == NULL)
		return adreno_of_get_legacy_pwrlevels(parent, pdata);
		return adreno_of_get_legacy_pwrlevels(adreno_dev, parent);

	for_each_child_of_node(node, child) {
		unsigned int bin;
@@ -925,7 +922,7 @@ static int adreno_of_get_pwrlevels(struct device_node *parent,
			continue;

		if (bin == adreno_dev->speed_bin)
			return adreno_of_parse_pwrlevels(child, pdata);
			return adreno_of_parse_pwrlevels(adreno_dev, child);
	}

	return -ENODEV;
@@ -947,95 +944,65 @@ static struct {
	 { ADRENO_QUIRK_IOMMU_SYNC, "qcom,gpu-quirk-iommu-sync" },
};

static int adreno_of_get_pdata(struct adreno_device *adreno_dev)
static int adreno_of_get_power(struct adreno_device *adreno_dev,
		struct platform_device *pdev)
{
	struct platform_device *pdev = adreno_dev->dev.pdev;
	struct kgsl_device_platform_data *pdata = NULL;
	int ret = -EINVAL;
	int i;
	struct kgsl_device *device = &adreno_dev->dev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct device_node *node = pdev->dev.of_node;
	int i, init_level;

	if (of_property_read_string(pdev->dev.of_node, "label", &pdev->name)) {
	if (of_property_read_string(node, "label", &pdev->name)) {
		KGSL_CORE_ERR("Unable to read 'label'\n");
		goto err;
		return -EINVAL;
	}

	if (adreno_of_read_property(pdev->dev.of_node, "qcom,id", &pdev->id))
		goto err;

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (pdata == NULL) {
		ret = -ENOMEM;
		goto err;
	}
	if (adreno_of_read_property(node, "qcom,id", &pdev->id))
		return -EINVAL;

	/* Set up quirks and other boolean options */

	for (i = 0; i < ARRAY_SIZE(adreno_quirks); i++) {
		if (of_property_read_bool(pdev->dev.of_node,
			adreno_quirks[i].prop))
		if (of_property_read_bool(node, adreno_quirks[i].prop))
			adreno_dev->quirks |= adreno_quirks[i].quirk;
	}

	/* pwrlevel Data */
	ret = adreno_of_get_pwrlevels(pdev->dev.of_node, adreno_dev, pdata);
	if (ret)
		goto err;
	if (adreno_of_get_pwrlevels(adreno_dev, node))
		return -EINVAL;

	if (of_property_read_u32(pdev->dev.of_node, "qcom,initial-pwrlevel",
		&pdata->init_level))
		pdata->init_level = 1;
	if (of_property_read_u32(node, "qcom,initial-pwrlevel", &init_level))
		init_level = 1;

	if (pdata->init_level < 0 || pdata->init_level > pdata->num_levels) {
		KGSL_CORE_ERR("Initial power level out of range\n");
		pdata->init_level = 1;
	}
	if (init_level < 0 || init_level > pwr->num_pwrlevels)
		init_level = 1;

	pwr->active_pwrlevel = init_level;
	pwr->default_pwrlevel = init_level;

	/* get pm-qos-active-latency, set it to default if not found */
	if (of_property_read_u32(pdev->dev.of_node,
		"qcom,pm-qos-active-latency",
		&pdata->pm_qos_active_latency))
		pdata->pm_qos_active_latency = 501;
	if (of_property_read_u32(node, "qcom,pm-qos-active-latency",
		&device->pwrctrl.pm_qos_active_latency))
		device->pwrctrl.pm_qos_active_latency = 501;

	/* get pm-qos-wakeup-latency, set it to default if not found */
	if (of_property_read_u32(pdev->dev.of_node,
		"qcom,pm-qos-wakeup-latency",
		&pdata->pm_qos_wakeup_latency))
		pdata->pm_qos_wakeup_latency = 101;
	if (of_property_read_u32(node, "qcom,pm-qos-wakeup-latency",
		&device->pwrctrl.pm_qos_wakeup_latency))
		device->pwrctrl.pm_qos_wakeup_latency = 101;

	if (of_property_read_u32(pdev->dev.of_node, "qcom,idle-timeout",
		&pdata->idle_timeout))
		pdata->idle_timeout = HZ/12;
	if (of_property_read_u32(node, "qcom,idle-timeout",
		(unsigned int *) &device->pwrctrl.interval_timeout))
		device->pwrctrl.interval_timeout = HZ/12;

	pdata->strtstp_sleepwake = of_property_read_bool(pdev->dev.of_node,
						"qcom,strtstp-sleepwake");
	device->pwrctrl.strtstp_sleepwake =
		of_property_read_bool(node, "qcom,strtstp-sleepwake");

	pdata->bus_control = of_property_read_bool(pdev->dev.of_node,
	device->pwrctrl.bus_control = of_property_read_bool(node,
		"qcom,bus-control");

	if (adreno_of_read_property(pdev->dev.of_node, "qcom,clk-map",
		&pdata->clk_map))
		goto err;

	/* Bus Scale Data */

	pdata->bus_scale_table = msm_bus_cl_get_pdata(pdev);
	if (IS_ERR_OR_NULL(pdata->bus_scale_table)) {
		ret = PTR_ERR(pdata->bus_scale_table);
		if (!ret)
			ret = -EINVAL;
		goto err;
	}

	pdata->coresight_pdata = of_get_coresight_platform_data(&pdev->dev,
			pdev->dev.of_node);
	if (adreno_of_read_property(node, "qcom,clk-map",
		&device->pwrctrl.clk_map))
		return -EINVAL;

	pdev->dev.platform_data = pdata;
	return 0;

err:
	kfree(pdata);

	return ret;
}

#ifdef CONFIG_MSM_OCMEM
@@ -1105,8 +1072,7 @@ static int adreno_probe(struct platform_device *pdev)
	/* Get the chip ID from the DT and set up target specific parameters */
	adreno_identify_gpu(adreno_dev);

	/* Get the rest of the device tree */
	status = adreno_of_get_pdata(adreno_dev);
	status = adreno_of_get_power(adreno_dev, pdev);
	if (status) {
		device->pdev = NULL;
		return status;
+3 −0
Original line number Diff line number Diff line
@@ -308,6 +308,7 @@ struct adreno_gpu_core {
 * @lm_threshold_count: register value for counter for lm threshold breakin
 * @lm_threshold_cross: number of current peaks exceeding threshold
 * @speed_bin: Indicate which power level set to use
 * @csdev: Pointer to a coresight device (if applicable)
 */
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -365,6 +366,8 @@ struct adreno_device {

	unsigned int speed_bin;
	unsigned int quirks;

	struct coresight_device *csdev;
};

/**
+11 −19
Original line number Diff line number Diff line
@@ -291,12 +291,8 @@ static const struct coresight_ops adreno_coresight_ops = {

void adreno_coresight_remove(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = &adreno_dev->dev;
	struct kgsl_device_platform_data *pdata =
		dev_get_platdata(&device->pdev->dev);

	coresight_unregister(pdata->csdev);
	pdata->csdev = NULL;
	coresight_unregister(adreno_dev->csdev);
	adreno_dev->csdev = NULL;
}

int adreno_coresight_init(struct adreno_device *adreno_dev)
@@ -304,36 +300,32 @@ int adreno_coresight_init(struct adreno_device *adreno_dev)
	int ret = 0;
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	struct kgsl_device *device = &adreno_dev->dev;
	struct kgsl_device_platform_data *pdata =
		dev_get_platdata(&device->pdev->dev);
	struct coresight_desc desc;

	if (pdata == NULL)
		return -ENODEV;

	if (gpudev->coresight == NULL)
		return -ENODEV;

	if (IS_ERR_OR_NULL(pdata->coresight_pdata))
		return -ENODEV;

	if (pdata->csdev != NULL)
	if (adreno_dev->csdev != NULL)
		return 0;

	memset(&desc, 0, sizeof(desc));

	desc.pdata = of_get_coresight_platform_data(&device->pdev->dev,
			device->pdev->dev.of_node);
	if (desc.pdata == NULL)
		return -ENODEV;

	desc.type = CORESIGHT_DEV_TYPE_SOURCE;
	desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
	desc.ops = &adreno_coresight_ops;
	desc.pdata = pdata->coresight_pdata;
	desc.dev = &device->pdev->dev;
	desc.owner = THIS_MODULE;
	desc.groups = gpudev->coresight->groups;

	pdata->csdev = coresight_register(&desc);
	adreno_dev->csdev = coresight_register(&desc);

	if (IS_ERR(pdata->csdev))
		ret = PTR_ERR(pdata->csdev);
	if (IS_ERR(adreno_dev->csdev))
		ret = PTR_ERR(adreno_dev->csdev);

	return ret;
}
+119 −138
Original line number Diff line number Diff line
@@ -54,6 +54,14 @@
#define DEFAULT_BUS_P 25
#define DEFAULT_BUS_DIV (100 / DEFAULT_BUS_P)

/* Clock map definitions */
#define KGSL_CLK_ALT_MEM_IFACE 0x00000040
#define KGSL_CLK_RBBMTIMER	0x00000080
#define KGSL_CLK_GFX_GTCU   0x00000100
#define KGSL_CLK_GFX_GTBU   0x00000200
#define KGSL_CLK_MX	0x00000400
#define KGSL_CLK_ALWAYSON   0x00000800

struct clk_pair {
	const char *name;
	uint map;
@@ -1518,6 +1526,67 @@ void kgsl_deep_nap_timer(unsigned long data)
	}
}

static int get_legacy_regulators(struct kgsl_device *device)
{
	struct device *dev = &device->pdev->dev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	pwr->gpu_reg[0] = regulator_get(dev, "vdd");
	if (IS_ERR(pwr->gpu_reg[0])) {
		KGSL_CORE_ERR("Couldn't get 'vdd' regulator\n");
		pwr->gpu_reg[0] = NULL;
		return -ENODEV;
	}

	/* Use vddcx only on targets that have it. */
	if (of_find_property(dev->of_node, "vddcx-supply", NULL)) {
		pwr->gpu_reg[1] = regulator_get(dev, "vddcx");
		if (IS_ERR(pwr->gpu_reg[1])) {
			KGSL_CORE_ERR("Couldn't get 'cx' regulator\n");
			pwr->gpu_reg[1] = NULL;
			return -ENODEV;
		}
	}

	return 0;
}

static int get_regulators(struct kgsl_device *device)
{
	struct device *dev = &device->pdev->dev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	int index = 0;
	const char *name;
	struct property *prop;

	if (!of_find_property(dev->of_node, "regulator-names", NULL))
		return get_legacy_regulators(device);

	of_property_for_each_string(dev->of_node, "regulator-names", prop,
		name) {
		struct regulator *reg;

		if (index == KGSL_MAX_REGULATORS) {
			KGSL_CORE_ERR("Too many regulators defined\n");
			return -ENOMEM;
		}

		reg = regulator_get(dev, name);
		if (IS_ERR(reg)) {
			KGSL_CORE_ERR("Couldn't get '%s' regulator\n", name);
			pwr->gpu_reg[index] = NULL;
			return -ENODEV;
		}

		pwr->gpu_reg[index] = reg;
		strlcpy(pwr->gpu_reg_name[index], name,
			KGSL_MAX_REGULATOR_NAME_LEN);
		index++;
	}

	return 0;
}

int kgsl_pwrctrl_init(struct kgsl_device *device)
{
	int i, k, m, n = 0, result = 0;
@@ -1525,20 +1594,26 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	struct clk *clk;
	struct platform_device *pdev = device->pdev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct kgsl_device_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct device_node *ocmem_bus_node;
	struct msm_bus_scale_pdata *ocmem_scale_table = NULL;
	struct msm_bus_scale_pdata *bus_scale_table;
	struct device_node *gpubw_dev_node;
	struct platform_device *p2dev;
	struct property *prop;
	const char *reg_name;

	bus_scale_table = msm_bus_cl_get_pdata(device->pdev);
	if (bus_scale_table == NULL)
		return -EINVAL;

	/*acquire clocks */
	for (i = 0; i < KGSL_MAX_CLKS; i++) {
		if (pdata->clk_map & clks[i].map) {
		if (pwr->clk_map & clks[i].map) {
			clk = clk_get(&pdev->dev, clks[i].name);
			if (IS_ERR(clk))
				goto clk_err;
			if (IS_ERR(clk)) {
				KGSL_PWR_ERR(device,
					"clk_get(%s) failed: %ld\n",
					clks[i].name, PTR_ERR(clk));
				return PTR_ERR(clk);
			}
			pwr->grp_clks[i] = clk;
		}
	}
@@ -1563,37 +1638,24 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	}
	pwr->power_flags = BIT(KGSL_PWRFLAGS_RETENTION_ON);

	if (pdata->num_levels > KGSL_MAX_PWRLEVELS ||
	    pdata->num_levels < 1) {
		KGSL_PWR_ERR(device, "invalid power level count: %d\n",
					 pdata->num_levels);
		result = -EINVAL;
		goto done;
	if (pwr->num_pwrlevels == 0) {
		KGSL_PWR_ERR(device, "No power levels are defined\n");
		return -EINVAL;
	}
	pwr->num_pwrlevels = pdata->num_levels;

	/* Initialize the user and thermal clock constraints */

	pwr->max_pwrlevel = 0;
	pwr->min_pwrlevel = pdata->num_levels - 2;
	pwr->min_pwrlevel = pwr->num_pwrlevels - 2;
	pwr->thermal_pwrlevel = 0;

	pwr->active_pwrlevel = pdata->init_level;
	pwr->default_pwrlevel = pdata->init_level;
	pwr->init_pwrlevel = pdata->init_level;
	pwr->wakeup_maxpwrlevel = 0;
	for (i = 0; i < pdata->num_levels; i++) {

	for (i = 0; i < pwr->num_pwrlevels; i++) {
		if (pwr->pwrlevels[i].gpu_freq > 0)
			pwr->pwrlevels[i].gpu_freq =
		(pdata->pwrlevel[i].gpu_freq > 0) ?
				clk_round_rate(pwr->grp_clks[0],
					   pdata->pwrlevel[i].
					   gpu_freq) : 0;
		pwr->pwrlevels[i].bus_freq =
			pdata->pwrlevel[i].bus_freq;
		pwr->pwrlevels[i].bus_min =
			pdata->pwrlevel[i].bus_min;
		pwr->pwrlevels[i].bus_max =
			pdata->pwrlevel[i].bus_max;
					pwr->pwrlevels[i].gpu_freq);
	}

	clk_set_rate(pwr->grp_clks[0], pwr->
@@ -1602,57 +1664,11 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
					KGSL_RBBMTIMER_CLK_FREQ);
	clk_set_rate(pwr->grp_clks[6], rbbmtimer_freq);

	if (of_find_property(device->pdev->dev.of_node,
				"regulator-names", NULL) && pwr->gpu_reg) {
		i = 0;
		of_property_for_each_string(device->pdev->dev.of_node,
						"regulator-names",
						prop,
						reg_name) {
			struct regulator *reg = regulator_get(&pdev->dev,
								reg_name);
			if (IS_ERR(reg)) {
				KGSL_CORE_ERR("Couldn't get regulator: %s\n",
					reg_name);
				result = -ENODEV;
				goto done;
			}
			if (i >= KGSL_MAX_REGULATORS) {
				KGSL_CORE_ERR("No buffer for regulator: %s\n",
					reg_name);
				result = -ENOBUFS;
				goto done;
			}
			pwr->gpu_reg[i] = reg;
			strlcpy(pwr->gpu_reg_name[i],
				reg_name,
				KGSL_MAX_REGULATOR_NAME_LEN);
			++i;
		}
	} else {
		/* for backward compatiblity */
		pwr->gpu_reg[0] = regulator_get(&pdev->dev, "vdd");
		if (IS_ERR(pwr->gpu_reg[0])) {
			KGSL_CORE_ERR("Couldn't get the core regulator.\n");
			result = -ENODEV;
			goto done;
		}

		/* Use vddcx only on targets that have it. */
		if (of_find_property(device->pdev->dev.of_node,
				"vddcx-supply", NULL)) {
			pwr->gpu_reg[1] = regulator_get(&pdev->dev, "vddcx");
			if (IS_ERR(pwr->gpu_reg[1])) {
				KGSL_CORE_ERR(
					"Couldn't get the cx regulator.\n");
				result = -ENODEV;
				goto done;
			}
		}
	}
	result = get_regulators(device);
	if (result)
		return result;

	pwr->interval_timeout = pdata->idle_timeout;
	pwr->strtstp_sleepwake = pdata->strtstp_sleepwake;
	pwr->power_flags = 0;

	if (kgsl_property_read_u32(device, "qcom,pm-qos-active-latency",
		&pwr->pm_qos_active_latency))
@@ -1675,27 +1691,21 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
			pwr->ocmem_pcl = msm_bus_scale_register_client
					(ocmem_scale_table);

		if (!pwr->ocmem_pcl) {
			KGSL_PWR_ERR(device,
				"msm_bus_scale_register_client failed: id %d table %p",
				device->id, ocmem_scale_table);
			result = -EINVAL;
			goto done;
		}
		if (!pwr->ocmem_pcl)
			return -EINVAL;
	}

	/* Set if independent bus BW voting is supported */
	pwr->bus_control = pdata->bus_control;
	/* Bus width in bytes, set it to zero if not found */
	if (of_property_read_u32(pdev->dev.of_node, "qcom,bus-width",
		&pwr->bus_width))
		pwr->bus_width = 0;

	/* Check if gpu bandwidth vote device is defined in dts */
	if (pwr->bus_control) {
	if (pwr->bus_control)
		/* Check if gpu bandwidth vote device is defined in dts */
		gpubw_dev_node = of_parse_phandle(pdev->dev.of_node,
					"qcom,gpubw-dev", 0);

	/*
	 * Governor support enables the gpu bus scaling via governor
	 * and hence no need to register for bus scaling client
@@ -1703,52 +1713,31 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	 */
	if (gpubw_dev_node) {
		p2dev = of_find_device_by_node(gpubw_dev_node);
			if (p2dev) {
		if (p2dev)
			pwr->devbw = &p2dev->dev;
			} else {
				KGSL_PWR_ERR(device,
					"gpubw-dev not available");
				result = -EINVAL;
				goto done;
			}
		} else {
			KGSL_PWR_ERR(device,
				"Unable to find gpubw-dev device in dts");
			result = -EINVAL;
			goto done;
		}
	} else {
		/*
		 * Register for gpu bus scaling if governor support
		 * is not enabled and gpu bus voting is to be done
		 * from the driver.
		 */
		pwr->pcl = msm_bus_scale_register_client
				(pdata->bus_scale_table);
		if (!pwr->pcl) {
			KGSL_PWR_ERR(device,
				"msm_bus_scale_register_client failed: id %d table %p",
				device->id, pdata->bus_scale_table);
			result = -EINVAL;
			goto done;
		}
		pwr->pcl = msm_bus_scale_register_client(bus_scale_table);
		if (pwr->pcl == 0)
			return -EINVAL;
	}

	pwr->bus_ib = kzalloc(pdata->bus_scale_table->num_usecases *
	pwr->bus_ib = kzalloc(bus_scale_table->num_usecases *
		sizeof(*pwr->bus_ib), GFP_KERNEL);
	if (pwr->bus_ib == NULL) {
		KGSL_PWR_ERR(device,
			"No memory allocated for bus structures\n");
		result = -ENOMEM;
		goto done;
	}
	if (pwr->bus_ib == NULL)
		return -ENOMEM;

	/*
	 * Pull the BW vote out of the bus table.  They will be used to
	 * calculate the ratio between the votes.
	 */
	for (i = 0; i < pdata->bus_scale_table->num_usecases; i++) {
	for (i = 0; i < bus_scale_table->num_usecases; i++) {
		struct msm_bus_paths *usecase =
				&pdata->bus_scale_table->usecase[i];
				&bus_scale_table->usecase[i];
		struct msm_bus_vectors *vector = &usecase->vectors[0];
		if (vector->dst == MSM_BUS_SLAVE_EBI_CH0 &&
				vector->ib != 0) {
@@ -1773,7 +1762,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
				n++;
				/* find which pwrlevels use this ib */
				for (m = 0; m < pwr->num_pwrlevels - 1; m++) {
					if (pdata->bus_scale_table->
					if (bus_scale_table->
						usecase[pwr->pwrlevels[m].
						bus_freq].vectors[0].ib
						== vector->ib)
@@ -1796,14 +1785,6 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	devfreq_vbif_register_callback(kgsl_get_bw);

	return result;

clk_err:
	result = PTR_ERR(clk);
	KGSL_PWR_ERR(device, "clk_get(%s) failed: %d\n",
				 clks[i].name, result);

done:
	return result;
}

void kgsl_pwrctrl_close(struct kgsl_device *device)
+21 −2
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
#ifndef __KGSL_PWRCTRL_H
#define __KGSL_PWRCTRL_H

#include <linux/pm_qos.h>

/*****************************************************************************
** power flags
*****************************************************************************/
@@ -30,6 +32,8 @@
#define KGSL_MAX_REGULATORS 2
#define KGSL_MAX_REGULATOR_NAME_LEN 8

#define KGSL_MAX_PWRLEVELS 10

/* Only two supported levels, min & max */
#define KGSL_CONSTRAINT_PWR_MAXLEVELS 2

@@ -85,6 +89,21 @@ struct kgsl_pwr_constraint {
	uint32_t owner_id;
};

/**
 * struct kgsl_pwrlevel - Struct holding different pwrlevel info obtained from
 * from dtsi file
 * @gpu_freq:          GPU frequency vote in Hz
 * @bus_freq:          Bus bandwidth vote index
 * @bus_min:           Min bus index @gpu_freq
 * @bus_max:           Max bus index @gpu_freq
 */
struct kgsl_pwrlevel {
	unsigned int gpu_freq;
	unsigned int bus_freq;
	unsigned int bus_min;
	unsigned int bus_max;
};

/**
 * struct kgsl_pwrctrl - Power control settings for a KGSL device
 * @interrupt_num - The interrupt number for the device
@@ -96,11 +115,11 @@ struct kgsl_pwr_constraint {
 * @previous_pwrlevel - The power level before transition
 * @thermal_pwrlevel - maximum powerlevel constraint from thermal
 * @default_pwrlevel - device wake up power level
 * @init_pwrlevel - device inital power level
 * @max_pwrlevel - maximum allowable powerlevel per the user
 * @min_pwrlevel - minimum allowable powerlevel per the user
 * @num_pwrlevels - number of available power levels
 * @interval_timeout - timeout in jiffies to be idle before a power event
 * @clk_map - bitmap of clock bits to enable for the device
 * @strtstp_sleepwake - true if the device supports low latency GPU start/stop
 * @gpu_reg - array of pointers to the regulator structures
 * @gpu_reg_name - array of pointers to the regulator names
@@ -145,12 +164,12 @@ struct kgsl_pwrctrl {
	unsigned int previous_pwrlevel;
	unsigned int thermal_pwrlevel;
	unsigned int default_pwrlevel;
	unsigned int init_pwrlevel;
	unsigned int wakeup_maxpwrlevel;
	unsigned int max_pwrlevel;
	unsigned int min_pwrlevel;
	unsigned int num_pwrlevels;
	unsigned long interval_timeout;
	unsigned int clk_map;
	bool strtstp_sleepwake;
	struct regulator *gpu_reg[KGSL_MAX_REGULATORS];
	char gpu_reg_name[KGSL_MAX_REGULATORS][KGSL_MAX_REGULATOR_NAME_LEN];
Loading