Commit 01f8938a authored by Georgi Djakov's avatar Georgi Djakov
Browse files

Merge branch 'icc-qcm2290' into icc-next

Add support for QCM2290 including a few prep changes.

* icc-qcm2290
  interconnect: icc-rpm: Define ICC device type
  interconnect: icc-rpm: Add QNOC type QoS support
  interconnect: icc-rpm: Support child NoC device probe
  dt-bindings: interconnect: Add Qualcomm QCM2290 NoC support
  interconnect: qcom: Add QCM2290 driver support

Link: https://lore.kernel.org/r/20211215002324.1727-1-shawn.guo@linaro.org


Signed-off-by: default avatarGeorgi Djakov <djakov@kernel.org>
parents 4a5cf65d 1a14b1ac
Loading
Loading
Loading
Loading
+137 −0
Original line number Original line Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,qcm2290.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Qualcomm QCM2290 Network-On-Chip interconnect

maintainers:
  - Shawn Guo <shawn.guo@linaro.org>

description: |
  The Qualcomm QCM2290 interconnect providers support adjusting the
  bandwidth requirements between the various NoC fabrics.

properties:
  reg:
    maxItems: 1

  compatible:
    enum:
      - qcom,qcm2290-bimc
      - qcom,qcm2290-cnoc
      - qcom,qcm2290-snoc

  '#interconnect-cells':
    const: 1

  clock-names:
    items:
      - const: bus
      - const: bus_a

  clocks:
    items:
      - description: Bus Clock
      - description: Bus A Clock

# Child node's properties
patternProperties:
  '^interconnect-[a-z0-9]+$':
    type: object
    description:
      The interconnect providers do not have a separate QoS register space,
      but share parent's space.

    properties:
      compatible:
        enum:
          - qcom,qcm2290-qup-virt
          - qcom,qcm2290-mmrt-virt
          - qcom,qcm2290-mmnrt-virt

      '#interconnect-cells':
        const: 1

      clock-names:
        items:
          - const: bus
          - const: bus_a

      clocks:
        items:
          - description: Bus Clock
          - description: Bus A Clock

    required:
      - compatible
      - '#interconnect-cells'
      - clock-names
      - clocks

    additionalProperties: false

required:
  - compatible
  - reg
  - '#interconnect-cells'
  - clock-names
  - clocks

additionalProperties: false

examples:
  - |
    #include <dt-bindings/clock/qcom,rpmcc.h>

    snoc: interconnect@1880000 {
        compatible = "qcom,qcm2290-snoc";
        reg = <0x01880000 0x60200>;
        #interconnect-cells = <1>;
        clock-names = "bus", "bus_a";
        clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
                 <&rpmcc RPM_SMD_SNOC_A_CLK>;

        qup_virt: interconnect-qup {
            compatible = "qcom,qcm2290-qup-virt";
            #interconnect-cells = <1>;
            clock-names = "bus", "bus_a";
            clocks = <&rpmcc RPM_SMD_QUP_CLK>,
                     <&rpmcc RPM_SMD_QUP_A_CLK>;
        };

        mmnrt_virt: interconnect-mmnrt {
            compatible = "qcom,qcm2290-mmnrt-virt";
            #interconnect-cells = <1>;
            clock-names = "bus", "bus_a";
            clocks = <&rpmcc RPM_SMD_MMNRT_CLK>,
                     <&rpmcc RPM_SMD_MMNRT_A_CLK>;
        };

        mmrt_virt: interconnect-mmrt {
            compatible = "qcom,qcm2290-mmrt-virt";
            #interconnect-cells = <1>;
            clock-names = "bus", "bus_a";
            clocks = <&rpmcc RPM_SMD_MMRT_CLK>,
                     <&rpmcc RPM_SMD_MMRT_A_CLK>;
        };
    };

    cnoc: interconnect@1900000 {
        compatible = "qcom,qcm2290-cnoc";
        reg = <0x01900000 0x8200>;
        #interconnect-cells = <1>;
        clock-names = "bus", "bus_a";
        clocks = <&rpmcc RPM_SMD_CNOC_CLK>,
                 <&rpmcc RPM_SMD_CNOC_A_CLK>;
    };

    bimc: interconnect@4480000 {
        compatible = "qcom,qcm2290-bimc";
        reg = <0x04480000 0x80000>;
        #interconnect-cells = <1>;
        clock-names = "bus", "bus_a";
        clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
                 <&rpmcc RPM_SMD_BIMC_A_CLK>;
    };
+9 −0
Original line number Original line Diff line number Diff line
@@ -51,6 +51,15 @@ config INTERCONNECT_QCOM_OSM_L3
	  Say y here to support the Operating State Manager (OSM) interconnect
	  Say y here to support the Operating State Manager (OSM) interconnect
	  driver which controls the scaling of L3 caches on Qualcomm SoCs.
	  driver which controls the scaling of L3 caches on Qualcomm SoCs.


