summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2021-04-08 17:41:52 +0200
committerArnd Bergmann <arnd@arndb.de>2021-04-08 17:41:53 +0200
commit207481077b07d53cb378bc5dc71ae5379c91e8a8 (patch)
tree1e58c95366eb635b878c137cb93b45f94fff1374
parent4be3f47e1bd5c9be4c4b95de5f3531f062a28a66 (diff)
parentac6ad7c2a862d682bb584a4bc904d89fa7721af8 (diff)
Merge tag 'qcom-drivers-for-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers
Qualcomm driver updates for 5.13 This introduces SC7280 and SM8350 support in the RPMH power-domain driver, SC7280 support to the LLCC driver, SC7280 support tot he AOSS QMP driver, cleanups to the RPMH driver and a few smaller fixes to the SMEM, QMI and EBI2 drivers. * tag 'qcom-drivers-for-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: bus: qcom: Put child node before return dt-bindings: firmware: scm: Add sc7280 support soc: qcom: rpmh-rsc: Fold WARN_ON() into if condition soc: qcom: rpmh-rsc: Loop over fewer bits in irq handler soc: qcom: rpmh-rsc: Remove tcs_is_free() API soc: qcom: smem: Update max processor count soc: qcom: aoss: Add AOSS QMP support for SC7280 dt-bindings: soc: qcom: aoss: Add SC7280 compatible soc: qcom: llcc: Add configuration data for SC7280 dt-bindings: arm: msm: Add LLCC for SC7280 soc: qcom: Fix typos in the file qmi_encdec.c soc: qcom: rpmhpd: Add sc7280 powerdomains dt-bindings: power: rpmpd: Add sc7280 to rpmpd binding soc: qcom: rpmhpd: Add SM8350 power domains dt-bindings: power: Add rpm power domain bindings for SM8350 Link: https://lore.kernel.org/r/20210404164951.713045-1-bjorn.andersson@linaro.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml1
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.txt1
-rw-r--r--Documentation/devicetree/bindings/power/qcom,rpmpd.yaml2
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt1
-rw-r--r--drivers/bus/qcom-ebi2.c4
-rw-r--r--drivers/soc/qcom/llcc-qcom.c19
-rw-r--r--drivers/soc/qcom/qcom_aoss.c1
-rw-r--r--drivers/soc/qcom/qmi_encdec.c8
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c65
-rw-r--r--drivers/soc/qcom/rpmhpd.c56
-rw-r--r--drivers/soc/qcom/smem.c2
-rw-r--r--include/dt-bindings/power/qcom-rpmpd.h26
12 files changed, 137 insertions, 49 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index c299dc907f6c..62fcbd883392 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -22,6 +22,7 @@ properties:
compatible:
enum:
- qcom,sc7180-llcc
+ - qcom,sc7280-llcc
- qcom,sdm845-llcc
- qcom,sm8150-llcc
- qcom,sm8250-llcc
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
index a884955f861e..1edc31165d23 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -20,6 +20,7 @@ Required properties:
* "qcom,scm-msm8996"
* "qcom,scm-msm8998"
* "qcom,scm-sc7180"
+ * "qcom,scm-sc7280"
* "qcom,scm-sdm845"
* "qcom,scm-sm8150"
* "qcom,scm-sm8250"
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 1ea21acbbd55..ff21bfef8204 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -25,10 +25,12 @@ properties:
- qcom,qcs404-rpmpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd
+ - qcom,sc7280-rpmhpd
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sm8150-rpmhpd
- qcom,sm8250-rpmhpd
+ - qcom,sm8350-rpmhpd
'#power-domain-cells':
const: 1
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt
index 19c059e44681..783dc81b0f26 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt
@@ -17,6 +17,7 @@ power-domains.
Value type: <string>
Definition: must be one of:
"qcom,sc7180-aoss-qmp"
+ "qcom,sc7280-aoss-qmp"
"qcom,sdm845-aoss-qmp"
"qcom,sm8150-aoss-qmp"
"qcom,sm8250-aoss-qmp"
diff --git a/drivers/bus/qcom-ebi2.c b/drivers/bus/qcom-ebi2.c
index 03ddcf426887..0b8f53a688b8 100644
--- a/drivers/bus/qcom-ebi2.c
+++ b/drivers/bus/qcom-ebi2.c
@@ -353,8 +353,10 @@ static int qcom_ebi2_probe(struct platform_device *pdev)
/* Figure out the chipselect */
ret = of_property_read_u32(child, "reg", &csindex);
- if (ret)
+ if (ret) {
+ of_node_put(child);
return ret;
+ }
if (csindex > 5) {
dev_err(dev,
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 8403a77b59fe..15a36dcab990 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -109,6 +109,18 @@ static const struct llcc_slice_config sc7180_data[] = {
{ LLCC_GPU, 12, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },
};
+static const struct llcc_slice_config sc7280_data[] = {
+ { LLCC_CPUSS, 1, 768, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 1, 0},
+ { LLCC_MDMHPGRW, 7, 512, 2, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_CMPT, 10, 768, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_GPUHTW, 11, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_GPU, 12, 512, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_MMUHWT, 13, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 1, 0},
+ { LLCC_MDMPNG, 21, 768, 0, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_WLHW, 24, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+ { LLCC_MODPE, 29, 64, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
+};
+
static const struct llcc_slice_config sdm845_data[] = {
{ LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 },
{ LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },
@@ -179,6 +191,12 @@ static const struct qcom_llcc_config sc7180_cfg = {
.need_llcc_cfg = true,
};
+static const struct qcom_llcc_config sc7280_cfg = {
+ .sct_data = sc7280_data,
+ .size = ARRAY_SIZE(sc7280_data),
+ .need_llcc_cfg = true,
+};
+
static const struct qcom_llcc_config sdm845_cfg = {
.sct_data = sdm845_data,
.size = ARRAY_SIZE(sdm845_data),
@@ -606,6 +624,7 @@ err:
static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg },
+ { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfg },
{ .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
{ .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
{ .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index 53acb9423bd6..934fcc4d2b05 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -597,6 +597,7 @@ static int qmp_remove(struct platform_device *pdev)
static const struct of_device_id qmp_dt_match[] = {
{ .compatible = "qcom,sc7180-aoss-qmp", },
+ { .compatible = "qcom,sc7280-aoss-qmp", },
{ .compatible = "qcom,sdm845-aoss-qmp", },
{ .compatible = "qcom,sm8150-aoss-qmp", },
{ .compatible = "qcom,sm8250-aoss-qmp", },
diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c
index 3aaab71d1b2c..328cc8237191 100644
--- a/drivers/soc/qcom/qmi_encdec.c
+++ b/drivers/soc/qcom/qmi_encdec.c
@@ -451,11 +451,11 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src,
/**
* qmi_decode_struct_elem() - Decodes elements of struct data type
- * @ei_array: Struct info array descibing the struct element.
+ * @ei_array: Struct info array describing the struct element.
* @buf_dst: Buffer to store the decoded element.
* @buf_src: Buffer containing the elements in QMI wire format.
* @elem_len: Number of elements to be decoded.
- * @tlv_len: Total size of the encoded inforation corresponding to
+ * @tlv_len: Total size of the encoded information corresponding to
* this struct element.
* @dec_level: Depth of the nested structure from the main structure.
*
@@ -499,10 +499,10 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array,
/**
* qmi_decode_string_elem() - Decodes elements of string data type
- * @ei_array: Struct info array descibing the string element.
+ * @ei_array: Struct info array describing the string element.
* @buf_dst: Buffer to store the decoded element.
* @buf_src: Buffer containing the elements in QMI wire format.
- * @tlv_len: Total size of the encoded inforation corresponding to
+ * @tlv_len: Total size of the encoded information corresponding to
* this string element.
* @dec_level: Depth of the string element from the main structure.
*
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index a84ab0d6a9d4..e749a2b285d8 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -195,22 +195,6 @@ static void write_tcs_reg_sync(const struct rsc_drv *drv, int reg, int tcs_id,
}
/**
- * tcs_is_free() - Return if a TCS is totally free.
- * @drv: The RSC controller.
- * @tcs_id: The global ID of this TCS.
- *
- * Returns true if nobody has claimed this TCS (by setting tcs_in_use).
- *
- * Context: Must be called with the drv->lock held.
- *
- * Return: true if the given TCS is free.
- */
-static bool tcs_is_free(struct rsc_drv *drv, int tcs_id)
-{
- return !test_bit(tcs_id, drv->tcs_in_use);
-}
-
-/**
* tcs_invalidate() - Invalidate all TCSes of the given type (sleep or wake).
* @drv: The RSC controller.
* @type: SLEEP_TCS or WAKE_TCS
@@ -408,12 +392,10 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
irq_status = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_STATUS);
- for_each_set_bit(i, &irq_status, BITS_PER_LONG) {
+ for_each_set_bit(i, &irq_status, BITS_PER_TYPE(u32)) {
req = get_req_from_tcs(drv, i);
- if (!req) {
- WARN_ON(1);
+ if (WARN_ON(!req))
goto skip;
- }
err = 0;
for (j = 0; j < req->num_cmds; j++) {
@@ -520,7 +502,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
*
* Return: 0 if nothing in flight or -EBUSY if we should try again later.
* The caller must re-enable interrupts between tries since that's
- * the only way tcs_is_free() will ever return true and the only way
+ * the only way tcs_in_use will ever be updated and the only way
* RSC_DRV_CMD_ENABLE will ever be cleared.
*/
static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
@@ -528,17 +510,14 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
{
unsigned long curr_enabled;
u32 addr;
- int i, j, k;
- int tcs_id = tcs->offset;
-
- for (i = 0; i < tcs->num_tcs; i++, tcs_id++) {
- if (tcs_is_free(drv, tcs_id))
- continue;
+ int j, k;
+ int i = tcs->offset;
- curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id);
+ for_each_set_bit_from(i, drv->tcs_in_use, tcs->offset + tcs->num_tcs) {
+ curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i);
for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
- addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j);
+ addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, i, j);
for (k = 0; k < msg->num_cmds; k++) {
if (addr == msg->cmds[k].addr)
return -EBUSY;
@@ -556,18 +535,19 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
*
* Must be called with the drv->lock held since that protects tcs_in_use.
*
- * Return: The first tcs that's free.
+ * Return: The first tcs that's free or -EBUSY if all in use.
*/
static int find_free_tcs(struct tcs_group *tcs)
{
- int i;
+ const struct rsc_drv *drv = tcs->drv;
+ unsigned long i;
+ unsigned long max = tcs->offset + tcs->num_tcs;
- for (i = 0; i < tcs->num_tcs; i++) {
- if (tcs_is_free(tcs->drv, tcs->offset + i))
- return tcs->offset + i;
- }
+ i = find_next_zero_bit(drv->tcs_in_use, max, tcs->offset);
+ if (i >= max)
+ return -EBUSY;
- return -EBUSY;
+ return i;
}
/**
@@ -754,8 +734,9 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg)
*/
static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv)
{
- int m;
- struct tcs_group *tcs = &drv->tcs[ACTIVE_TCS];
+ unsigned long set;
+ const struct tcs_group *tcs = &drv->tcs[ACTIVE_TCS];
+ unsigned long max;
/*
* If we made an active request on a RSC that does not have a
@@ -766,12 +747,10 @@ static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv)
if (!tcs->num_tcs)
tcs = &drv->tcs[WAKE_TCS];
- for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) {
- if (!tcs_is_free(drv, m))
- return true;
- }
+ max = tcs->offset + tcs->num_tcs;
+ set = find_next_bit(drv->tcs_in_use, max, tcs->offset);
- return false;
+ return set < max;
}
/**
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
index 7ce06356d24c..bb21c4f1c0c4 100644
--- a/drivers/soc/qcom/rpmhpd.c
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -200,6 +200,42 @@ static const struct rpmhpd_desc sm8250_desc = {
.num_pds = ARRAY_SIZE(sm8250_rpmhpds),
};
+/* SM8350 Power domains */
+static struct rpmhpd sm8350_mxc_ao;
+static struct rpmhpd sm8350_mxc = {
+ .pd = { .name = "mxc", },
+ .peer = &sm8150_mmcx_ao,
+ .res_name = "mxc.lvl",
+};
+
+static struct rpmhpd sm8350_mxc_ao = {
+ .pd = { .name = "mxc_ao", },
+ .active_only = true,
+ .peer = &sm8350_mxc,
+ .res_name = "mxc.lvl",
+};
+
+static struct rpmhpd *sm8350_rpmhpds[] = {
+ [SM8350_CX] = &sdm845_cx,
+ [SM8350_CX_AO] = &sdm845_cx_ao,
+ [SM8350_EBI] = &sdm845_ebi,
+ [SM8350_GFX] = &sdm845_gfx,
+ [SM8350_LCX] = &sdm845_lcx,
+ [SM8350_LMX] = &sdm845_lmx,
+ [SM8350_MMCX] = &sm8150_mmcx,
+ [SM8350_MMCX_AO] = &sm8150_mmcx_ao,
+ [SM8350_MX] = &sdm845_mx,
+ [SM8350_MX_AO] = &sdm845_mx_ao,
+ [SM8350_MXC] = &sm8350_mxc,
+ [SM8350_MXC_AO] = &sm8350_mxc_ao,
+ [SM8350_MSS] = &sdm845_mss,
+};
+
+static const struct rpmhpd_desc sm8350_desc = {
+ .rpmhpds = sm8350_rpmhpds,
+ .num_pds = ARRAY_SIZE(sm8350_rpmhpds),
+};
+
/* SC7180 RPMH powerdomains */
static struct rpmhpd *sc7180_rpmhpds[] = {
[SC7180_CX] = &sdm845_cx,
@@ -217,12 +253,32 @@ static const struct rpmhpd_desc sc7180_desc = {
.num_pds = ARRAY_SIZE(sc7180_rpmhpds),
};
+/* SC7280 RPMH powerdomains */
+static struct rpmhpd *sc7280_rpmhpds[] = {
+ [SC7280_CX] = &sdm845_cx,
+ [SC7280_CX_AO] = &sdm845_cx_ao,
+ [SC7280_EBI] = &sdm845_ebi,
+ [SC7280_GFX] = &sdm845_gfx,
+ [SC7280_MX] = &sdm845_mx,
+ [SC7280_MX_AO] = &sdm845_mx_ao,
+ [SC7280_LMX] = &sdm845_lmx,
+ [SC7280_LCX] = &sdm845_lcx,
+ [SC7280_MSS] = &sdm845_mss,
+};
+
+static const struct rpmhpd_desc sc7280_desc = {
+ .rpmhpds = sc7280_rpmhpds,
+ .num_pds = ARRAY_SIZE(sc7280_rpmhpds),
+};
+
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
+ { .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
+ { .compatible = "qcom,sm8350-rpmhpd", .data = &sm8350_desc },
{ }
};
MODULE_DEVICE_TABLE(of, rpmhpd_match_table);
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index cc4e0655a47b..4fb5aeeb0843 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -84,7 +84,7 @@
#define SMEM_GLOBAL_HOST 0xfffe
/* Max number of processors/hosts in a system */
-#define SMEM_HOST_COUNT 11
+#define SMEM_HOST_COUNT 14
/**
* struct smem_proc_comm - proc_comm communication struct (legacy)
diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
index d711e250cf2c..eedb5d94c020 100644
--- a/include/dt-bindings/power/qcom-rpmpd.h
+++ b/include/dt-bindings/power/qcom-rpmpd.h
@@ -45,6 +45,21 @@
#define SM8250_MX 8
#define SM8250_MX_AO 9
+/* SM8350 Power Domain Indexes */
+#define SM8350_CX 0
+#define SM8350_CX_AO 1
+#define SM8350_EBI 2
+#define SM8350_GFX 3
+#define SM8350_LCX 4
+#define SM8350_LMX 5
+#define SM8350_MMCX 6
+#define SM8350_MMCX_AO 7
+#define SM8350_MX 8
+#define SM8350_MX_AO 9
+#define SM8350_MXC 10
+#define SM8350_MXC_AO 11
+#define SM8350_MSS 12
+
/* SC7180 Power Domain Indexes */
#define SC7180_CX 0
#define SC7180_CX_AO 1
@@ -55,6 +70,17 @@
#define SC7180_LCX 6
#define SC7180_MSS 7
+/* SC7280 Power Domain Indexes */
+#define SC7280_CX 0
+#define SC7280_CX_AO 1
+#define SC7280_EBI 2
+#define SC7280_GFX 3
+#define SC7280_MX 4
+#define SC7280_MX_AO 5
+#define SC7280_LMX 6
+#define SC7280_LCX 7
+#define SC7280_MSS 8
+
/* SDM845 Power Domain performance levels */
#define RPMH_REGULATOR_LEVEL_RETENTION 16
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48