Skip to content

Commit 1924272

Browse files
quic-kdybcioRob Clark
authored andcommitted
soc: qcom: Add UBWC config provider
Add a file that will serve as a single source of truth for UBWC configuration data for various multimedia blocks. Reviewed-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Konrad Dybcio <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/660959/ Signed-off-by: Rob Clark <[email protected]>
1 parent 6733d82 commit 1924272

File tree

4 files changed

+325
-0
lines changed

4 files changed

+325
-0
lines changed

drivers/soc/qcom/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,11 @@ config QCOM_PBS
296296
PBS trigger event to the PBS RAM.
297297

298298
endmenu
299+
300+
config QCOM_UBWC_CONFIG
301+
tristate
302+
help
303+
Most Qualcomm SoCs feature a number of Universal Bandwidth Compression
304+
(UBWC) engines across various IP blocks, which need to be initialized
305+
with coherent configuration data. This module functions as a single
306+
source of truth for that information.

drivers/soc/qcom/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ obj-$(CONFIG_QCOM_ICC_BWMON) += icc-bwmon.o
3939
qcom_ice-objs += ice.o
4040
obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE) += qcom_ice.o
4141
obj-$(CONFIG_QCOM_PBS) += qcom-pbs.o
42+
obj-$(CONFIG_QCOM_UBWC_CONFIG) += ubwc_config.o