config INTERCONNECT_QCOM_QCM2290
	tristate "Qualcomm QCM2290 interconnect driver"
	depends on INTERCONNECT_QCOM
	depends on QCOM_SMD_RPM
	select INTERCONNECT_QCOM_SMD_RPM
	help
	  This is a driver for the Qualcomm Network-on-Chip on qcm2290-based
	  platforms.

config INTERCONNECT_QCOM_QCS404
config INTERCONNECT_QCOM_QCS404
	tristate "Qualcomm QCS404 interconnect driver"
	tristate "Qualcomm QCS404 interconnect driver"
	depends on INTERCONNECT_QCOM
	depends on INTERCONNECT_QCOM
+2 −0
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@ qnoc-msm8939-objs := msm8939.o
qnoc-msm8974-objs			:= msm8974.o
qnoc-msm8974-objs			:= msm8974.o
qnoc-msm8996-objs			:= msm8996.o
qnoc-msm8996-objs			:= msm8996.o
icc-osm-l3-objs				:= osm-l3.o
icc-osm-l3-objs				:= osm-l3.o
qnoc-qcm2290-objs			:= qcm2290.o
qnoc-qcs404-objs			:= qcs404.o
qnoc-qcs404-objs			:= qcs404.o
icc-rpmh-obj				:= icc-rpmh.o
icc-rpmh-obj				:= icc-rpmh.o
qnoc-sc7180-objs			:= sc7180.o
qnoc-sc7180-objs			:= sc7180.o
@@ -26,6 +27,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8939) += qnoc-msm8939.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o
obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o
obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o
obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o
+47 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,13 @@
#include "smd-rpm.h"
#include "smd-rpm.h"
#include "icc-rpm.h"
#include "icc-rpm.h"


/* QNOC QoS */
#define QNOC_QOS_MCTL_LOWn_ADDR(n)	(0x8 + (n * 0x1000))
#define QNOC_QOS_MCTL_DFLT_PRIO_MASK	0x70
#define QNOC_QOS_MCTL_DFLT_PRIO_SHIFT	4
#define QNOC_QOS_MCTL_URGFWD_EN_MASK	0x8
#define QNOC_QOS_MCTL_URGFWD_EN_SHIFT	3

/* BIMC QoS */
/* BIMC QoS */
#define M_BKE_REG_BASE(n)		(0x300 + (0x4000 * n))
#define M_BKE_REG_BASE(n)		(0x300 + (0x4000 * n))
#define M_BKE_EN_ADDR(n)		(M_BKE_REG_BASE(n))
#define M_BKE_EN_ADDR(n)		(M_BKE_REG_BASE(n))
@@ -40,6 +47,27 @@
#define NOC_QOS_MODEn_ADDR(n)		(0xc + (n * 0x1000))
#define NOC_QOS_MODEn_ADDR(n)		(0xc + (n * 0x1000))
#define NOC_QOS_MODEn_MASK		0x3
#define NOC_QOS_MODEn_MASK		0x3


static int qcom_icc_set_qnoc_qos(struct icc_node *src, u64 max_bw)
{
	struct icc_provider *provider = src->provider;
	struct qcom_icc_provider *qp = to_qcom_provider(provider);
	struct qcom_icc_node *qn = src->data;
	struct qcom_icc_qos *qos = &qn->qos;
	int rc;

	rc = regmap_update_bits(qp->regmap,
			qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port),
			QNOC_QOS_MCTL_DFLT_PRIO_MASK,
			qos->areq_prio << QNOC_QOS_MCTL_DFLT_PRIO_SHIFT);
	if (rc)
		return rc;

	return regmap_update_bits(qp->regmap,
			qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port),
			QNOC_QOS_MCTL_URGFWD_EN_MASK,
			!!qos->urg_fwd_en << QNOC_QOS_MCTL_URGFWD_EN_SHIFT);
}

static int qcom_icc_bimc_set_qos_health(struct qcom_icc_provider *qp,
static int qcom_icc_bimc_set_qos_health(struct qcom_icc_provider *qp,
					struct qcom_icc_qos *qos,
					struct qcom_icc_qos *qos,
					int regnum)
					int regnum)
@@ -164,11 +192,15 @@ static int qcom_icc_qos_set(struct icc_node *node, u64 sum_bw)


	dev_dbg(node->provider->dev, "Setting QoS for %s\n", qn->name);
	dev_dbg(node->provider->dev, "Setting QoS for %s\n", qn->name);


	if (qp->is_bimc_node)
	switch (qp->type) {
	case QCOM_ICC_BIMC:
		return qcom_icc_set_bimc_qos(node, sum_bw);
		return qcom_icc_set_bimc_qos(node, sum_bw);

	case QCOM_ICC_QNOC:
		return qcom_icc_set_qnoc_qos(node, sum_bw);
	default:
		return qcom_icc_set_noc_qos(node, sum_bw);
		return qcom_icc_set_noc_qos(node, sum_bw);
	}
	}
}


static int qcom_icc_rpm_set(int mas_rpm_id, int slv_rpm_id, u64 sum_bw)
static int qcom_icc_rpm_set(int mas_rpm_id, int slv_rpm_id, u64 sum_bw)
{
{
@@ -309,7 +341,7 @@ int qnoc_probe(struct platform_device *pdev)
		qp->bus_clks[i].id = cds[i];
		qp->bus_clks[i].id = cds[i];
	qp->num_clks = cd_num;
	qp->num_clks = cd_num;


	qp->is_bimc_node = desc->is_bimc_node;
	qp->type = desc->type;
	qp->qos_offset = desc->qos_offset;
	qp->qos_offset = desc->qos_offset;


	if (desc->regmap_cfg) {
	if (desc->regmap_cfg) {
@@ -317,8 +349,13 @@ int qnoc_probe(struct platform_device *pdev)
		void __iomem *mmio;
		void __iomem *mmio;


		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		if (!res)
		if (!res) {
			/* Try parent's regmap */
			qp->regmap = dev_get_regmap(dev->parent, NULL);
			if (qp->regmap)
				goto regmap_done;
			return -ENODEV;
			return -ENODEV;
		}


		mmio = devm_ioremap_resource(dev, res);
		mmio = devm_ioremap_resource(dev, res);


@@ -334,6 +371,7 @@ int qnoc_probe(struct platform_device *pdev)
		}
		}
	}
	}


regmap_done:
	ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
	ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
	if (ret)
	if (ret)
		return ret;
		return ret;
@@ -385,6 +423,10 @@ int qnoc_probe(struct platform_device *pdev)


	platform_set_drvdata(pdev, qp);
	platform_set_drvdata(pdev, qp);


	/* Populate child NoC devices if any */
	if (of_get_child_count(dev->of_node) > 0)
		return of_platform_populate(dev->of_node, NULL, NULL, dev);

	return 0;
	return 0;
err:
err:
	icc_nodes_remove(provider);
	icc_nodes_remove(provider);
+11 −3
Original line number Original line Diff line number Diff line
@@ -12,19 +12,25 @@
#define to_qcom_provider(_provider) \
#define to_qcom_provider(_provider) \
	container_of(_provider, struct qcom_icc_provider, provider)
	container_of(_provider, struct qcom_icc_provider, provider)


enum qcom_icc_type {
	QCOM_ICC_NOC,
	QCOM_ICC_BIMC,
	QCOM_ICC_QNOC,
};

/**
/**
 * struct qcom_icc_provider - Qualcomm specific interconnect provider
 * struct qcom_icc_provider - Qualcomm specific interconnect provider
 * @provider: generic interconnect provider
 * @provider: generic interconnect provider
 * @bus_clks: the clk_bulk_data table of bus clocks
 * @bus_clks: the clk_bulk_data table of bus clocks
 * @num_clks: the total number of clk_bulk_data entries
 * @num_clks: the total number of clk_bulk_data entries
 * @is_bimc_node: indicates whether to use bimc specific setting
 * @type: the ICC provider type
 * @qos_offset: offset to QoS registers
 * @qos_offset: offset to QoS registers
 * @regmap: regmap for QoS registers read/write access
 * @regmap: regmap for QoS registers read/write access
 */
 */
struct qcom_icc_provider {
struct qcom_icc_provider {
	struct icc_provider provider;
	struct icc_provider provider;
	int num_clks;
	int num_clks;
	bool is_bimc_node;
	enum qcom_icc_type type;
	struct regmap *regmap;
	struct regmap *regmap;
	unsigned int qos_offset;
	unsigned int qos_offset;
	struct clk_bulk_data bus_clks[];
	struct clk_bulk_data bus_clks[];
@@ -38,6 +44,7 @@ struct qcom_icc_provider {
 * @ap_owned: indicates if the node is owned by the AP or by the RPM
 * @ap_owned: indicates if the node is owned by the AP or by the RPM
 * @qos_mode: default qos mode for this node
 * @qos_mode: default qos mode for this node
 * @qos_port: qos port number for finding qos registers of this node
 * @qos_port: qos port number for finding qos registers of this node
 * @urg_fwd_en: enable urgent forwarding
 */
 */
struct qcom_icc_qos {
struct qcom_icc_qos {
	u32 areq_prio;
	u32 areq_prio;
@@ -46,6 +53,7 @@ struct qcom_icc_qos {
	bool ap_owned;
	bool ap_owned;
	int qos_mode;
	int qos_mode;
	int qos_port;
	int qos_port;
	bool urg_fwd_en;
};
};


/**
/**
@@ -78,7 +86,7 @@ struct qcom_icc_desc {
	const char * const *clocks;
	const char * const *clocks;
	size_t num_clocks;
	size_t num_clocks;
	bool has_bus_pd;
	bool has_bus_pd;
	bool is_bimc_node;
	enum qcom_icc_type type;
	const struct regmap_config *regmap_cfg;
	const struct regmap_config *regmap_cfg;
	unsigned int qos_offset;
	unsigned int qos_offset;
};
};
Loading