summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/llcc-qcom.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2022-12-08 00:07:48 +0300
committerArnd Bergmann <arnd@arndb.de>2022-12-08 00:07:48 +0300
commit9379885d07c466a9207e88c0fd0c8b3541536fe3 (patch)
treedc145b21adef05a74bc3ca70df44606b9a289a3c /drivers/soc/qcom/llcc-qcom.c
parent66310b5a0fc1ccdce9a3a5e6c6a12c08e4e0b7b1 (diff)
parentf33ca7ec5e5e3a53d5636a4eab270bacac751f6e (diff)
downloadlinux-9379885d07c466a9207e88c0fd0c8b3541536fe3.tar.xz
Merge tag 'qcom-drivers-for-6.2-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers
More Qualcomm driver updates for 6.2 Socinfo is extended with knowledge about MSM8956, MSM8976, SM6115, SM4250, SM8150, SA8155 and SM8550. Support for RSC v3, as found in SM8550 is added to the RPMH RSC driver. Support for SM8550 and SM4250 ARC regulators are added to the RPM(h) power-domain drivers. SM8550 support is added to the LLCC driver. The AOSS QMP binding is declared compatible for SM8550. BWMON and LLCC now selects REGMAP_MMIO to ensure dependencies are built properly. * tag 'qcom-drivers-for-6.2-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: soc: qcom: socinfo: Add SM6115 / SM4250 SoC IDs to the soc_id table dt-bindings: arm: qcom,ids: Add SoC IDs for SM6115 / SM4250 and variants soc: qcom: socinfo: Add SM8150 and SA8155 SoC IDs to the soc_id table dt-bindings: arm: qcom,ids: Add SoC IDs for SM8150 and SA8155 dt-bindings: soc: qcom: apr: document generic qcom,apr compatible soc: qcom: Select REMAP_MMIO for ICC_BWMON driver soc: qcom: Select REMAP_MMIO for LLCC driver soc: qcom: rpmpd: Add SM4250 support dt-bindings: power: rpmpd: Add SM4250 support dt-bindings: soc: qcom: aoss: Add compatible for SM8550 soc: qcom: llcc: Add configuration data for SM8550 dt-bindings: arm: msm: Add LLCC compatible for SM8550 soc: qcom: llcc: Add v4.1 HW version support soc: qcom: socinfo: Add SM8550 ID soc: qcom: rpmh-rsc: Avoid unnecessary checks on irq-done response soc: qcom: rpmh-rsc: Add support for RSC v3 register offsets soc: qcom: rpmhpd: Add SM8550 power domains dt-bindings: power: rpmpd: Add SM8550 to rpmpd binding soc: qcom: socinfo: Add MSM8956/76 SoC IDs to the soc_id table dt-bindings: arm: qcom,ids: Add SoC IDs for MSM8956 and MSM8976 Link: https://lore.kernel.org/r/20221207154134.3233779-1-andersson@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/soc/qcom/llcc-qcom.c')
-rw-r--r--drivers/soc/qcom/llcc-qcom.c166
1 files changed, 159 insertions, 7 deletions
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 82c3cfdcc560..23ce2f78c4ed 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -21,6 +21,8 @@
#define ACTIVATE BIT(0)
#define DEACTIVATE BIT(1)
+#define ACT_CLEAR BIT(0)
+#define ACT_COMPLETE BIT(4)
#define ACT_CTRL_OPCODE_ACTIVATE BIT(0)
#define ACT_CTRL_OPCODE_DEACTIVATE BIT(1)
#define ACT_CTRL_ACT_TRIG BIT(0)
@@ -41,19 +43,30 @@
#define MAX_CAP_TO_BYTES(n) (n * SZ_1K)
#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K)
+#define LLCC_TRP_ACT_CLEARn(n) (8 + n * SZ_4K)
#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K)
#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
+#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_8 * n)
#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
#define LLCC_TRP_PCB_ACT 0x21f04
+#define LLCC_TRP_ALGO_CFG1 0x21f0c
+#define LLCC_TRP_ALGO_CFG2 0x21f10
+#define LLCC_TRP_ALGO_CFG3 0x21f14
+#define LLCC_TRP_ALGO_CFG4 0x21f18
+#define LLCC_TRP_ALGO_CFG5 0x21f1c
#define LLCC_TRP_WRSC_EN 0x21f20
+#define LLCC_TRP_ALGO_CFG6 0x21f24
+#define LLCC_TRP_ALGO_CFG7 0x21f28
#define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c
+#define LLCC_TRP_ALGO_CFG8 0x21f30
#define BANK_OFFSET_STRIDE 0x80000
#define LLCC_VERSION_2_0_0_0 0x02000000
#define LLCC_VERSION_2_1_0_0 0x02010000
+#define LLCC_VERSION_4_1_0_0 0x04010000
/**
* struct llcc_slice_config - Data associated with the llcc slice
@@ -97,6 +110,14 @@ struct llcc_slice_config {
bool activate_on_init;
bool write_scid_en;
bool write_scid_cacheable_en;
+ bool stale_en;
+ bool stale_cap_en;
+ bool mru_uncap_en;
+ bool mru_rollover;
+ bool alloc_oneway_en;
+ bool ovcap_en;
+ bool ovcap_prio;
+ bool vict_prio;
};
struct qcom_llcc_config {
@@ -297,6 +318,38 @@ static const struct llcc_slice_config sm8450_data[] = {
{LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },
};
+static const struct llcc_slice_config sm8550_data[] = {
+ {LLCC_CPUSS, 1, 5120, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_VIDSC0, 2, 512, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_MDMHPGRW, 25, 1024, 4, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_MODHW, 26, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_GPU, 9, 3096, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_MMUHWT, 18, 768, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_DISP, 16, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_MDMPNG, 27, 1024, 0, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CVP, 8, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_MODPE, 29, 64, 1, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },
+ {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CAMEXP0, 4, 256, 4, 1, 0xF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CAMEXP1, 7, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CMPTHCP, 17, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_LCPDARE, 30, 128, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },
+ {LLCC_AENPU, 3, 3072, 1, 1, 0xFE01FF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_ISLAND1, 12, 1792, 7, 1, 0xFE00, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_ISLAND4, 15, 256, 7, 1, 0x10000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CAMEXP2, 19, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CAMEXP3, 20, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_CAMEXP4, 21, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_DISP_WB, 23, 1024, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_DISP_1, 24, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ {LLCC_VIDVSP, 28, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+};
+
static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {
.trp_ecc_error_status0 = 0x20344,
.trp_ecc_error_status1 = 0x20348,
@@ -443,6 +496,14 @@ static const struct qcom_llcc_config sm8450_cfg = {
.edac_reg_offset = &llcc_v2_1_edac_reg_offset,
};
+static const struct qcom_llcc_config sm8550_cfg = {
+ .sct_data = sm8550_data,
+ .size = ARRAY_SIZE(sm8550_data),
+ .need_llcc_cfg = true,
+ .reg_offset = llcc_v2_1_reg_offset,
+ .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
+};
+
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
/**
@@ -497,6 +558,7 @@ static int llcc_update_act_ctrl(u32 sid,
u32 act_ctrl_reg_val, u32 status)
{
u32 act_ctrl_reg;
+ u32 act_clear_reg;
u32 status_reg;
u32 slice_status;
int ret;
@@ -505,6 +567,7 @@ static int llcc_update_act_ctrl(u32 sid,
return PTR_ERR(drv_data);
act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
+ act_clear_reg = LLCC_TRP_ACT_CLEARn(sid);
status_reg = LLCC_TRP_STATUSn(sid);
/* Set the ACTIVE trigger */
@@ -521,9 +584,22 @@ static int llcc_update_act_ctrl(u32 sid,
if (ret)
return ret;
+ if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
+ ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
+ slice_status, (slice_status & ACT_COMPLETE),
+ 0, LLCC_STATUS_READ_DELAY);
+ if (ret)
+ return ret;
+ }
+
ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
slice_status, !(slice_status & status),
0, LLCC_STATUS_READ_DELAY);
+
+ if (drv_data->version >= LLCC_VERSION_4_1_0_0)
+ ret = regmap_write(drv_data->bcast_regmap, act_clear_reg,
+ ACT_CLEAR);
+
return ret;
}
@@ -636,8 +712,10 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
const struct qcom_llcc_config *cfg)
{
int ret;
+ u32 attr2_cfg;
u32 attr1_cfg;
u32 attr0_cfg;
+ u32 attr2_val;
u32 attr1_val;
u32 attr0_val;
u32 max_cap_cacheline;
@@ -667,8 +745,14 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
if (ret)
return ret;
- attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;
- attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
+ if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
+ attr2_cfg = LLCC_TRP_ATTR2_CFGn(config->slice_id);
+ attr0_val = config->res_ways;
+ attr2_val = config->bonus_ways;
+ } else {
+ attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;
+ attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
+ }
attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id);
@@ -676,6 +760,12 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
if (ret)
return ret;
+ if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
+ ret = regmap_write(drv_data->bcast_regmap, attr2_cfg, attr2_val);
+ if (ret)
+ return ret;
+ }
+
if (cfg->need_llcc_cfg) {
u32 disable_cap_alloc, retain_pc;
@@ -685,11 +775,13 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
if (ret)
return ret;
- retain_pc = config->retain_on_pc << config->slice_id;
- ret = regmap_write(drv_data->bcast_regmap,
- LLCC_TRP_PCB_ACT, retain_pc);
- if (ret)
- return ret;
+ if (drv_data->version < LLCC_VERSION_4_1_0_0) {
+ retain_pc = config->retain_on_pc << config->slice_id;
+ ret = regmap_write(drv_data->bcast_regmap,
+ LLCC_TRP_PCB_ACT, retain_pc);
+ if (ret)
+ return ret;
+ }
}
if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
@@ -712,6 +804,65 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
return ret;
}
+ if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
+ u32 stale_en;
+ u32 stale_cap_en;
+ u32 mru_uncap_en;
+ u32 mru_rollover;
+ u32 alloc_oneway_en;
+ u32 ovcap_en;
+ u32 ovcap_prio;
+ u32 vict_prio;
+
+ stale_en = config->stale_en << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG1,
+ BIT(config->slice_id), stale_en);
+ if (ret)
+ return ret;
+
+ stale_cap_en = config->stale_cap_en << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG2,
+ BIT(config->slice_id), stale_cap_en);
+ if (ret)
+ return ret;
+
+ mru_uncap_en = config->mru_uncap_en << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG3,
+ BIT(config->slice_id), mru_uncap_en);
+ if (ret)
+ return ret;
+
+ mru_rollover = config->mru_rollover << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG4,
+ BIT(config->slice_id), mru_rollover);
+ if (ret)
+ return ret;
+
+ alloc_oneway_en = config->alloc_oneway_en << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG5,
+ BIT(config->slice_id), alloc_oneway_en);
+ if (ret)
+ return ret;
+
+ ovcap_en = config->ovcap_en << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG6,
+ BIT(config->slice_id), ovcap_en);
+ if (ret)
+ return ret;
+
+ ovcap_prio = config->ovcap_prio << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG7,
+ BIT(config->slice_id), ovcap_prio);
+ if (ret)
+ return ret;
+
+ vict_prio = config->vict_prio << config->slice_id;
+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG8,
+ BIT(config->slice_id), vict_prio);
+ if (ret)
+ return ret;
+ }
+
if (config->activate_on_init) {
desc.slice_id = config->slice_id;
ret = llcc_slice_activate(&desc);
@@ -875,6 +1026,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
{ .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
{ .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
+ { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfg },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);