Commit 9d2877a5 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'icc-6.11-rc1' of...

Merge tag 'icc-6.11-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/djakov/icc into char-misc-next

Georgi writes:

interconnect changes for 6.11

This pull request contains the interconnect changes for the 6.11-rc1 merge
window. It contains just driver changes with the following highlights:

Driver changes:
- New driver for MediaTek MT8183/8195 platforms
- New driver for MSM8953 platforms
- New QoS support for RPMh-based platforms with SC7280 being the
  first one to benefit from it.
- Fix incorrect master-id value in qcm2290 driver
- Add missing MODULE_DESCRIPTION in a few drivers
Signed-off-by: default avatarGeorgi Djakov <djakov@kernel.org>

* tag 'icc-6.11-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/djakov/icc:
  interconnect: qcom: Fix DT backwards compatibility for QoS
  interconnect: qcom: Add MSM8953 driver
  dt-bindings: interconnect: qcom: Add Qualcomm MSM8953 NoC
  interconnect: qcom: qcm2290: Fix mas_snoc_bimc RPM master ID
  interconnect: qcom: sc7280: enable QoS configuration
  interconnect: qcom: icc-rpmh: Add QoS configuration support
  dt-bindings: interconnect: add clock property to enable QOS on SC7280
  interconnect: mediatek: remove unneeded semicolon
  interconnect: qcom: add missing MODULE_DESCRIPTION() macros
  interconnect: imx: add missing MODULE_DESCRIPTION() macros
  interconnect: mediatek: Add MediaTek MT8183/8195 EMI Interconnect driver
  dt-bindings: interconnect: Add MediaTek EMI Interconnect bindings