drivers/soc/qcom/ubwc_config.c

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
*/
5+
6+
#include <linux/debugfs.h>
7+
#include <linux/io.h>
8+
#include <linux/module.h>
9+
#include <linux/of.h>
10+
#include <linux/of_address.h>
11+
#include <linux/platform_device.h>
12+
13+
#include <linux/soc/qcom/ubwc.h>
14+
15+
static const struct qcom_ubwc_cfg_data msm8937_data = {
16+
.ubwc_enc_version = UBWC_1_0,
17+
.ubwc_dec_version = UBWC_1_0,
18+
.highest_bank_bit = 14,
19+
};
20+
21+
static const struct qcom_ubwc_cfg_data msm8998_data = {
22+
.ubwc_enc_version = UBWC_1_0,
23+
.ubwc_dec_version = UBWC_1_0,
24+
.highest_bank_bit = 15,
25+
};
26+
27+
static const struct qcom_ubwc_cfg_data qcm2290_data = {
28+
/* no UBWC */
29+
.highest_bank_bit = 15,
30+
};
31+
32+
static const struct qcom_ubwc_cfg_data sa8775p_data = {
33+
.ubwc_enc_version = UBWC_4_0,
34+
.ubwc_dec_version = UBWC_4_0,
35+
.ubwc_swizzle = 4,
36+
.ubwc_bank_spread = true,
37+
.highest_bank_bit = 13,
38+
.macrotile_mode = true,
39+
};
40+
41+
static const struct qcom_ubwc_cfg_data sar2130p_data = {
42+
.ubwc_enc_version = UBWC_3_0, /* 4.0.2 in hw */
43+
.ubwc_dec_version = UBWC_4_3,
44+
.ubwc_swizzle = 6,
45+
.ubwc_bank_spread = true,
46+
.highest_bank_bit = 13,
47+
.macrotile_mode = true,
48+
};
49+
50+
static const struct qcom_ubwc_cfg_data sc7180_data = {
51+
.ubwc_enc_version = UBWC_2_0,
52+
.ubwc_dec_version = UBWC_2_0,
53+
.ubwc_swizzle = 6,
54+
.ubwc_bank_spread = true,
55+
.highest_bank_bit = 14,
56+
};
57+
58+
static const struct qcom_ubwc_cfg_data sc7280_data = {
59+
.ubwc_enc_version = UBWC_3_0,
60+
.ubwc_dec_version = UBWC_4_0,
61+
.ubwc_swizzle = 6,
62+
.ubwc_bank_spread = true,
63+
.highest_bank_bit = 14,
64+
.macrotile_mode = true,
65+
};
66+
67+
static const struct qcom_ubwc_cfg_data sc8180x_data = {
68+
.ubwc_enc_version = UBWC_3_0,
69+
.ubwc_dec_version = UBWC_3_0,
70+
.highest_bank_bit = 16,
71+
.macrotile_mode = true,
72+
};
73+
74+
static const struct qcom_ubwc_cfg_data sc8280xp_data = {
75+
.ubwc_enc_version = UBWC_4_0,
76+
.ubwc_dec_version = UBWC_4_0,
77+
.ubwc_swizzle = 6,
78+
.ubwc_bank_spread = true,
79+
.highest_bank_bit = 16,
80+
.macrotile_mode = true,
81+
};
82+
83+
static const struct qcom_ubwc_cfg_data sdm670_data = {
84+
.ubwc_enc_version = UBWC_2_0,
85+
.ubwc_dec_version = UBWC_2_0,
86+
.highest_bank_bit = 14,
87+
};
88+
89+
static const struct qcom_ubwc_cfg_data sdm845_data = {
90+
.ubwc_enc_version = UBWC_2_0,
91+
.ubwc_dec_version = UBWC_2_0,
92+
.highest_bank_bit = 15,
93+
};
94+
95+
static const struct qcom_ubwc_cfg_data sm6115_data = {
96+
.ubwc_enc_version = UBWC_1_0,
97+
.ubwc_dec_version = UBWC_2_0,
98+
.ubwc_swizzle = 7,
99+
.ubwc_bank_spread = true,
100+
.highest_bank_bit = 14,
101+
};
102+
103+
static const struct qcom_ubwc_cfg_data sm6125_data = {
104+
.ubwc_enc_version = UBWC_1_0,
105+
.ubwc_dec_version = UBWC_3_0,
106+
.ubwc_swizzle = 1,
107+
.highest_bank_bit = 14,
108+
};
109+
110+
static const struct qcom_ubwc_cfg_data sm6150_data = {
111+
.ubwc_enc_version = UBWC_2_0,
112+
.ubwc_dec_version = UBWC_2_0,
113+
.highest_bank_bit = 14,
114+
};
115+
116+
static const struct qcom_ubwc_cfg_data sm6350_data = {
117+
.ubwc_enc_version = UBWC_2_0,
118+
.ubwc_dec_version = UBWC_2_0,
119+
.ubwc_swizzle = 6,
120+
.ubwc_bank_spread = true,
121+
.highest_bank_bit = 14,
122+
};
123+
124+
static const struct qcom_ubwc_cfg_data sm7150_data = {
125+
.ubwc_enc_version = UBWC_2_0,
126+
.ubwc_dec_version = UBWC_2_0,
127+
.highest_bank_bit = 14,
128+
};
129+
130+
static const struct qcom_ubwc_cfg_data sm8150_data = {
131+
.ubwc_enc_version = UBWC_3_0,
132+
.ubwc_dec_version = UBWC_3_0,
133+
.highest_bank_bit = 15,
134+
};
135+
136+
static const struct qcom_ubwc_cfg_data sm8250_data = {
137+
.ubwc_enc_version = UBWC_4_0,
138+
.ubwc_dec_version = UBWC_4_0,
139+
.ubwc_swizzle = 6,
140+
.ubwc_bank_spread = true,
141+
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
142+
.highest_bank_bit = 16,
143+
.macrotile_mode = true,
144+
};
145+
146+
static const struct qcom_ubwc_cfg_data sm8350_data = {
147+
.ubwc_enc_version = UBWC_4_0,
148+
.ubwc_dec_version = UBWC_4_0,
149+
.ubwc_swizzle = 6,
150+
.ubwc_bank_spread = true,
151+
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
152+
.highest_bank_bit = 16,
153+
.macrotile_mode = true,
154+
};
155+
156+
static const struct qcom_ubwc_cfg_data sm8550_data = {
157+
.ubwc_enc_version = UBWC_4_0,
158+
.ubwc_dec_version = UBWC_4_3,
159+
.ubwc_swizzle = 6,
160+
.ubwc_bank_spread = true,
161+
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
162+
.highest_bank_bit = 16,
163+
.macrotile_mode = true,
164+
};
165+
166+
static const struct qcom_ubwc_cfg_data sm8750_data = {
167+
.ubwc_enc_version = UBWC_5_0,
168+
.ubwc_dec_version = UBWC_5_0,
169+
.ubwc_swizzle = 6,
170+
.ubwc_bank_spread = true,
171+
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
172+
.highest_bank_bit = 16,
173+
.macrotile_mode = true,
174+
};
175+
176+
static const struct qcom_ubwc_cfg_data x1e80100_data = {
177+
.ubwc_enc_version = UBWC_4_0,
178+
.ubwc_dec_version = UBWC_4_3,
179+
.ubwc_swizzle = 6,
180+
.ubwc_bank_spread = true,
181+
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
182+
.highest_bank_bit = 16,
183+
.macrotile_mode = true,
184+
};
185+
186+
static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
187+
{ .compatible = "qcom,apq8096", .data = &msm8998_data },
188+
{ .compatible = "qcom,msm8917", .data = &msm8937_data },
189+
{ .compatible = "qcom,msm8937", .data = &msm8937_data },
190+
{ .compatible = "qcom,msm8953", .data = &msm8937_data },
191+
{ .compatible = "qcom,msm8956", .data = &msm8937_data },
192+
{ .compatible = "qcom,msm8976", .data = &msm8937_data },
193+
{ .compatible = "qcom,msm8996", .data = &msm8998_data },
194+
{ .compatible = "qcom,msm8998", .data = &msm8998_data },
195+
{ .compatible = "qcom,qcm2290", .data = &qcm2290_data, },
196+
{ .compatible = "qcom,qcm6490", .data = &sc7280_data, },
197+
{ .compatible = "qcom,sa8155p", .data = &sm8150_data, },
198+
{ .compatible = "qcom,sa8540p", .data = &sc8280xp_data, },
199+
{ .compatible = "qcom,sa8775p", .data = &sa8775p_data, },
200+
{ .compatible = "qcom,sar2130p", .data = &sar2130p_data },
201+
{ .compatible = "qcom,sc7180", .data = &sc7180_data },
202+
{ .compatible = "qcom,sc7280", .data = &sc7280_data, },
203+
{ .compatible = "qcom,sc8180x", .data = &sc8180x_data, },
204+
{ .compatible = "qcom,sc8280xp", .data = &sc8280xp_data, },
205+
{ .compatible = "qcom,sdm630", .data = &msm8937_data },
206+
{ .compatible = "qcom,sdm636", .data = &msm8937_data },
207+
{ .compatible = "qcom,sdm660", .data = &msm8937_data },
208+
{ .compatible = "qcom,sdm670", .data = &sdm670_data, },
209+
{ .compatible = "qcom,sdm845", .data = &sdm845_data, },
210+
{ .compatible = "qcom,sm4250", .data = &sm6115_data, },
211+
{ .compatible = "qcom,sm6115", .data = &sm6115_data, },
212+
{ .compatible = "qcom,sm6125", .data = &sm6125_data, },
213+
{ .compatible = "qcom,sm6150", .data = &sm6150_data, },
214+
{ .compatible = "qcom,sm6350", .data = &sm6350_data, },
215+
{ .compatible = "qcom,sm6375", .data = &sm6350_data, },
216+
{ .compatible = "qcom,sm7125", .data = &sc7180_data },
217+
{ .compatible = "qcom,sm7150", .data = &sm7150_data, },
218+
{ .compatible = "qcom,sm8150", .data = &sm8150_data, },
219+
{ .compatible = "qcom,sm8250", .data = &sm8250_data, },
220+
{ .compatible = "qcom,sm8350", .data = &sm8350_data, },
221+
{ .compatible = "qcom,sm8450", .data = &sm8350_data, },
222+
{ .compatible = "qcom,sm8550", .data = &sm8550_data, },
223+
{ .compatible = "qcom,sm8650", .data = &sm8550_data, },
224+
{ .compatible = "qcom,sm8750", .data = &sm8750_data, },
225+
{ .compatible = "qcom,x1e80100", .data = &x1e80100_data, },
226+
{ .compatible = "qcom,x1p42100", .data = &x1e80100_data, },
227+
{ }
228+
};
229+
230+
const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void)
231+
{
232+
const struct of_device_id *match;
233+
struct device_node *root;
234+
235+
root = of_find_node_by_path("/");
236+
if (!root)
237+
return ERR_PTR(-ENODEV);
238+
239+
match = of_match_node(qcom_ubwc_configs, root);
240+
of_node_put(root);
241+
if (!match) {
242+
pr_err("Couldn't find UBWC config data for this platform!\n");
243+
return ERR_PTR(-EINVAL);
244+
}
245+
246+
return match->data;
247+
}
248+
EXPORT_SYMBOL_GPL(qcom_ubwc_config_get_data);
249+
250+
MODULE_LICENSE("GPL");
251+
MODULE_DESCRIPTION("UBWC config database for QTI SoCs");

