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

Commit 7fef54d3 authored by Rama Aparna Mallavarapu's avatar Rama Aparna Mallavarapu
Browse files

devfreq: detect ddr type and add frequency table accordingly



Some targets support different DDR types. Detect the DDR type
and populate the frequency table accordingly. OPP framework
supports opp-supported-hw bit map which allows the selected
frequencies to be added to the opp table based on the hardware
version check. Implement the same in the bandwidth monitor device
so that the right frequencies would be added to the opp table.
This patch also adds checks for the latency based device to detect
the DDR type at runtime and add the corresponding frequency map.

Change-Id: Ice5a0b14da67b3f2f07e98bc7349220da7d4efdb
Signed-off-by: default avatarSantosh Mardi <gsantosh@codeaurora.org>
Signed-off-by: default avatarRama Aparna Mallavarapu <aparnam@codeaurora.org>
parent cf8acfa8
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/cpu_pm.h>
#include <linux/cpu_pm.h>
#include <linux/cpu.h>
#include <linux/cpu.h>
#include <linux/of_fdt.h>
#include "governor.h"
#include "governor.h"
#include "governor_memlat.h"
#include "governor_memlat.h"
#include <linux/perf_event.h>
#include <linux/perf_event.h>
@@ -252,6 +253,26 @@ static int get_mask_from_dev_handle(struct platform_device *pdev,
	return ret;
	return ret;
}
}


static struct device_node *parse_child_nodes(struct device *dev)
{
	struct device_node *of_child;
	int ddr_type_of = -1;
	int ddr_type = of_fdt_get_ddrtype();
	int ret;

	for_each_child_of_node(dev->of_node, of_child) {
		ret = of_property_read_u32(of_child, "qcom,ddr-type",
							&ddr_type_of);
		if (!ret && (ddr_type == ddr_type_of)) {
			dev_dbg(dev,
				"ddr-type = %d, is matching DT entry\n",
				ddr_type_of);
			return of_child;
		}
	}
	return NULL;
}

