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

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

Merge "ARM: dts: msm: Enable the OSM clock controller for TRINKET"

parents 6b62afdd cfdafba1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -11,7 +11,8 @@ Properties:
	Value type: <string>
	Definition: must be "qcom,clk-cpu-osm" or "qcom,clk-cpu-osm-sdmshrike"
			or "qcom,clk-cpu-osm-sm6150" or
			"qcom,clk-cpu-osm-sdmmagpie".
			"qcom,clk-cpu-osm-sdmmagpie" or
			"qcom,clk-cpu-osm-trinket".

- reg
	Usage:      required
+14 −6
Original line number Diff line number Diff line
@@ -829,6 +829,19 @@
		reg = <0x0447d200 0x100>;
	};

	cpucc_debug: syscon@f11101c {
		compatible = "syscon";
		reg = <0xf11101c 0x4>;
	};

	clock_cpucc: qcom,cpucc@f521000 {
		compatible = "qcom,clk-cpu-osm-trinket";
		reg = <0xf521000 0x1400>,
			<0xf523000 0x1400>;
		reg-names = "osm_pwrcl_base", "osm_perfcl_base";
		#clock-cells = <1>;
	};

	clock_debugcc: qcom,cc-debug {
		compatible = "qcom,debugcc-trinket";
		qcom,gcc = <&clock_gcc>;
@@ -836,17 +849,12 @@
		qcom,dispcc = <&clock_dispcc>;
		qcom,gpucc = <&clock_gpucc>;
		qcom,mccc = <&mccc_debug>;
		qcom,cpucc = <&cpucc_debug>;
		clock-names = "cxo";
		clocks = <&clock_rpmcc RPM_SMD_XO_CLK_SRC>;
		#clock-cells = <1>;
	};

	clock_cpucc: qcom,cpucc {
		compatible = "qcom,dummycc";
		clock-output-names = "cpucc_clocks";
		#clock-cells = <1>;
	};

	icnss: qcom,icnss@C800000 {
		compatible = "qcom,icnss";
		reg = <0xC800000 0x800000>,
+83 −35
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/err.h>
#include <asm/smp_plat.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
@@ -41,6 +42,7 @@
#define OSM_INIT_RATE			300000000UL
#define XO_RATE				19200000UL
#define OSM_TABLE_SIZE			40
#define OSM_TABLE_REDUCED_SIZE		12
#define SINGLE_CORE_COUNT		1
#define CORE_COUNT_VAL(val)		((val & GENMASK(18, 16)) >> 16)

@@ -76,6 +78,7 @@ struct clk_osm {
	u32 num_entries;
	u32 cluster_num;
	u32 core_num;
	u32 osm_table_size;
	u64 total_cycle_counter;
	u32 prev_cycle_counter;
	unsigned long rate;
@@ -85,6 +88,7 @@ struct clk_osm {
static bool is_sdmshrike;
static bool is_sm6150;
static bool is_sdmmagpie;
static bool is_trinket;

static inline struct clk_osm *to_clk_osm(struct clk_hw *_hw)
{
@@ -301,6 +305,7 @@ static struct clk_init_data osm_clks_init[] = {

static struct clk_osm l3_clk = {
	.cluster_num = 0,
	.osm_table_size = OSM_TABLE_SIZE,
	.hw.init = &osm_clks_init[0],
};

@@ -312,6 +317,7 @@ static DEFINE_CLK_VOTER(l3_gpu_vote_clk, l3_clk, 0);

static struct clk_osm pwrcl_clk = {
	.cluster_num = 1,
	.osm_table_size = OSM_TABLE_SIZE,
	.hw.init = &osm_clks_init[1],
};

@@ -389,6 +395,7 @@ static struct clk_osm cpu5_pwrcl_clk = {

static struct clk_osm perfcl_clk = {
	.cluster_num = 2,
	.osm_table_size = OSM_TABLE_SIZE,
	.hw.init = &osm_clks_init[2],
};

@@ -442,6 +449,7 @@ static struct clk_osm cpu7_perfcl_clk = {

static struct clk_osm perfpcl_clk = {
	.cluster_num = 3,
	.osm_table_size = OSM_TABLE_SIZE,
	.hw.init = &osm_clks_init[3],
};

@@ -512,7 +520,11 @@ static struct clk_osm *logical_cpu_to_clk(int cpu)
		}

		hwid = of_read_number(cell, of_n_addr_cells(cpu_node));
		if (is_trinket)
			hwid = get_logical_index(hwid);
		else
			hwid = (hwid >> 8) & 0xff;

		of_node_put(cpu_node);
		if (hwid >= ARRAY_SIZE(clk_cpu_map)) {
			pr_err("unsupported CPU number - %d (hw_id - %llu)\n",
@@ -643,11 +655,11 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
	parent = to_clk_osm(p_hw);
	c->vbase = parent->vbase;

	table = kcalloc(OSM_TABLE_SIZE + 1, sizeof(*table), GFP_KERNEL);
	table = kcalloc(parent->osm_table_size + 1, sizeof(*table), GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	for (i = 0; i < OSM_TABLE_SIZE; i++) {
	for (i = 0; i < parent->osm_table_size; i++) {
		u32 data, src, div, lval, core_count;

		data = clk_osm_read_reg(c, FREQ_REG + i * OSM_REG_SIZE);
@@ -876,6 +888,7 @@ static void populate_opp_table(struct platform_device *pdev)
					dev_name(cpu_dev));
	}

	if (!is_trinket)
		populate_l3_opp_table(np, "l3-devs");
}

@@ -920,9 +933,9 @@ static u64 clk_osm_get_cpu_cycle_counter(int cpu)

static int clk_osm_read_lut(struct platform_device *pdev, struct clk_osm *c)
{
	u32 data, src, lval, i, j = OSM_TABLE_SIZE;
	u32 data, src, lval, i, j = c->osm_table_size;

	for (i = 0; i < OSM_TABLE_SIZE; i++) {
	for (i = 0; i < c->osm_table_size; i++) {
		data = clk_osm_read_reg(c, FREQ_REG + i * OSM_REG_SIZE);
		src = ((data & GENMASK(31, 30)) >> 30);
		lval = (data & GENMASK(7, 0));
@@ -942,7 +955,8 @@ static int clk_osm_read_lut(struct platform_device *pdev, struct clk_osm *c)
			 c->osm_table[i].virtual_corner,
			 c->osm_table[i].open_loop_volt);

		if (i > 0 && j == OSM_TABLE_SIZE && c->osm_table[i].frequency ==
		if (i > 0 && j == c->osm_table_size &&
				c->osm_table[i].frequency ==
				c->osm_table[i - 1].frequency)
			j = i;
	}
@@ -965,6 +979,7 @@ static int clk_osm_resources_init(struct platform_device *pdev)
{
	struct resource *res;

	if (!is_trinket) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"osm_l3_base");
		if (!res) {
@@ -974,12 +989,14 @@ static int clk_osm_resources_init(struct platform_device *pdev)
		}

		l3_clk.pbase = (unsigned long)res->start;
	l3_clk.vbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		l3_clk.vbase = devm_ioremap(&pdev->dev, res->start,
							resource_size(res));

		if (!l3_clk.vbase) {
			dev_err(&pdev->dev, "Unable to map osm_l3_base base\n");
			return -ENOMEM;
		}
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						"osm_pwrcl_base");
@@ -1014,7 +1031,7 @@ static int clk_osm_resources_init(struct platform_device *pdev)
		return -ENOMEM;
	}

	if (is_sdmshrike || is_sm6150 || is_sdmmagpie)
	if (is_sdmshrike || is_sm6150 || is_sdmmagpie || is_trinket)
		return 0;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -1056,6 +1073,25 @@ static void clk_cpu_osm_driver_sm6150_fixup(void)
	clk_cpu_map[7] = &cpu7_perfcl_clk;
}

static void clk_cpu_osm_driver_trinket_fixup(void)
{
	pwrcl_clk.osm_table_size = OSM_TABLE_REDUCED_SIZE;
	perfcl_clk.osm_table_size = OSM_TABLE_REDUCED_SIZE;

	osm_qcom_clk_hws[L3_CLUSTER0_VOTE_CLK] = NULL,
	osm_qcom_clk_hws[L3_CLUSTER1_VOTE_CLK] = NULL,
	osm_qcom_clk_hws[L3_CLUSTER2_VOTE_CLK] = NULL,
	osm_qcom_clk_hws[L3_MISC_VOTE_CLK] = NULL,
	osm_qcom_clk_hws[L3_GPU_VOTE_CLK] = NULL,
	osm_qcom_clk_hws[L3_CLK] = NULL,
	osm_qcom_clk_hws[CPU7_PERFPCL_CLK] = NULL,
	osm_qcom_clk_hws[PERFPCL_CLK] = NULL,
	osm_qcom_clk_hws[CPU4_PWRCL_CLK] = NULL,
	osm_qcom_clk_hws[CPU5_PWRCL_CLK] = NULL,
	osm_qcom_clk_hws[CPU7_PERFCL_CLK] = &cpu7_perfcl_clk.hw;
	clk_cpu_map[7] = &cpu7_perfcl_clk;
}

static void clk_cpu_osm_driver_sdmshrike_fixup(void)
{
	osm_qcom_clk_hws[CPU7_PERFPCL_CLK] = NULL;
@@ -1077,6 +1113,9 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
		.get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter,
	};

	is_trinket = of_device_is_compatible(pdev->dev.of_node,
				"qcom,clk-cpu-osm-trinket");

	is_sdmmagpie = of_device_is_compatible(pdev->dev.of_node,
				"qcom,clk-cpu-osm-sdmmagpie");

@@ -1089,6 +1128,8 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
		clk_cpu_osm_driver_sdmshrike_fixup();
	else if (is_sm6150 || is_sdmmagpie)
		clk_cpu_osm_driver_sm6150_fixup();
	else if (is_trinket)
		clk_cpu_osm_driver_trinket_fixup();

	clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
								GFP_KERNEL);
@@ -1119,12 +1160,14 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
	if (val & BIT(0))
		perfcl_clk.per_core_dcvs = true;

	if (!is_trinket) {
		rc = clk_osm_read_lut(pdev, &l3_clk);
		if (rc) {
			dev_err(&pdev->dev, "Unable to read OSM LUT for L3, rc=%d\n",
				rc);
			return rc;
		}
	}

	rc = clk_osm_read_lut(pdev, &pwrcl_clk);
	if (rc) {
@@ -1140,7 +1183,7 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
		return rc;
	}

	if (!is_sdmshrike && !is_sm6150 && !is_sdmmagpie) {
	if (!is_sdmshrike && !is_sm6150 && !is_sdmmagpie && !is_trinket) {
		rc = clk_osm_read_lut(pdev, &perfpcl_clk);
		if (rc) {
			dev_err(&pdev->dev, "Unable to read OSM LUT for perf plus cluster, rc=%d\n",
@@ -1149,9 +1192,11 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
		}
	}

	if (!is_trinket)
		spin_lock_init(&l3_clk.lock);
	spin_lock_init(&pwrcl_clk.lock);
	spin_lock_init(&perfcl_clk.lock);
	if (!is_trinket)
		spin_lock_init(&perfpcl_clk.lock);

	/* Register OSM l3, pwr and perf clocks with Clock Framework */
@@ -1177,6 +1222,7 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)

	get_online_cpus();

	if (!is_trinket) {
		WARN(clk_prepare_enable(l3_cluster0_vote_clk.hw.clk),
			"clk: Failed to enable cluster0 clock for L3\n");
		WARN(clk_prepare_enable(l3_cluster1_vote_clk.hw.clk),
@@ -1187,6 +1233,7 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
			"clk: Failed to enable misc clock for L3\n");
		WARN(clk_prepare_enable(l3_gpu_vote_clk.hw.clk),
			"clk: Failed to enable gpu clock for L3\n");
	}

	populate_opp_table(pdev);

@@ -1216,6 +1263,7 @@ static const struct of_device_id match_table[] = {
	{ .compatible = "qcom,clk-cpu-osm" },
	{ .compatible = "qcom,clk-cpu-osm-sm6150" },
	{ .compatible = "qcom,clk-cpu-osm-sdmmagpie" },
	{ .compatible = "qcom,clk-cpu-osm-trinket" },
	{ .compatible = "qcom,clk-cpu-osm-sdmshrike" },
	{}
};
+10 −0
Original line number Diff line number Diff line
@@ -226,6 +226,8 @@ static const char *const debug_mux_parent_names[] = {
	"video_cc_venus_ctl_axi_clk",
	"video_cc_venus_ctl_core_clk",
	"video_cc_xo_clk",
	"pwrcl_clk",
	"perfcl_clk",
};

static struct clk_debug_mux gcc_debug_mux = {
@@ -625,6 +627,10 @@ static struct clk_debug_mux gcc_debug_mux = {
			0x1, 0x3F, 0, 0x7, 0, 5, 0xA4C, 0xA30, 0xA38 },
		{ "video_cc_xo_clk", 0x42, 1, VIDEO_CC,
			0xC, 0x3F, 0, 0x7, 0, 5, 0xA4C, 0xA30, 0xA38 },
		{ "pwrcl_clk", 0xAB, 4, CPU_CC,
			0x0, 0x3FF, 8, 0xF, 28, 1, 0x0, 0x0, U32_MAX, 8 },
		{ "perfcl_clk", 0xAB, 4, CPU_CC,
			0x1, 0x3FF, 8, 0xF, 28, 1, 0x0, 0x0, U32_MAX, 8 },
	),
	.hw.init = &(struct clk_init_data){
		.name = "gcc_debug_mux",
@@ -698,6 +704,10 @@ static int clk_debug_trinket_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	ret = map_debug_bases(pdev, "qcom,cpucc", CPU_CC);
	if (ret)
		return ret;

	clk = devm_clk_register(&pdev->dev, &gcc_debug_mux.hw);
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "Unable to register GCC debug mux\n");