include/linux/soc/qcom/ubwc.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (c) 2018, The Linux Foundation
4+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5+
*/
6+
7+
#ifndef __QCOM_UBWC_H__
8+
#define __QCOM_UBWC_H__
9+
10+
#include <linux/bits.h>
11+
#include <linux/types.h>
12+
13+
struct qcom_ubwc_cfg_data {
14+
u32 ubwc_enc_version;
15+
/* Can be read from MDSS_BASE + 0x58 */
16+
u32 ubwc_dec_version;
17+
18+
/**
19+
* @ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling.
20+
*
21+
* UBWC 1.0 always enables all three levels.
22+
* UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3.
23+
* UBWC 4.0 adds the optional ability to disable levels 2 & 3.
24+
*
25+
* This is a bitmask where BIT(0) enables level 1, BIT(1)
26+
* controls level 2, and BIT(2) enables level 3.
27+
*/
28+
u32 ubwc_swizzle;
29+
30+
/**
31+
* @highest_bank_bit: Highest Bank Bit
32+
*
33+
* The Highest Bank Bit value represents the bit of the highest
34+
* DDR bank. This should ideally use DRAM type detection.
35+
*/
36+
int highest_bank_bit;
37+
bool ubwc_bank_spread;
38+
39+
/**
40+
* @macrotile_mode: Macrotile Mode
41+
*
42+
* Whether to use 4-channel macrotiling mode or the newer
43+
* 8-channel macrotiling mode introduced in UBWC 3.1. 0 is
44+
* 4-channel and 1 is 8-channel.
45+
*/
46+
bool macrotile_mode;
47+
};
48+
49+
#define UBWC_1_0 0x10000000
50+
#define UBWC_2_0 0x20000000
51+
#define UBWC_3_0 0x30000000
52+
#define UBWC_4_0 0x40000000
53+
#define UBWC_4_3 0x40030000
54+
#define UBWC_5_0 0x50000000
55+
56+
#ifdef CONFIG_QCOM_UBWC_CONFIG
57+
const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void);
58+
#else
59+
static inline const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void)
60+
{
61+
return ERR_PTR(-EOPNOTSUPP);
62+
}
63+
#endif
64+
65+
#endif /* __QCOM_UBWC_H__ */

0 commit comments

Comments
 (0)