static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
{
{
	struct device *dev = &pdev->dev;
	struct device *dev = &pdev->dev;
@@ -297,6 +318,8 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
	hw->start_hwmon = &start_hwmon;
	hw->start_hwmon = &start_hwmon;
	hw->stop_hwmon = &stop_hwmon;
	hw->stop_hwmon = &stop_hwmon;
	hw->get_cnt = &get_cnt;
	hw->get_cnt = &get_cnt;
	if (of_get_child_count(dev->of_node))
		hw->get_child_of_node = &parse_child_nodes;


	spec = of_device_get_match_data(dev);
	spec = of_device_get_match_data(dev);
	if (spec && spec->is_compute) {
	if (spec && spec->is_compute) {
+15 −0
Original line number Original line Diff line number Diff line
@@ -17,7 +17,9 @@
#include <linux/mutex.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/devfreq.h>
#include <linux/devfreq.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <trace/events/power.h>
#include <trace/events/power.h>
#include <linux/msm-bus.h>
#include <linux/msm-bus.h>
#include <linux/msm-bus-board.h>
#include <linux/msm-bus-board.h>
@@ -101,6 +103,8 @@ int devfreq_add_devbw(struct device *dev)
	u32 ports[MAX_PATHS * 2];
	u32 ports[MAX_PATHS * 2];
	const char *gov_name;
	const char *gov_name;
	int ret, len, i, num_paths;
	int ret, len, i, num_paths;
	struct opp_table *opp_table;
	u32 version;


	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
	if (!d)
	if (!d)
@@ -147,6 +151,15 @@ int devfreq_add_devbw(struct device *dev)
	p->target = devbw_target;
	p->target = devbw_target;
	p->get_dev_status = devbw_get_dev_status;
	p->get_dev_status = devbw_get_dev_status;


	if (of_device_is_compatible(dev->of_node, "qcom,devbw-ddr")) {
		version = (1 << of_fdt_get_ddrtype());
		opp_table = dev_pm_opp_set_supported_hw(dev, &version, 1);
		if (IS_ERR(opp_table)) {
			dev_err(dev, "Failed to set supported hardware\n");
			return PTR_ERR(opp_table);
		}
	}

	ret = dev_pm_opp_of_add_table(dev);
	ret = dev_pm_opp_of_add_table(dev);
	if (ret)
	if (ret)
		dev_err(dev, "Couldn't parse OPP table:%d\n", ret);
		dev_err(dev, "Couldn't parse OPP table:%d\n", ret);
@@ -203,6 +216,8 @@ static int devfreq_devbw_remove(struct platform_device *pdev)
}
}


static const struct of_device_id devbw_match_table[] = {
static const struct of_device_id devbw_match_table[] = {
	{ .compatible = "qcom,devbw-llcc" },
	{ .compatible = "qcom,devbw-ddr" },
	{ .compatible = "qcom,devbw" },
	{ .compatible = "qcom,devbw" },
	{}
	{}
};
};
+18 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/mutex.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/devfreq.h>
#include <linux/devfreq.h>
#include "governor.h"
#include "governor.h"
@@ -419,6 +420,7 @@ static struct devfreq_governor devfreq_gov_compute = {


#define NUM_COLS	2
#define NUM_COLS	2
static struct core_dev_map *init_core_dev_map(struct device *dev,
static struct core_dev_map *init_core_dev_map(struct device *dev,
					struct device_node *of_node,
					char *prop_name)
					char *prop_name)
{
{
	int len, nf, i, j;
	int len, nf, i, j;
@@ -426,7 +428,10 @@ static struct core_dev_map *init_core_dev_map(struct device *dev,
	struct core_dev_map *tbl;
	struct core_dev_map *tbl;
	int ret;
	int ret;


	if (!of_find_property(dev->of_node, prop_name, &len))
	if (!of_node)
		of_node = dev->of_node;

	if (!of_find_property(of_node, prop_name, &len))
		return NULL;
		return NULL;
	len /= sizeof(data);
	len /= sizeof(data);


@@ -440,13 +445,13 @@ static struct core_dev_map *init_core_dev_map(struct device *dev,
		return NULL;
		return NULL;


	for (i = 0, j = 0; i < nf; i++, j += 2) {
	for (i = 0, j = 0; i < nf; i++, j += 2) {
		ret = of_property_read_u32_index(dev->of_node, prop_name, j,
		ret = of_property_read_u32_index(of_node, prop_name, j,
				&data);
				&data);
		if (ret)
		if (ret)
			return NULL;
			return NULL;
		tbl[i].core_mhz = data / 1000;
		tbl[i].core_mhz = data / 1000;


		ret = of_property_read_u32_index(dev->of_node, prop_name, j + 1,
		ret = of_property_read_u32_index(of_node, prop_name, j + 1,
				&data);
				&data);
		if (ret)
		if (ret)
			return NULL;
			return NULL;
@@ -463,6 +468,7 @@ static struct memlat_node *register_common(struct device *dev,
					   struct memlat_hwmon *hw)
					   struct memlat_hwmon *hw)
{
{
	struct memlat_node *node;
	struct memlat_node *node;
	struct device_node *of_child;


	if (!hw->dev && !hw->of_node)
	if (!hw->dev && !hw->of_node)
		return ERR_PTR(-EINVAL);
		return ERR_PTR(-EINVAL);
@@ -474,7 +480,14 @@ static struct memlat_node *register_common(struct device *dev,
	node->ratio_ceil = 10;
	node->ratio_ceil = 10;
	node->hw = hw;
	node->hw = hw;


	hw->freq_map = init_core_dev_map(dev, "qcom,core-dev-table");
	if (hw->get_child_of_node) {
		of_child = hw->get_child_of_node(dev);
		hw->freq_map = init_core_dev_map(dev, of_child,
					"qcom,core-dev-table");
	} else {
		hw->freq_map = init_core_dev_map(dev, NULL,
					"qcom,core-dev-table");
	}
	if (!hw->freq_map) {
	if (!hw->freq_map) {
		dev_err(dev, "Couldn't find the core-dev freq table!\n");
		dev_err(dev, "Couldn't find the core-dev freq table!\n");
		return ERR_PTR(-EINVAL);
		return ERR_PTR(-EINVAL);
+1 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ struct memlat_hwmon {
	int (*start_hwmon)(struct memlat_hwmon *hw);
	int (*start_hwmon)(struct memlat_hwmon *hw);
	void (*stop_hwmon)(struct memlat_hwmon *hw);
	void (*stop_hwmon)(struct memlat_hwmon *hw);
	unsigned long (*get_cnt)(struct memlat_hwmon *hw);
	unsigned long (*get_cnt)(struct memlat_hwmon *hw);
	struct device_node *(*get_child_of_node)(struct device *dev);
	struct device *dev;
	struct device *dev;
	struct device_node *of_node;
	struct device_node *of_node;