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

Commit 76f54bf6 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Fixup the RGMU probe



Fix the RGMU probe to use standard helper functions and do proper
reference counting.

Change-Id: Ic0dedbadf5af14338de83cd9041674cc6f1ea304
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 05fb6786
Loading
Loading
Loading
Loading
+51 −94
Original line number Original line Diff line number Diff line
@@ -23,88 +23,65 @@ static int rgmu_irq_probe(struct kgsl_device *device)
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	int ret;
	int ret;


	rgmu->oob_interrupt_num = platform_get_irq_byname(rgmu->pdev,
	ret = kgsl_request_irq(rgmu->pdev, "kgsl_oob", oob_irq_handler, device);
					"kgsl_oob");
	if (ret < 0)

	ret = devm_request_irq(&rgmu->pdev->dev,
				rgmu->oob_interrupt_num,
				oob_irq_handler, IRQF_TRIGGER_HIGH,
				"kgsl-oob", device);
	if (ret) {
		dev_err(&rgmu->pdev->dev,
				"Request kgsl-oob interrupt failed:%d\n", ret);
		return ret;
		return ret;
	}

	rgmu->rgmu_interrupt_num = platform_get_irq_byname(rgmu->pdev,
			"kgsl_rgmu");


	ret = devm_request_irq(&rgmu->pdev->dev,
	rgmu->oob_interrupt_num  = ret;
			rgmu->rgmu_interrupt_num,
			rgmu_irq_handler, IRQF_TRIGGER_HIGH,
			"kgsl-rgmu", device);
	if (ret)
		dev_err(&rgmu->pdev->dev,
				"Request kgsl-rgmu interrupt failed:%d\n", ret);


	ret = kgsl_request_irq(rgmu->pdev,
		"kgsl_rgmu", rgmu_irq_handler, device);
	if (ret < 0)
		return ret;
		return ret;

	rgmu->rgmu_interrupt_num = ret;
	return 0;
}
}


static int rgmu_regulators_probe(struct rgmu_device *rgmu,
static int rgmu_regulators_probe(struct rgmu_device *rgmu)
		struct device_node *node)
{
{
	int ret;
	int ret = 0;


	rgmu->cx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vddcx");
	rgmu->cx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vddcx");
	if (IS_ERR_OR_NULL(rgmu->cx_gdsc)) {
	if (IS_ERR(rgmu->cx_gdsc)) {
		ret = PTR_ERR(rgmu->cx_gdsc);
		ret = PTR_ERR(rgmu->cx_gdsc);
		if (ret != -EPROBE_DEFER)
			dev_err(&rgmu->pdev->dev,
			dev_err(&rgmu->pdev->dev,
				"Couldn't get CX gdsc error:%d\n", ret);
				"Couldn't get CX gdsc error:%d\n", ret);
		rgmu->cx_gdsc = NULL;
		return ret;
		return ret;
	}
	}


	rgmu->gx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vdd");
	rgmu->gx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vdd");
	if (IS_ERR_OR_NULL(rgmu->gx_gdsc)) {
	if (IS_ERR(rgmu->gx_gdsc)) {
		ret = PTR_ERR(rgmu->gx_gdsc);
		ret = PTR_ERR(rgmu->gx_gdsc);
		if (ret != -EPROBE_DEFER)
			dev_err(&rgmu->pdev->dev,
			dev_err(&rgmu->pdev->dev,
				"Couldn't get GX gdsc error:%d\n", ret);
				"Couldn't get GX gdsc error:%d\n", ret);
		rgmu->gx_gdsc = NULL;
		return ret;
	}
	}


	return 0;
	return ret;
}
}


static int rgmu_clocks_probe(struct rgmu_device *rgmu, struct device_node *node)
static int rgmu_clocks_probe(struct rgmu_device *rgmu, struct device_node *node)
{
{
	const char *cname;
	int ret;
	struct property *prop;
	struct clk *c;
	int i = 0;


	of_property_for_each_string(node, "clock-names", prop, cname) {
	ret = devm_clk_bulk_get_all(&rgmu->pdev->dev, &rgmu->clks);
	if (ret < 0)
		return ret;


		if (i >= ARRAY_SIZE(rgmu->clks)) {
	rgmu->num_clks = ret;
			dev_err(&rgmu->pdev->dev,
				"dt: too many RGMU clocks defined\n");
			return -EINVAL;
		}


		c = devm_clk_get(&rgmu->pdev->dev, cname);
	rgmu->gpu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "core");
		if (IS_ERR_OR_NULL(c)) {
	if (!rgmu->gpu_clk) {
			dev_err(&rgmu->pdev->dev,
		dev_err(&rgmu->pdev->dev, "The GPU clock isn't defined\n");
				"dt: Couldn't get clock: %s\n", cname);
		return -ENODEV;
			return PTR_ERR(c);
	}
	}


		/* Remember the key clocks that we need to control later */
	rgmu->rgmu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "gmu");
		if (!strcmp(cname, "core"))
	if (!rgmu->rgmu_clk) {
			rgmu->gpu_clk = c;
		dev_err(&rgmu->pdev->dev, "The RGMU clock isn't defined\n");
		else if (!strcmp(cname, "gmu"))
		return -ENODEV;
			rgmu->rgmu_clk = c;

		rgmu->clks[i++] = c;
	}
	}


	return 0;
	return 0;
@@ -114,7 +91,7 @@ static void rgmu_disable_clks(struct kgsl_device *device)
{
{
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
	struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
	int j = 0, ret;
	int  ret;


	/* Check GX GDSC is status */
	/* Check GX GDSC is status */
	if (gmu_dev_ops->gx_is_on(device)) {
	if (gmu_dev_ops->gx_is_on(device)) {
@@ -141,22 +118,17 @@ static void rgmu_disable_clks(struct kgsl_device *device)
			dev_err(&rgmu->pdev->dev, "gx is stuck on\n");
			dev_err(&rgmu->pdev->dev, "gx is stuck on\n");
	}
	}


	for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++)
	clk_bulk_disable_unprepare(rgmu->num_clks, rgmu->clks);
		clk_disable_unprepare(rgmu->clks[j]);


	clear_bit(GMU_CLK_ON, &device->gmu_core.flags);
	clear_bit(GMU_CLK_ON, &device->gmu_core.flags);
}
}


static int rgmu_enable_clks(struct kgsl_device *device)
static int rgmu_enable_clks(struct kgsl_device *device)
{
{
	int ret, j = 0;
	int ret;
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;


	if (IS_ERR_OR_NULL(rgmu->rgmu_clk) ||
			IS_ERR_OR_NULL(rgmu->gpu_clk))
		return -EINVAL;

	ret = clk_set_rate(rgmu->rgmu_clk, RGMU_CLK_FREQ);
	ret = clk_set_rate(rgmu->rgmu_clk, RGMU_CLK_FREQ);
	if (ret) {
	if (ret) {
		dev_err(&rgmu->pdev->dev, "Couldn't set the RGMU clock\n");
		dev_err(&rgmu->pdev->dev, "Couldn't set the RGMU clock\n");
@@ -170,15 +142,11 @@ static int rgmu_enable_clks(struct kgsl_device *device)
		return ret;
		return ret;
	}
	}


	for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++) {
	ret = clk_bulk_prepare_enable(rgmu->num_clks, rgmu->clks);
		ret = clk_prepare_enable(rgmu->clks[j]);
	if (ret) {
	if (ret) {
			dev_err(&rgmu->pdev->dev,
		dev_err(&rgmu->pdev->dev, "Failed to enable RGMU clocks\n");
					"Fail(%d) to enable gpucc clk idx %d\n",
					ret, j);
		return ret;
		return ret;
	}
	}
	}


	set_bit(GMU_CLK_ON, &device->gmu_core.flags);
	set_bit(GMU_CLK_ON, &device->gmu_core.flags);
	return 0;
	return 0;
@@ -289,42 +257,31 @@ static int rgmu_probe(struct kgsl_device *device, struct platform_device *pdev)
	rgmu->pdev = pdev;
	rgmu->pdev = pdev;


	/* Set up RGMU regulators */
	/* Set up RGMU regulators */
	ret = rgmu_regulators_probe(rgmu, pdev->dev.of_node);
	ret = rgmu_regulators_probe(rgmu);
	if (ret)
	if (ret)
		return ret;
		return ret;


	/* Set up RGMU clocks */
	ret = rgmu_clocks_probe(rgmu, pdev->dev.of_node);
	ret = rgmu_clocks_probe(rgmu, pdev->dev.of_node);
	if (ret)
	if (ret)
		return ret;
		return ret;


	/* Map and reserve RGMU CSRs registers */
	/* Map and reserve RGMU CSRs registers */
	res = platform_get_resource_byname(rgmu->pdev,
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "kgsl_rgmu");
			IORESOURCE_MEM, "kgsl_rgmu");
	if (!res) {
	if (res == NULL) {
		dev_err(&pdev->dev, "The RGMU register region isn't defined\n");
		dev_err(&rgmu->pdev->dev,
		return -ENODEV;
				"platform_get_resource failed\n");
		return -EINVAL;
	}

	if (res->start == 0 || resource_size(res) == 0) {
		dev_err(&rgmu->pdev->dev,
				"Register region is invalid\n");
		return -EINVAL;
	}
	}


	rgmu->reg_phys = res->start;
	device->gmu_core.gmu2gpu_offset = (res->start - device->reg_phys) >> 2;
	rgmu->reg_len = resource_size(res);
	device->gmu_core.reg_len = resource_size(res);
	device->gmu_core.reg_virt = devm_ioremap(&rgmu->pdev->dev, res->start,
	device->gmu_core.reg_virt = devm_ioremap_resource(&pdev->dev, res);
			resource_size(res));


	if (device->gmu_core.reg_virt == NULL) {
	if (IS_ERR(device->gmu_core.reg_virt)) {
		dev_err(&rgmu->pdev->dev, "Unable to remap rgmu registers\n");
		dev_err(&pdev->dev, "Unable to map the RGMU registers\n");
		return -ENODEV;
		return PTR_ERR(device->gmu_core.reg_virt);
	}
	}


	device->gmu_core.gmu2gpu_offset =
			(rgmu->reg_phys - device->reg_phys) >> 2;
	device->gmu_core.reg_len = rgmu->reg_len;
	device->gmu_core.ptr = (void *)rgmu;
	device->gmu_core.ptr = (void *)rgmu;


	/* Initialize OOB and RGMU interrupts */
	/* Initialize OOB and RGMU interrupts */
+4 −7
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */
 */
#ifndef __KGSL_RGMU_H
#ifndef __KGSL_RGMU_H
#define __KGSL_RGMU_H
#define __KGSL_RGMU_H
@@ -18,9 +18,6 @@
/**
/**
 * struct rgmu_device - rGMU device structure
 * struct rgmu_device - rGMU device structure
 * @ver: RGMU firmware version
 * @ver: RGMU firmware version
 * @reg_phys: RGMU CSR physical address
 * @reg_virt: RGMU CSR virtual address
 * @reg_len: RGMU CSR range
 * @rgmu_interrupt_num: RGMU interrupt number
 * @rgmu_interrupt_num: RGMU interrupt number
 * @oob_interrupt_num: number of RGMU asserted OOB interrupt
 * @oob_interrupt_num: number of RGMU asserted OOB interrupt
 * @fw_hostptr: Buffer which holds the RGMU firmware
 * @fw_hostptr: Buffer which holds the RGMU firmware
@@ -37,15 +34,15 @@
struct rgmu_device {
struct rgmu_device {
	u32 ver;
	u32 ver;
	struct platform_device *pdev;
	struct platform_device *pdev;
	unsigned long reg_phys;
	unsigned int reg_len;
	unsigned int rgmu_interrupt_num;
	unsigned int rgmu_interrupt_num;
	unsigned int oob_interrupt_num;
	unsigned int oob_interrupt_num;
	unsigned int *fw_hostptr;
	unsigned int *fw_hostptr;
	uint32_t fw_size;
	uint32_t fw_size;
	struct regulator *cx_gdsc;
	struct regulator *cx_gdsc;
	struct regulator *gx_gdsc;
	struct regulator *gx_gdsc;
	struct clk *clks[MAX_RGMU_CLKS];
	struct clk_bulk_data *clks;
	/** @num_clks: Number of clocks in @clks */
	int num_clks;
	struct clk *gpu_clk;
	struct clk *gpu_clk;
	struct clk *rgmu_clk;
	struct clk *rgmu_clk;
	unsigned int idle_level;
	unsigned int idle_level;