parents 1ebab783 226e58b2
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/mediatek,mt8183-emi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek External Memory Interface (EMI) Interconnect
maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
description: |
EMI interconnect providers support system bandwidth requirements through
Dynamic Voltage Frequency Scaling Resource Collector (DVFSRC) hardware.
The provider is able to communicate with the DVFSRC through Secure Monitor
Call (SMC).
ICC provider ICC Nodes
---- ----
_________ |CPU | |--- |VPU |
_____ | |----- ---- | ----
| |->| DRAM | ---- | ----
|DRAM |->|scheduler|----- |GPU | |--- |DISP|
| |->| (EMI) | ---- | ----
|_____|->|_________|---. ----- | ----
/|\ `-|MMSYS|--|--- |VDEC|
| ----- | ----
| | ----
| change DRAM freq |--- |VENC|
-------- | ----
SMC --> | DVFSRC | | ----
-------- |--- |IMG |
| ----
| ----
|--- |CAM |
----
properties:
compatible:
enum:
- mediatek,mt8183-emi
- mediatek,mt8195-emi
'#interconnect-cells':
const: 1
required:
- compatible
- '#interconnect-cells'
unevaluatedProperties: false
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,msm8953.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm MSM8953 Network-On-Chip interconnect
maintainers:
- Barnabas Czeman <barnabas.czeman@mainlining.org>
description: |
The Qualcomm MSM8953 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
See also:
- dt-bindings/interconnect/qcom,msm8953.h
properties:
compatible:
enum:
- qcom,msm8953-bimc
- qcom,msm8953-pcnoc
- qcom,msm8953-snoc
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
maxItems: 1
'#interconnect-cells':
const: 2
patternProperties:
'^interconnect-[a-z0-9\-]+$':
type: object
$ref: qcom,rpm-common.yaml#
unevaluatedProperties: false
description:
The interconnect providers do not have a separate QoS register space,
but share parent's space.
properties:
compatible:
const: qcom,msm8953-snoc-mm
required:
- compatible
- '#interconnect-cells'
required:
- compatible
- reg
- '#interconnect-cells'
allOf:
- $ref: qcom,rpm-common.yaml#
- if:
properties:
compatible:
const: qcom,msm8953-pcnoc
then:
properties:
clocks:
items:
- description: PCNOC USB3 AXI Clock.
clock-names:
const: pcnoc_usb3_axi
required:
- clocks
- clock-names
else:
properties:
clocks: false
clock-names: false
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8953.h>
snoc: interconnect@580000 {
compatible = "qcom,msm8953-snoc";
reg = <0x580000 0x16080>;
#interconnect-cells = <2>;
snoc_mm: interconnect-snoc {
compatible = "qcom,msm8953-snoc-mm";
#interconnect-cells = <2>;
};
};
......@@ -35,6 +35,10 @@ properties:
reg:
maxItems: 1
clocks:
minItems: 1
maxItems: 2
required:
- compatible
......@@ -53,10 +57,50 @@ allOf:
required:
- reg
- if:
properties:
compatible:
contains:
enum:
- qcom,sc7280-aggre1-noc
then:
properties:
clocks:
items:
- description: aggre UFS PHY AXI clock
- description: aggre USB3 PRIM AXI clock
- if:
properties:
compatible:
contains:
enum:
- qcom,sc7280-aggre2-noc
then:
properties:
clocks:
items:
- description: RPMH CC IPA clock
- if:
properties:
compatible:
contains:
enum:
- qcom,sc7280-aggre1-noc
- qcom,sc7280-aggre2-noc
then:
required:
- clocks
else:
properties:
clocks: false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
interconnect {
compatible = "qcom,sc7280-clk-virt";
#interconnect-cells = <2>;
......@@ -69,3 +113,12 @@ examples:
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
};
interconnect@16e0000 {
reg = <0x016e0000 0x1c080>;
compatible = "qcom,sc7280-aggre1-noc";
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
};
......@@ -12,6 +12,7 @@ menuconfig INTERCONNECT
if INTERCONNECT
source "drivers/interconnect/imx/Kconfig"
source "drivers/interconnect/mediatek/Kconfig"
source "drivers/interconnect/qcom/Kconfig"
source "drivers/interconnect/samsung/Kconfig"
......
......@@ -5,6 +5,7 @@ icc-core-objs := core.o bulk.o debugfs-client.o
obj-$(CONFIG_INTERCONNECT) += icc-core.o
obj-$(CONFIG_INTERCONNECT_IMX) += imx/
obj-$(CONFIG_INTERCONNECT_MTK) += mediatek/
obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
obj-$(CONFIG_INTERCONNECT_SAMSUNG) += samsung/
......
......@@ -334,4 +334,5 @@ void imx_icc_unregister(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(imx_icc_unregister);
MODULE_DESCRIPTION("Interconnect framework driver for i.MX SoC");
MODULE_LICENSE("GPL v2");
......@@ -96,5 +96,6 @@ static struct platform_driver imx8mm_icc_driver = {
module_platform_driver(imx8mm_icc_driver);
MODULE_AUTHOR("Alexandre Bailon <abailon@baylibre.com>");
MODULE_DESCRIPTION("Interconnect framework driver for i.MX8MM SoC");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:imx8mm-interconnect");
......@@ -86,4 +86,5 @@ static struct platform_driver imx8mn_icc_driver = {
module_platform_driver(imx8mn_icc_driver);
MODULE_ALIAS("platform:imx8mn-interconnect");
MODULE_AUTHOR("Leonard Crestez <leonard.crestez@nxp.com>");
MODULE_DESCRIPTION("Interconnect framework driver for i.MX8MN SoC");
MODULE_LICENSE("GPL v2");
......@@ -249,5 +249,6 @@ static struct platform_driver imx8mp_icc_driver = {
module_platform_driver(imx8mp_icc_driver);
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_DESCRIPTION("Interconnect framework driver for i.MX8MP SoC");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:imx8mp-interconnect");
......@@ -97,4 +97,5 @@ static struct platform_driver imx8mq_icc_driver = {
module_platform_driver(imx8mq_icc_driver);
MODULE_ALIAS("platform:imx8mq-interconnect");
MODULE_AUTHOR("Leonard Crestez <leonard.crestez@nxp.com>");
MODULE_DESCRIPTION("Interconnect framework driver for i.MX8MQ SoC");
MODULE_LICENSE("GPL v2");
# SPDX-License-Identifier: GPL-2.0-only
config INTERCONNECT_MTK
bool "MediaTek interconnect drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
help
Support for MediaTek's bus interconnect hardware.
config INTERCONNECT_MTK_DVFSRC_EMI
tristate "MediaTek DVFSRC EMI interconnect driver"
depends on INTERCONNECT_MTK && MTK_DVFSRC
help
This is a driver for the MediaTek External Memory Interface
interconnect on SoCs equipped with the integrated Dynamic
Voltage Frequency Scaling Resource Collector (DVFSRC) MCU
config INTERCONNECT_MTK_MT8183
tristate "MediaTek MT8183 interconnect driver"
depends on INTERCONNECT_MTK_DVFSRC_EMI
help
This is a driver for the MediaTek bus interconnect on MT8183-based
platforms.
config INTERCONNECT_MTK_MT8195
tristate "MediaTek MT8195 interconnect driver"
depends on INTERCONNECT_MTK_DVFSRC_EMI
help
This is a driver for the MediaTek bus interconnect on MT8195-based
platforms.
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_INTERCONNECT_MTK_DVFSRC_EMI) += icc-emi.o
obj-$(CONFIG_INTERCONNECT_MTK_MT8183) += mt8183.o
obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8195.o
// SPDX-License-Identifier: GPL-2.0
/*
* MediaTek External Memory Interface (EMI) Interconnect driver
*
* Copyright (c) 2021 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/dvfsrc.h>
#include "icc-emi.h"
static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
{
struct mtk_icc_node *in = node->data;
*agg_avg += avg_bw;
*agg_peak = max_t(u32, *agg_peak, peak_bw);
in->sum_avg = *agg_avg;
in->max_peak = *agg_peak;
return 0;
}
static int mtk_emi_icc_set(struct icc_node *src, struct icc_node *dst)
{
struct mtk_icc_node *node = dst->data;
struct device *dev;
int ret;
if (unlikely(!src->provider))
return -EINVAL;
dev = src->provider->dev;
switch (node->ep) {
case 0:
break;
case 1:
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_PEAK_BW, node->max_peak);
if (ret) {
dev_err(dev, "Cannot send peak bw request: %d\n", ret);
return ret;
}
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_BW, node->sum_avg);
if (ret) {
dev_err(dev, "Cannot send bw request: %d\n", ret);
return ret;
}
break;
case 2:
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_HRT_BW, node->sum_avg);
if (ret) {
dev_err(dev, "Cannot send HRT bw request: %d\n", ret);
return ret;
}
break;
default:
dev_err(src->provider->dev, "Unknown endpoint %u\n", node->ep);
return -EINVAL;
}
return 0;
}
int mtk_emi_icc_probe(struct platform_device *pdev)
{
const struct mtk_icc_desc *desc;
struct device *dev = &pdev->dev;
struct icc_node *node;
struct icc_onecell_data *data;
struct icc_provider *provider;
struct mtk_icc_node **mnodes;
int i, j, ret;
desc = of_device_get_match_data(dev);
if (!desc)
return -EINVAL;
mnodes = desc->nodes;
provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
if (!provider)
return -ENOMEM;
data = devm_kzalloc(dev, struct_size(data, nodes, desc->num_nodes), GFP_KERNEL);
if (!data)
return -ENOMEM;
provider->dev = pdev->dev.parent;
provider->set = mtk_emi_icc_set;
provider->aggregate = mtk_emi_icc_aggregate;
provider->xlate = of_icc_xlate_onecell;
INIT_LIST_HEAD(&provider->nodes);
provider->data = data;
for (i = 0; i < desc->num_nodes; i++) {
if (!mnodes[i])
continue;
node = icc_node_create(mnodes[i]->id);
if (IS_ERR(node)) {
ret = PTR_ERR(node);
goto err;
}
node->name = mnodes[i]->name;
node->data = mnodes[i];
icc_node_add(node, provider);
for (j = 0; j < mnodes[i]->num_links; j++)
icc_link_create(node, mnodes[i]->links[j]);
data->nodes[i] = node;
}
data->num_nodes = desc->num_nodes;
ret = icc_provider_register(provider);
if (ret)
goto err;
platform_set_drvdata(pdev, provider);
return 0;
err:
icc_nodes_remove(provider);
return ret;
}
EXPORT_SYMBOL_GPL(mtk_emi_icc_probe);
void mtk_emi_icc_remove(struct platform_device *pdev)
{
struct icc_provider *provider = platform_get_drvdata(pdev);
icc_provider_deregister(provider);
icc_nodes_remove(provider);
}
EXPORT_SYMBOL_GPL(mtk_emi_icc_remove);
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
MODULE_DESCRIPTION("MediaTek External Memory Interface interconnect driver");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#ifndef __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H
#define __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H
/**
* struct mtk_icc_node - Mediatek EMI Interconnect Node
* @name: The interconnect node name which is shown in debugfs
* @ep: Type of this endpoint
* @id: Unique node identifier
* @sum_avg: Current sum aggregate value of all average bw requests in kBps
* @max_peak: Current max aggregate value of all peak bw requests in kBps
* @num_links: The total number of @links
* @links: Array of @id linked to this node
*/
struct mtk_icc_node {
unsigned char *name;
int ep;
u16 id;
u64 sum_avg;
u64 max_peak;
u16 num_links;
u16 links[] __counted_by(num_links);
};
struct mtk_icc_desc {
struct mtk_icc_node **nodes;
size_t num_nodes;
};
int mtk_emi_icc_probe(struct platform_device *pdev);
void mtk_emi_icc_remove(struct platform_device *pdev);
#endif /* __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H */
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <dt-bindings/interconnect/mediatek,mt8183.h>
#include "icc-emi.h"
static struct mtk_icc_node ddr_emi = {
.name = "ddr-emi",
.id = SLAVE_DDR_EMI,
.ep = 1,
};
static struct mtk_icc_node mcusys = {
.name = "mcusys",
.id = MASTER_MCUSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node gpu = {
.name = "gpu",
.id = MASTER_MFG,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node mmsys = {
.name = "mmsys",
.id = MASTER_MMSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node mm_vpu = {
.name = "mm-vpu",
.id = MASTER_MM_VPU,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_disp = {
.name = "mm-disp",
.id = MASTER_MM_DISP,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_vdec = {
.name = "mm-vdec",
.id = MASTER_MM_VDEC,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_venc = {
.name = "mm-venc",
.id = MASTER_MM_VENC,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_cam = {
.name = "mm-cam",
.id = MASTER_MM_CAM,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_img = {
.name = "mm-img",
.id = MASTER_MM_IMG,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_mdp = {
.name = "mm-mdp",
.id = MASTER_MM_MDP,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node *mt8183_emi_icc_nodes[] = {
[SLAVE_DDR_EMI] = &ddr_emi,
[MASTER_MCUSYS] = &mcusys,
[MASTER_MFG] = &gpu,
[MASTER_MMSYS] = &mmsys,
[MASTER_MM_VPU] = &mm_vpu,
[MASTER_MM_DISP] = &mm_disp,
[MASTER_MM_VDEC] = &mm_vdec,
[MASTER_MM_VENC] = &mm_venc,
[MASTER_MM_CAM] = &mm_cam,
[MASTER_MM_IMG] = &mm_img,
[MASTER_MM_MDP] = &mm_mdp
};
static const struct mtk_icc_desc mt8183_emi_icc = {
.nodes = mt8183_emi_icc_nodes,
.num_nodes = ARRAY_SIZE(mt8183_emi_icc_nodes),
};
static const struct of_device_id mtk_mt8183_emi_icc_of_match[] = {
{ .compatible = "mediatek,mt8183-emi", .data = &mt8183_emi_icc },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mtk_mt8183_emi_icc_of_match);
static struct platform_driver mtk_emi_icc_mt8183_driver = {
.driver = {
.name = "emi-icc-mt8183",
.of_match_table = mtk_mt8183_emi_icc_of_match,
.sync_state = icc_sync_state,
},
.probe = mtk_emi_icc_probe,
.remove_new = mtk_emi_icc_remove,
};
module_platform_driver(mtk_emi_icc_mt8183_driver);
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
MODULE_DESCRIPTION("MediaTek MT8183 EMI ICC driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <dt-bindings/interconnect/mediatek,mt8195.h>
#include "icc-emi.h"
static struct mtk_icc_node ddr_emi = {
.name = "ddr-emi",
.id = SLAVE_DDR_EMI,
.ep = 1,
};
static struct mtk_icc_node mcusys = {
.name = "mcusys",
.id = MASTER_MCUSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node gpu = {
.name = "gpu",
.id = MASTER_GPUSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node mmsys = {
.name = "mmsys",
.id = MASTER_MMSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node mm_vpu = {
.name = "mm-vpu",
.id = MASTER_MM_VPU,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_disp = {
.name = "mm-disp",
.id = MASTER_MM_DISP,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_vdec = {
.name = "mm-vdec",
.id = MASTER_MM_VDEC,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_venc = {
.name = "mm-venc",
.id = MASTER_MM_VENC,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_cam = {
.name = "mm-cam",
.id = MASTER_MM_CAM,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_img = {
.name = "mm-img",
.id = MASTER_MM_IMG,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node mm_mdp = {
.name = "mm-mdp",
.id = MASTER_MM_MDP,
.ep = 0,
.num_links = 1,
.links = { MASTER_MMSYS }
};
static struct mtk_icc_node vpusys = {
.name = "vpusys",
.id = MASTER_VPUSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node vpu_port0 = {
.name = "vpu-port0",
.id = MASTER_VPU_0,
.ep = 0,
.num_links = 1,
.links = { MASTER_VPUSYS }
};
static struct mtk_icc_node vpu_port1 = {
.name = "vpu-port1",
.id = MASTER_VPU_1,
.ep = 0,
.num_links = 1,
.links = { MASTER_VPUSYS }
};
static struct mtk_icc_node mdlasys = {
.name = "mdlasys",
.id = MASTER_MDLASYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node mdla_port0 = {
.name = "mdla-port0",
.id = MASTER_MDLA_0,
.ep = 0,
.num_links = 1,
.links = { MASTER_MDLASYS }
};
static struct mtk_icc_node ufs = {
.name = "ufs",
.id = MASTER_UFS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node pcie0 = {
.name = "pcie0",
.id = MASTER_PCIE_0,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node pcie1 = {
.name = "pcie1",
.id = MASTER_PCIE_1,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node usb = {
.name = "usb",
.id = MASTER_USB,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node wifi = {
.name = "wifi",
.id = MASTER_WIFI,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node bt = {
.name = "bt",
.id = MASTER_BT,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node netsys = {
.name = "netsys",
.id = MASTER_NETSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node dbgif = {
.name = "dbgif",
.id = MASTER_DBGIF,
.ep = 0,
.num_links = 1,
.links = { SLAVE_DDR_EMI }
};
static struct mtk_icc_node hrt_ddr_emi = {
.name = "hrt-ddr-emi",
.id = SLAVE_HRT_DDR_EMI,
.ep = 2,
};
static struct mtk_icc_node hrt_mmsys = {
.name = "hrt-mmsys",
.id = MASTER_HRT_MMSYS,
.ep = 0,
.num_links = 1,
.links = { SLAVE_HRT_DDR_EMI }
};
static struct mtk_icc_node hrt_mm_disp = {
.name = "hrt-mm-disp",
.id = MASTER_HRT_MM_DISP,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_mm_vdec = {
.name = "hrt-mm-vdec",
.id = MASTER_HRT_MM_VDEC,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_mm_venc = {
.name = "hrt-mm-venc",
.id = MASTER_HRT_MM_VENC,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_mm_cam = {
.name = "hrt-mm-cam",
.id = MASTER_HRT_MM_CAM,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_mm_img = {
.name = "hrt-mm-img",
.id = MASTER_HRT_MM_IMG,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_mm_mdp = {
.name = "hrt-mm-mdp",
.id = MASTER_HRT_MM_MDP,
.ep = 0,
.num_links = 1,
.links = { MASTER_HRT_MMSYS }
};
static struct mtk_icc_node hrt_dbgif = {
.name = "hrt-dbgif",
.id = MASTER_HRT_DBGIF,
.ep = 0,
.num_links = 1,
.links = { SLAVE_HRT_DDR_EMI }
};
static struct mtk_icc_node *mt8195_emi_icc_nodes[] = {
[SLAVE_DDR_EMI] = &ddr_emi,
[MASTER_MCUSYS] = &mcusys,
[MASTER_GPUSYS] = &gpu,
[MASTER_MMSYS] = &mmsys,
[MASTER_MM_VPU] = &mm_vpu,
[MASTER_MM_DISP] = &mm_disp,
[MASTER_MM_VDEC] = &mm_vdec,
[MASTER_MM_VENC] = &mm_venc,
[MASTER_MM_CAM] = &mm_cam,
[MASTER_MM_IMG] = &mm_img,
[MASTER_MM_MDP] = &mm_mdp,
[MASTER_VPUSYS] = &vpusys,
[MASTER_VPU_0] = &vpu_port0,
[MASTER_VPU_1] = &vpu_port1,
[MASTER_MDLASYS] = &mdlasys,
[MASTER_MDLA_0] = &mdla_port0,
[MASTER_UFS] = &ufs,
[MASTER_PCIE_0] = &pcie0,
[MASTER_PCIE_1] = &pcie1,
[MASTER_USB] = &usb,
[MASTER_WIFI] = &wifi,
[MASTER_BT] = &bt,
[MASTER_NETSYS] = &netsys,
[MASTER_DBGIF] = &dbgif,
[SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi,
[MASTER_HRT_MMSYS] = &hrt_mmsys,
[MASTER_HRT_MM_DISP] = &hrt_mm_disp,
[MASTER_HRT_MM_VDEC] = &hrt_mm_vdec,
[MASTER_HRT_MM_VENC] = &hrt_mm_venc,
[MASTER_HRT_MM_CAM] = &hrt_mm_cam,
[MASTER_HRT_MM_IMG] = &hrt_mm_img,
[MASTER_HRT_MM_MDP] = &hrt_mm_mdp,
[MASTER_HRT_DBGIF] = &hrt_dbgif
};
static struct mtk_icc_desc mt8195_emi_icc = {
.nodes = mt8195_emi_icc_nodes,
.num_nodes = ARRAY_SIZE(mt8195_emi_icc_nodes),
};
static const struct of_device_id mtk_mt8195_emi_icc_of_match[] = {
{ .compatible = "mediatek,mt8195-emi", .data = &mt8195_emi_icc },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mtk_mt8195_emi_icc_of_match);
static struct platform_driver mtk_emi_icc_mt8195_driver = {
.driver = {
.name = "emi-icc-mt8195",
.of_match_table = mtk_mt8195_emi_icc_of_match,
.sync_state = icc_sync_state,
},
.probe = mtk_emi_icc_probe,
.remove_new = mtk_emi_icc_remove,
};
module_platform_driver(mtk_emi_icc_mt8195_driver);
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
MODULE_DESCRIPTION("MediaTek MT8195 EMI ICC driver");
MODULE_LICENSE("GPL");
......@@ -35,6 +35,15 @@ config INTERCONNECT_QCOM_MSM8939
This is a driver for the Qualcomm Network-on-Chip on msm8939-based
platforms.
config INTERCONNECT_QCOM_MSM8953
tristate "Qualcomm MSM8953 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 msm8953-based
platforms.
config INTERCONNECT_QCOM_MSM8974
tristate "Qualcomm MSM8974 interconnect driver"
depends on INTERCONNECT_QCOM
......
......@@ -7,6 +7,7 @@ icc-bcm-voter-objs := bcm-voter.o
qnoc-msm8909-objs := msm8909.o
qnoc-msm8916-objs := msm8916.o
qnoc-msm8939-objs := msm8939.o
qnoc-msm8953-objs := msm8953.o
qnoc-msm8974-objs := msm8974.o
qnoc-msm8996-objs := msm8996.o
icc-osm-l3-objs := osm-l3.o
......@@ -41,6 +42,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_BCM_VOTER) += icc-bcm-voter.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8909) += qnoc-msm8909.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8939) += qnoc-msm8939.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8953) += qnoc-msm8953.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
......
......@@ -35,4 +35,5 @@ struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec
}
EXPORT_SYMBOL_GPL(qcom_icc_xlate_extended);
MODULE_DESCRIPTION("Qualcomm interconnect common functions");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/module.h>
......@@ -14,6 +17,38 @@
#include "icc-common.h"
#include "icc-rpmh.h"
/* QNOC QoS */
#define QOSGEN_MAINCTL_LO(p, qp) (0x8 + (p->port_offsets[qp]))
#define QOS_SLV_URG_MSG_EN_MASK GENMASK(3, 3)
#define QOS_DFLT_PRIO_MASK GENMASK(6, 4)
#define QOS_DISABLE_MASK GENMASK(24, 24)
/**
* qcom_icc_set_qos - initialize static QoS configurations
* @qp: qcom icc provider to which @node belongs
* @node: qcom icc node to operate on
*/
static void qcom_icc_set_qos(struct qcom_icc_provider *qp,
struct qcom_icc_node *node)
{
const struct qcom_icc_qosbox *qos = node->qosbox;
int port;
for (port = 0; port < qos->num_ports; port++) {
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
QOS_DISABLE_MASK,
FIELD_PREP(QOS_DISABLE_MASK, qos->prio_fwd_disable));
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
QOS_DFLT_PRIO_MASK,
FIELD_PREP(QOS_DFLT_PRIO_MASK, qos->prio));
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
QOS_SLV_URG_MSG_EN_MASK,
FIELD_PREP(QOS_SLV_URG_MSG_EN_MASK, qos->urg_fwd));
}
}
/**
* qcom_icc_pre_aggregate - cleans up stale values from prior icc_set
* @node: icc node to operate on
......@@ -159,6 +194,36 @@ int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev)
}
EXPORT_SYMBOL_GPL(qcom_icc_bcm_init);
/**
* qcom_icc_rpmh_configure_qos - configure QoS parameters
* @qp: qcom icc provider associated with QoS endpoint nodes
*
* Return: 0 on success, or an error code otherwise
*/
static int qcom_icc_rpmh_configure_qos(struct qcom_icc_provider *qp)
{
struct qcom_icc_node *qnode;
size_t i;
int ret;
ret = clk_bulk_prepare_enable(qp->num_clks, qp->clks);
if (ret)
return ret;
for (i = 0; i < qp->num_nodes; i++) {
qnode = qp->nodes[i];
if (!qnode)
continue;
if (qnode->qosbox)
qcom_icc_set_qos(qp, qnode);
}
clk_bulk_disable_unprepare(qp->num_clks, qp->clks);
return ret;
}
int qcom_icc_rpmh_probe(struct platform_device *pdev)
{
const struct qcom_icc_desc *desc;
......@@ -199,7 +264,9 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
qp->dev = dev;
qp->bcms = desc->bcms;
qp->nodes = desc->nodes;
qp->num_bcms = desc->num_bcms;
qp->num_nodes = desc->num_nodes;
qp->voter = of_bcm_voter_get(qp->dev, NULL);
if (IS_ERR(qp->voter))
......@@ -229,6 +296,32 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
data->nodes[i] = node;
}
if (desc->config) {
struct resource *res;
void __iomem *base;
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(base))
goto skip_qos_config;
qp->regmap = devm_regmap_init_mmio(dev, base, desc->config);
if (IS_ERR(qp->regmap)) {
dev_info(dev, "Skipping QoS, regmap failed; %ld\n", PTR_ERR(qp->regmap));
goto skip_qos_config;
}
qp->num_clks = devm_clk_bulk_get_all(qp->dev, &qp->clks);
if (qp->num_clks < 0 || (!qp->num_clks && desc->qos_clks_required)) {
dev_info(dev, "Skipping QoS, failed to get clk: %d\n", qp->num_clks);
goto skip_qos_config;
}
ret = qcom_icc_rpmh_configure_qos(qp);
if (ret)
dev_info(dev, "Failed to program QoS: %d\n", ret);
}
skip_qos_config:
ret = icc_provider_register(provider);
if (ret)
goto err_remove_nodes;
......@@ -262,4 +355,5 @@ void qcom_icc_rpmh_remove(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(qcom_icc_rpmh_remove);
MODULE_DESCRIPTION("Qualcomm RPMh interconnect driver");
MODULE_LICENSE("GPL v2");
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
#define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
#include <dt-bindings/interconnect/qcom,icc.h>
#include <linux/regmap.h>
#define to_qcom_provider(_provider) \
container_of(_provider, struct qcom_icc_provider, provider)
......@@ -18,6 +20,11 @@
* @bcms: list of bcms that maps to the provider
* @num_bcms: number of @bcms
* @voter: bcm voter targeted by this provider
* @nodes: list of icc nodes that maps to the provider
* @num_nodes: number of @nodes
* @regmap: used for QoS, register access
* @clks : clks required for register access
* @num_clks: number of @clks
*/
struct qcom_icc_provider {
struct icc_provider provider;
......@@ -25,6 +32,11 @@ struct qcom_icc_provider {
struct qcom_icc_bcm * const *bcms;
size_t num_bcms;
struct bcm_voter *voter;
struct qcom_icc_node * const *nodes;
size_t num_nodes;
struct regmap *regmap;
struct clk_bulk_data *clks;
int num_clks;
};
/**
......@@ -41,6 +53,26 @@ struct bcm_db {
u8 reserved;
};
#define MAX_PORTS 2
/**
* struct qcom_icc_qosbox - Qualcomm specific QoS config
* @prio: priority value assigned to requests on the node
* @urg_fwd: whether to forward the urgency promotion issued by master
* (endpoint), or discard
* @prio_fwd_disable: whether to forward the priority driven by master, or
* override by @prio
* @num_ports: number of @ports
* @port_offsets: qos register offsets
*/
struct qcom_icc_qosbox {
const u32 prio;
const bool urg_fwd;
const bool prio_fwd_disable;
const u32 num_ports;
const u32 port_offsets[MAX_PORTS];
};
#define MAX_LINKS 128
#define MAX_BCMS 64
#define MAX_BCM_PER_NODE 3
......@@ -58,6 +90,7 @@ struct bcm_db {
* @max_peak: current max aggregate value of all peak bw requests
* @bcms: list of bcms associated with this logical node
* @num_bcms: num of @bcms
* @qosbox: QoS config data associated with node
*/
struct qcom_icc_node {
const char *name;
......@@ -70,6 +103,7 @@ struct qcom_icc_node {
u64 max_peak[QCOM_ICC_NUM_BUCKETS];
struct qcom_icc_bcm *bcms[MAX_BCM_PER_NODE];
size_t num_bcms;
const struct qcom_icc_qosbox *qosbox;
};
/**
......@@ -114,10 +148,12 @@ struct qcom_icc_fabric {
};
struct qcom_icc_desc {
const struct regmap_config *config;
struct qcom_icc_node * const *nodes;
size_t num_nodes;
struct qcom_icc_bcm * const *bcms;
size_t num_bcms;
bool qos_clks_required;
};
int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
......
This diff is collapsed.
......@@ -166,7 +166,7 @@ static struct qcom_icc_node mas_snoc_bimc = {
.qos.ap_owned = true,
.qos.qos_port = 6,
.qos.qos_mode = NOC_QOS_MODE_BYPASS,
.mas_rpm_id = 164,
.mas_rpm_id = 3,
.slv_rpm_id = -1,
.num_links = ARRAY_SIZE(mas_snoc_bimc_links),
.links = mas_snoc_bimc_links,
......
This diff is collapsed.
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (c) 2021 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#ifndef __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8183_H
#define __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8183_H
#define SLAVE_DDR_EMI 0
#define MASTER_MCUSYS 1
#define MASTER_MFG 2
#define MASTER_MMSYS 3
#define MASTER_MM_VPU 4
#define MASTER_MM_DISP 5
#define MASTER_MM_VDEC 6
#define MASTER_MM_VENC 7
#define MASTER_MM_CAM 8
#define MASTER_MM_IMG 9
#define MASTER_MM_MDP 10
#endif
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (c) 2020 MediaTek Inc.
* Copyright (c) 2024 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#ifndef __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8195_H
#define __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8195_H
#define SLAVE_DDR_EMI 0
#define MASTER_MCUSYS 1
#define MASTER_GPUSYS 2
#define MASTER_MMSYS 3
#define MASTER_MM_VPU 4
#define MASTER_MM_DISP 5
#define MASTER_MM_VDEC 6
#define MASTER_MM_VENC 7
#define MASTER_MM_CAM 8
#define MASTER_MM_IMG 9
#define MASTER_MM_MDP 10
#define MASTER_VPUSYS 11
#define MASTER_VPU_0 12
#define MASTER_VPU_1 13
#define MASTER_MDLASYS 14
#define MASTER_MDLA_0 15
#define MASTER_UFS 16
#define MASTER_PCIE_0 17
#define MASTER_PCIE_1 18
#define MASTER_USB 19
#define MASTER_DBGIF 20
#define SLAVE_HRT_DDR_EMI 21
#define MASTER_HRT_MMSYS 22
#define MASTER_HRT_MM_DISP 23
#define MASTER_HRT_MM_VDEC 24
#define MASTER_HRT_MM_VENC 25
#define MASTER_HRT_MM_CAM 26
#define MASTER_HRT_MM_IMG 27
#define MASTER_HRT_MM_MDP 28
#define MASTER_HRT_DBGIF 29
#define MASTER_WIFI 30
#define MASTER_BT 31
#define MASTER_NETSYS 32
#endif
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Qualcomm MSM8953 interconnect IDs
*/
#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8953_H
#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8953_H
/* BIMC fabric */
#define MAS_APPS_PROC 0
#define MAS_OXILI 1
#define MAS_SNOC_BIMC_0 2
#define MAS_SNOC_BIMC_2 3
#define MAS_SNOC_BIMC_1 4
#define MAS_TCU_0 5
#define SLV_EBI 6
#define SLV_BIMC_SNOC 7
/* PCNOC fabric */
#define MAS_SPDM 0
#define MAS_BLSP_1 1
#define MAS_BLSP_2 2
#define MAS_USB3 3
#define MAS_CRYPTO 4
#define MAS_SDCC_1 5
#define MAS_SDCC_2 6
#define MAS_SNOC_PCNOC 7
#define PCNOC_M_0 8
#define PCNOC_M_1 9
#define PCNOC_INT_1 10
#define PCNOC_INT_2 11
#define PCNOC_S_0 12
#define PCNOC_S_1 13
#define PCNOC_S_2 14
#define PCNOC_S_3 15
#define PCNOC_S_4 16
#define PCNOC_S_6 17
#define PCNOC_S_7 18
#define PCNOC_S_8 19
#define PCNOC_S_9 20
#define SLV_SPDM 21
#define SLV_PDM 22
#define SLV_TCSR 23
#define SLV_SNOC_CFG 24
#define SLV_TLMM 25
#define SLV_MESSAGE_RAM 26
#define SLV_BLSP_1 27
#define SLV_BLSP_2 28
#define SLV_PRNG 29
#define SLV_CAMERA_SS_CFG 30
#define SLV_DISP_SS_CFG 31
#define SLV_VENUS_CFG 32
#define SLV_GPU_CFG 33
#define SLV_SDCC_1 34
#define SLV_SDCC_2 35
#define SLV_CRYPTO_0_CFG 36
#define SLV_PMIC_ARB 37
#define SLV_USB3 38
#define SLV_IPA_CFG 39
#define SLV_TCU 40
#define SLV_PCNOC_SNOC 41
/* SNOC fabric */
#define MAS_QDSS_BAM 0
#define MAS_BIMC_SNOC 1
#define MAS_PCNOC_SNOC 2
#define MAS_IPA 3
#define MAS_QDSS_ETR 4
#define QDSS_INT 5
#define SNOC_INT_0 6
#define SNOC_INT_1 7
#define SNOC_INT_2 8
#define SLV_KPSS_AHB 9
#define SLV_WCSS 10
#define SLV_SNOC_BIMC_1 11
#define SLV_IMEM 12
#define SLV_SNOC_PCNOC 13
#define SLV_QDSS_STM 14
#define SLV_CATS_1 15
#define SLV_LPASS 16
/* SNOC-MM fabric */
#define MAS_JPEG 0
#define MAS_MDP 1
#define MAS_VENUS 2
#define MAS_VFE0 3
#define MAS_VFE1 4
#define MAS_CPP 5
#define SLV_SNOC_BIMC_0 6
#define SLV_SNOC_BIMC_2 7
#define SLV_CATS_0 8
#endif /* __DT_BINDINGS_INTERCONNECT_QCOM_MSM8953_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment