Skip to content

Commit de0818e

Browse files
author
Georgi Djakov
committed
Merge branch 'icc-mtk' into icc-next
MediaTek DVFSRC Bus Bandwidth and Regulator knobs This series adds support for the MediaTek Dynamic Voltage and Frequency Scaling Resource Controller (DVFSRC), found on many MediaTek SoCs. This hardware collects requests from both software and the various remote processors embededd into the SoC, and decides about a minimum operating voltage and a minimum DRAM frequency to fulfill those requests, in an effort to provide the best achievable performance per watt. Such hardware IP is capable of transparently performing direct register R/W on all of the DVFSRC-controlled regulators and SoC bandwidth knobs. Summarizing how the DVFSRC works for Interconnect: ICC provider ICC Nodes ---- ---- _________ |CPU | |--- |VPU | _____ | |----- ---- | ---- | |->| DRAM | ---- | ---- |DRAM |->|scheduler|----- |GPU | |--- |DISP| | |->| (EMI) | ---- | ---- |_____|->|_________|---. ----- | ---- /|\ `-|MMSYS|--|--- |VDEC| | ----- | ---- | | ---- | change DRAM freq |--- |VENC| -------- | ---- SMC --> | DVFSRC | | ---- -------- |--- |IMG | | ---- | ---- |--- |CAM | ---- * icc-mtk dt-bindings: interconnect: Add MediaTek EMI Interconnect bindings interconnect: mediatek: Add MediaTek MT8183/8195 EMI Interconnect driver interconnect: mediatek: remove unneeded semicolon Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Georgi Djakov <[email protected]>
2 parents b14aa62 + 9265ea0 commit de0818e

File tree

11 files changed

+829
-0
lines changed

11 files changed

+829
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/interconnect/mediatek,mt8183-emi.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: MediaTek External Memory Interface (EMI) Interconnect
8+
9+
maintainers:
10+
- AngeloGioacchino Del Regno <[email protected]>
11+
12+
description: |
13+
EMI interconnect providers support system bandwidth requirements through
14+
Dynamic Voltage Frequency Scaling Resource Collector (DVFSRC) hardware.
15+
The provider is able to communicate with the DVFSRC through Secure Monitor
16+
Call (SMC).
17+
18+
ICC provider ICC Nodes
19+
---- ----
20+
_________ |CPU | |--- |VPU |
21+
_____ | |----- ---- | ----
22+
| |->| DRAM | ---- | ----
23+
|DRAM |->|scheduler|----- |GPU | |--- |DISP|
24+
| |->| (EMI) | ---- | ----
25+
|_____|->|_________|---. ----- | ----
26+
/|\ `-|MMSYS|--|--- |VDEC|
27+
| ----- | ----
28+
| | ----
29+
| change DRAM freq |--- |VENC|
30+
-------- | ----
31+
SMC --> | DVFSRC | | ----
32+
-------- |--- |IMG |
33+
| ----
34+
| ----
35+
|--- |CAM |
36+
----
37+
38+
properties:
39+
compatible:
40+
enum:
41+
- mediatek,mt8183-emi
42+
- mediatek,mt8195-emi
43+
44+
'#interconnect-cells':
45+
const: 1
46+
47+
required:
48+
- compatible
49+
- '#interconnect-cells'
50+
51+
unevaluatedProperties: false

drivers/interconnect/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ menuconfig INTERCONNECT
1212
if INTERCONNECT
1313

1414
source "drivers/interconnect/imx/Kconfig"
15+
source "drivers/interconnect/mediatek/Kconfig"
1516
source "drivers/interconnect/qcom/Kconfig"
1617
source "drivers/interconnect/samsung/Kconfig"
1718

drivers/interconnect/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ icc-core-objs := core.o bulk.o debugfs-client.o
55

66
obj-$(CONFIG_INTERCONNECT) += icc-core.o
77
obj-$(CONFIG_INTERCONNECT_IMX) += imx/
8+
obj-$(CONFIG_INTERCONNECT_MTK) += mediatek/
89
obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
910
obj-$(CONFIG_INTERCONNECT_SAMSUNG) += samsung/
1011

drivers/interconnect/mediatek/Kconfig

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
3+
config INTERCONNECT_MTK
4+
bool "MediaTek interconnect drivers"
5+
depends on ARCH_MEDIATEK || COMPILE_TEST
6+
help
7+
Support for MediaTek's bus interconnect hardware.
8+
9+
config INTERCONNECT_MTK_DVFSRC_EMI
10+
tristate "MediaTek DVFSRC EMI interconnect driver"
11+
depends on INTERCONNECT_MTK && MTK_DVFSRC
12+
help
13+
This is a driver for the MediaTek External Memory Interface
14+
interconnect on SoCs equipped with the integrated Dynamic
15+
Voltage Frequency Scaling Resource Collector (DVFSRC) MCU
16+
17+
config INTERCONNECT_MTK_MT8183
18+
tristate "MediaTek MT8183 interconnect driver"
19+
depends on INTERCONNECT_MTK_DVFSRC_EMI
20+
help
21+
This is a driver for the MediaTek bus interconnect on MT8183-based
22+
platforms.
23+
24+
config INTERCONNECT_MTK_MT8195
25+
tristate "MediaTek MT8195 interconnect driver"
26+
depends on INTERCONNECT_MTK_DVFSRC_EMI
27+
help
28+
This is a driver for the MediaTek bus interconnect on MT8195-based
29+
platforms.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
obj-$(CONFIG_INTERCONNECT_MTK_DVFSRC_EMI) += icc-emi.o
4+
obj-$(CONFIG_INTERCONNECT_MTK_MT8183) += mt8183.o
5+
obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8195.o
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* MediaTek External Memory Interface (EMI) Interconnect driver
4+
*
5+
* Copyright (c) 2021 MediaTek Inc.
6+
* Copyright (c) 2024 Collabora Ltd.
7+
* AngeloGioacchino Del Regno <[email protected]>
8+
*/
9+
10+
#include <linux/interconnect.h>
11+
#include <linux/interconnect-provider.h>
12+
#include <linux/module.h>
13+
#include <linux/of.h>
14+
#include <linux/of_platform.h>
15+
#include <linux/platform_device.h>
16+
#include <linux/soc/mediatek/dvfsrc.h>
17+
18+
#include "icc-emi.h"
19+
20+
static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
21+
u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
22+
{
23+
struct mtk_icc_node *in = node->data;
24+
25+
*agg_avg += avg_bw;
26+
*agg_peak = max_t(u32, *agg_peak, peak_bw);
27+
28+
in->sum_avg = *agg_avg;
29+
in->max_peak = *agg_peak;
30+
31+
return 0;
32+
}
33+
34+
static int mtk_emi_icc_set(struct icc_node *src, struct icc_node *dst)
35+
{
36+
struct mtk_icc_node *node = dst->data;
37+
struct device *dev;
38+
int ret;
39+
40+
if (unlikely(!src->provider))
41+
return -EINVAL;
42+
43+
dev = src->provider->dev;
44+
45+
switch (node->ep) {
46+
case 0:
47+
break;
48+
case 1:
49+
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_PEAK_BW, node->max_peak);
50+
if (ret) {
51+
dev_err(dev, "Cannot send peak bw request: %d\n", ret);
52+
return ret;
53+
}
54+
55+
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_BW, node->sum_avg);
56+
if (ret) {
57+
dev_err(dev, "Cannot send bw request: %d\n", ret);
58+
return ret;
59+
}
60+
break;
61+
case 2:
62+
ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_HRT_BW, node->sum_avg);
63+
if (ret) {
64+
dev_err(dev, "Cannot send HRT bw request: %d\n", ret);
65+
return ret;
66+
}
67+
break;
68+
default:
69+
dev_err(src->provider->dev, "Unknown endpoint %u\n", node->ep);
70+
return -EINVAL;
71+
}
72+
73+
return 0;
74+
}
75+
76+
int mtk_emi_icc_probe(struct platform_device *pdev)
77+
{
78+
const struct mtk_icc_desc *desc;
79+
struct device *dev = &pdev->dev;
80+
struct icc_node *node;
81+
struct icc_onecell_data *data;
82+
struct icc_provider *provider;
83+
struct mtk_icc_node **mnodes;
84+
int i, j, ret;
85+
86+
desc = of_device_get_match_data(dev);
87+
if (!desc)
88+
return -EINVAL;
89+
90+
mnodes = desc->nodes;
91+
92+
provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
93+
if (!provider)
94+
return -ENOMEM;
95+
96+
data = devm_kzalloc(dev, struct_size(data, nodes, desc->num_nodes), GFP_KERNEL);
97+
if (!data)
98+
return -ENOMEM;
99+
100+
provider->dev = pdev->dev.parent;
101+
provider->set = mtk_emi_icc_set;
102+
provider->aggregate = mtk_emi_icc_aggregate;
103+
provider->xlate = of_icc_xlate_onecell;
104+
INIT_LIST_HEAD(&provider->nodes);
105+
provider->data = data;
106+
107+
for (i = 0; i < desc->num_nodes; i++) {
108+
if (!mnodes[i])
109+
continue;
110+
111+
node = icc_node_create(mnodes[i]->id);
112+
if (IS_ERR(node)) {
113+
ret = PTR_ERR(node);
114+
goto err;
115+
}
116+
117+
node->name = mnodes[i]->name;
118+
node->data = mnodes[i];
119+
icc_node_add(node, provider);
120+
121+
for (j = 0; j < mnodes[i]->num_links; j++)
122+
icc_link_create(node, mnodes[i]->links[j]);
123+
124+
data->nodes[i] = node;
125+
}
126+
data->num_nodes = desc->num_nodes;
127+
128+
ret = icc_provider_register(provider);
129+
if (ret)
130+
goto err;
131+
132+
platform_set_drvdata(pdev, provider);
133+
134+
return 0;
135+
err:
136+
icc_nodes_remove(provider);
137+
return ret;
138+
}
139+
EXPORT_SYMBOL_GPL(mtk_emi_icc_probe);
140+
141+
void mtk_emi_icc_remove(struct platform_device *pdev)
142+
{
143+
struct icc_provider *provider = platform_get_drvdata(pdev);
144+
145+
icc_provider_deregister(provider);
146+
icc_nodes_remove(provider);
147+
}
148+
EXPORT_SYMBOL_GPL(mtk_emi_icc_remove);
149+
150+
MODULE_AUTHOR("AngeloGioacchino Del Regno <[email protected]>");
151+
MODULE_AUTHOR("Henry Chen <[email protected]>");
152+
MODULE_DESCRIPTION("MediaTek External Memory Interface interconnect driver");
153+
MODULE_LICENSE("GPL");
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (c) 2021 MediaTek Inc.
4+
* Copyright (c) 2024 Collabora Ltd.
5+
* AngeloGioacchino Del Regno <[email protected]>
6+
*/
7+
8+
#ifndef __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H
9+
#define __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H
10+
11+
/**
12+
* struct mtk_icc_node - Mediatek EMI Interconnect Node
13+
* @name: The interconnect node name which is shown in debugfs
14+
* @ep: Type of this endpoint
15+
* @id: Unique node identifier
16+
* @sum_avg: Current sum aggregate value of all average bw requests in kBps
17+
* @max_peak: Current max aggregate value of all peak bw requests in kBps
18+
* @num_links: The total number of @links
19+
* @links: Array of @id linked to this node
20+
*/
21+
struct mtk_icc_node {
22+
unsigned char *name;
23+
int ep;
24+
u16 id;
25+
u64 sum_avg;
26+
u64 max_peak;
27+
28+
u16 num_links;
29+
u16 links[] __counted_by(num_links);
30+
};
31+
32+
struct mtk_icc_desc {
33+
struct mtk_icc_node **nodes;
34+
size_t num_nodes;
35+
};
36+
37+
int mtk_emi_icc_probe(struct platform_device *pdev);
38+
void mtk_emi_icc_remove(struct platform_device *pdev);
39+
40+
#endif /* __DRIVERS_INTERCONNECT_MEDIATEK_ICC_EMI_H */

0 commit comments

Comments
 (0)