History

Merge tag 'arm-drivers-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM driver updates from Arnd Bergmann: "These are the usual updates for SoC specific device drivers and related subsystems that don't have their own top-level maintainers: - ARM SCMI/SCPI updates to allow pluggable transport layers - TEE subsystem cleanups - A new driver for the Amlogic secure power domain controller - Various driver updates for the NXP Layerscape DPAA2, NXP i.MX SCU and TI OMAP2+ sysc drivers. - Qualcomm SoC driver updates, including a new library module for "protection domain" notifications - Lots of smaller bugfixes and cleanups in other drivers" * tag 'arm-drivers-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (70 commits) soc: fsl: qe: fix sparse warnings for ucc_slow.c soc: fsl: qe: ucc_slow: remove 0 assignment for kzalloc'ed structure soc: fsl: qe: fix sparse warnings for ucc_fast.c soc: fsl: qe: fix sparse warnings for qe_ic.c soc: fsl: qe: fix sparse warnings for ucc.c soc: fsl: qe: fix sparse warning for qe_common.c soc: fsl: qe: fix sparse warnings for qe.c soc: qcom: Fix QCOM_APR dependencies soc: qcom: pdr: Avoid uninitialized use of found in pdr_indication_cb soc: imx: drop COMPILE_TEST for IMX_SCU_SOC firmware: imx: add COMPILE_TEST for IMX_SCU driver soc: imx: gpc: fix power up sequencing soc: imx: increase build coverage for imx8m soc driver soc: qcom: apr: Add avs/audio tracking functionality dt-bindings: soc: qcom: apr: Add protection domain bindings soc: qcom: Introduce Protection Domain Restart helpers devicetree: bindings: firmware: add ipq806x to qcom_scm memory: tegra: Correct debugfs clk rate-range on Tegra124 memory: tegra: Correct debugfs clk rate-range on Tegra30 memory: tegra: Correct debugfs clk rate-range on Tegra20 ...

Linus Torvalds committed 6 years ago

Commit d18292d2 parents 0e8fb69 cedb41468 files · +3692 −633Browse files

Unified · Split

68 files
  1. Documentation/devicetree/bindings/bus/ti-sysc.txt +1 −0
  2. Documentation/devicetree/bindings/firmware/qcom,scm.txt +1 −0
  3. Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml +40 −0
  4. Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt +50 −0
  5. arch/arm/mach-omap2/pdata-quirks.c +6 −0
  6. drivers/bus/hisi_lpc.c +25 −2
  7. drivers/bus/ti-sysc.c +515 −89
  8. drivers/firmware/arm_scmi/Makefile +2 −1
  9. drivers/firmware/arm_scmi/common.h +113 −2
  10. drivers/firmware/arm_scmi/driver.c +34 −259
  11. drivers/firmware/arm_scmi/mailbox.c +184 −0
  12. drivers/firmware/arm_scmi/perf.c +1 −1
  13. drivers/firmware/arm_scmi/shmem.c +83 −0
  14. drivers/firmware/arm_scpi.c +2 −2
  15. drivers/firmware/imx/scu-pd.c +12 −1
  16. drivers/firmware/meson/meson_sm.c +2 −0
  17. drivers/firmware/tegra/Kconfig +1 −1
  18. drivers/gpu/drm/omapdrm/dss/dss.c +22 −3
  19. drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c +17 −8
  20. drivers/memory/tegra/tegra124-emc.c +5 −0
  21. drivers/memory/tegra/tegra20-emc.c +5 −0
  22. drivers/memory/tegra/tegra30-emc.c +5 −0
  23. drivers/soc/Makefile +1 −1
  24. drivers/soc/amlogic/Kconfig +13 −0
  25. drivers/soc/amlogic/Makefile +1 −0
  26. drivers/soc/amlogic/meson-secure-pwrc.c +204 −0
  27. drivers/soc/fsl/dpio/dpio-service.c +66 −3
  28. drivers/soc/fsl/dpio/qbman-portal.c +686 −81
  29. drivers/soc/fsl/dpio/qbman-portal.h +151 −7
  30. drivers/soc/fsl/qe/qe.c +2 −2
  31. drivers/soc/fsl/qe/qe_common.c +1 −1
  32. drivers/soc/fsl/qe/qe_ic.c +1 −1
  33. drivers/soc/fsl/qe/ucc.c +1 −1
  34. drivers/soc/fsl/qe/ucc_slow.c +13 −20
  35. drivers/soc/imx/Kconfig +10 −1
  36. drivers/soc/imx/Makefile +1 −1
  37. drivers/soc/imx/gpc.c +13 −11
  38. drivers/soc/imx/gpcv2.c +1 −0
  39. drivers/soc/imx/soc-imx8m.c +0 −0
  40. drivers/soc/qcom/Kconfig +6 −1
  41. drivers/soc/qcom/Makefile +1 −0
  42. drivers/soc/qcom/apr.c +114 −9
  43. drivers/soc/qcom/pdr_interface.c +757 −0
  44. drivers/soc/qcom/pdr_internal.h +379 −0
  45. drivers/soc/qcom/qcom_aoss.c +5 −1
  46. drivers/soc/qcom/rpmh-internal.h +1 −0
  47. drivers/soc/qcom/rpmh-rsc.c +1 −1
  48. drivers/soc/qcom/rpmh.c +10 −12
  49. drivers/soc/qcom/socinfo.c +1 −1
  50. drivers/soc/renesas/Kconfig +8 −8
  51. drivers/soc/renesas/rcar-sysc.h +2 −2
  52. drivers/soc/renesas/renesas-soc.c +1 −1
  53. drivers/tee/tee_core.c +0 −1
  54. drivers/tee/tee_private.h +2 −1
  55. drivers/tee/tee_shm.c +24 −61
  56. include/dt-bindings/bus/ti-sysc.h +4 −0
  57. include/dt-bindings/power/meson-a1-power.h +32 −0
  58. include/linux/firmware/imx/ipc.h +0 −1
  59. include/linux/firmware/meson/meson_sm.h +2 −0
  60. include/linux/platform_data/ti-sysc.h +5 −0
  61. include/linux/soc/qcom/apr.h +1 −0
  62. include/linux/soc/qcom/pdr.h +29 −0
  63. include/linux/soc/qcom/qmi.h +1 −0
  64. include/linux/tee_drv.h +1 −18
  65. include/soc/fsl/dpaa2-io.h +5 −1
  66. include/soc/fsl/qe/ucc_fast.h +3 −3
  67. include/soc/fsl/qe/ucc_slow.h +6 −7
  68. include/soc/qcom/rpmh.h +0 −5
Documentation/devicetree/bindings/bus/ti-sysc.txt+1−0
@@ -38,6 +38,7 @@ Required standard properties: · 37 unmodified lines
3838 "ti,sysc-dra7-mcasp"
3939 "ti,sysc-usb-host-fs"
4040 "ti,sysc-dra7-mcan"
41+ "ti,sysc-pruss"
4142
4243 - reg shall have register areas implemented for the interconnect
4344 target module in question such as revision, sysc and syss
Documentation/devicetree/bindings/firmware/qcom,scm.txt+1−0
@@ -10,6 +10,7 @@ Required properties: · 9 unmodified lines
1010 * "qcom,scm-apq8064"
1111 * "qcom,scm-apq8084"
1212 * "qcom,scm-ipq4019"
13+ * "qcom,scm-ipq806x"
1314 * "qcom,scm-msm8660"
1415 * "qcom,scm-msm8916"
1516 * "qcom,scm-msm8960"
Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2+# Copyright (c) 2019 Amlogic, Inc
3+# Author: Jianxin Pan <jianxin.pan@amlogic.com>
4+%YAML 1.2
5+---
6+$id: "http://devicetree.org/schemas/power/amlogic,meson-sec-pwrc.yaml#"
7+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
8+
9+title: Amlogic Meson Secure Power Domains
10+
11+maintainers:
12+ - Jianxin Pan <jianxin.pan@amlogic.com>
13+
14+description: |+
15+ Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node
16+ of secure-monitor.
17+
18+properties:
19+ compatible:
20+ enum:
21+ - amlogic,meson-a1-pwrc
22+
23+ "#power-domain-cells":
24+ const: 1
25+
26+required:
27+ - compatible
28+ - "#power-domain-cells"
29+
30+examples:
31+ - |
32+ secure-monitor {
33+ compatible = "amlogic,meson-gxbb-sm";
34+
35+ pwrc: power-controller {
36+ compatible = "amlogic,meson-a1-pwrc";
37+ #power-domain-cells = <1>;
38+ };
39+ };
40+
Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt+50−0
@@ -45,6 +45,18 @@ by the individual bindings for the specific service · 44 unmodified lines
4545 12 - Ultrasound stream manager.
4646 13 - Listen stream manager.
4747
48+- qcom,protection-domain
49+ Usage: optional
50+ Value type: <stringlist>
51+ Definition: Must list the protection domain service name and path
52+ that the particular apr service has a dependency on.
53+ Possible values are :
54+ "avs/audio", "msm/adsp/audio_pd".
55+ "kernel/elf_loader", "msm/modem/wlan_pd".
56+ "tms/servreg", "msm/adsp/audio_pd".
57+ "tms/servreg", "msm/modem/wlan_pd".
58+ "tms/servreg", "msm/slpi/sensor_pd".
59+
4860 = EXAMPLE
4961 The following example represents a QDSP based sound card on a MSM8996 device
5062 which uses apr as communication between Apps and QDSP.
@@ -82,3 +94,41 @@ which uses apr as communication between Apps and QDSP. · 31 unmodified lines
8294 ...
8395 };
8496 };
97+
98+= EXAMPLE 2
99+The following example represents a QDSP based sound card with protection domain
100+dependencies specified. Here some of the apr services are dependent on services
101+running on protection domain hosted on ADSP/SLPI remote processors while others
102+have no such dependency.
103+
104+ apr {
105+ compatible = "qcom,apr-v2";
106+ qcom,glink-channels = "apr_audio_svc";
107+ qcom,apr-domain = <APR_DOMAIN_ADSP>;
108+
109+ q6core {
110+ compatible = "qcom,q6core";
111+ reg = <APR_SVC_ADSP_CORE>;
112+ };
113+
114+ q6afe: q6afe {
115+ compatible = "qcom,q6afe";
116+ reg = <APR_SVC_AFE>;
117+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
118+ ...
119+ };
120+
121+ q6asm: q6asm {
122+ compatible = "qcom,q6asm";
123+ reg = <APR_SVC_ASM>;
124+ qcom,protection-domain = "tms/servreg", "msm/slpi/sensor_pd";
125+ ...
126+ };
127+
128+ q6adm: q6adm {
129+ compatible = "qcom,q6adm";
130+ reg = <APR_SVC_ADM>;
131+ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
132+ ...
133+ };
134+ };
arch/arm/mach-omap2/pdata-quirks.c+6−0
@@ -397,10 +397,16 @@ static int ti_sysc_shutdown_module(struct device *dev, · 396 unmodified lines
397397 return omap_hwmod_shutdown(cookie->data);
398398 }
399399
400+static bool ti_sysc_soc_type_gp(void)
401+{
402+ return omap_type() == OMAP2_DEVICE_TYPE_GP;
403+}
404+
400405 static struct of_dev_auxdata omap_auxdata_lookup[];
401406
402407 static struct ti_sysc_platform_data ti_sysc_pdata = {
403408 .auxdata = omap_auxdata_lookup,
409+ .soc_type_gp = ti_sysc_soc_type_gp,
404410 .init_clockdomain = ti_sysc_clkdm_init,
405411 .clkdm_deny_idle = ti_sysc_clkdm_deny_idle,
406412 .clkdm_allow_idle = ti_sysc_clkdm_allow_idle,
drivers/bus/hisi_lpc.c+25−2
@@ -357,6 +357,26 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, · 356 unmodified lines
357357 return 0;
358358 }
359359
360+/*
361+ * Released firmware describes the IO port max address as 0x3fff, which is
362+ * the max host bus address. Fixup to a proper range. This will probably
363+ * never be fixed in firmware.
364+ */
365+static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev,
366+ struct resource *r)
367+{
368+ if (r->end != 0x3fff)
369+ return;
370+
371+ if (r->start == 0xe4)
372+ r->end = 0xe4 + 0x04 - 1;
373+ else if (r->start == 0x2f8)
374+ r->end = 0x2f8 + 0x08 - 1;
375+ else
376+ dev_warn(hostdev, "unrecognised resource %pR to fixup, ignoring\n",
377+ r);
378+}
379+
360380 /*
361381 * hisi_lpc_acpi_set_io_res - set the resources for a child
362382 * @child: the device node to be updated the I/O resource
@@ -418,8 +438,11 @@ static int hisi_lpc_acpi_set_io_res(struct device *child, · 55 unmodified lines
418438 return -ENOMEM;
419439 }
420440 count = 0;
421− list_for_each_entry(rentry, &resource_list, node)
422− resources[count++] = *rentry->res;
441+ list_for_each_entry(rentry, &resource_list, node) {
442+ resources[count] = *rentry->res;
443+ hisi_lpc_acpi_fixup_child_resource(hostdev, &resources[count]);
444+ count++;
445+ }
423446
424447 acpi_dev_free_resource_list(&resource_list);
425448
drivers/bus/ti-sysc.c+515−89
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/clk.h>
88 #include <linux/clkdev.h>
99 #include <linux/delay.h>
10+#include <linux/list.h>
1011 #include <linux/module.h>
1112 #include <linux/platform_device.h>
1213 #include <linux/pm_domain.h>
@@ -15,15 +16,47 @@ · 2 unmodified lines
1516 #include <linux/of_address.h>
1617 #include <linux/of_platform.h>
1718 #include <linux/slab.h>
19+#include <linux/sys_soc.h>
1820 #include <linux/iopoll.h>
1921
2022 #include <linux/platform_data/ti-sysc.h>
2123
2224 #include <dt-bindings/bus/ti-sysc.h>
2325
26+#define DIS_ISP BIT(2)
27+#define DIS_IVA BIT(1)
28+#define DIS_SGX BIT(0)
29+
30+#define SOC_FLAG(match, flag) { .machine = match, .data = (void *)(flag), }
31+
2432 #define MAX_MODULE_SOFTRESET_WAIT 10000
2533
26−static const char * const reg_names[] = { "rev", "sysc", "syss", };
34+enum sysc_soc {
35+ SOC_UNKNOWN,
36+ SOC_2420,
37+ SOC_2430,
38+ SOC_3430,
39+ SOC_3630,
40+ SOC_4430,
41+ SOC_4460,
42+ SOC_4470,
43+ SOC_5430,
44+ SOC_AM3,
45+ SOC_AM4,
46+ SOC_DRA7,
47+};
48+
49+struct sysc_address {
50+ unsigned long base;
51+ struct list_head node;
52+};
53+
54+struct sysc_soc_info {
55+ unsigned long general_purpose:1;
56+ enum sysc_soc soc;
57+ struct mutex list_lock; /* disabled modules list lock */
58+ struct list_head disabled_modules;
59+};
2760
2861 enum sysc_clocks {
2962 SYSC_FCK,
@@ -39,6 +72,8 @@ enum sysc_clocks { · 9 unmodified lines
3972 SYSC_MAX_CLOCKS,
4073 };
4174
75+static struct sysc_soc_info *sysc_soc;
76+static const char * const reg_names[] = { "rev", "sysc", "syss", };
4277 static const char * const clock_names[SYSC_MAX_CLOCKS] = {
4378 "fck", "ick", "opt0", "opt1", "opt2", "opt3", "opt4",
4479 "opt5", "opt6", "opt7",
@@ -70,11 +105,13 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = { · 25 unmodified lines
70105 * @child_needs_resume: runtime resume needed for child on resume from suspend
71106 * @disable_on_idle: status flag used for disabling modules with resets
72107 * @idle_work: work structure used to perform delayed idle on a module
73− * @clk_enable_quirk: module specific clock enable quirk
74− * @clk_disable_quirk: module specific clock disable quirk
108+ * @pre_reset_quirk: module specific pre-reset quirk
109+ * @post_reset_quirk: module specific post-reset quirk
75110 * @reset_done_quirk: module specific reset done quirk
76111 * @module_enable_quirk: module specific enable quirk
77112 * @module_disable_quirk: module specific disable quirk
113+ * @module_unlock_quirk: module specific sysconfig unlock quirk
114+ * @module_lock_quirk: module specific sysconfig lock quirk
78115 */
79116 struct sysc {
80117 struct device *dev;
@@ -97,11 +134,13 @@ struct sysc { · 16 unmodified lines
97134 unsigned int needs_resume:1;
98135 unsigned int child_needs_resume:1;
99136 struct delayed_work idle_work;
100− void (*clk_enable_quirk)(struct sysc *sysc);
101− void (*clk_disable_quirk)(struct sysc *sysc);
137+ void (*pre_reset_quirk)(struct sysc *sysc);
138+ void (*post_reset_quirk)(struct sysc *sysc);
102139 void (*reset_done_quirk)(struct sysc *sysc);
103140 void (*module_enable_quirk)(struct sysc *sysc);
104141 void (*module_disable_quirk)(struct sysc *sysc);
142+ void (*module_unlock_quirk)(struct sysc *sysc);
143+ void (*module_lock_quirk)(struct sysc *sysc);
105144 };
106145
107146 static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
@@ -624,7 +663,7 @@ static void sysc_check_one_child(struct sysc *ddata, · 516 unmodified lines
624663 const char *name;
625664
626665 name = of_get_property(np, "ti,hwmods", NULL);
627− if (name)
666+ if (name && !of_device_is_compatible(np, "ti,sysc"))
628667 dev_warn(ddata->dev, "really a child ti,hwmods property?");
629668
630669 sysc_check_quirk_stdout(ddata, np);
@@ -861,6 +900,22 @@ static void sysc_show_registers(struct sysc *ddata) · 230 unmodified lines
861900 buf);
862901 }
863902
903+/**
904+ * sysc_write_sysconfig - handle sysconfig quirks for register write
905+ * @ddata: device driver data
906+ * @value: register value
907+ */
908+static void sysc_write_sysconfig(struct sysc *ddata, u32 value)
909+{
910+ if (ddata->module_unlock_quirk)
911+ ddata->module_unlock_quirk(ddata);
912+
913+ sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], value);
914+
915+ if (ddata->module_lock_quirk)
916+ ddata->module_lock_quirk(ddata);
917+}
918+
864919 #define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1)
865920 #define SYSC_CLOCACT_ICK 2
866921
@@ -907,7 +962,7 @@ static int sysc_enable_module(struct device *dev) · 40 unmodified lines
907962
908963 reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
909964 reg |= best_mode << regbits->sidle_shift;
910− sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
965+ sysc_write_sysconfig(ddata, reg);
911966
912967 set_midle:
913968 /* Set MIDLE mode */
@@ -926,14 +981,14 @@ set_midle: · 12 unmodified lines
926981
927982 reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
928983 reg |= best_mode << regbits->midle_shift;
929− sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
984+ sysc_write_sysconfig(ddata, reg);
930985
931986 set_autoidle:
932987 /* Autoidle bit must enabled separately if available */
933988 if (regbits->autoidle_shift >= 0 &&
934989 ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) {
935990 reg |= 1 << regbits->autoidle_shift;
936− sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
991+ sysc_write_sysconfig(ddata, reg);
937992 }
938993
939994 if (ddata->module_enable_quirk)
@@ -991,7 +1046,7 @@ static int sysc_disable_module(struct device *dev) · 51 unmodified lines
9911046
9921047 reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift);
9931048 reg |= best_mode << regbits->midle_shift;
994− sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
1049+ sysc_write_sysconfig(ddata, reg);
9951050
9961051 set_sidle:
9971052 /* Set SIDLE mode */
@@ -1014,7 +1069,7 @@ set_sidle: · 16 unmodified lines
10141069 if (regbits->autoidle_shift >= 0 &&
10151070 ddata->cfg.sysc_val & BIT(regbits->autoidle_shift))
10161071 reg |= 1 << regbits->autoidle_shift;
1017− sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
1072+ sysc_write_sysconfig(ddata, reg);
10181073
10191074 return 0;
10201075 }
@@ -1216,16 +1271,16 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { · 195 unmodified lines
12161271 SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET),
12171272 SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff,
12181273 SYSC_QUIRK_LEGACY_IDLE),
1219− SYSC_QUIRK("smartreflex", 0, -1, 0x24, -1, 0x00000000, 0xffffffff,
1274+ SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x24, -ENODEV, 0x00000000, 0xffffffff,
12201275 SYSC_QUIRK_LEGACY_IDLE),
1221− SYSC_QUIRK("smartreflex", 0, -1, 0x38, -1, 0x00000000, 0xffffffff,
1276+ SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x38, -ENODEV, 0x00000000, 0xffffffff,
12221277 SYSC_QUIRK_LEGACY_IDLE),
12231278 SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff,
12241279 0),
12251280 /* Some timers on omap4 and later */
1226− SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x50002100, 0xffffffff,
1281+ SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x50002100, 0xffffffff,
12271282 0),
1228− SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff,
1283+ SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x4fff1301, 0xffff00ff,
12291284 0),
12301285 SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
12311286 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
@@ -1238,19 +1293,27 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { · 6 unmodified lines
12381293 SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
12391294
12401295 /* Quirks that need to be set based on the module address */
1241− SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -1, 0x50000800, 0xffffffff,
1296+ SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,
12421297 SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT |
12431298 SYSC_QUIRK_SWSUP_SIDLE),
12441299
12451300 /* Quirks that need to be set based on detected module */
1246− SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff,
1301+ SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff,
12471302 SYSC_MODULE_QUIRK_AESS),
1248− SYSC_QUIRK("dcan", 0x48480000, 0x20, -1, -1, 0xa3170504, 0xffffffff,
1303+ SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff,
12491304 SYSC_QUIRK_CLKDM_NOAUTO),
1250− SYSC_QUIRK("dwc3", 0x48880000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
1305+ SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
1306+ SYSC_QUIRK_OPT_CLKS_IN_RESET | SYSC_MODULE_QUIRK_DSS_RESET),
1307+ SYSC_QUIRK("dss", 0x58000000, 0, -ENODEV, 0x14, 0x00000040, 0xffffffff,
1308+ SYSC_QUIRK_OPT_CLKS_IN_RESET | SYSC_MODULE_QUIRK_DSS_RESET),
1309+ SYSC_QUIRK("dss", 0x58000000, 0, -ENODEV, 0x14, 0x00000061, 0xffffffff,
1310+ SYSC_QUIRK_OPT_CLKS_IN_RESET | SYSC_MODULE_QUIRK_DSS_RESET),
1311+ SYSC_QUIRK("dwc3", 0x48880000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
12511312 SYSC_QUIRK_CLKDM_NOAUTO),
1252− SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
1313+ SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
12531314 SYSC_QUIRK_CLKDM_NOAUTO),
1315+ SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff,
1316+ SYSC_QUIRK_OPT_CLKS_NEEDED),
12541317 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
12551318 SYSC_MODULE_QUIRK_HDQ1W),
12561319 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
@@ -1263,72 +1326,92 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { · 6 unmodified lines
12631326 SYSC_MODULE_QUIRK_I2C),
12641327 SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0,
12651328 SYSC_MODULE_QUIRK_I2C),
1266− SYSC_QUIRK("gpu", 0x50000000, 0x14, -1, -1, 0x00010201, 0xffffffff, 0),
1267− SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff,
1329+ SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0),
1330+ SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff,
12681331 SYSC_MODULE_QUIRK_SGX),
1269− SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff,
1332+ SYSC_QUIRK("lcdc", 0, 0, 0x54, -ENODEV, 0x4f201000, 0xffffffff,
1333+ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
1334+ SYSC_QUIRK("rtc", 0, 0x74, 0x78, -ENODEV, 0x4eb01908, 0xffff00f0,
1335+ SYSC_MODULE_QUIRK_RTC_UNLOCK),
1336+ SYSC_QUIRK("tptc", 0, 0, 0x10, -ENODEV, 0x40006c00, 0xffffefff,
1337+ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
1338+ SYSC_QUIRK("tptc", 0, 0, -ENODEV, -ENODEV, 0x40007c00, 0xffffffff,
12701339 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
12711340 SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
12721341 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
1273− SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -1, 0x4ea2080d, 0xffffffff,
1342+ SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff,
12741343 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
12751344 SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
12761345 SYSC_MODULE_QUIRK_WDT),
1346+ /* PRUSS on am3, am4 and am5 */
1347+ SYSC_QUIRK("pruss", 0, 0x26000, 0x26004, -ENODEV, 0x47000000, 0xff000000,
1348+ SYSC_MODULE_QUIRK_PRUSS),
12771349 /* Watchdog on am3 and am4 */
12781350 SYSC_QUIRK("wdt", 0x44e35000, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
12791351 SYSC_MODULE_QUIRK_WDT | SYSC_QUIRK_SWSUP_SIDLE),
12801352
12811353 #ifdef DEBUG
1282− SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
1283− SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0),
1284− SYSC_QUIRK("cm", 0, 0, -1, -1, 0x40000301, 0xffffffff, 0),
1285− SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0),
1354+ SYSC_QUIRK("adc", 0, 0, 0x10, -ENODEV, 0x47300001, 0xffffffff, 0),
1355+ SYSC_QUIRK("atl", 0, 0, -ENODEV, -ENODEV, 0x0a070100, 0xffffffff, 0),
1356+ SYSC_QUIRK("cm", 0, 0, -ENODEV, -ENODEV, 0x40000301, 0xffffffff, 0),
1357+ SYSC_QUIRK("control", 0, 0, 0x10, -ENODEV, 0x40000900, 0xffffffff, 0),
12861358 SYSC_QUIRK("cpgmac", 0, 0x1200, 0x1208, 0x1204, 0x4edb1902,
12871359 0xffff00f0, 0),
1288− SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0xa3170504, 0xffffffff, 0),
1289− SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0x4edb1902, 0xffffffff, 0),
1290− SYSC_QUIRK("dmic", 0, 0, 0x10, -1, 0x50010000, 0xffffffff, 0),
1291− SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
1360+ SYSC_QUIRK("dcan", 0, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, 0),
1361+ SYSC_QUIRK("dcan", 0, 0x20, -ENODEV, -ENODEV, 0x4edb1902, 0xffffffff, 0),
1362+ SYSC_QUIRK("dispc", 0x4832a400, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0),
1363+ SYSC_QUIRK("dispc", 0x58001000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0),
1364+ SYSC_QUIRK("dispc", 0x58001000, 0, 0x10, 0x14, 0x00000051, 0xffffffff, 0),
1365+ SYSC_QUIRK("dmic", 0, 0, 0x10, -ENODEV, 0x50010000, 0xffffffff, 0),
1366+ SYSC_QUIRK("dsi", 0x58004000, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0),
1367+ SYSC_QUIRK("dsi", 0x58005000, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0),
1368+ SYSC_QUIRK("dsi", 0x58005000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0),
1369+ SYSC_QUIRK("dsi", 0x58009000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0),
1370+ SYSC_QUIRK("dwc3", 0, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, 0),
12921371 SYSC_QUIRK("d2d", 0x4a0b6000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
12931372 SYSC_QUIRK("d2d", 0x4a0cd000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
1294− SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),
1295− SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0),
1296− SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff, 0),
1373+ SYSC_QUIRK("epwmss", 0, 0, 0x4, -ENODEV, 0x47400001, 0xffffffff, 0),
1374+ SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -ENODEV, 0, 0, 0),
1375+ SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, 0),
1376+ SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50031d00, 0xffffffff, 0),
12971377 SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
1298− SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0),
1299− SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0),
1300− SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0),
1301− SYSC_QUIRK("mcbsp", 0, -1, 0x8c, -1, 0, 0, 0),
1302− SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffff00ff, 0),
1378+ SYSC_QUIRK("iss", 0, 0, 0x10, -ENODEV, 0x40000101, 0xffffffff, 0),
1379+ SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44306302, 0xffffffff, 0),
1380+ SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44307b02, 0xffffffff, 0),
1381+ SYSC_QUIRK("mcbsp", 0, -ENODEV, 0x8c, -ENODEV, 0, 0, 0),
1382+ SYSC_QUIRK("mcspi", 0, 0, 0x10, -ENODEV, 0x40300a0b, 0xffff00ff, 0),
13031383 SYSC_QUIRK("mcspi", 0, 0, 0x110, 0x114, 0x40300a0b, 0xffffffff, 0),
1304− SYSC_QUIRK("mailbox", 0, 0, 0x10, -1, 0x00000400, 0xffffffff, 0),
1305− SYSC_QUIRK("m3", 0, 0, -1, -1, 0x5f580105, 0x0fff0f00, 0),
1384+ SYSC_QUIRK("mailbox", 0, 0, 0x10, -ENODEV, 0x00000400, 0xffffffff, 0),
1385+ SYSC_QUIRK("m3", 0, 0, -ENODEV, -ENODEV, 0x5f580105, 0x0fff0f00, 0),
13061386 SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0),
1307− SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0),
1308− SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0),
1309− SYSC_QUIRK("padconf", 0, 0, -1, -1, 0x40001100, 0xffffffff, 0),
1310− SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0),
1311− SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0),
1312− SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0),
1313− SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0),
1314− SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4e8b0100, 0xffffffff, 0),
1315− SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4f000100, 0xffffffff, 0),
1316− SYSC_QUIRK("scm", 0, 0, -1, -1, 0x40000900, 0xffffffff, 0),
1317− SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff, 0),
1318− SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffff0ff0, 0),
1387+ SYSC_QUIRK("ocp2scp", 0, 0, -ENODEV, -ENODEV, 0x50060007, 0xffffffff, 0),
1388+ SYSC_QUIRK("padconf", 0, 0, 0x10, -ENODEV, 0x4fff0800, 0xffffffff, 0),
1389+ SYSC_QUIRK("padconf", 0, 0, -ENODEV, -ENODEV, 0x40001100, 0xffffffff, 0),
1390+ SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000100, 0xffffffff, 0),
1391+ SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x00004102, 0xffffffff, 0),
1392+ SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000400, 0xffffffff, 0),
1393+ SYSC_QUIRK("rfbi", 0x4832a800, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
1394+ SYSC_QUIRK("rfbi", 0x58002000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
1395+ SYSC_QUIRK("scm", 0, 0, 0x10, -ENODEV, 0x40000900, 0xffffffff, 0),
1396+ SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4e8b0100, 0xffffffff, 0),
1397+ SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4f000100, 0xffffffff, 0),
1398+ SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x40000900, 0xffffffff, 0),
1399+ SYSC_QUIRK("scrm", 0, 0, -ENODEV, -ENODEV, 0x00000010, 0xffffffff, 0),
1400+ SYSC_QUIRK("sdio", 0, 0, 0x10, -ENODEV, 0x40202301, 0xffff0ff0, 0),
13191401 SYSC_QUIRK("sdio", 0, 0x2fc, 0x110, 0x114, 0x31010000, 0xffffffff, 0),
13201402 SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, 0),
1321− SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40000902, 0xffffffff, 0),
1322− SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40002903, 0xffffffff, 0),
1323− SYSC_QUIRK("spinlock", 0, 0, 0x10, -1, 0x50020000, 0xffffffff, 0),
1324− SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -1, 0x00000020, 0xffffffff, 0),
1325− SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0),
1326− SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0),
1403+ SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40000902, 0xffffffff, 0),
1404+ SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40002903, 0xffffffff, 0),
1405+ SYSC_QUIRK("spinlock", 0, 0, 0x10, -ENODEV, 0x50020000, 0xffffffff, 0),
1406+ SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -ENODEV, 0x00000020, 0xffffffff, 0),
1407+ SYSC_QUIRK("timer32k", 0, 0, 0x4, -ENODEV, 0x00000060, 0xffffffff, 0),
1408+ SYSC_QUIRK("tpcc", 0, 0, -ENODEV, -ENODEV, 0x40014c00, 0xffffffff, 0),
13271409 SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
13281410 SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0),
13291411 SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
1330− SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
1331− SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0),
1412+ SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff, 0),
1413+ SYSC_QUIRK("venc", 0x58003000, 0, -ENODEV, -ENODEV, 0x00000002, 0xffffffff, 0),
1414+ SYSC_QUIRK("vfpe", 0, 0, 0x104, -ENODEV, 0x4d001200, 0xffffffff, 0),
13321415 #endif
13331416 };
13341417
@@ -1350,16 +1433,13 @@ static void sysc_init_early_quirks(struct sysc *ddata) · 15 unmodified lines
13501433 if (q->base != ddata->module_pa)
13511434 continue;
13521435
1353− if (q->rev_offset >= 0 &&
1354− q->rev_offset != ddata->offsets[SYSC_REVISION])
1436+ if (q->rev_offset != ddata->offsets[SYSC_REVISION])
13551437 continue;
13561438
1357− if (q->sysc_offset >= 0 &&
1358− q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG])
1439+ if (q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG])
13591440 continue;
13601441
1361− if (q->syss_offset >= 0 &&
1362− q->syss_offset != ddata->offsets[SYSC_SYSSTATUS])
1442+ if (q->syss_offset != ddata->offsets[SYSC_SYSSTATUS])
13631443 continue;
13641444
13651445 ddata->name = q->name;
@@ -1379,16 +1459,13 @@ static void sysc_init_revision_quirks(struct sysc *ddata) · 13 unmodified lines
13791459 if (q->base && q->base != ddata->module_pa)
13801460 continue;
13811461
1382− if (q->rev_offset >= 0 &&
1383− q->rev_offset != ddata->offsets[SYSC_REVISION])
1462+ if (q->rev_offset != ddata->offsets[SYSC_REVISION])
13841463 continue;
13851464
1386− if (q->sysc_offset >= 0 &&
1387− q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG])
1465+ if (q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG])
13881466 continue;
13891467
1390− if (q->syss_offset >= 0 &&
1391− q->syss_offset != ddata->offsets[SYSC_SYSSTATUS])
1468+ if (q->syss_offset != ddata->offsets[SYSC_SYSSTATUS])
13921469 continue;
13931470
13941471 if (q->revision == ddata->revision ||
@@ -1400,6 +1477,128 @@ static void sysc_init_revision_quirks(struct sysc *ddata) · 5 unmodified lines
14001477 }
14011478 }
14021479
1480+/*
1481+ * DSS needs dispc outputs disabled to reset modules. Returns mask of
1482+ * enabled DSS interrupts. Eventually we may be able to do this on
1483+ * dispc init rather than top-level DSS init.
1484+ */
1485+static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset,
1486+ bool disable)
1487+{
1488+ bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false;
1489+ const int lcd_en_mask = BIT(0), digit_en_mask = BIT(1);
1490+ int manager_count;
1491+ bool framedonetv_irq;
1492+ u32 val, irq_mask = 0;
1493+
1494+ switch (sysc_soc->soc) {
1495+ case SOC_2420 ... SOC_3630:
1496+ manager_count = 2;
1497+ framedonetv_irq = false;
1498+ break;
1499+ case SOC_4430 ... SOC_4470:
1500+ manager_count = 3;
1501+ break;
1502+ case SOC_5430:
1503+ case SOC_DRA7:
1504+ manager_count = 4;
1505+ break;
1506+ case SOC_AM4:
1507+ manager_count = 1;
1508+ break;
1509+ case SOC_UNKNOWN:
1510+ default:
1511+ return 0;
1512+ };
1513+
1514+ /* Remap the whole module range to be able to reset dispc outputs */
1515+ devm_iounmap(ddata->dev, ddata->module_va);
1516+ ddata->module_va = devm_ioremap(ddata->dev,
1517+ ddata->module_pa,
1518+ ddata->module_size);
1519+ if (!ddata->module_va)
1520+ return -EIO;
1521+
1522+ /* DISP_CONTROL */
1523+ val = sysc_read(ddata, dispc_offset + 0x40);
1524+ lcd_en = val & lcd_en_mask;
1525+ digit_en = val & digit_en_mask;
1526+ if (lcd_en)
1527+ irq_mask |= BIT(0); /* FRAMEDONE */
1528+ if (digit_en) {
1529+ if (framedonetv_irq)
1530+ irq_mask |= BIT(24); /* FRAMEDONETV */
1531+ else
1532+ irq_mask |= BIT(2) | BIT(3); /* EVSYNC bits */
1533+ }
1534+ if (disable & (lcd_en | digit_en))
1535+ sysc_write(ddata, dispc_offset + 0x40,
1536+ val & ~(lcd_en_mask | digit_en_mask));
1537+
1538+ if (manager_count <= 2)
1539+ return irq_mask;
1540+
1541+ /* DISPC_CONTROL2 */
1542+ val = sysc_read(ddata, dispc_offset + 0x238);
1543+ lcd2_en = val & lcd_en_mask;
1544+ if (lcd2_en)
1545+ irq_mask |= BIT(22); /* FRAMEDONE2 */
1546+ if (disable && lcd2_en)
1547+ sysc_write(ddata, dispc_offset + 0x238,
1548+ val & ~lcd_en_mask);
1549+
1550+ if (manager_count <= 3)
1551+ return irq_mask;
1552+
1553+ /* DISPC_CONTROL3 */
1554+ val = sysc_read(ddata, dispc_offset + 0x848);
1555+ lcd3_en = val & lcd_en_mask;
1556+ if (lcd3_en)
1557+ irq_mask |= BIT(30); /* FRAMEDONE3 */
1558+ if (disable && lcd3_en)
1559+ sysc_write(ddata, dispc_offset + 0x848,
1560+ val & ~lcd_en_mask);
1561+
1562+ return irq_mask;
1563+}
1564+
1565+/* DSS needs child outputs disabled and SDI registers cleared for reset */
1566+static void sysc_pre_reset_quirk_dss(struct sysc *ddata)
1567+{
1568+ const int dispc_offset = 0x1000;
1569+ int error;
1570+ u32 irq_mask, val;
1571+
1572+ /* Get enabled outputs */
1573+ irq_mask = sysc_quirk_dispc(ddata, dispc_offset, false);
1574+ if (!irq_mask)
1575+ return;
1576+
1577+ /* Clear IRQSTATUS */
1578+ sysc_write(ddata, dispc_offset + 0x18, irq_mask);
1579+
1580+ /* Disable outputs */
1581+ val = sysc_quirk_dispc(ddata, dispc_offset, true);
1582+
1583+ /* Poll IRQSTATUS */
1584+ error = readl_poll_timeout(ddata->module_va + dispc_offset + 0x18,
1585+ val, val != irq_mask, 100, 50);
1586+ if (error)
1587+ dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n",
1588+ __func__, val, irq_mask);
1589+
1590+ if (sysc_soc->soc == SOC_3430) {
1591+ /* Clear DSS_SDI_CONTROL */
1592+ sysc_write(ddata, 0x44, 0);
1593+
1594+ /* Clear DSS_PLL_CONTROL */
1595+ sysc_write(ddata, 0x48, 0);
1596+ }
1597+
1598+ /* Clear DSS_CONTROL to switch DSS clock sources to PRCM if not */
1599+ sysc_write(ddata, 0x40, 0);
1600+}
1601+
14031602 /* 1-wire needs module's internal clocks enabled for reset */
14041603 static void sysc_pre_reset_quirk_hdq1w(struct sysc *ddata)
14051604 {
@@ -1419,7 +1618,7 @@ static void sysc_module_enable_quirk_aess(struct sysc *ddata) · 13 unmodified lines
14191618 sysc_write(ddata, offset, 1);
14201619 }
14211620
1422−/* I2C needs extra enable bit toggling for reset */
1621+/* I2C needs to be disabled for reset */
14231622 static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable)
14241623 {
14251624 int offset;
@@ -1440,14 +1639,48 @@ static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable) · 14 unmodified lines
14401639 sysc_write(ddata, offset, val);
14411640 }
14421641
1443−static void sysc_clk_enable_quirk_i2c(struct sysc *ddata)
1642+static void sysc_pre_reset_quirk_i2c(struct sysc *ddata)
1643+{
1644+ sysc_clk_quirk_i2c(ddata, false);
1645+}
1646+
1647+static void sysc_post_reset_quirk_i2c(struct sysc *ddata)
14441648 {
14451649 sysc_clk_quirk_i2c(ddata, true);
14461650 }
14471651
1448−static void sysc_clk_disable_quirk_i2c(struct sysc *ddata)
1652+/* RTC on am3 and 4 needs to be unlocked and locked for sysconfig */
1653+static void sysc_quirk_rtc(struct sysc *ddata, bool lock)
14491654 {
1450− sysc_clk_quirk_i2c(ddata, false);
1655+ u32 val, kick0_val = 0, kick1_val = 0;
1656+ unsigned long flags;
1657+ int error;
1658+
1659+ if (!lock) {
1660+ kick0_val = 0x83e70b13;
1661+ kick1_val = 0x95a4f1e0;
1662+ }
1663+
1664+ local_irq_save(flags);
1665+ /* RTC_STATUS BUSY bit may stay active for 1/32768 seconds (~30 usec) */
1666+ error = readl_poll_timeout(ddata->module_va + 0x44, val,
1667+ !(val & BIT(0)), 100, 50);
1668+ if (error)
1669+ dev_warn(ddata->dev, "rtc busy timeout\n");
1670+ /* Now we have ~15 microseconds to read/write various registers */
1671+ sysc_write(ddata, 0x6c, kick0_val);
1672+ sysc_write(ddata, 0x70, kick1_val);
1673+ local_irq_restore(flags);
1674+}
1675+
1676+static void sysc_module_unlock_quirk_rtc(struct sysc *ddata)
1677+{
1678+ sysc_quirk_rtc(ddata, false);
1679+}
1680+
1681+static void sysc_module_lock_quirk_rtc(struct sysc *ddata)
1682+{
1683+ sysc_quirk_rtc(ddata, true);
14511684 }
14521685
14531686 /* 36xx SGX needs a quirk for to bypass OCP IPG interrupt logic */
@@ -1483,20 +1716,30 @@ static void sysc_reset_done_quirk_wdt(struct sysc *ddata) · 29 unmodified lines
14831716 dev_warn(ddata->dev, "wdt disable step2 failed\n");
14841717 }
14851718
1719+/* PRUSS needs to set MSTANDBY_INIT inorder to idle properly */
1720+static void sysc_module_disable_quirk_pruss(struct sysc *ddata)
1721+{
1722+ u32 reg;
1723+
1724+ reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
1725+ reg |= SYSC_PRUSS_STANDBY_INIT;
1726+ sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg);
1727+}
1728+
14861729 static void sysc_init_module_quirks(struct sysc *ddata)
14871730 {
14881731 if (ddata->legacy_mode || !ddata->name)
14891732 return;
14901733
14911734 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) {
1492− ddata->clk_disable_quirk = sysc_pre_reset_quirk_hdq1w;
1735+ ddata->pre_reset_quirk = sysc_pre_reset_quirk_hdq1w;
14931736
14941737 return;
14951738 }
14961739
14971740 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
1498− ddata->clk_enable_quirk = sysc_clk_enable_quirk_i2c;
1499− ddata->clk_disable_quirk = sysc_clk_disable_quirk_i2c;
1741+ ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c;
1742+ ddata->post_reset_quirk = sysc_post_reset_quirk_i2c;
15001743
15011744 return;
15021745 }
@@ -1504,6 +1747,16 @@ static void sysc_init_module_quirks(struct sysc *ddata) · 1 unmodified line
15041747 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_AESS)
15051748 ddata->module_enable_quirk = sysc_module_enable_quirk_aess;
15061749
1750+ if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_DSS_RESET)
1751+ ddata->pre_reset_quirk = sysc_pre_reset_quirk_dss;
1752+
1753+ if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_RTC_UNLOCK) {
1754+ ddata->module_unlock_quirk = sysc_module_unlock_quirk_rtc;
1755+ ddata->module_lock_quirk = sysc_module_lock_quirk_rtc;
1756+
1757+ return;
1758+ }
1759+
15071760 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX)
15081761 ddata->module_enable_quirk = sysc_module_enable_quirk_sgx;
15091762
@@ -1511,6 +1764,9 @@ static void sysc_init_module_quirks(struct sysc *ddata) · 1 unmodified line
15111764 ddata->reset_done_quirk = sysc_reset_done_quirk_wdt;
15121765 ddata->module_disable_quirk = sysc_reset_done_quirk_wdt;
15131766 }
1767+
1768+ if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_PRUSS)
1769+ ddata->module_disable_quirk = sysc_module_disable_quirk_pruss;
15141770 }
15151771
15161772 static int sysc_clockdomain_init(struct sysc *ddata)
@@ -1572,7 +1828,7 @@ static int sysc_reset(struct sysc *ddata) · 55 unmodified lines
15721828 sysc_offset = ddata->offsets[SYSC_SYSCONFIG];
15731829 syss_offset = ddata->offsets[SYSC_SYSSTATUS];
15741830
1575− if (ddata->legacy_mode || sysc_offset < 0 ||
1831+ if (ddata->legacy_mode ||
15761832 ddata->cap->regbits->srst_shift < 0 ||
15771833 ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
15781834 return 0;
@@ -1584,19 +1840,21 @@ static int sysc_reset(struct sysc *ddata) · 5 unmodified lines
15841840 else
15851841 syss_done = ddata->cfg.syss_mask;
15861842
1587− if (ddata->clk_disable_quirk)
1588− ddata->clk_disable_quirk(ddata);
1843+ if (ddata->pre_reset_quirk)
1844+ ddata->pre_reset_quirk(ddata);
15891845
1590− sysc_val = sysc_read_sysconfig(ddata);
1591− sysc_val |= sysc_mask;
1592− sysc_write(ddata, sysc_offset, sysc_val);
1846+ if (sysc_offset >= 0) {
1847+ sysc_val = sysc_read_sysconfig(ddata);
1848+ sysc_val |= sysc_mask;
1849+ sysc_write(ddata, sysc_offset, sysc_val);
1850+ }
15931851
15941852 if (ddata->cfg.srst_udelay)
15951853 usleep_range(ddata->cfg.srst_udelay,
15961854 ddata->cfg.srst_udelay * 2);
15971855
1598− if (ddata->clk_enable_quirk)
1599− ddata->clk_enable_quirk(ddata);
1856+ if (ddata->post_reset_quirk)
1857+ ddata->post_reset_quirk(ddata);
16001858
16011859 /* Poll on reset status */
16021860 if (syss_offset >= 0) {
@@ -2314,6 +2572,16 @@ static const struct sysc_capabilities sysc_dra7_mcan = { · 711 unmodified lines
23142572 .mod_quirks = SYSS_QUIRK_RESETDONE_INVERTED,
23152573 };
23162574
2575+/*
2576+ * PRUSS found on some AM33xx, AM437x and AM57xx SoCs
2577+ */
2578+static const struct sysc_capabilities sysc_pruss = {
2579+ .type = TI_SYSC_PRUSS,
2580+ .sysc_mask = SYSC_PRUSS_STANDBY_INIT | SYSC_PRUSS_SUB_MWAIT,
2581+ .regbits = &sysc_regbits_omap4_simple,
2582+ .mod_quirks = SYSC_MODULE_QUIRK_PRUSS,
2583+};
2584+
23172585 static int sysc_init_pdata(struct sysc *ddata)
23182586 {
23192587 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
@@ -2387,6 +2655,154 @@ static void ti_sysc_idle(struct work_struct *work) · 67 unmodified lines
23872655 pm_runtime_put_sync(ddata->dev);
23882656 }
23892657
2658+/*
2659+ * SoC model and features detection. Only needed for SoCs that need
2660+ * special handling for quirks, no need to list others.
2661+ */
2662+static const struct soc_device_attribute sysc_soc_match[] = {
2663+ SOC_FLAG("OMAP242*", SOC_2420),
2664+ SOC_FLAG("OMAP243*", SOC_2430),
2665+ SOC_FLAG("OMAP3[45]*", SOC_3430),
2666+ SOC_FLAG("OMAP3[67]*", SOC_3630),
2667+ SOC_FLAG("OMAP443*", SOC_4430),
2668+ SOC_FLAG("OMAP446*", SOC_4460),
2669+ SOC_FLAG("OMAP447*", SOC_4470),
2670+ SOC_FLAG("OMAP54*", SOC_5430),
2671+ SOC_FLAG("AM433", SOC_AM3),
2672+ SOC_FLAG("AM43*", SOC_AM4),
2673+ SOC_FLAG("DRA7*", SOC_DRA7),
2674+
2675+ { /* sentinel */ },
2676+};
2677+
2678+/*
2679+ * List of SoCs variants with disabled features. By default we assume all
2680+ * devices in the device tree are available so no need to list those SoCs.
2681+ */
2682+static const struct soc_device_attribute sysc_soc_feat_match[] = {
2683+ /* OMAP3430/3530 and AM3517 variants with some accelerators disabled */
2684+ SOC_FLAG("AM3505", DIS_SGX),
2685+ SOC_FLAG("OMAP3525", DIS_SGX),
2686+ SOC_FLAG("OMAP3515", DIS_IVA | DIS_SGX),
2687+ SOC_FLAG("OMAP3503", DIS_ISP | DIS_IVA | DIS_SGX),
2688+
2689+ /* OMAP3630/DM3730 variants with some accelerators disabled */
2690+ SOC_FLAG("AM3703", DIS_IVA | DIS_SGX),
2691+ SOC_FLAG("DM3725", DIS_SGX),
2692+ SOC_FLAG("OMAP3611", DIS_ISP | DIS_IVA | DIS_SGX),
2693+ SOC_FLAG("OMAP3615/AM3715", DIS_IVA),
2694+ SOC_FLAG("OMAP3621", DIS_ISP),
2695+
2696+ { /* sentinel */ },
2697+};
2698+
2699+static int sysc_add_disabled(unsigned long base)
2700+{
2701+ struct sysc_address *disabled_module;
2702+
2703+ disabled_module = kzalloc(sizeof(*disabled_module), GFP_KERNEL);
2704+ if (!disabled_module)
2705+ return -ENOMEM;
2706+
2707+ disabled_module->base = base;
2708+
2709+ mutex_lock(&sysc_soc->list_lock);
2710+ list_add(&disabled_module->node, &sysc_soc->disabled_modules);
2711+ mutex_unlock(&sysc_soc->list_lock);
2712+
2713+ return 0;
2714+}
2715+
2716+/*
2717+ * One time init to detect the booted SoC and disable unavailable features.
2718+ * Note that we initialize static data shared across all ti-sysc instances
2719+ * so ddata is only used for SoC type. This can be called from module_init
2720+ * once we no longer need to rely on platform data.
2721+ */
2722+static int sysc_init_soc(struct sysc *ddata)
2723+{
2724+ const struct soc_device_attribute *match;
2725+ struct ti_sysc_platform_data *pdata;
2726+ unsigned long features = 0;
2727+
2728+ if (sysc_soc)
2729+ return 0;
2730+
2731+ sysc_soc = kzalloc(sizeof(*sysc_soc), GFP_KERNEL);
2732+ if (!sysc_soc)
2733+ return -ENOMEM;
2734+
2735+ mutex_init(&sysc_soc->list_lock);
2736+ INIT_LIST_HEAD(&sysc_soc->disabled_modules);
2737+ sysc_soc->general_purpose = true;
2738+
2739+ pdata = dev_get_platdata(ddata->dev);
2740+ if (pdata && pdata->soc_type_gp)
2741+ sysc_soc->general_purpose = pdata->soc_type_gp();
2742+
2743+ match = soc_device_match(sysc_soc_match);
2744+ if (match && match->data)
2745+ sysc_soc->soc = (int)match->data;
2746+
2747+ match = soc_device_match(sysc_soc_feat_match);
2748+ if (!match)
2749+ return 0;
2750+
2751+ if (match->data)
2752+ features = (unsigned long)match->data;
2753+
2754+ /*
2755+ * Add disabled devices to the list based on the module base.
2756+ * Note that this must be done before we attempt to access the
2757+ * device and have module revision checks working.
2758+ */
2759+ if (features & DIS_ISP)
2760+ sysc_add_disabled(0x480bd400);
2761+ if (features & DIS_IVA)
2762+ sysc_add_disabled(0x5d000000);
2763+ if (features & DIS_SGX)
2764+ sysc_add_disabled(0x50000000);
2765+
2766+ return 0;
2767+}
2768+
2769+static void sysc_cleanup_soc(void)
2770+{
2771+ struct sysc_address *disabled_module;
2772+ struct list_head *pos, *tmp;
2773+
2774+ if (!sysc_soc)
2775+ return;
2776+
2777+ mutex_lock(&sysc_soc->list_lock);
2778+ list_for_each_safe(pos, tmp, &sysc_soc->disabled_modules) {
2779+ disabled_module = list_entry(pos, struct sysc_address, node);
2780+ list_del(pos);
2781+ kfree(disabled_module);
2782+ }
2783+ mutex_unlock(&sysc_soc->list_lock);
2784+}
2785+
2786+static int sysc_check_disabled_devices(struct sysc *ddata)
2787+{
2788+ struct sysc_address *disabled_module;
2789+ struct list_head *pos;
2790+ int error = 0;
2791+
2792+ mutex_lock(&sysc_soc->list_lock);
2793+ list_for_each(pos, &sysc_soc->disabled_modules) {
2794+ disabled_module = list_entry(pos, struct sysc_address, node);
2795+ if (ddata->module_pa == disabled_module->base) {
2796+ dev_dbg(ddata->dev, "module disabled for this SoC\n");
2797+ error = -ENODEV;
2798+ break;
2799+ }
2800+ }
2801+ mutex_unlock(&sysc_soc->list_lock);
2802+
2803+ return error;
2804+}
2805+
23902806 static const struct of_device_id sysc_match_table[] = {
23912807 { .compatible = "simple-bus", },
23922808 { /* sentinel */ },
@@ -2405,6 +2821,10 @@ static int sysc_probe(struct platform_device *pdev) · 12 unmodified lines
24052821 ddata->dev = &pdev->dev;
24062822 platform_set_drvdata(pdev, ddata);
24072823
2824+ error = sysc_init_soc(ddata);
2825+ if (error)
2826+ return error;
2827+
24082828 error = sysc_init_match(ddata);
24092829 if (error)
24102830 return error;
@@ -2435,6 +2855,10 @@ static int sysc_probe(struct platform_device *pdev) · 24 unmodified lines
24352855
24362856 sysc_init_early_quirks(ddata);
24372857
2858+ error = sysc_check_disabled_devices(ddata);
2859+ if (error)
2860+ return error;
2861+
24382862 error = sysc_get_clocks(ddata);
24392863 if (error)
24402864 return error;
@@ -2539,6 +2963,7 @@ static const struct of_device_id sysc_match[] = { · 98 unmodified lines
25392963 { .compatible = "ti,sysc-usb-host-fs",
25402964 .data = &sysc_omap4_usb_host_fs, },
25412965 { .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },
2966+ { .compatible = "ti,sysc-pruss", .data = &sysc_pruss, },
25422967 { },
25432968 };
25442969 MODULE_DEVICE_TABLE(of, sysc_match);
@@ -2565,6 +2990,7 @@ static void __exit sysc_exit(void) · 20 unmodified lines
25652990 {
25662991 bus_unregister_notifier(&platform_bus_type, &sysc_nb);
25672992 platform_driver_unregister(&sysc_driver);
2993+ sysc_cleanup_soc();
25682994 }
25692995 module_exit(sysc_exit);
25702996
drivers/firmware/arm_scmi/Makefile+2−1
@@ -1,6 +1,7 @@
11 # SPDX-License-Identifier: GPL-2.0-only
2−obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o
2+obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o scmi-transport.o
33 scmi-bus-y = bus.o
44 scmi-driver-y = driver.o
5+scmi-transport-y = mailbox.o shmem.o
56 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
67 obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
drivers/firmware/arm_scmi/common.h+113−2
@@ -33,8 +33,8 @@ enum scmi_common_cmd { · 32 unmodified lines
3333 /**
3434 * struct scmi_msg_resp_prot_version - Response for a message
3535 *
36− * @major_version: Major version of the ABI that firmware supports
3736 * @minor_version: Minor version of the ABI that firmware supports
37+ * @major_version: Major version of the ABI that firmware supports
3838 *
3939 * In general, ABI version changes follow the rule that minor version increments
4040 * are backward compatible. Major revision changes in ABI may not be
@@ -47,6 +47,19 @@ struct scmi_msg_resp_prot_version { · 6 unmodified lines
4747 __le16 major_version;
4848 };
4949
50+#define MSG_ID_MASK GENMASK(7, 0)
51+#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr))
52+#define MSG_TYPE_MASK GENMASK(9, 8)
53+#define MSG_XTRACT_TYPE(hdr) FIELD_GET(MSG_TYPE_MASK, (hdr))
54+#define MSG_TYPE_COMMAND 0
55+#define MSG_TYPE_DELAYED_RESP 2
56+#define MSG_TYPE_NOTIFICATION 3
57+#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10)
58+#define MSG_XTRACT_PROT_ID(hdr) FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr))
59+#define MSG_TOKEN_ID_MASK GENMASK(27, 18)
60+#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
61+#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
62+
5063 /**
5164 * struct scmi_msg_hdr - Message(Tx/Rx) header
5265 *
@@ -67,6 +80,33 @@ struct scmi_msg_hdr { · 14 unmodified lines
6780 bool poll_completion;
6881 };
6982
83+/**
84+ * pack_scmi_header() - packs and returns 32-bit header
85+ *
86+ * @hdr: pointer to header containing all the information on message id,
87+ * protocol id and sequence id.
88+ *
89+ * Return: 32-bit packed message header to be sent to the platform.
90+ */
91+static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
92+{
93+ return FIELD_PREP(MSG_ID_MASK, hdr->id) |
94+ FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
95+ FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
96+}
97+
98+/**
99+ * unpack_scmi_header() - unpacks and records message and protocol id
100+ *
101+ * @msg_hdr: 32-bit packed message header sent from the platform
102+ * @hdr: pointer to header to fetch message and protocol id.
103+ */
104+static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
105+{
106+ hdr->id = MSG_XTRACT_ID(msg_hdr);
107+ hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
108+}
109+
70110 /**
71111 * struct scmi_msg - Message(Tx/Rx) structure
72112 *
@@ -88,7 +128,7 @@ struct scmi_msg { · 15 unmodified lines
88128 * message. If request-ACK protocol is used, we can reuse the same
89129 * buffer for the rx path as we use for the tx path.
90130 * @done: command message transmit completion event
91− * @async: pointer to delayed response message received event completion
131+ * @async_done: pointer to delayed response message received event completion
92132 */
93133 struct scmi_xfer {
94134 int transfer_id;
@@ -113,3 +153,74 @@ void scmi_setup_protocol_implemented(const struct scmi_handle *handle, · 18 unmodified lines
113153 u8 *prot_imp);
114154
115155 int scmi_base_protocol_init(struct scmi_handle *h);
156+
157+/* SCMI Transport */
158+/**
159+ * struct scmi_chan_info - Structure representing a SCMI channel information
160+ *
161+ * @dev: Reference to device in the SCMI hierarchy corresponding to this
162+ * channel
163+ * @handle: Pointer to SCMI entity handle
164+ * @transport_info: Transport layer related information
165+ */
166+struct scmi_chan_info {
167+ struct device *dev;
168+ struct scmi_handle *handle;
169+ void *transport_info;
170+};
171+
172+/**
173+ * struct scmi_transport_ops - Structure representing a SCMI transport ops
174+ *
175+ * @chan_available: Callback to check if channel is available or not
176+ * @chan_setup: Callback to allocate and setup a channel
177+ * @chan_free: Callback to free a channel
178+ * @send_message: Callback to send a message
179+ * @mark_txdone: Callback to mark tx as done
180+ * @fetch_response: Callback to fetch response
181+ * @poll_done: Callback to poll transfer status
182+ */
183+struct scmi_transport_ops {
184+ bool (*chan_available)(struct device *dev, int idx);
185+ int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
186+ bool tx);
187+ int (*chan_free)(int id, void *p, void *data);
188+ int (*send_message)(struct scmi_chan_info *cinfo,
189+ struct scmi_xfer *xfer);
190+ void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
191+ void (*fetch_response)(struct scmi_chan_info *cinfo,
192+ struct scmi_xfer *xfer);
193+ bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
194+};
195+
196+/**
197+ * struct scmi_desc - Description of SoC integration
198+ *
199+ * @ops: Pointer to the transport specific ops structure
200+ * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
201+ * @max_msg: Maximum number of messages that can be pending
202+ * simultaneously in the system
203+ * @max_msg_size: Maximum size of data per message that can be handled.
204+ */
205+struct scmi_desc {
206+ struct scmi_transport_ops *ops;
207+ int max_rx_timeout_ms;
208+ int max_msg;
209+ int max_msg_size;
210+};
211+
212+extern const struct scmi_desc scmi_mailbox_desc;
213+
214+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr);
215+void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
216+
217+/* shmem related declarations */
218+struct scmi_shared_mem;
219+
220+void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
221+ struct scmi_xfer *xfer);
222+u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
223+void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
224+ struct scmi_xfer *xfer);
225+bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
226+ struct scmi_xfer *xfer);
drivers/firmware/arm_scmi/driver.c+34−259
@@ -19,12 +19,10 @@ · 18 unmodified lines
1919 #include <linux/io.h>
2020 #include <linux/kernel.h>
2121 #include <linux/ktime.h>
22−#include <linux/mailbox_client.h>
2322 #include <linux/module.h>
2423 #include <linux/of_address.h>
2524 #include <linux/of_device.h>
2625 #include <linux/processor.h>
27−#include <linux/semaphore.h>
2826 #include <linux/slab.h>
2927
3028 #include "common.h"
@@ -32,19 +30,6 @@ · 1 unmodified line
3230 #define CREATE_TRACE_POINTS
3331 #include <trace/events/scmi.h>
3432
35−#define MSG_ID_MASK GENMASK(7, 0)
36−#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr))
37−#define MSG_TYPE_MASK GENMASK(9, 8)
38−#define MSG_XTRACT_TYPE(hdr) FIELD_GET(MSG_TYPE_MASK, (hdr))
39−#define MSG_TYPE_COMMAND 0
40−#define MSG_TYPE_DELAYED_RESP 2
41−#define MSG_TYPE_NOTIFICATION 3
42−#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10)
43−#define MSG_XTRACT_PROT_ID(hdr) FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr))
44−#define MSG_TOKEN_ID_MASK GENMASK(27, 18)
45−#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
46−#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
47−
4833 enum scmi_error_codes {
4934 SCMI_SUCCESS = 0, /* Success */
5035 SCMI_ERR_SUPPORT = -1, /* Not supported */
@@ -82,46 +67,14 @@ struct scmi_xfers_info { · 31 unmodified lines
8267 spinlock_t xfer_lock;
8368 };
8469
85−/**
86− * struct scmi_desc - Description of SoC integration
87− *
88− * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
89− * @max_msg: Maximum number of messages that can be pending
90− * simultaneously in the system
91− * @max_msg_size: Maximum size of data per message that can be handled.
92− */
93−struct scmi_desc {
94− int max_rx_timeout_ms;
95− int max_msg;
96− int max_msg_size;
97−};
98−
99−/**
100− * struct scmi_chan_info - Structure representing a SCMI channel information
101− *
102− * @cl: Mailbox Client
103− * @chan: Transmit/Receive mailbox channel
104− * @payload: Transmit/Receive mailbox channel payload area
105− * @dev: Reference to device in the SCMI hierarchy corresponding to this
106− * channel
107− * @handle: Pointer to SCMI entity handle
108− */
109−struct scmi_chan_info {
110− struct mbox_client cl;
111− struct mbox_chan *chan;
112− void __iomem *payload;
113− struct device *dev;
114− struct scmi_handle *handle;
115−};
116−
11770 /**
11871 * struct scmi_info - Structure representing a SCMI instance
11972 *
12073 * @dev: Device pointer
12174 * @desc: SoC description for this instance
122− * @handle: Instance of SCMI handle to send to clients
12375 * @version: SCMI revision information containing protocol version,
12476 * implementation version and (sub-)vendor identification.
77+ * @handle: Instance of SCMI handle to send to clients
12578 * @tx_minfo: Universal Transmit Message management info
12679 * @tx_idr: IDR object to map protocol id to Tx channel info pointer
12780 * @rx_idr: IDR object to map protocol id to Rx channel info pointer
@@ -143,27 +96,8 @@ struct scmi_info { · 15 unmodified lines
14396 int users;
14497 };
14598
146−#define client_to_scmi_chan_info(c) container_of(c, struct scmi_chan_info, cl)
14799 #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle)
148100
149−/*
150− * SCMI specification requires all parameters, message headers, return
151− * arguments or any protocol data to be expressed in little endian
152− * format only.
153− */
154−struct scmi_shared_mem {
155− __le32 reserved;
156− __le32 channel_status;
157−#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1)
158−#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0)
159− __le32 reserved1[2];
160− __le32 flags;
161−#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0)
162− __le32 length;
163− __le32 msg_header;
164− u8 msg_payload[0];
165−};
166−
167101 static const int scmi_linux_errmap[] = {
168102 /* better than switch case as long as return value is continuous */
169103 0, /* SCMI_SUCCESS */
@@ -199,77 +133,6 @@ static inline void scmi_dump_header_dbg(struct device *dev, · 29 unmodified lines
199133 hdr->id, hdr->seq, hdr->protocol_id);
200134 }
201135
202−static void scmi_fetch_response(struct scmi_xfer *xfer,
203− struct scmi_shared_mem __iomem *mem)
204−{
205− xfer->hdr.status = ioread32(mem->msg_payload);
206− /* Skip the length of header and status in payload area i.e 8 bytes */
207− xfer->rx.len = min_t(size_t, xfer->rx.len, ioread32(&mem->length) - 8);
208−
209− /* Take a copy to the rx buffer.. */
210− memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
211−}
212−
213−/**
214− * pack_scmi_header() - packs and returns 32-bit header
215− *
216− * @hdr: pointer to header containing all the information on message id,
217− * protocol id and sequence id.
218− *
219− * Return: 32-bit packed message header to be sent to the platform.
220− */
221−static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
222−{
223− return FIELD_PREP(MSG_ID_MASK, hdr->id) |
224− FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
225− FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
226−}
227−
228−/**
229− * unpack_scmi_header() - unpacks and records message and protocol id
230− *
231− * @msg_hdr: 32-bit packed message header sent from the platform
232− * @hdr: pointer to header to fetch message and protocol id.
233− */
234−static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
235−{
236− hdr->id = MSG_XTRACT_ID(msg_hdr);
237− hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
238−}
239−
240−/**
241− * scmi_tx_prepare() - mailbox client callback to prepare for the transfer
242− *
243− * @cl: client pointer
244− * @m: mailbox message
245− *
246− * This function prepares the shared memory which contains the header and the
247− * payload.
248− */
249−static void scmi_tx_prepare(struct mbox_client *cl, void *m)
250−{
251− struct scmi_xfer *t = m;
252− struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
253− struct scmi_shared_mem __iomem *mem = cinfo->payload;
254−
255− /*
256− * Ideally channel must be free by now unless OS timeout last
257− * request and platform continued to process the same, wait
258− * until it releases the shared memory, otherwise we may endup
259− * overwriting its response with new message payload or vice-versa
260− */
261− spin_until_cond(ioread32(&mem->channel_status) &
262− SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
263− /* Mark channel busy + clear error */
264− iowrite32(0x0, &mem->channel_status);
265− iowrite32(t->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
266− &mem->flags);
267− iowrite32(sizeof(mem->msg_header) + t->tx.len, &mem->length);
268− iowrite32(pack_scmi_header(&t->hdr), &mem->msg_header);
269− if (t->tx.buf)
270− memcpy_toio(mem->msg_payload, t->tx.buf, t->tx.len);
271−}
272−
273136 /**
274137 * scmi_xfer_get() - Allocate one message
275138 *
@@ -338,10 +201,10 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 62 unmodified lines
338201 }
339202
340203 /**
341− * scmi_rx_callback() - mailbox client callback for receive messages
204+ * scmi_rx_callback() - callback for receiving messages
342205 *
343− * @cl: client pointer
344− * @m: mailbox message
206+ * @cinfo: SCMI channel info
207+ * @msg_hdr: Message header
345208 *
346209 * Processes one received message to appropriate transfer information and
347210 * signals completion of the transfer.
@@ -349,21 +212,14 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 1 unmodified line
349212 * NOTE: This function will be invoked in IRQ context, hence should be
350213 * as optimal as possible.
351214 */
352−static void scmi_rx_callback(struct mbox_client *cl, void *m)
215+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
353216 {
354− u8 msg_type;
355− u32 msg_hdr;
356− u16 xfer_id;
357− struct scmi_xfer *xfer;
358− struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
359− struct device *dev = cinfo->dev;
360217 struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
361218 struct scmi_xfers_info *minfo = &info->tx_minfo;
362− struct scmi_shared_mem __iomem *mem = cinfo->payload;
363−
364− msg_hdr = ioread32(&mem->msg_header);
365− msg_type = MSG_XTRACT_TYPE(msg_hdr);
366− xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
219+ u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
220+ u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
221+ struct device *dev = cinfo->dev;
222+ struct scmi_xfer *xfer;
367223
368224 if (msg_type == MSG_TYPE_NOTIFICATION)
369225 return; /* Notifications not yet supported */
@@ -378,7 +234,7 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m) · 8 unmodified lines
378234
379235 scmi_dump_header_dbg(dev, &xfer->hdr);
380236
381− scmi_fetch_response(xfer, mem);
237+ info->desc->ops->fetch_response(cinfo, xfer);
382238
383239 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
384240 xfer->hdr.protocol_id, xfer->hdr.seq,
@@ -403,28 +259,15 @@ void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 18 unmodified lines
403259 __scmi_xfer_put(&info->tx_minfo, xfer);
404260 }
405261
406−static bool
407−scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
408−{
409− struct scmi_shared_mem __iomem *mem = cinfo->payload;
410− u16 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
411−
412− if (xfer->hdr.seq != xfer_id)
413− return false;
414−
415− return ioread32(&mem->channel_status) &
416− (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
417− SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
418−}
419−
420262 #define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC)
421263
422−static bool scmi_xfer_done_no_timeout(const struct scmi_chan_info *cinfo,
264+static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
423265 struct scmi_xfer *xfer, ktime_t stop)
424266 {
425− ktime_t __cur = ktime_get();
267+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
426268
427− return scmi_xfer_poll_done(cinfo, xfer) || ktime_after(__cur, stop);
269+ return info->desc->ops->poll_done(cinfo, xfer) ||
270+ ktime_after(ktime_get(), stop);
428271 }
429272
430273 /**
@@ -453,29 +296,26 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 22 unmodified lines
453296 xfer->hdr.protocol_id, xfer->hdr.seq,
454297 xfer->hdr.poll_completion);
455298
456− ret = mbox_send_message(cinfo->chan, xfer);
299+ ret = info->desc->ops->send_message(cinfo, xfer);
457300 if (ret < 0) {
458− dev_dbg(dev, "mbox send fail %d\n", ret);
301+ dev_dbg(dev, "Failed to send message %d\n", ret);
459302 return ret;
460303 }
461304
462− /* mbox_send_message returns non-negative value on success, so reset */
463− ret = 0;
464−
465305 if (xfer->hdr.poll_completion) {
466306 ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
467307
468308 spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
469309
470310 if (ktime_before(ktime_get(), stop))
471− scmi_fetch_response(xfer, cinfo->payload);
311+ info->desc->ops->fetch_response(cinfo, xfer);
472312 else
473313 ret = -ETIMEDOUT;
474314 } else {
475315 /* And we wait for the response. */
476316 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
477317 if (!wait_for_completion_timeout(&xfer->done, timeout)) {
478− dev_err(dev, "mbox timed out in resp(caller: %pS)\n",
318+ dev_err(dev, "timed out in resp(caller: %pS)\n",
479319 (void *)_RET_IP_);
480320 ret = -ETIMEDOUT;
481321 }
@@ -484,13 +324,8 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 2 unmodified lines
484324 if (!ret && xfer->hdr.status)
485325 ret = scmi_to_linux_errno(xfer->hdr.status);
486326
487− /*
488− * NOTE: we might prefer not to need the mailbox ticker to manage the
489− * transfer queueing since the protocol layer queues things by itself.
490− * Unfortunately, we have to kick the mailbox framework after we have
491− * received our message.
492− */
493− mbox_client_txdone(cinfo->chan, ret);
327+ if (info->desc->ops->mark_txdone)
328+ info->desc->ops->mark_txdone(cinfo, ret);
494329
495330 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
496331 xfer->hdr.protocol_id, xfer->hdr.seq,
@@ -731,23 +566,12 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) · 234 unmodified lines
731566 return 0;
732567 }
733568
734−static int scmi_mailbox_check(struct device_node *np, int idx)
735−{
736− return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells",
737− idx, NULL);
738−}
739−
740−static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
741− int prot_id, bool tx)
569+static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
570+ int prot_id, bool tx)
742571 {
743572 int ret, idx;
744− struct resource res;
745− resource_size_t size;
746− struct device_node *shmem, *np = dev->of_node;
747573 struct scmi_chan_info *cinfo;
748− struct mbox_client *cl;
749574 struct idr *idr;
750− const char *desc = tx ? "Tx" : "Rx";
751575
752576 /* Transmit channel is first entry i.e. index 0 */
753577 idx = tx ? 0 : 1;
@@ -758,7 +582,7 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 4 unmodified lines
758582 if (cinfo)
759583 return 0;
760584
761− if (scmi_mailbox_check(np, idx)) {
585+ if (!info->desc->ops->chan_available(dev, idx)) {
762586 cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
763587 if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
764588 return -EINVAL;
@@ -771,36 +595,9 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 6 unmodified lines
771595
772596 cinfo->dev = dev;
773597
774− cl = &cinfo->cl;
775− cl->dev = dev;
776− cl->rx_callback = scmi_rx_callback;
777− cl->tx_prepare = tx ? scmi_tx_prepare : NULL;
778− cl->tx_block = false;
779− cl->knows_txdone = tx;
780−
781− shmem = of_parse_phandle(np, "shmem", idx);
782− ret = of_address_to_resource(shmem, 0, &res);
783− of_node_put(shmem);
784− if (ret) {
785− dev_err(dev, "failed to get SCMI %s payload memory\n", desc);
786− return ret;
787− }
788−
789− size = resource_size(&res);
790− cinfo->payload = devm_ioremap(info->dev, res.start, size);
791− if (!cinfo->payload) {
792− dev_err(dev, "failed to ioremap SCMI %s payload\n", desc);
793− return -EADDRNOTAVAIL;
794− }
795−
796− cinfo->chan = mbox_request_channel(cl, idx);
797− if (IS_ERR(cinfo->chan)) {
798− ret = PTR_ERR(cinfo->chan);
799− if (ret != -EPROBE_DEFER)
800− dev_err(dev, "failed to request SCMI %s mailbox\n",
801− desc);
598+ ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
599+ if (ret)
802600 return ret;
803− }
804601
805602 idr_alloc:
806603 ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
@@ -814,12 +611,12 @@ idr_alloc: · 7 unmodified lines
814611 }
815612
816613 static inline int
817−scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
614+scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
818615 {
819− int ret = scmi_mbox_chan_setup(info, dev, prot_id, true);
616+ int ret = scmi_chan_setup(info, dev, prot_id, true);
820617
821618 if (!ret) /* Rx is optional, hence no error check */
822− scmi_mbox_chan_setup(info, dev, prot_id, false);
619+ scmi_chan_setup(info, dev, prot_id, false);
823620
824621 return ret;
825622 }
@@ -837,7 +634,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, · 11 unmodified lines
837634 return;
838635 }
839636
840− if (scmi_mbox_txrx_setup(info, &sdev->dev, prot_id)) {
637+ if (scmi_txrx_setup(info, &sdev->dev, prot_id)) {
841638 dev_err(&sdev->dev, "failed to setup transport\n");
842639 scmi_device_destroy(sdev);
843640 return;
@@ -890,12 +687,6 @@ static int scmi_probe(struct platform_device *pdev) · 46 unmodified lines
890687 struct device *dev = &pdev->dev;
891688 struct device_node *child, *np = dev->of_node;
892689
893− /* Only mailbox method supported, check for the presence of one */
894− if (scmi_mailbox_check(np, 0)) {
895− dev_err(dev, "no mailbox found in %pOF\n", np);
896− return -EINVAL;
897− }
898−
899690 desc = of_device_get_match_data(dev);
900691 if (!desc)
901692 return -EINVAL;
@@ -920,7 +711,7 @@ static int scmi_probe(struct platform_device *pdev) · 18 unmodified lines
920711 handle->dev = info->dev;
921712 handle->version = &info->version;
922713
923− ret = scmi_mbox_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
714+ ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
924715 if (ret)
925716 return ret;
926717
@@ -955,19 +746,9 @@ static int scmi_probe(struct platform_device *pdev) · 28 unmodified lines
955746 return 0;
956747 }
957748
958−static int scmi_mbox_free_channel(int id, void *p, void *data)
749+void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
959750 {
960− struct scmi_chan_info *cinfo = p;
961− struct idr *idr = data;
962−
963− if (!IS_ERR_OR_NULL(cinfo->chan)) {
964− mbox_free_channel(cinfo->chan);
965− cinfo->chan = NULL;
966− }
967−
968751 idr_remove(idr, id);
969−
970− return 0;
971752 }
972753
973754 static int scmi_remove(struct platform_device *pdev)
@@ -987,11 +768,11 @@ static int scmi_remove(struct platform_device *pdev) · 13 unmodified lines
987768 return ret;
988769
989770 /* Safe to free channels since no more users */
990− ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
771+ ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
991772 idr_destroy(&info->tx_idr);
992773
993774 idr = &info->rx_idr;
994− ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
775+ ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
995776 idr_destroy(&info->rx_idr);
996777
997778 return ret;
@@ -1043,15 +824,9 @@ static struct attribute *versions_attrs[] = { · 45 unmodified lines
1043824 };
1044825 ATTRIBUTE_GROUPS(versions);
1045826
1046−static const struct scmi_desc scmi_generic_desc = {
1047− .max_rx_timeout_ms = 30, /* We may increase this if required */
1048− .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
1049− .max_msg_size = 128,
1050−};
1051−
1052827 /* Each compatible listed below must have descriptor associated with it */
1053828 static const struct of_device_id scmi_of_match[] = {
1054− { .compatible = "arm,scmi", .data = &scmi_generic_desc },
829+ { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
1055830 { /* Sentinel */ },
1056831 };
1057832
drivers/firmware/arm_scmi/mailbox.c+184−0
@@ -0,0 +1,184 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * System Control and Management Interface (SCMI) Message Mailbox Transport
4+ * driver.
5+ *
6+ * Copyright (C) 2019 ARM Ltd.
7+ */
8+
9+#include <linux/err.h>
10+#include <linux/device.h>
11+#include <linux/mailbox_client.h>
12+#include <linux/of.h>
13+#include <linux/of_address.h>
14+#include <linux/slab.h>
15+
16+#include "common.h"
17+
18+/**
19+ * struct scmi_mailbox - Structure representing a SCMI mailbox transport
20+ *
21+ * @cl: Mailbox Client
22+ * @chan: Transmit/Receive mailbox channel
23+ * @cinfo: SCMI channel info
24+ * @shmem: Transmit/Receive shared memory area
25+ */
26+struct scmi_mailbox {
27+ struct mbox_client cl;
28+ struct mbox_chan *chan;
29+ struct scmi_chan_info *cinfo;
30+ struct scmi_shared_mem __iomem *shmem;
31+};
32+
33+#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
34+
35+static void tx_prepare(struct mbox_client *cl, void *m)
36+{
37+ struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
38+
39+ shmem_tx_prepare(smbox->shmem, m);
40+}
41+
42+static void rx_callback(struct mbox_client *cl, void *m)
43+{
44+ struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
45+
46+ scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem));
47+}
48+
49+static bool mailbox_chan_available(struct device *dev, int idx)
50+{
51+ return !of_parse_phandle_with_args(dev->of_node, "mboxes",
52+ "#mbox-cells", idx, NULL);
53+}
54+
55+static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
56+ bool tx)
57+{
58+ const char *desc = tx ? "Tx" : "Rx";
59+ struct device *cdev = cinfo->dev;
60+ struct scmi_mailbox *smbox;
61+ struct device_node *shmem;
62+ int ret, idx = tx ? 0 : 1;
63+ struct mbox_client *cl;
64+ resource_size_t size;
65+ struct resource res;
66+
67+ smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL);
68+ if (!smbox)
69+ return -ENOMEM;
70+
71+ shmem = of_parse_phandle(cdev->of_node, "shmem", idx);
72+ ret = of_address_to_resource(shmem, 0, &res);
73+ of_node_put(shmem);
74+ if (ret) {
75+ dev_err(cdev, "failed to get SCMI %s shared memory\n", desc);
76+ return ret;
77+ }
78+
79+ size = resource_size(&res);
80+ smbox->shmem = devm_ioremap(dev, res.start, size);
81+ if (!smbox->shmem) {
82+ dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc);
83+ return -EADDRNOTAVAIL;
84+ }
85+
86+ cl = &smbox->cl;
87+ cl->dev = cdev;
88+ cl->tx_prepare = tx ? tx_prepare : NULL;
89+ cl->rx_callback = rx_callback;
90+ cl->tx_block = false;
91+ cl->knows_txdone = tx;
92+
93+ smbox->chan = mbox_request_channel(cl, tx ? 0 : 1);
94+ if (IS_ERR(smbox->chan)) {
95+ ret = PTR_ERR(smbox->chan);
96+ if (ret != -EPROBE_DEFER)
97+ dev_err(cdev, "failed to request SCMI %s mailbox\n",
98+ tx ? "Tx" : "Rx");
99+ return ret;
100+ }
101+
102+ cinfo->transport_info = smbox;
103+ smbox->cinfo = cinfo;
104+
105+ return 0;
106+}
107+
108+static int mailbox_chan_free(int id, void *p, void *data)
109+{
110+ struct scmi_chan_info *cinfo = p;
111+ struct scmi_mailbox *smbox = cinfo->transport_info;
112+
113+ if (!IS_ERR(smbox->chan)) {
114+ mbox_free_channel(smbox->chan);
115+ cinfo->transport_info = NULL;
116+ smbox->chan = NULL;
117+ smbox->cinfo = NULL;
118+ }
119+
120+ scmi_free_channel(cinfo, data, id);
121+
122+ return 0;
123+}
124+
125+static int mailbox_send_message(struct scmi_chan_info *cinfo,
126+ struct scmi_xfer *xfer)
127+{
128+ struct scmi_mailbox *smbox = cinfo->transport_info;
129+ int ret;
130+
131+ ret = mbox_send_message(smbox->chan, xfer);
132+
133+ /* mbox_send_message returns non-negative value on success, so reset */
134+ if (ret > 0)
135+ ret = 0;
136+
137+ return ret;
138+}
139+
140+static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)
141+{
142+ struct scmi_mailbox *smbox = cinfo->transport_info;
143+
144+ /*
145+ * NOTE: we might prefer not to need the mailbox ticker to manage the
146+ * transfer queueing since the protocol layer queues things by itself.
147+ * Unfortunately, we have to kick the mailbox framework after we have
148+ * received our message.
149+ */
150+ mbox_client_txdone(smbox->chan, ret);
151+}
152+
153+static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
154+ struct scmi_xfer *xfer)
155+{
156+ struct scmi_mailbox *smbox = cinfo->transport_info;
157+
158+ shmem_fetch_response(smbox->shmem, xfer);
159+}
160+
161+static bool
162+mailbox_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
163+{
164+ struct scmi_mailbox *smbox = cinfo->transport_info;
165+
166+ return shmem_poll_done(smbox->shmem, xfer);
167+}
168+
169+static struct scmi_transport_ops scmi_mailbox_ops = {
170+ .chan_available = mailbox_chan_available,
171+ .chan_setup = mailbox_chan_setup,
172+ .chan_free = mailbox_chan_free,
173+ .send_message = mailbox_send_message,
174+ .mark_txdone = mailbox_mark_txdone,
175+ .fetch_response = mailbox_fetch_response,
176+ .poll_done = mailbox_poll_done,
177+};
178+
179+const struct scmi_desc scmi_mailbox_desc = {
180+ .ops = &scmi_mailbox_ops,
181+ .max_rx_timeout_ms = 30, /* We may increase this if required */
182+ .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
183+ .max_msg_size = 128,
184+};
drivers/firmware/arm_scmi/perf.c+1−1
@@ -89,7 +89,7 @@ struct scmi_msg_resp_perf_describe_levels { · 88 unmodified lines
8989 __le32 power;
9090 __le16 transition_latency_us;
9191 __le16 reserved;
92− } opp[0];
92+ } opp[];
9393 };
9494
9595 struct scmi_perf_get_fc_info {
drivers/firmware/arm_scmi/shmem.c+83−0
@@ -0,0 +1,83 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * For transport using shared mem structure.
4+ *
5+ * Copyright (C) 2019 ARM Ltd.
6+ */
7+
8+#include <linux/io.h>
9+#include <linux/processor.h>
10+#include <linux/types.h>
11+
12+#include "common.h"
13+
14+/*
15+ * SCMI specification requires all parameters, message headers, return
16+ * arguments or any protocol data to be expressed in little endian
17+ * format only.
18+ */
19+struct scmi_shared_mem {
20+ __le32 reserved;
21+ __le32 channel_status;
22+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1)
23+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0)
24+ __le32 reserved1[2];
25+ __le32 flags;
26+#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0)
27+ __le32 length;
28+ __le32 msg_header;
29+ u8 msg_payload[];
30+};
31+
32+void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
33+ struct scmi_xfer *xfer)
34+{
35+ /*
36+ * Ideally channel must be free by now unless OS timeout last
37+ * request and platform continued to process the same, wait
38+ * until it releases the shared memory, otherwise we may endup
39+ * overwriting its response with new message payload or vice-versa
40+ */
41+ spin_until_cond(ioread32(&shmem->channel_status) &
42+ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
43+ /* Mark channel busy + clear error */
44+ iowrite32(0x0, &shmem->channel_status);
45+ iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
46+ &shmem->flags);
47+ iowrite32(sizeof(shmem->msg_header) + xfer->tx.len, &shmem->length);
48+ iowrite32(pack_scmi_header(&xfer->hdr), &shmem->msg_header);
49+ if (xfer->tx.buf)
50+ memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
51+}
52+
53+u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
54+{
55+ return ioread32(&shmem->msg_header);
56+}
57+
58+void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
59+ struct scmi_xfer *xfer)
60+{
61+ xfer->hdr.status = ioread32(shmem->msg_payload);
62+ /* Skip the length of header and status in shmem area i.e 8 bytes */
63+ xfer->rx.len = min_t(size_t, xfer->rx.len,
64+ ioread32(&shmem->length) - 8);
65+
66+ /* Take a copy to the rx buffer.. */
67+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
68+}
69+
70+bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
71+ struct scmi_xfer *xfer)
72+{
73+ u16 xfer_id;
74+
75+ xfer_id = MSG_XTRACT_TOKEN(ioread32(&shmem->msg_header));
76+
77+ if (xfer->hdr.seq != xfer_id)
78+ return false;
79+
80+ return ioread32(&shmem->channel_status) &
81+ (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
82+ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
83+}
drivers/firmware/arm_scpi.c+2−2
@@ -262,12 +262,12 @@ struct scpi_drvinfo { · 261 unmodified lines
262262 struct scpi_shared_mem {
263263 __le32 command;
264264 __le32 status;
265− u8 payload[0];
265+ u8 payload[];
266266 } __packed;
267267
268268 struct legacy_scpi_shared_mem {
269269 __le32 status;
270− u8 payload[0];
270+ u8 payload[];
271271 } __packed;
272272
273273 struct scp_capabilities {
drivers/firmware/imx/scu-pd.c+12−1
@@ -93,7 +93,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { · 92 unmodified lines
9393 { "kpp", IMX_SC_R_KPP, 1, false, 0 },
9494 { "fspi", IMX_SC_R_FSPI_0, 2, true, 0 },
9595 { "mu_a", IMX_SC_R_MU_0A, 14, true, 0 },
96− { "mu_b", IMX_SC_R_MU_13B, 1, true, 13 },
96+ { "mu_b", IMX_SC_R_MU_5B, 9, true, 5 },
9797
9898 /* CONN SS */
9999 { "usb", IMX_SC_R_USB_0, 2, true, 0 },
@@ -109,6 +109,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { · 9 unmodified lines
109109 { "audio-pll0", IMX_SC_R_AUDIO_PLL_0, 1, false, 0 },
110110 { "audio-pll1", IMX_SC_R_AUDIO_PLL_1, 1, false, 0 },
111111 { "audio-clk-0", IMX_SC_R_AUDIO_CLK_0, 1, false, 0 },
112+ { "audio-clk-1", IMX_SC_R_AUDIO_CLK_1, 1, false, 0 },
112113 { "dma0-ch", IMX_SC_R_DMA_0_CH0, 16, true, 0 },
113114 { "dma1-ch", IMX_SC_R_DMA_1_CH0, 16, true, 0 },
114115 { "dma2-ch", IMX_SC_R_DMA_2_CH0, 5, true, 0 },
@@ -116,7 +117,13 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { · 1 unmodified line
116117 { "asrc1", IMX_SC_R_ASRC_1, 1, false, 0 },
117118 { "esai0", IMX_SC_R_ESAI_0, 1, false, 0 },
118119 { "spdif0", IMX_SC_R_SPDIF_0, 1, false, 0 },
120+ { "spdif1", IMX_SC_R_SPDIF_1, 1, false, 0 },
119121 { "sai", IMX_SC_R_SAI_0, 3, true, 0 },
122+ { "sai3", IMX_SC_R_SAI_3, 1, false, 0 },
123+ { "sai4", IMX_SC_R_SAI_4, 1, false, 0 },
124+ { "sai5", IMX_SC_R_SAI_5, 1, false, 0 },
125+ { "sai6", IMX_SC_R_SAI_6, 1, false, 0 },
126+ { "sai7", IMX_SC_R_SAI_7, 1, false, 0 },
120127 { "amix", IMX_SC_R_AMIX, 1, false, 0 },
121128 { "mqs0", IMX_SC_R_MQS_0, 1, false, 0 },
122129 { "dsp", IMX_SC_R_DSP, 1, false, 0 },
@@ -158,6 +165,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { · 35 unmodified lines
158165 /* DC SS */
159166 { "dc0", IMX_SC_R_DC_0, 1, false, 0 },
160167 { "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 },
168+
169+ /* CM40 SS */
170+ { "cm40_i2c", IMX_SC_R_M4_0_I2C, 1, 0 },
171+ { "cm40_intmux", IMX_SC_R_M4_0_INTMUX, 1, 0 },
161172 };
162173
163174 static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
drivers/firmware/meson/meson_sm.c+2−0
@@ -44,6 +44,8 @@ static const struct meson_sm_chip gxbb_chip = { · 43 unmodified lines
4444 CMD(SM_EFUSE_WRITE, 0x82000031),
4545 CMD(SM_EFUSE_USER_MAX, 0x82000033),
4646 CMD(SM_GET_CHIP_ID, 0x82000044),
47+ CMD(SM_A1_PWRC_SET, 0x82000093),
48+ CMD(SM_A1_PWRC_GET, 0x82000095),
4749 { /* sentinel */ },
4850 },
4951 };
drivers/firmware/tegra/Kconfig+1−1
@@ -7,7 +7,7 @@ config TEGRA_IVC · 6 unmodified lines
77 help
88 IVC (Inter-VM Communication) protocol is part of the IPC
99 (Inter Processor Communication) framework on Tegra. It maintains the
10− data and the different commuication channels in SysRAM or RAM and
10+ data and the different communication channels in SysRAM or RAM and
1111 keeps the content is synchronization between host CPU and remote
1212 processors.
1313
drivers/gpu/drm/omapdrm/dss/dss.c+22−3
@@ -1348,9 +1348,15 @@ static int dss_component_compare(struct device *dev, void *data) · 1347 unmodified lines
13481348 return dev == child;
13491349 }
13501350
1351+struct dss_component_match_data {
1352+ struct device *dev;
1353+ struct component_match **match;
1354+};
1355+
13511356 static int dss_add_child_component(struct device *dev, void *data)
13521357 {
1353− struct component_match **match = data;
1358+ struct dss_component_match_data *cmatch = data;
1359+ struct component_match **match = cmatch->match;
13541360
13551361 /*
13561362 * HACK
@@ -1361,7 +1367,17 @@ static int dss_add_child_component(struct device *dev, void *data) · 4 unmodified lines
13611367 if (strstr(dev_name(dev), "rfbi"))
13621368 return 0;
13631369
1364− component_match_add(dev->parent, match, dss_component_compare, dev);
1370+ /*
1371+ * Handle possible interconnect target modules defined within the DSS.
1372+ * The DSS components can be children of an interconnect target module
1373+ * after the device tree has been updated for the module data.
1374+ * See also omapdss_boot_init() for compatible fixup.
1375+ */
1376+ if (strstr(dev_name(dev), "target-module"))
1377+ return device_for_each_child(dev, cmatch,
1378+ dss_add_child_component);
1379+
1380+ component_match_add(cmatch->dev, match, dss_component_compare, dev);
13651381
13661382 return 0;
13671383 }
@@ -1404,6 +1420,7 @@ static int dss_probe_hardware(struct dss_device *dss) · 36 unmodified lines
14041420 static int dss_probe(struct platform_device *pdev)
14051421 {
14061422 const struct soc_device_attribute *soc;
1423+ struct dss_component_match_data cmatch;
14071424 struct component_match *match = NULL;
14081425 struct resource *dss_mem;
14091426 struct dss_device *dss;
@@ -1481,7 +1498,9 @@ static int dss_probe(struct platform_device *pdev) · 71 unmodified lines
14811498
14821499 omapdss_gather_components(&pdev->dev);
14831500
1484− device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1501+ cmatch.dev = &pdev->dev;
1502+ cmatch.match = &match;
1503+ device_for_each_child(&pdev->dev, &cmatch, dss_add_child_component);
14851504
14861505 r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
14871506 if (r)
drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c+17−8
@@ -178,9 +178,24 @@ static const struct of_device_id omapdss_of_fixups_whitelist[] __initconst = { · 177 unmodified lines
178178 {},
179179 };
180180
181+static void __init omapdss_find_children(struct device_node *np)
182+{
183+ struct device_node *child;
184+
185+ for_each_available_child_of_node(np, child) {
186+ if (!of_find_property(child, "compatible", NULL))
187+ continue;
188+
189+ omapdss_walk_device(child, true);
190+
191+ if (of_device_is_compatible(child, "ti,sysc"))
192+ omapdss_find_children(child);
193+ }
194+}
195+
181196 static int __init omapdss_boot_init(void)
182197 {
183− struct device_node *dss, *child;
198+ struct device_node *dss;
184199
185200 INIT_LIST_HEAD(&dss_conv_list);
186201
@@ -190,13 +205,7 @@ static int __init omapdss_boot_init(void) · 3 unmodified lines
190205 goto put_node;
191206
192207 omapdss_walk_device(dss, true);
193−
194− for_each_available_child_of_node(dss, child) {
195− if (!of_find_property(child, "compatible", NULL))
196− continue;
197−
198− omapdss_walk_device(child, true);
199− }
208+ omapdss_find_children(dss);
200209
201210 while (!list_empty(&dss_conv_list)) {
202211 struct dss_conv_node *n;
drivers/memory/tegra/tegra124-emc.c+5−0
@@ -1158,6 +1158,11 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) · 1157 unmodified lines
11581158 emc->debugfs.max_rate = emc->timings[i].rate;
11591159 }
11601160
1161+ if (!emc->num_timings) {
1162+ emc->debugfs.min_rate = clk_get_rate(emc->clk);
1163+ emc->debugfs.max_rate = emc->debugfs.min_rate;
1164+ }
1165+
11611166 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
11621167 emc->debugfs.max_rate);
11631168 if (err < 0) {
drivers/memory/tegra/tegra20-emc.c+5−0
@@ -628,6 +628,11 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc) · 627 unmodified lines
628628 emc->debugfs.max_rate = emc->timings[i].rate;
629629 }
630630
631+ if (!emc->num_timings) {
632+ emc->debugfs.min_rate = clk_get_rate(emc->clk);
633+ emc->debugfs.max_rate = emc->debugfs.min_rate;
634+ }
635+
631636 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
632637 emc->debugfs.max_rate);
633638 if (err < 0) {
drivers/memory/tegra/tegra30-emc.c+5−0
@@ -1256,6 +1256,11 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc) · 1255 unmodified lines
12561256 emc->debugfs.max_rate = emc->timings[i].rate;
12571257 }
12581258
1259+ if (!emc->num_timings) {
1260+ emc->debugfs.min_rate = clk_get_rate(emc->clk);
1261+ emc->debugfs.max_rate = emc->debugfs.min_rate;
1262+ }
1263+
12591264 err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
12601265 emc->debugfs.max_rate);
12611266 if (err < 0) {
drivers/soc/Makefile+1−1
@@ -11,7 +11,7 @@ obj-$(CONFIG_ARCH_DOVE) += dove/ · 10 unmodified lines
1111 obj-$(CONFIG_MACH_DOVE) += dove/
1212 obj-y += fsl/
1313 obj-$(CONFIG_ARCH_GEMINI) += gemini/
14−obj-$(CONFIG_ARCH_MXC) += imx/
14+obj-y += imx/
1515 obj-$(CONFIG_ARCH_IXP4XX) += ixp4xx/
1616 obj-$(CONFIG_SOC_XWAY) += lantiq/
1717 obj-y += mediatek/
drivers/soc/amlogic/Kconfig+13−0
@@ -48,6 +48,19 @@ config MESON_EE_PM_DOMAINS · 47 unmodified lines
4848 Say yes to expose Amlogic Meson Everything-Else Power Domains as
4949 Generic Power Domains.
5050
51+config MESON_SECURE_PM_DOMAINS
52+ bool "Amlogic Meson Secure Power Domains driver"
53+ depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
54+ depends on PM && OF
55+ depends on HAVE_ARM_SMCCC
56+ default ARCH_MESON
57+ select PM_GENERIC_DOMAINS
58+ select PM_GENERIC_DOMAINS_OF
59+ help
60+ Support for the power controller on Amlogic A1/C1 series.
61+ Say yes to expose Amlogic Meson Secure Power Domains as Generic
62+ Power Domains.
63+
5164 config MESON_MX_SOCINFO
5265 bool "Amlogic Meson MX SoC Information driver"
5366 depends on ARCH_MESON || COMPILE_TEST
drivers/soc/amlogic/Makefile+1−0
@@ -5,3 +5,4 @@ obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o · 4 unmodified lines
55 obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
66 obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
77 obj-$(CONFIG_MESON_EE_PM_DOMAINS) += meson-ee-pwrc.o
8+obj-$(CONFIG_MESON_SECURE_PM_DOMAINS) += meson-secure-pwrc.o
drivers/soc/amlogic/meson-secure-pwrc.c+204−0
@@ -0,0 +1,204 @@
1+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2+/*
3+ * Copyright (c) 2019 Amlogic, Inc.
4+ * Author: Jianxin Pan <jianxin.pan@amlogic.com>
5+ */
6+
7+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8+
9+#include <linux/io.h>
10+#include <linux/of_device.h>
11+#include <linux/platform_device.h>
12+#include <linux/pm_domain.h>
13+#include <dt-bindings/power/meson-a1-power.h>
14+#include <linux/arm-smccc.h>
15+#include <linux/firmware/meson/meson_sm.h>
16+
17+#define PWRC_ON 1
18+#define PWRC_OFF 0
19+
20+struct meson_secure_pwrc_domain {
21+ struct generic_pm_domain base;
22+ unsigned int index;
23+ struct meson_secure_pwrc *pwrc;
24+};
25+
26+struct meson_secure_pwrc {
27+ struct meson_secure_pwrc_domain *domains;
28+ struct genpd_onecell_data xlate;
29+ struct meson_sm_firmware *fw;
30+};
31+
32+struct meson_secure_pwrc_domain_desc {
33+ unsigned int index;
34+ unsigned int flags;
35+ char *name;
36+ bool (*is_off)(struct meson_secure_pwrc_domain *pwrc_domain);
37+};
38+
39+struct meson_secure_pwrc_domain_data {
40+ unsigned int count;
41+ struct meson_secure_pwrc_domain_desc *domains;
42+};
43+
44+static bool pwrc_secure_is_off(struct meson_secure_pwrc_domain *pwrc_domain)
45+{
46+ int is_off = 1;
47+
48+ if (meson_sm_call(pwrc_domain->pwrc->fw, SM_A1_PWRC_GET, &is_off,
49+ pwrc_domain->index, 0, 0, 0, 0) < 0)
50+ pr_err("failed to get power domain status\n");
51+
52+ return is_off;
53+}
54+
55+static int meson_secure_pwrc_off(struct generic_pm_domain *domain)
56+{
57+ int ret = 0;
58+ struct meson_secure_pwrc_domain *pwrc_domain =
59+ container_of(domain, struct meson_secure_pwrc_domain, base);
60+
61+ if (meson_sm_call(pwrc_domain->pwrc->fw, SM_A1_PWRC_SET, NULL,
62+ pwrc_domain->index, PWRC_OFF, 0, 0, 0) < 0) {
63+ pr_err("failed to set power domain off\n");
64+ ret = -EINVAL;
65+ }
66+
67+ return ret;
68+}
69+
70+static int meson_secure_pwrc_on(struct generic_pm_domain *domain)
71+{
72+ int ret = 0;
73+ struct meson_secure_pwrc_domain *pwrc_domain =
74+ container_of(domain, struct meson_secure_pwrc_domain, base);
75+
76+ if (meson_sm_call(pwrc_domain->pwrc->fw, SM_A1_PWRC_SET, NULL,
77+ pwrc_domain->index, PWRC_ON, 0, 0, 0) < 0) {
78+ pr_err("failed to set power domain on\n");
79+ ret = -EINVAL;
80+ }
81+
82+ return ret;
83+}
84+
85+#define SEC_PD(__name, __flag) \
86+[PWRC_##__name##_ID] = \
87+{ \
88+ .name = #__name, \
89+ .index = PWRC_##__name##_ID, \
90+ .is_off = pwrc_secure_is_off, \
91+ .flags = __flag, \
92+}
93+
94+static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
95+ SEC_PD(DSPA, 0),
96+ SEC_PD(DSPB, 0),
97+ /* UART should keep working in ATF after suspend and before resume */
98+ SEC_PD(UART, GENPD_FLAG_ALWAYS_ON),
99+ /* DMC is for DDR PHY ana/dig and DMC, and should be always on */
100+ SEC_PD(DMC, GENPD_FLAG_ALWAYS_ON),
101+ SEC_PD(I2C, 0),
102+ SEC_PD(PSRAM, 0),
103+ SEC_PD(ACODEC, 0),
104+ SEC_PD(AUDIO, 0),
105+ SEC_PD(OTP, 0),
106+ SEC_PD(DMA, 0),
107+ SEC_PD(SD_EMMC, 0),
108+ SEC_PD(RAMA, 0),
109+ /* SRAMB is used as ATF runtime memory, and should be always on */
110+ SEC_PD(RAMB, GENPD_FLAG_ALWAYS_ON),
111+ SEC_PD(IR, 0),
112+ SEC_PD(SPICC, 0),
113+ SEC_PD(SPIFC, 0),
114+ SEC_PD(USB, 0),
115+ /* NIC is for the Arm NIC-400 interconnect, and should be always on */
116+ SEC_PD(NIC, GENPD_FLAG_ALWAYS_ON),
117+ SEC_PD(PDMIN, 0),
118+ SEC_PD(RSA, 0),
119+};
120+
121+static int meson_secure_pwrc_probe(struct platform_device *pdev)
122+{
123+ int i;
124+ struct device_node *sm_np;
125+ struct meson_secure_pwrc *pwrc;
126+ const struct meson_secure_pwrc_domain_data *match;
127+
128+ match = of_device_get_match_data(&pdev->dev);
129+ if (!match) {
130+ dev_err(&pdev->dev, "failed to get match data\n");
131+ return -ENODEV;
132+ }
133+
134+ sm_np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gxbb-sm");
135+ if (!sm_np) {
136+ dev_err(&pdev->dev, "no secure-monitor node\n");
137+ return -ENODEV;
138+ }
139+
140+ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
141+ if (!pwrc)
142+ return -ENOMEM;
143+
144+ pwrc->fw = meson_sm_get(sm_np);
145+ of_node_put(sm_np);
146+ if (!pwrc->fw)
147+ return -EPROBE_DEFER;
148+
149+ pwrc->xlate.domains = devm_kcalloc(&pdev->dev, match->count,
150+ sizeof(*pwrc->xlate.domains),
151+ GFP_KERNEL);
152+ if (!pwrc->xlate.domains)
153+ return -ENOMEM;
154+
155+ pwrc->domains = devm_kcalloc(&pdev->dev, match->count,
156+ sizeof(*pwrc->domains), GFP_KERNEL);
157+ if (!pwrc->domains)
158+ return -ENOMEM;
159+
160+ pwrc->xlate.num_domains = match->count;
161+ platform_set_drvdata(pdev, pwrc);
162+
163+ for (i = 0 ; i < match->count ; ++i) {
164+ struct meson_secure_pwrc_domain *dom = &pwrc->domains[i];
165+
166+ if (!match->domains[i].index)
167+ continue;
168+
169+ dom->pwrc = pwrc;
170+ dom->index = match->domains[i].index;
171+ dom->base.name = match->domains[i].name;
172+ dom->base.flags = match->domains[i].flags;
173+ dom->base.power_on = meson_secure_pwrc_on;
174+ dom->base.power_off = meson_secure_pwrc_off;
175+
176+ pm_genpd_init(&dom->base, NULL, match->domains[i].is_off(dom));
177+
178+ pwrc->xlate.domains[i] = &dom->base;
179+ }
180+
181+ return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
182+}
183+
184+static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = {
185+ .domains = a1_pwrc_domains,
186+ .count = ARRAY_SIZE(a1_pwrc_domains),
187+};
188+
189+static const struct of_device_id meson_secure_pwrc_match_table[] = {
190+ {
191+ .compatible = "amlogic,meson-a1-pwrc",
192+ .data = &meson_secure_a1_pwrc_data,
193+ },
194+ { /* sentinel */ }
195+};
196+
197+static struct platform_driver meson_secure_pwrc_driver = {
198+ .probe = meson_secure_pwrc_probe,
199+ .driver = {
200+ .name = "meson_secure_pwrc",
201+ .of_match_table = meson_secure_pwrc_match_table,
202+ },
203+};
204+builtin_platform_driver(meson_secure_pwrc_driver);
drivers/soc/fsl/dpio/dpio-service.c+66−3
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
22 /*
33 * Copyright 2014-2016 Freescale Semiconductor Inc.
4− * Copyright 2016 NXP
4+ * Copyright 2016-2019 NXP
55 *
66 */
77 #include <linux/types.h>
@@ -432,6 +432,69 @@ int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, · 424 unmodified lines
432432 }
433433 EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);
434434
435+/**
436+ * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames
437+ * to a frame queue using one fqid.
438+ * @d: the given DPIO service.
439+ * @fqid: the given frame queue id.
440+ * @fd: the frame descriptor which is enqueued.
441+ * @nb: number of frames to be enqueud
442+ *
443+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
444+ * or -ENODEV if there is no dpio service.
445+ */
446+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d,
447+ u32 fqid,
448+ const struct dpaa2_fd *fd,
449+ int nb)
450+{
451+ struct qbman_eq_desc ed;
452+
453+ d = service_select(d);
454+ if (!d)
455+ return -ENODEV;
456+
457+ qbman_eq_desc_clear(&ed);
458+ qbman_eq_desc_set_no_orp(&ed, 0);
459+ qbman_eq_desc_set_fq(&ed, fqid);
460+
461+ return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb);
462+}
463+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq);
464+
465+/**
466+ * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames
467+ * to different frame queue using a list of fqids.
468+ * @d: the given DPIO service.
469+ * @fqid: the given list of frame queue ids.
470+ * @fd: the frame descriptor which is enqueued.
471+ * @nb: number of frames to be enqueud
472+ *
473+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
474+ * or -ENODEV if there is no dpio service.
475+ */
476+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
477+ u32 *fqid,
478+ const struct dpaa2_fd *fd,
479+ int nb)
480+{
481+ int i;
482+ struct qbman_eq_desc ed[32];
483+
484+ d = service_select(d);
485+ if (!d)
486+ return -ENODEV;
487+
488+ for (i = 0; i < nb; i++) {
489+ qbman_eq_desc_clear(&ed[i]);
490+ qbman_eq_desc_set_no_orp(&ed[i], 0);
491+ qbman_eq_desc_set_fq(&ed[i], fqid[i]);
492+ }
493+
494+ return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
495+}
496+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq);
497+
435498 /**
436499 * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
437500 * @d: the given DPIO service.
@@ -526,7 +589,7 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire); · 88 unmodified lines
526589
527590 /**
528591 * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
529− * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
592+ * @max_frames: the maximum number of dequeued result for frames, must be <= 32.
530593 * @dev: the device to allow mapping/unmapping the DMAable region.
531594 *
532595 * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
@@ -541,7 +604,7 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames, · 8 unmodified lines
541604 struct dpaa2_io_store *ret;
542605 size_t size;
543606
544− if (!max_frames || (max_frames > 16))
607+ if (!max_frames || (max_frames > 32))
545608 return NULL;
546609
547610 ret = kmalloc(sizeof(*ret), GFP_KERNEL);
drivers/soc/fsl/dpio/qbman-portal.c+686−81
@@ -1,24 +1,18 @@
11 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
22 /*
33 * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
4− * Copyright 2016 NXP
4+ * Copyright 2016-2019 NXP
55 *
66 */
77
88 #include <asm/cacheflush.h>
99 #include <linux/io.h>
1010 #include <linux/slab.h>
11+#include <linux/spinlock.h>
1112 #include <soc/fsl/dpaa2-global.h>
1213
1314 #include "qbman-portal.h"
1415
15−#define QMAN_REV_4000 0x04000000
16−#define QMAN_REV_4100 0x04010000
17−#define QMAN_REV_4101 0x04010001
18−#define QMAN_REV_5000 0x05000000
19−
20−#define QMAN_REV_MASK 0xffff0000
21−
2216 /* All QBMan command and result structures use this "valid bit" encoding */
2317 #define QB_VALID_BIT ((u32)0x80)
2418
@@ -28,6 +22,7 @@ · 3 unmodified lines
2822
2923 /* CINH register offsets */
3024 #define QBMAN_CINH_SWP_EQCR_PI 0x800
25+#define QBMAN_CINH_SWP_EQCR_CI 0x840
3126 #define QBMAN_CINH_SWP_EQAR 0x8c0
3227 #define QBMAN_CINH_SWP_CR_RT 0x900
3328 #define QBMAN_CINH_SWP_VDQCR_RT 0x940
@@ -51,6 +46,8 @@ · 17 unmodified lines
5146 #define QBMAN_CENA_SWP_CR 0x600
5247 #define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1))
5348 #define QBMAN_CENA_SWP_VDQCR 0x780
49+#define QBMAN_CENA_SWP_EQCR_CI 0x840
50+#define QBMAN_CENA_SWP_EQCR_CI_MEMBACK 0x1840
5451
5552 /* CENA register offsets in memory-backed mode */
5653 #define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6))
@@ -78,6 +75,12 @@ · 21 unmodified lines
7875 /* opaque token for static dequeues */
7976 #define QMAN_SDQCR_TOKEN 0xbb
8077
78+#define QBMAN_EQCR_DCA_IDXMASK 0x0f
79+#define QBMAN_ENQUEUE_FLAG_DCA (1ULL << 31)
80+
81+#define EQ_DESC_SIZE_WITHOUT_FD 29
82+#define EQ_DESC_SIZE_FD_START 32
83+
8184 enum qbman_sdqcr_dct {
8285 qbman_sdqcr_dct_null = 0,
8386 qbman_sdqcr_dct_prio_ics,
@@ -90,6 +93,82 @@ enum qbman_sdqcr_fc { · 6 unmodified lines
9093 qbman_sdqcr_fc_up_to_3 = 1
9194 };
9295
96+/* Internal Function declaration */
97+static int qbman_swp_enqueue_direct(struct qbman_swp *s,
98+ const struct qbman_eq_desc *d,
99+ const struct dpaa2_fd *fd);
100+static int qbman_swp_enqueue_mem_back(struct qbman_swp *s,
101+ const struct qbman_eq_desc *d,
102+ const struct dpaa2_fd *fd);
103+static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
104+ const struct qbman_eq_desc *d,
105+ const struct dpaa2_fd *fd,
106+ uint32_t *flags,
107+ int num_frames);
108+static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
109+ const struct qbman_eq_desc *d,
110+ const struct dpaa2_fd *fd,
111+ uint32_t *flags,
112+ int num_frames);
113+static int
114+qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
115+ const struct qbman_eq_desc *d,
116+ const struct dpaa2_fd *fd,
117+ int num_frames);
118+static
119+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
120+ const struct qbman_eq_desc *d,
121+ const struct dpaa2_fd *fd,
122+ int num_frames);
123+static int qbman_swp_pull_direct(struct qbman_swp *s,
124+ struct qbman_pull_desc *d);
125+static int qbman_swp_pull_mem_back(struct qbman_swp *s,
126+ struct qbman_pull_desc *d);
127+
128+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s);
129+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s);
130+
131+static int qbman_swp_release_direct(struct qbman_swp *s,
132+ const struct qbman_release_desc *d,
133+ const u64 *buffers,
134+ unsigned int num_buffers);
135+static int qbman_swp_release_mem_back(struct qbman_swp *s,
136+ const struct qbman_release_desc *d,
137+ const u64 *buffers,
138+ unsigned int num_buffers);
139+
140+/* Function pointers */
141+int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s,
142+ const struct qbman_eq_desc *d,
143+ const struct dpaa2_fd *fd)
144+ = qbman_swp_enqueue_direct;
145+
146+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
147+ const struct qbman_eq_desc *d,
148+ const struct dpaa2_fd *fd,
149+ uint32_t *flags,
150+ int num_frames)
151+ = qbman_swp_enqueue_multiple_direct;
152+
153+int
154+(*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
155+ const struct qbman_eq_desc *d,
156+ const struct dpaa2_fd *fd,
157+ int num_frames)
158+ = qbman_swp_enqueue_multiple_desc_direct;
159+
160+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d)
161+ = qbman_swp_pull_direct;
162+
163+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s)
164+ = qbman_swp_dqrr_next_direct;
165+
166+int (*qbman_swp_release_ptr)(struct qbman_swp *s,
167+ const struct qbman_release_desc *d,
168+ const u64 *buffers,
169+ unsigned int num_buffers)
170+ = qbman_swp_release_direct;
171+
93172 /* Portal Access */
94173
95174 static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
@@ -146,6 +225,15 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm, · 50 unmodified lines
146225
147226 #define QMAN_RT_MODE 0x00000100
148227
228+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
229+{
230+ /* 'first' is included, 'last' is excluded */
231+ if (first <= last)
232+ return last - first;
233+ else
234+ return (2 * ringsize) - (first - last);
235+}
236+
149237 /**
150238 * qbman_swp_init() - Create a functional object representing the given
151239 * QBMan portal descriptor.
@@ -156,11 +244,16 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm, · 4 unmodified lines
156244 */
157245 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
158246 {
159− struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
247+ struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL);
160248 u32 reg;
249+ u32 mask_size;
250+ u32 eqcr_pi;
161251
162252 if (!p)
163253 return NULL;
254+
255+ spin_lock_init(&p->access_spinlock);
256+
164257 p->desc = d;
165258 p->mc.valid_bit = QB_VALID_BIT;
166259 p->sdq = 0;
@@ -186,25 +279,38 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) · 19 unmodified lines
186279 p->addr_cena = d->cena_bar;
187280 p->addr_cinh = d->cinh_bar;
188281
189− if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
190− memset(p->addr_cena, 0, 64 * 1024);
282+ if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
191283
192− reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
193− 1, /* Writes Non-cacheable */
194− 0, /* EQCR_CI stashing threshold */
195− 3, /* RPM: Valid bit mode, RCR in array mode */
196− 2, /* DCM: Discrete consumption ack mode */
197− 3, /* EPM: Valid bit mode, EQCR in array mode */
198− 1, /* mem stashing drop enable == TRUE */
199− 1, /* mem stashing priority == TRUE */
200− 1, /* mem stashing enable == TRUE */
201− 1, /* dequeue stashing priority == TRUE */
202− 0, /* dequeue stashing enable == FALSE */
203− 0); /* EQCR_CI stashing priority == FALSE */
204− if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
284+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
285+ 1, /* Writes Non-cacheable */
286+ 0, /* EQCR_CI stashing threshold */
287+ 3, /* RPM: RCR in array mode */
288+ 2, /* DCM: Discrete consumption ack */
289+ 2, /* EPM: EQCR in ring mode */
290+ 1, /* mem stashing drop enable enable */
291+ 1, /* mem stashing priority enable */
292+ 1, /* mem stashing enable */
293+ 1, /* dequeue stashing priority enable */
294+ 0, /* dequeue stashing enable enable */
295+ 0); /* EQCR_CI stashing priority enable */
296+ } else {
297+ memset(p->addr_cena, 0, 64 * 1024);
298+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
299+ 1, /* Writes Non-cacheable */
300+ 1, /* EQCR_CI stashing threshold */
301+ 3, /* RPM: RCR in array mode */
302+ 2, /* DCM: Discrete consumption ack */
303+ 0, /* EPM: EQCR in ring mode */
304+ 1, /* mem stashing drop enable */
305+ 1, /* mem stashing priority enable */
306+ 1, /* mem stashing enable */
307+ 1, /* dequeue stashing priority enable */
308+ 0, /* dequeue stashing enable */
309+ 0); /* EQCR_CI stashing priority enable */
205310 reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */
206311 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */
207312 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */
313+ }
208314
209315 qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
210316 reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
@@ -225,6 +331,30 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) · 14 unmodified lines
225331 * applied when dequeues from a specific channel are enabled.
226332 */
227333 qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0);
334+
335+ p->eqcr.pi_ring_size = 8;
336+ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
337+ p->eqcr.pi_ring_size = 32;
338+ qbman_swp_enqueue_ptr =
339+ qbman_swp_enqueue_mem_back;
340+ qbman_swp_enqueue_multiple_ptr =
341+ qbman_swp_enqueue_multiple_mem_back;
342+ qbman_swp_enqueue_multiple_desc_ptr =
343+ qbman_swp_enqueue_multiple_desc_mem_back;
344+ qbman_swp_pull_ptr = qbman_swp_pull_mem_back;
345+ qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back;
346+ qbman_swp_release_ptr = qbman_swp_release_mem_back;
347+ }
348+
349+ for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1)
350+ p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask << 1) + 1;
351+ eqcr_pi = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_PI);
352+ p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask;
353+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
354+ p->eqcr.ci = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_CI)
355+ & p->eqcr.pi_ci_mask;
356+ p->eqcr.available = p->eqcr.pi_ring_size;
357+
228358 return p;
229359 }
230360
@@ -378,6 +508,7 @@ enum qb_enqueue_commands { · 147 unmodified lines
378508 #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2
379509 #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
380510 #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4
511+#define QB_ENQUEUE_CMD_DCA_EN_SHIFT 7
381512
382513 /**
383514 * qbman_eq_desc_clear() - Clear the contents of a descriptor to
@@ -453,8 +584,9 @@ static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p, · 69 unmodified lines
453584 QMAN_RT_MODE);
454585 }
455586
587+#define QB_RT_BIT ((u32)0x100)
456588 /**
457− * qbman_swp_enqueue() - Issue an enqueue command
589+ * qbman_swp_enqueue_direct() - Issue an enqueue command
458590 * @s: the software portal used for enqueue
459591 * @d: the enqueue descriptor
460592 * @fd: the frame descriptor to be enqueued
@@ -464,30 +596,351 @@ static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p, · 3 unmodified lines
464596 *
465597 * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
466598 */
467−int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
468− const struct dpaa2_fd *fd)
599+static
600+int qbman_swp_enqueue_direct(struct qbman_swp *s,
601+ const struct qbman_eq_desc *d,
602+ const struct dpaa2_fd *fd)
469603 {
470− struct qbman_eq_desc *p;
471− u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
604+ int flags = 0;
605+ int ret = qbman_swp_enqueue_multiple_direct(s, d, fd, &flags, 1);
472606
473− if (!EQAR_SUCCESS(eqar))
474− return -EBUSY;
607+ if (ret >= 0)
608+ ret = 0;
609+ else
610+ ret = -EBUSY;
611+ return ret;
612+}
613+
614+/**
615+ * qbman_swp_enqueue_mem_back() - Issue an enqueue command
616+ * @s: the software portal used for enqueue
617+ * @d: the enqueue descriptor
618+ * @fd: the frame descriptor to be enqueued
619+ *
620+ * Please note that 'fd' should only be NULL if the "action" of the
621+ * descriptor is "orp_hole" or "orp_nesn".
622+ *
623+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
624+ */
625+static
626+int qbman_swp_enqueue_mem_back(struct qbman_swp *s,
627+ const struct qbman_eq_desc *d,
628+ const struct dpaa2_fd *fd)
629+{
630+ int flags = 0;
631+ int ret = qbman_swp_enqueue_multiple_mem_back(s, d, fd, &flags, 1);
475632
476− p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
477− memcpy(&p->dca, &d->dca, 31);
478− memcpy(&p->fd, fd, sizeof(*fd));
633+ if (ret >= 0)
634+ ret = 0;
635+ else
636+ ret = -EBUSY;
637+ return ret;
638+}
479639
480− if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
481− /* Set the verb byte, have to substitute in the valid-bit */
482− dma_wmb();
483− p->verb = d->verb | EQAR_VB(eqar);
484− } else {
485− p->verb = d->verb | EQAR_VB(eqar);
486− dma_wmb();
487− qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
640+/**
641+ * qbman_swp_enqueue_multiple_direct() - Issue a multi enqueue command
642+ * using one enqueue descriptor
643+ * @s: the software portal used for enqueue
644+ * @d: the enqueue descriptor
645+ * @fd: table pointer of frame descriptor table to be enqueued
646+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
647+ * @num_frames: number of fd to be enqueued
648+ *
649+ * Return the number of fd enqueued, or a negative error number.
650+ */
651+static
652+int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
653+ const struct qbman_eq_desc *d,
654+ const struct dpaa2_fd *fd,
655+ uint32_t *flags,
656+ int num_frames)
657+{
658+ uint32_t *p = NULL;
659+ const uint32_t *cl = (uint32_t *)d;
660+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
661+ int i, num_enqueued = 0;
662+ uint64_t addr_cena;
663+
664+ spin_lock(&s->access_spinlock);
665+ half_mask = (s->eqcr.pi_ci_mask>>1);
666+ full_mask = s->eqcr.pi_ci_mask;
667+
668+ if (!s->eqcr.available) {
669+ eqcr_ci = s->eqcr.ci;
670+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
671+ s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
672+
673+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
674+ eqcr_ci, s->eqcr.ci);
675+ if (!s->eqcr.available) {
676+ spin_unlock(&s->access_spinlock);
677+ return 0;
678+ }
488679 }
489680
490− return 0;
681+ eqcr_pi = s->eqcr.pi;
682+ num_enqueued = (s->eqcr.available < num_frames) ?
683+ s->eqcr.available : num_frames;
684+ s->eqcr.available -= num_enqueued;
685+ /* Fill in the EQCR ring */
686+ for (i = 0; i < num_enqueued; i++) {
687+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
688+ /* Skip copying the verb */
689+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
690+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
691+ &fd[i], sizeof(*fd));
692+ eqcr_pi++;
693+ }
694+
695+ dma_wmb();
696+
697+ /* Set the verb byte, have to substitute in the valid-bit */
698+ eqcr_pi = s->eqcr.pi;
699+ for (i = 0; i < num_enqueued; i++) {
700+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
701+ p[0] = cl[0] | s->eqcr.pi_vb;
702+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
703+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
704+
705+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
706+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
707+ }
708+ eqcr_pi++;
709+ if (!(eqcr_pi & half_mask))
710+ s->eqcr.pi_vb ^= QB_VALID_BIT;
711+ }
712+
713+ /* Flush all the cacheline without load/store in between */
714+ eqcr_pi = s->eqcr.pi;
715+ addr_cena = (size_t)s->addr_cena;
716+ for (i = 0; i < num_enqueued; i++)
717+ eqcr_pi++;
718+ s->eqcr.pi = eqcr_pi & full_mask;
719+ spin_unlock(&s->access_spinlock);
720+
721+ return num_enqueued;
722+}
723+
724+/**
725+ * qbman_swp_enqueue_multiple_mem_back() - Issue a multi enqueue command
726+ * using one enqueue descriptor
727+ * @s: the software portal used for enqueue
728+ * @d: the enqueue descriptor
729+ * @fd: table pointer of frame descriptor table to be enqueued
730+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
731+ * @num_frames: number of fd to be enqueued
732+ *
733+ * Return the number of fd enqueued, or a negative error number.
734+ */
735+static
736+int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
737+ const struct qbman_eq_desc *d,
738+ const struct dpaa2_fd *fd,
739+ uint32_t *flags,
740+ int num_frames)
741+{
742+ uint32_t *p = NULL;
743+ const uint32_t *cl = (uint32_t *)(d);
744+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
745+ int i, num_enqueued = 0;
746+ unsigned long irq_flags;
747+
748+ spin_lock(&s->access_spinlock);
749+ local_irq_save(irq_flags);
750+
751+ half_mask = (s->eqcr.pi_ci_mask>>1);
752+ full_mask = s->eqcr.pi_ci_mask;
753+ if (!s->eqcr.available) {
754+ eqcr_ci = s->eqcr.ci;
755+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
756+ s->eqcr.ci = __raw_readl(p) & full_mask;
757+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
758+ eqcr_ci, s->eqcr.ci);
759+ if (!s->eqcr.available) {
760+ local_irq_restore(irq_flags);
761+ spin_unlock(&s->access_spinlock);
762+ return 0;
763+ }
764+ }
765+
766+ eqcr_pi = s->eqcr.pi;
767+ num_enqueued = (s->eqcr.available < num_frames) ?
768+ s->eqcr.available : num_frames;
769+ s->eqcr.available -= num_enqueued;
770+ /* Fill in the EQCR ring */
771+ for (i = 0; i < num_enqueued; i++) {
772+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
773+ /* Skip copying the verb */
774+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
775+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
776+ &fd[i], sizeof(*fd));
777+ eqcr_pi++;
778+ }
779+
780+ /* Set the verb byte, have to substitute in the valid-bit */
781+ eqcr_pi = s->eqcr.pi;
782+ for (i = 0; i < num_enqueued; i++) {
783+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
784+ p[0] = cl[0] | s->eqcr.pi_vb;
785+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
786+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
787+
788+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
789+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
790+ }
791+ eqcr_pi++;
792+ if (!(eqcr_pi & half_mask))
793+ s->eqcr.pi_vb ^= QB_VALID_BIT;
794+ }
795+ s->eqcr.pi = eqcr_pi & full_mask;
796+
797+ dma_wmb();
798+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI,
799+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
800+ local_irq_restore(irq_flags);
801+ spin_unlock(&s->access_spinlock);
802+
803+ return num_enqueued;
804+}
805+
806+/**
807+ * qbman_swp_enqueue_multiple_desc_direct() - Issue a multi enqueue command
808+ * using multiple enqueue descriptor
809+ * @s: the software portal used for enqueue
810+ * @d: table of minimal enqueue descriptor
811+ * @fd: table pointer of frame descriptor table to be enqueued
812+ * @num_frames: number of fd to be enqueued
813+ *
814+ * Return the number of fd enqueued, or a negative error number.
815+ */
816+static
817+int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
818+ const struct qbman_eq_desc *d,
819+ const struct dpaa2_fd *fd,
820+ int num_frames)
821+{
822+ uint32_t *p;
823+ const uint32_t *cl;
824+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
825+ int i, num_enqueued = 0;
826+ uint64_t addr_cena;
827+
828+ half_mask = (s->eqcr.pi_ci_mask>>1);
829+ full_mask = s->eqcr.pi_ci_mask;
830+ if (!s->eqcr.available) {
831+ eqcr_ci = s->eqcr.ci;
832+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
833+ s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
834+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
835+ eqcr_ci, s->eqcr.ci);
836+ if (!s->eqcr.available)
837+ return 0;
838+ }
839+
840+ eqcr_pi = s->eqcr.pi;
841+ num_enqueued = (s->eqcr.available < num_frames) ?
842+ s->eqcr.available : num_frames;
843+ s->eqcr.available -= num_enqueued;
844+ /* Fill in the EQCR ring */
845+ for (i = 0; i < num_enqueued; i++) {
846+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
847+ cl = (uint32_t *)(&d[i]);
848+ /* Skip copying the verb */
849+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
850+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
851+ &fd[i], sizeof(*fd));
852+ eqcr_pi++;
853+ }
854+
855+ dma_wmb();
856+
857+ /* Set the verb byte, have to substitute in the valid-bit */
858+ eqcr_pi = s->eqcr.pi;
859+ for (i = 0; i < num_enqueued; i++) {
860+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
861+ cl = (uint32_t *)(&d[i]);
862+ p[0] = cl[0] | s->eqcr.pi_vb;
863+ eqcr_pi++;
864+ if (!(eqcr_pi & half_mask))
865+ s->eqcr.pi_vb ^= QB_VALID_BIT;
866+ }
867+
868+ /* Flush all the cacheline without load/store in between */
869+ eqcr_pi = s->eqcr.pi;
870+ addr_cena = (uint64_t)s->addr_cena;
871+ for (i = 0; i < num_enqueued; i++)
872+ eqcr_pi++;
873+ s->eqcr.pi = eqcr_pi & full_mask;
874+
875+ return num_enqueued;
876+}
877+
878+/**
879+ * qbman_swp_enqueue_multiple_desc_mem_back() - Issue a multi enqueue command
880+ * using multiple enqueue descriptor
881+ * @s: the software portal used for enqueue
882+ * @d: table of minimal enqueue descriptor
883+ * @fd: table pointer of frame descriptor table to be enqueued
884+ * @num_frames: number of fd to be enqueued
885+ *
886+ * Return the number of fd enqueued, or a negative error number.
887+ */
888+static
889+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
890+ const struct qbman_eq_desc *d,
891+ const struct dpaa2_fd *fd,
892+ int num_frames)
893+{
894+ uint32_t *p;
895+ const uint32_t *cl;
896+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
897+ int i, num_enqueued = 0;
898+
899+ half_mask = (s->eqcr.pi_ci_mask>>1);
900+ full_mask = s->eqcr.pi_ci_mask;
901+ if (!s->eqcr.available) {
902+ eqcr_ci = s->eqcr.ci;
903+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
904+ s->eqcr.ci = __raw_readl(p) & full_mask;
905+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
906+ eqcr_ci, s->eqcr.ci);
907+ if (!s->eqcr.available)
908+ return 0;
909+ }
910+
911+ eqcr_pi = s->eqcr.pi;
912+ num_enqueued = (s->eqcr.available < num_frames) ?
913+ s->eqcr.available : num_frames;
914+ s->eqcr.available -= num_enqueued;
915+ /* Fill in the EQCR ring */
916+ for (i = 0; i < num_enqueued; i++) {
917+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
918+ cl = (uint32_t *)(&d[i]);
919+ /* Skip copying the verb */
920+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
921+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
922+ &fd[i], sizeof(*fd));
923+ eqcr_pi++;
924+ }
925+
926+ /* Set the verb byte, have to substitute in the valid-bit */
927+ eqcr_pi = s->eqcr.pi;
928+ for (i = 0; i < num_enqueued; i++) {
929+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
930+ cl = (uint32_t *)(&d[i]);
931+ p[0] = cl[0] | s->eqcr.pi_vb;
932+ eqcr_pi++;
933+ if (!(eqcr_pi & half_mask))
934+ s->eqcr.pi_vb ^= QB_VALID_BIT;
935+ }
936+
937+ s->eqcr.pi = eqcr_pi & full_mask;
938+
939+ dma_wmb();
940+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI,
941+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
942+
943+ return num_enqueued;
491944 }
492945
493946 /* Static (push) dequeue */
@@ -645,7 +1098,7 @@ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid, · 151 unmodified lines
6451098 }
6461099
6471100 /**
648− * qbman_swp_pull() - Issue the pull dequeue command
1101+ * qbman_swp_pull_direct() - Issue the pull dequeue command
6491102 * @s: the software portal object
6501103 * @d: the software portal descriptor which has been configured with
6511104 * the set of qbman_pull_desc_set_*() calls
@@ -653,7 +1106,8 @@ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid, · 1 unmodified line
6531106 * Return 0 for success, and -EBUSY if the software portal is not ready
6541107 * to do pull dequeue.
6551108 */
656−int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
1109+static
1110+int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d)
6571111 {
6581112 struct qbman_pull_desc *p;
6591113
@@ -671,18 +1125,48 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) · 11 unmodified lines
6711125 p->dq_src = d->dq_src;
6721126 p->rsp_addr = d->rsp_addr;
6731127 p->rsp_addr_virt = d->rsp_addr_virt;
1128+ dma_wmb();
1129+ /* Set the verb byte, have to substitute in the valid-bit */
1130+ p->verb = d->verb | s->vdq.valid_bit;
1131+ s->vdq.valid_bit ^= QB_VALID_BIT;
6741132
675− if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
676− dma_wmb();
677− /* Set the verb byte, have to substitute in the valid-bit */
678− p->verb = d->verb | s->vdq.valid_bit;
679− s->vdq.valid_bit ^= QB_VALID_BIT;
680− } else {
681− p->verb = d->verb | s->vdq.valid_bit;
682− s->vdq.valid_bit ^= QB_VALID_BIT;
683− dma_wmb();
684− qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
1133+ return 0;
1134+}
1135+
1136+/**
1137+ * qbman_swp_pull_mem_back() - Issue the pull dequeue command
1138+ * @s: the software portal object
1139+ * @d: the software portal descriptor which has been configured with
1140+ * the set of qbman_pull_desc_set_*() calls
1141+ *
1142+ * Return 0 for success, and -EBUSY if the software portal is not ready
1143+ * to do pull dequeue.
1144+ */
1145+static
1146+int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d)
1147+{
1148+ struct qbman_pull_desc *p;
1149+
1150+ if (!atomic_dec_and_test(&s->vdq.available)) {
1151+ atomic_inc(&s->vdq.available);
1152+ return -EBUSY;
6851153 }
1154+ s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt;
1155+ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
1156+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
1157+ else
1158+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM);
1159+ p->numf = d->numf;
1160+ p->tok = QMAN_DQ_TOKEN_VALID;
1161+ p->dq_src = d->dq_src;
1162+ p->rsp_addr = d->rsp_addr;
1163+ p->rsp_addr_virt = d->rsp_addr_virt;
1164+
1165+ /* Set the verb byte, have to substitute in the valid-bit */
1166+ p->verb = d->verb | s->vdq.valid_bit;
1167+ s->vdq.valid_bit ^= QB_VALID_BIT;
1168+ dma_wmb();
1169+ qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
6861170
6871171 return 0;
6881172 }
@@ -690,14 +1174,14 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) · 1 unmodified line
6901174 #define QMAN_DQRR_PI_MASK 0xf
6911175
6921176 /**
693− * qbman_swp_dqrr_next() - Get an valid DQRR entry
1177+ * qbman_swp_dqrr_next_direct() - Get an valid DQRR entry
6941178 * @s: the software portal object
6951179 *
6961180 * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
6971181 * only once, so repeated calls can return a sequence of DQRR entries, without
6981182 * requiring they be consumed immediately or in any particular order.
6991183 */
700−const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
1184+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s)
7011185 {
7021186 u32 verb;
7031187 u32 response_verb;
@@ -740,10 +1224,99 @@ const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) · 36 unmodified lines
7401224 QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
7411225 }
7421226
743− if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
744− p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
745− else
746− p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
1227+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
1228+ verb = p->dq.verb;
1229+
1230+ /*
1231+ * If the valid-bit isn't of the expected polarity, nothing there. Note,
1232+ * in the DQRR reset bug workaround, we shouldn't need to skip these
1233+ * check, because we've already determined that a new entry is available
1234+ * and we've invalidated the cacheline before reading it, so the
1235+ * valid-bit behaviour is repaired and should tell us what we already
1236+ * knew from reading PI.
1237+ */
1238+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
1239+ prefetch(qbman_get_cmd(s,
1240+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
1241+ return NULL;
1242+ }
1243+ /*
1244+ * There's something there. Move "next_idx" attention to the next ring
1245+ * entry (and prefetch it) before returning what we found.
1246+ */
1247+ s->dqrr.next_idx++;
1248+ s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
1249+ if (!s->dqrr.next_idx)
1250+ s->dqrr.valid_bit ^= QB_VALID_BIT;
1251+
1252+ /*
1253+ * If this is the final response to a volatile dequeue command
1254+ * indicate that the vdq is available
1255+ */
1256+ flags = p->dq.stat;
1257+ response_verb = verb & QBMAN_RESULT_MASK;
1258+ if ((response_verb == QBMAN_RESULT_DQ) &&
1259+ (flags & DPAA2_DQ_STAT_VOLATILE) &&
1260+ (flags & DPAA2_DQ_STAT_EXPIRED))
1261+ atomic_inc(&s->vdq.available);
1262+
1263+ prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
1264+
1265+ return p;
1266+}
1267+
1268+/**
1269+ * qbman_swp_dqrr_next_mem_back() - Get an valid DQRR entry
1270+ * @s: the software portal object
1271+ *
1272+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
1273+ * only once, so repeated calls can return a sequence of DQRR entries, without
1274+ * requiring they be consumed immediately or in any particular order.
1275+ */
1276+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s)
1277+{
1278+ u32 verb;
1279+ u32 response_verb;
1280+ u32 flags;
1281+ struct dpaa2_dq *p;
1282+
1283+ /* Before using valid-bit to detect if something is there, we have to
1284+ * handle the case of the DQRR reset bug...
1285+ */
1286+ if (unlikely(s->dqrr.reset_bug)) {
1287+ /*
1288+ * We pick up new entries by cache-inhibited producer index,
1289+ * which means that a non-coherent mapping would require us to
1290+ * invalidate and read *only* once that PI has indicated that
1291+ * there's an entry here. The first trip around the DQRR ring
1292+ * will be much less efficient than all subsequent trips around
1293+ * it...
1294+ */
1295+ u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) &
1296+ QMAN_DQRR_PI_MASK;
1297+
1298+ /* there are new entries if pi != next_idx */
1299+ if (pi == s->dqrr.next_idx)
1300+ return NULL;
1301+
1302+ /*
1303+ * if next_idx is/was the last ring index, and 'pi' is
1304+ * different, we can disable the workaround as all the ring
1305+ * entries have now been DMA'd to so valid-bit checking is
1306+ * repaired. Note: this logic needs to be based on next_idx
1307+ * (which increments one at a time), rather than on pi (which
1308+ * can burst and wrap-around between our snapshots of it).
1309+ */
1310+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
1311+ pr_debug("next_idx=%d, pi=%d, clear reset bug\n",
1312+ s->dqrr.next_idx, pi);
1313+ s->dqrr.reset_bug = 0;
1314+ }
1315+ prefetch(qbman_get_cmd(s,
1316+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
1317+ }
1318+
1319+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
7471320 verb = p->dq.verb;
7481321
7491322 /*
@@ -872,7 +1445,7 @@ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable) · 122 unmodified lines
8721445 #define RAR_SUCCESS(rar) ((rar) & 0x100)
8731446
8741447 /**
875− * qbman_swp_release() - Issue a buffer release command
1448+ * qbman_swp_release_direct() - Issue a buffer release command
8761449 * @s: the software portal object
8771450 * @d: the release descriptor
8781451 * @buffers: a pointer pointing to the buffer address to be released
@@ -880,8 +1453,9 @@ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable) · 1 unmodified line
8801453 *
8811454 * Return 0 for success, -EBUSY if the release command ring is not ready.
8821455 */
883−int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
884− const u64 *buffers, unsigned int num_buffers)
1456+int qbman_swp_release_direct(struct qbman_swp *s,
1457+ const struct qbman_release_desc *d,
1458+ const u64 *buffers, unsigned int num_buffers)
8851459 {
8861460 int i;
8871461 struct qbman_release_desc *p;
@@ -895,28 +1469,59 @@ int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, · 7 unmodified lines
8951469 return -EBUSY;
8961470
8971471 /* Start the release command */
898− if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
899− p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
900− else
901− p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
1472+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
1473+
9021474 /* Copy the caller's buffer pointers to the command */
9031475 for (i = 0; i < num_buffers; i++)
9041476 p->buf[i] = cpu_to_le64(buffers[i]);
9051477 p->bpid = d->bpid;
9061478
907− if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
908− /*
909− * Set the verb byte, have to substitute in the valid-bit
910− * and the number of buffers.
911− */
912− dma_wmb();
913− p->verb = d->verb | RAR_VB(rar) | num_buffers;
914− } else {
915− p->verb = d->verb | RAR_VB(rar) | num_buffers;
916− dma_wmb();
917− qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT +
918− RAR_IDX(rar) * 4, QMAN_RT_MODE);
919− }
1479+ /*
1480+ * Set the verb byte, have to substitute in the valid-bit
1481+ * and the number of buffers.
1482+ */
1483+ dma_wmb();
1484+ p->verb = d->verb | RAR_VB(rar) | num_buffers;
1485+
1486+ return 0;
1487+}
1488+
1489+/**
1490+ * qbman_swp_release_mem_back() - Issue a buffer release command
1491+ * @s: the software portal object
1492+ * @d: the release descriptor
1493+ * @buffers: a pointer pointing to the buffer address to be released
1494+ * @num_buffers: number of buffers to be released, must be less than 8
1495+ *
1496+ * Return 0 for success, -EBUSY if the release command ring is not ready.
1497+ */
1498+int qbman_swp_release_mem_back(struct qbman_swp *s,
1499+ const struct qbman_release_desc *d,
1500+ const u64 *buffers, unsigned int num_buffers)
1501+{
1502+ int i;
1503+ struct qbman_release_desc *p;
1504+ u32 rar;
1505+
1506+ if (!num_buffers || (num_buffers > 7))
1507+ return -EINVAL;
1508+
1509+ rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR);
1510+ if (!RAR_SUCCESS(rar))
1511+ return -EBUSY;
1512+
1513+ /* Start the release command */
1514+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
1515+
1516+ /* Copy the caller's buffer pointers to the command */
1517+ for (i = 0; i < num_buffers; i++)
1518+ p->buf[i] = cpu_to_le64(buffers[i]);
1519+ p->bpid = d->bpid;
1520+
1521+ p->verb = d->verb | RAR_VB(rar) | num_buffers;
1522+ dma_wmb();
1523+ qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT +
1524+ RAR_IDX(rar) * 4, QMAN_RT_MODE);
9201525
9211526 return 0;
9221527 }
drivers/soc/fsl/dpio/qbman-portal.h+151−7
@@ -9,6 +9,13 @@ · 8 unmodified lines
99
1010 #include <soc/fsl/dpaa2-fd.h>
1111
12+#define QMAN_REV_4000 0x04000000
13+#define QMAN_REV_4100 0x04010000
14+#define QMAN_REV_4101 0x04010001
15+#define QMAN_REV_5000 0x05000000
16+
17+#define QMAN_REV_MASK 0xffff0000
18+
1219 struct dpaa2_dq;
1320 struct qbman_swp;
1421
@@ -81,6 +88,10 @@ struct qbman_eq_desc { · 66 unmodified lines
8188 u8 wae;
8289 u8 rspid;
8390 __le64 rsp_addr;
91+};
92+
93+struct qbman_eq_desc_with_fd {
94+ struct qbman_eq_desc desc;
8495 u8 fd[32];
8596 };
8697
@@ -132,8 +143,48 @@ struct qbman_swp { · 45 unmodified lines
132143 u8 dqrr_size;
133144 int reset_bug; /* indicates dqrr reset workaround is needed */
134145 } dqrr;
146+
147+ struct {
148+ u32 pi;
149+ u32 pi_vb;
150+ u32 pi_ring_size;
151+ u32 pi_ci_mask;
152+ u32 ci;
153+ int available;
154+ u32 pend;
155+ u32 no_pfdr;
156+ } eqcr;
157+
158+ spinlock_t access_spinlock;
135159 };
136160
161+/* Function pointers */
162+extern
163+int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s,
164+ const struct qbman_eq_desc *d,
165+ const struct dpaa2_fd *fd);
166+extern
167+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
168+ const struct qbman_eq_desc *d,
169+ const struct dpaa2_fd *fd,
170+ uint32_t *flags,
171+ int num_frames);
172+extern
173+int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
174+ const struct qbman_eq_desc *d,
175+ const struct dpaa2_fd *fd,
176+ int num_frames);
177+extern
178+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d);
179+extern
180+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s);
181+extern
182+int (*qbman_swp_release_ptr)(struct qbman_swp *s,
183+ const struct qbman_release_desc *d,
184+ const u64 *buffers,
185+ unsigned int num_buffers);
186+
187+/* Functions */
137188 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
138189 void qbman_swp_finish(struct qbman_swp *p);
139190 u32 qbman_swp_interrupt_read_status(struct qbman_swp *p);
@@ -158,9 +209,6 @@ void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid, · 18 unmodified lines
158209 void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
159210 enum qbman_pull_type_e dct);
160211
161−int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d);
162−
163−const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
164212 void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
165213
166214 int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq);
@@ -172,15 +220,11 @@ void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid); · 5 unmodified lines
172220 void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
173221 u32 qd_bin, u32 qd_prio);
174222
175−int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
176− const struct dpaa2_fd *fd);
177223
178224 void qbman_release_desc_clear(struct qbman_release_desc *d);
179225 void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
180226 void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
181227
182−int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
183− const u64 *buffers, unsigned int num_buffers);
184228 int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
185229 unsigned int num_buffers);
186230 int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
@@ -193,6 +237,61 @@ void *qbman_swp_mc_start(struct qbman_swp *p); · 6 unmodified lines
193237 void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
194238 void *qbman_swp_mc_result(struct qbman_swp *p);
195239
240+/**
241+ * qbman_swp_enqueue() - Issue an enqueue command
242+ * @s: the software portal used for enqueue
243+ * @d: the enqueue descriptor
244+ * @fd: the frame descriptor to be enqueued
245+ *
246+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
247+ */
248+static inline int
249+qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
250+ const struct dpaa2_fd *fd)
251+{
252+ return qbman_swp_enqueue_ptr(s, d, fd);
253+}
254+
255+/**
256+ * qbman_swp_enqueue_multiple() - Issue a multi enqueue command
257+ * using one enqueue descriptor
258+ * @s: the software portal used for enqueue
259+ * @d: the enqueue descriptor
260+ * @fd: table pointer of frame descriptor table to be enqueued
261+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
262+ * @num_frames: number of fd to be enqueued
263+ *
264+ * Return the number of fd enqueued, or a negative error number.
265+ */
266+static inline int
267+qbman_swp_enqueue_multiple(struct qbman_swp *s,
268+ const struct qbman_eq_desc *d,
269+ const struct dpaa2_fd *fd,
270+ uint32_t *flags,
271+ int num_frames)
272+{
273+ return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames);
274+}
275+
276+/**
277+ * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command
278+ * using multiple enqueue descriptor
279+ * @s: the software portal used for enqueue
280+ * @d: table of minimal enqueue descriptor
281+ * @fd: table pointer of frame descriptor table to be enqueued
282+ * @num_frames: number of fd to be enqueued
283+ *
284+ * Return the number of fd enqueued, or a negative error number.
285+ */
286+static inline int
287+qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
288+ const struct qbman_eq_desc *d,
289+ const struct dpaa2_fd *fd,
290+ int num_frames)
291+{
292+ return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, num_frames);
293+}
294+
196295 /**
197296 * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
198297 * @dq: the dequeue result to be checked
@@ -504,4 +603,49 @@ int qbman_bp_query(struct qbman_swp *s, u16 bpid, · 305 unmodified lines
504603
505604 u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a);
506605
606+/**
607+ * qbman_swp_release() - Issue a buffer release command
608+ * @s: the software portal object
609+ * @d: the release descriptor
610+ * @buffers: a pointer pointing to the buffer address to be released
611+ * @num_buffers: number of buffers to be released, must be less than 8
612+ *
613+ * Return 0 for success, -EBUSY if the release command ring is not ready.
614+ */
615+static inline int qbman_swp_release(struct qbman_swp *s,
616+ const struct qbman_release_desc *d,
617+ const u64 *buffers,
618+ unsigned int num_buffers)
619+{
620+ return qbman_swp_release_ptr(s, d, buffers, num_buffers);
621+}
622+
623+/**
624+ * qbman_swp_pull() - Issue the pull dequeue command
625+ * @s: the software portal object
626+ * @d: the software portal descriptor which has been configured with
627+ * the set of qbman_pull_desc_set_*() calls
628+ *
629+ * Return 0 for success, and -EBUSY if the software portal is not ready
630+ * to do pull dequeue.
631+ */
632+static inline int qbman_swp_pull(struct qbman_swp *s,
633+ struct qbman_pull_desc *d)
634+{
635+ return qbman_swp_pull_ptr(s, d);
636+}
637+
638+/**
639+ * qbman_swp_dqrr_next() - Get an valid DQRR entry
640+ * @s: the software portal object
641+ *
642+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
643+ * only once, so repeated calls can return a sequence of DQRR entries, without
644+ * requiring they be consumed immediately or in any particular order.
645+ */
646+static inline const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
647+{
648+ return qbman_swp_dqrr_next_ptr(s);
649+}
650+
507651 #endif /* __FSL_QBMAN_PORTAL_H */
drivers/soc/fsl/qe/qe.c+2−2
@@ -423,7 +423,7 @@ static void qe_upload_microcode(const void *base, · 422 unmodified lines
423423 qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
424424
425425 /* Set I-RAM Ready Register */
426− qe_iowrite32be(be32_to_cpu(QE_IRAM_READY), &qe_immr->iram.iready);
426+ qe_iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready);
427427 }
428428
429429 /*
@@ -525,7 +525,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) · 95 unmodified lines
525525 */
526526 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
527527 strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
528− qe_firmware_info.extended_modes = firmware->extended_modes;
528+ qe_firmware_info.extended_modes = be64_to_cpu(firmware->extended_modes);
529529 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
530530 sizeof(firmware->vtraps));
531531
drivers/soc/fsl/qe/qe_common.c+1−1
@@ -46,7 +46,7 @@ int cpm_muram_init(void) · 45 unmodified lines
4646 {
4747 struct device_node *np;
4848 struct resource r;
49− u32 zero[OF_MAX_ADDR_CELLS] = {};
49+ __be32 zero[OF_MAX_ADDR_CELLS] = {};
5050 resource_size_t max = 0;
5151 int i = 0;
5252 int ret = 0;
drivers/soc/fsl/qe/qe_ic.c+1−1
@@ -44,7 +44,7 @@ · 43 unmodified lines
4444
4545 struct qe_ic {
4646 /* Control registers offset */
47− u32 __iomem *regs;
47+ __be32 __iomem *regs;
4848
4949 /* The remapper for this QEIC */
5050 struct irq_domain *irqhost;
drivers/soc/fsl/qe/ucc.c+1−1
@@ -632,7 +632,7 @@ int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock, · 631 unmodified lines
632632 {
633633 int source;
634634 u32 shift;
635− struct qe_mux *qe_mux_reg;
635+ struct qe_mux __iomem *qe_mux_reg;
636636
637637 qe_mux_reg = &qe_immr->qmx;
638638
drivers/soc/fsl/qe/ucc_slow.c+13−20
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(ucc_slow_restart_tx); · 71 unmodified lines
7272
7373 void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
7474 {
75− struct ucc_slow *us_regs;
75+ struct ucc_slow __iomem *us_regs;
7676 u32 gumr_l;
7777
7878 us_regs = uccs->us_regs;
@@ -93,7 +93,7 @@ EXPORT_SYMBOL(ucc_slow_enable); · 14 unmodified lines
9393
9494 void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
9595 {
96− struct ucc_slow *us_regs;
96+ struct ucc_slow __iomem *us_regs;
9797 u32 gumr_l;
9898
9999 us_regs = uccs->us_regs;
@@ -122,7 +122,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc · 22 unmodified lines
122122 u32 i;
123123 struct ucc_slow __iomem *us_regs;
124124 u32 gumr;
125− struct qe_bd *bd;
125+ struct qe_bd __iomem *bd;
126126 u32 id;
127127 u32 command;
128128 int ret = 0;
@@ -168,16 +168,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc · 39 unmodified lines
168168 return -ENOMEM;
169169 }
170170
171− uccs->saved_uccm = 0;
172− uccs->p_rx_frame = 0;
173171 us_regs = uccs->us_regs;
174− uccs->p_ucce = (u16 *) & (us_regs->ucce);
175− uccs->p_uccm = (u16 *) & (us_regs->uccm);
176−#ifdef STATISTICS
177− uccs->rx_frames = 0;
178− uccs->tx_frames = 0;
179− uccs->rx_discarded = 0;
180−#endif /* STATISTICS */
172+ uccs->p_ucce = &us_regs->ucce;
173+ uccs->p_uccm = &us_regs->uccm;
181174
182175 /* Get PRAM base */
183176 uccs->us_pram_offset =
@@ -231,24 +224,24 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc · 47 unmodified lines
231224 /* clear bd buffer */
232225 qe_iowrite32be(0, &bd->buf);
233226 /* set bd status and length */
234− qe_iowrite32be(0, (u32 *)bd);
227+ qe_iowrite32be(0, (u32 __iomem *)bd);
235228 bd++;
236229 }
237230 /* for last BD set Wrap bit */
238231 qe_iowrite32be(0, &bd->buf);
239− qe_iowrite32be(cpu_to_be32(T_W), (u32 *)bd);
232+ qe_iowrite32be(T_W, (u32 __iomem *)bd);
240233
241234 /* Init Rx bds */
242235 bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
243236 for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
244237 /* set bd status and length */
245− qe_iowrite32be(0, (u32 *)bd);
238+ qe_iowrite32be(0, (u32 __iomem *)bd);
246239 /* clear bd buffer */
247240 qe_iowrite32be(0, &bd->buf);
248241 bd++;
249242 }
250243 /* for last BD set Wrap bit */
251− qe_iowrite32be(cpu_to_be32(R_W), (u32 *)bd);
244+ qe_iowrite32be(R_W, (u32 __iomem *)bd);
252245 qe_iowrite32be(0, &bd->buf);
253246
254247 /* Set GUMR (For more details see the hardware spec.). */
@@ -273,8 +266,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc · 18 unmodified lines
273266 qe_iowrite32be(gumr, &us_regs->gumr_h);
274267
275268 /* gumr_l */
276− gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
277− us_info->diag | us_info->mode;
269+ gumr = (u32)us_info->tdcr | (u32)us_info->rdcr | (u32)us_info->tenc |
270+ (u32)us_info->renc | (u32)us_info->diag | (u32)us_info->mode;
278271 if (us_info->tci)
279272 gumr |= UCC_SLOW_GUMR_L_TCI;
280273 if (us_info->rinv)
@@ -289,8 +282,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc · 8 unmodified lines
289282
290283 /* if the data is in cachable memory, the 'global' */
291284 /* in the function code should be set. */
292− uccs->us_pram->tbmr = UCC_BMR_BO_BE;
293− uccs->us_pram->rbmr = UCC_BMR_BO_BE;
285+ qe_iowrite8(UCC_BMR_BO_BE, &uccs->us_pram->tbmr);
286+ qe_iowrite8(UCC_BMR_BO_BE, &uccs->us_pram->rbmr);
294287
295288 /* rbase, tbase are offsets from MURAM base */
296289 qe_iowrite16be(uccs->rx_base_offset, &uccs->us_pram->rbase);
drivers/soc/imx/Kconfig+10−1
@@ -10,11 +10,20 @@ config IMX_GPCV2_PM_DOMAINS · 9 unmodified lines
1010
1111 config IMX_SCU_SOC
1212 bool "i.MX System Controller Unit SoC info support"
13− depends on IMX_SCU || COMPILE_TEST
13+ depends on IMX_SCU
1414 select SOC_BUS
1515 help
1616 If you say yes here you get support for the NXP i.MX System
1717 Controller Unit SoC info module, it will provide the SoC info
1818 like SoC family, ID and revision etc.
1919
20+config SOC_IMX8M
21+ bool "i.MX8M SoC family support"
22+ depends on ARCH_MXC || COMPILE_TEST
23+ default ARCH_MXC && ARM64
24+ help
25+ If you say yes here you get support for the NXP i.MX8M family
26+ support, it will provide the SoC info like SoC family,
27+ ID and revision etc.
28+
2029 endmenu
drivers/soc/imx/Makefile+1−1
@@ -1,5 +1,5 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
33 obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
4−obj-$(CONFIG_ARCH_MXC) += soc-imx8.o
4+obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
55 obj-$(CONFIG_IMX_SCU_SOC) += soc-imx-scu.o
drivers/soc/imx/gpc.c+13−11
@@ -87,8 +87,8 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd) · 86 unmodified lines
8787 static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
8888 {
8989 struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
90− int i, ret, sw, sw2iso;
91− u32 val;
90+ int i, ret;
91+ u32 val, req;
9292
9393 if (pd->supply) {
9494 ret = regulator_enable(pd->supply);
@@ -107,17 +107,18 @@ static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd) · 12 unmodified lines
107107 regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS,
108108 0x1, 0x1);
109109
110− /* Read ISO and ISO2SW power up delays */
111− regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
112− sw = val & 0x3f;
113− sw2iso = (val >> 8) & 0x3f;
114−
115110 /* Request GPC to power up domain */
116− val = BIT(pd->cntr_pdn_bit + 1);
117− regmap_update_bits(pd->regmap, GPC_CNTR, val, val);
111+ req = BIT(pd->cntr_pdn_bit + 1);
112+ regmap_update_bits(pd->regmap, GPC_CNTR, req, req);
118113
119− /* Wait ISO + ISO2SW IPG clock cycles */
120− udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz));
114+ /* Wait for the PGC to handle the request */
115+ ret = regmap_read_poll_timeout(pd->regmap, GPC_CNTR, val, !(val & req),
116+ 1, 50);
117+ if (ret)
118+ pr_err("powerup request on domain %s timed out\n", genpd->name);
119+
120+ /* Wait for reset to propagate through peripherals */
121+ usleep_range(5, 10);
121122
122123 /* Disable reset clocks for all devices in the domain */
123124 for (i = 0; i < pd->num_clks; i++)
@@ -343,6 +344,7 @@ static const struct regmap_config imx_gpc_regmap_config = { · 219 unmodified lines
343344 .rd_table = &access_table,
344345 .wr_table = &access_table,
345346 .max_register = 0x2ac,
347+ .fast_io = true,
346348 };
347349
348350 static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
drivers/soc/imx/gpcv2.c+1−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/pm_domain.h>
1515 #include <linux/regmap.h>
1616 #include <linux/regulator/consumer.h>
17+#include <linux/sizes.h>
1718 #include <dt-bindings/power/imx7-power.h>
1819 #include <dt-bindings/power/imx8mq-power.h>
1920
drivers/soc/imx/soc-imx8m.crenamed from drivers/soc/imx/soc-imx8.c+0−0

File renamed without changes.

drivers/soc/qcom/Kconfig+6−1
@@ -76,6 +76,10 @@ config QCOM_OCMEM · 75 unmodified lines
7676 requirements. This is typically used by the GPU, camera/video, and
7777 audio components on some Snapdragon SoCs.
7878
79+config QCOM_PDR_HELPERS
80+ tristate
81+ select QCOM_QMI_HELPERS
82+
7983 config QCOM_PM
8084 bool "Qualcomm Power Management"
8185 depends on ARCH_QCOM && !ARM64
@@ -88,7 +92,6 @@ config QCOM_PM · 6 unmodified lines
8892
8993 config QCOM_QMI_HELPERS
9094 tristate
91− depends on ARCH_QCOM || COMPILE_TEST
9295 depends on NET
9396
9497 config QCOM_RMTFS_MEM
@@ -197,6 +200,8 @@ config QCOM_APR · 102 unmodified lines
197200 tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
198201 depends on ARCH_QCOM || COMPILE_TEST
199202 depends on RPMSG
203+ depends on NET
204+ select QCOM_PDR_HELPERS
200205 help
201206 Enable APR IPC protocol support between
202207 application processor and QDSP6. APR is
drivers/soc/qcom/Makefile+1−0
@@ -7,6 +7,7 @@ obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o · 6 unmodified lines
77 obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
88 obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
99 obj-$(CONFIG_QCOM_OCMEM) += ocmem.o
10+obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o
1011 obj-$(CONFIG_QCOM_PM) += spm.o
1112 obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
1213 qmi_helpers-y += qmi_encdec.o qmi_interface.o
drivers/soc/qcom/apr.c+114−9
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/workqueue.h>
1212 #include <linux/of_device.h>
1313 #include <linux/soc/qcom/apr.h>
14+#include <linux/soc/qcom/pdr.h>
1415 #include <linux/rpmsg.h>
1516 #include <linux/of.h>
1617
@@ -21,6 +22,7 @@ struct apr { · 4 unmodified lines
2122 spinlock_t rx_lock;
2223 struct idr svcs_idr;
2324 int dest_domain_id;
25+ struct pdr_handle *pdr;
2426 struct workqueue_struct *rxwq;
2527 struct work_struct rx_work;
2628 struct list_head rx_list;
@@ -289,6 +291,9 @@ static int apr_add_device(struct device *dev, struct device_node *np, · 262 unmodified lines
289291 id->svc_id + 1, GFP_ATOMIC);
290292 spin_unlock(&apr->svcs_lock);
291293
294+ of_property_read_string_index(np, "qcom,protection-domain",
295+ 1, &adev->service_path);
296+
292297 dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
293298
294299 ret = device_register(&adev->dev);
@@ -300,14 +305,75 @@ static int apr_add_device(struct device *dev, struct device_node *np, · 5 unmodified lines
300305 return ret;
301306 }
302307
303−static void of_register_apr_devices(struct device *dev)
308+static int of_apr_add_pd_lookups(struct device *dev)
309+{
310+ const char *service_name, *service_path;
311+ struct apr *apr = dev_get_drvdata(dev);
312+ struct device_node *node;
313+ struct pdr_service *pds;
314+ int ret;
315+
316+ for_each_child_of_node(dev->of_node, node) {
317+ ret = of_property_read_string_index(node, "qcom,protection-domain",
318+ 0, &service_name);
319+ if (ret < 0)
320+ continue;
321+
322+ ret = of_property_read_string_index(node, "qcom,protection-domain",
323+ 1, &service_path);
324+ if (ret < 0) {
325+ dev_err(dev, "pdr service path missing: %d\n", ret);
326+ return ret;
327+ }
328+
329+ pds = pdr_add_lookup(apr->pdr, service_name, service_path);
330+ if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
331+ dev_err(dev, "pdr add lookup failed: %d\n", ret);
332+ return PTR_ERR(pds);
333+ }
334+ }
335+
336+ return 0;
337+}
338+
339+static void of_register_apr_devices(struct device *dev, const char *svc_path)
304340 {
305341 struct apr *apr = dev_get_drvdata(dev);
306342 struct device_node *node;
343+ const char *service_path;
344+ int ret;
307345
308346 for_each_child_of_node(dev->of_node, node) {
309347 struct apr_device_id id = { {0} };
310348
349+ /*
350+ * This function is called with svc_path NULL during
351+ * apr_probe(), in which case we register any apr devices
352+ * without a qcom,protection-domain specified.
353+ *
354+ * Then as the protection domains becomes available
355+ * (if applicable) this function is again called, but with
356+ * svc_path representing the service becoming available. In
357+ * this case we register any apr devices with a matching
358+ * qcom,protection-domain.
359+ */
360+
361+ ret = of_property_read_string_index(node, "qcom,protection-domain",
362+ 1, &service_path);
363+ if (svc_path) {
364+ /* skip APR services that are PD independent */
365+ if (ret)
366+ continue;
367+
368+ /* skip APR services whose PD paths don't match */
369+ if (strcmp(service_path, svc_path))
370+ continue;
371+ } else {
372+ /* skip APR services whose PD lookups are registered */
373+ if (ret == 0)
374+ continue;
375+ }
376+
311377 if (of_property_read_u32(node, "reg", &id.svc_id))
312378 continue;
313379
@@ -318,6 +384,34 @@ static void of_register_apr_devices(struct device *dev) · 4 unmodified lines
318384 }
319385 }
320386
387+static int apr_remove_device(struct device *dev, void *svc_path)
388+{
389+ struct apr_device *adev = to_apr_device(dev);
390+
391+ if (svc_path && adev->service_path) {
392+ if (!strcmp(adev->service_path, (char *)svc_path))
393+ device_unregister(&adev->dev);
394+ } else {
395+ device_unregister(&adev->dev);
396+ }
397+
398+ return 0;
399+}
400+
401+static void apr_pd_status(int state, char *svc_path, void *priv)
402+{
403+ struct apr *apr = (struct apr *)priv;
404+
405+ switch (state) {
406+ case SERVREG_SERVICE_STATE_UP:
407+ of_register_apr_devices(apr->dev, svc_path);
408+ break;
409+ case SERVREG_SERVICE_STATE_DOWN:
410+ device_for_each_child(apr->dev, svc_path, apr_remove_device);
411+ break;
412+ }
413+}
414+
321415 static int apr_probe(struct rpmsg_device *rpdev)
322416 {
323417 struct device *dev = &rpdev->dev;
@@ -343,28 +437,39 @@ static int apr_probe(struct rpmsg_device *rpdev) · 19 unmodified lines
343437 return -ENOMEM;
344438 }
345439 INIT_WORK(&apr->rx_work, apr_rxwq);
440+
441+ apr->pdr = pdr_handle_alloc(apr_pd_status, apr);
442+ if (IS_ERR(apr->pdr)) {
443+ dev_err(dev, "Failed to init PDR handle\n");
444+ ret = PTR_ERR(apr->pdr);
445+ goto destroy_wq;
446+ }
447+
346448 INIT_LIST_HEAD(&apr->rx_list);
347449 spin_lock_init(&apr->rx_lock);
348450 spin_lock_init(&apr->svcs_lock);
349451 idr_init(&apr->svcs_idr);
350− of_register_apr_devices(dev);
351−
352− return 0;
353−}
354452
355−static int apr_remove_device(struct device *dev, void *null)
356−{
357− struct apr_device *adev = to_apr_device(dev);
453+ ret = of_apr_add_pd_lookups(dev);
454+ if (ret)
455+ goto handle_release;
358456
359− device_unregister(&adev->dev);
457+ of_register_apr_devices(dev, NULL);
360458
361459 return 0;
460+
461+handle_release:
462+ pdr_handle_release(apr->pdr);
463+destroy_wq:
464+ destroy_workqueue(apr->rxwq);
465+ return ret;
362466 }
363467
364468 static void apr_remove(struct rpmsg_device *rpdev)
365469 {
366470 struct apr *apr = dev_get_drvdata(&rpdev->dev);
367471
472+ pdr_handle_release(apr->pdr);
368473 device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
369474 flush_workqueue(apr->rxwq);
370475 destroy_workqueue(apr->rxwq);
drivers/soc/qcom/pdr_interface.c+757−0
@@ -0,0 +1,757 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2020 The Linux Foundation. All rights reserved.
4+ */
5+
6+#include <linux/kernel.h>
7+#include <linux/module.h>
8+#include <linux/string.h>
9+#include <linux/workqueue.h>
10+
11+#include "pdr_internal.h"
12+
13+struct pdr_service {
14+ char service_name[SERVREG_NAME_LENGTH + 1];
15+ char service_path[SERVREG_NAME_LENGTH + 1];
16+
17+ struct sockaddr_qrtr addr;
18+
19+ unsigned int instance;
20+ unsigned int service;
21+ u8 service_data_valid;
22+ u32 service_data;
23+ int state;
24+
25+ bool need_notifier_register;
26+ bool need_notifier_remove;
27+ bool need_locator_lookup;
28+ bool service_connected;
29+
30+ struct list_head node;
31+};
32+
33+struct pdr_handle {
34+ struct qmi_handle locator_hdl;
35+ struct qmi_handle notifier_hdl;
36+
37+ struct sockaddr_qrtr locator_addr;
38+
39+ struct list_head lookups;
40+ struct list_head indack_list;
41+
42+ /* control access to pdr lookup/indack lists */
43+ struct mutex list_lock;
44+
45+ /* serialize pd status invocation */
46+ struct mutex status_lock;
47+
48+ /* control access to the locator state */
49+ struct mutex lock;
50+
51+ bool locator_init_complete;
52+
53+ struct work_struct locator_work;
54+ struct work_struct notifier_work;
55+ struct work_struct indack_work;
56+
57+ struct workqueue_struct *notifier_wq;
58+ struct workqueue_struct *indack_wq;
59+
60+ void (*status)(int state, char *service_path, void *priv);
61+ void *priv;
62+};
63+
64+struct pdr_list_node {
65+ enum servreg_service_state curr_state;
66+ u16 transaction_id;
67+ struct pdr_service *pds;
68+ struct list_head node;
69+};
70+
71+static int pdr_locator_new_server(struct qmi_handle *qmi,
72+ struct qmi_service *svc)
73+{
74+ struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
75+ locator_hdl);
76+ struct pdr_service *pds;
77+
78+ /* Create a local client port for QMI communication */
79+ pdr->locator_addr.sq_family = AF_QIPCRTR;
80+ pdr->locator_addr.sq_node = svc->node;
81+ pdr->locator_addr.sq_port = svc->port;
82+
83+ mutex_lock(&pdr->lock);
84+ pdr->locator_init_complete = true;
85+ mutex_unlock(&pdr->lock);
86+
87+ /* Service pending lookup requests */
88+ mutex_lock(&pdr->list_lock);
89+ list_for_each_entry(pds, &pdr->lookups, node) {
90+ if (pds->need_locator_lookup)
91+ schedule_work(&pdr->locator_work);
92+ }
93+ mutex_unlock(&pdr->list_lock);
94+
95+ return 0;
96+}
97+
98+static void pdr_locator_del_server(struct qmi_handle *qmi,
99+ struct qmi_service *svc)
100+{
101+ struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
102+ locator_hdl);
103+
104+ mutex_lock(&pdr->lock);
105+ pdr->locator_init_complete = false;
106+ mutex_unlock(&pdr->lock);
107+
108+ pdr->locator_addr.sq_node = 0;
109+ pdr->locator_addr.sq_port = 0;
110+}
111+
112+static struct qmi_ops pdr_locator_ops = {
113+ .new_server = pdr_locator_new_server,
114+ .del_server = pdr_locator_del_server,
115+};
116+
117+static int pdr_register_listener(struct pdr_handle *pdr,
118+ struct pdr_service *pds,
119+ bool enable)
120+{
121+ struct servreg_register_listener_resp resp;
122+ struct servreg_register_listener_req req;
123+ struct qmi_txn txn;
124+ int ret;
125+
126+ ret = qmi_txn_init(&pdr->notifier_hdl, &txn,
127+ servreg_register_listener_resp_ei,
128+ &resp);
129+ if (ret < 0)
130+ return ret;
131+
132+ req.enable = enable;
133+ strcpy(req.service_path, pds->service_path);
134+
135+ ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
136+ &txn, SERVREG_REGISTER_LISTENER_REQ,
137+ SERVREG_REGISTER_LISTENER_REQ_LEN,
138+ servreg_register_listener_req_ei,
139+ &req);
140+ if (ret < 0) {
141+ qmi_txn_cancel(&txn);
142+ return ret;
143+ }
144+
145+ ret = qmi_txn_wait(&txn, 5 * HZ);
146+ if (ret < 0) {
147+ pr_err("PDR: %s register listener txn wait failed: %d\n",
148+ pds->service_path, ret);
149+ return ret;
150+ }
151+
152+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
153+ pr_err("PDR: %s register listener failed: 0x%x\n",
154+ pds->service_path, resp.resp.error);
155+ return ret;
156+ }
157+
158+ if ((int)resp.curr_state < INT_MIN || (int)resp.curr_state > INT_MAX)
159+ pr_err("PDR: %s notification state invalid: 0x%x\n",
160+ pds->service_path, resp.curr_state);
161+
162+ pds->state = resp.curr_state;
163+
164+ return 0;
165+}
166+
167+static void pdr_notifier_work(struct work_struct *work)
168+{
169+ struct pdr_handle *pdr = container_of(work, struct pdr_handle,
170+ notifier_work);
171+ struct pdr_service *pds;
172+ int ret;
173+
174+ mutex_lock(&pdr->list_lock);
175+ list_for_each_entry(pds, &pdr->lookups, node) {
176+ if (pds->service_connected) {
177+ if (!pds->need_notifier_register)
178+ continue;
179+
180+ pds->need_notifier_register = false;
181+ ret = pdr_register_listener(pdr, pds, true);
182+ if (ret < 0)
183+ pds->state = SERVREG_SERVICE_STATE_DOWN;
184+ } else {
185+ if (!pds->need_notifier_remove)
186+ continue;
187+
188+ pds->need_notifier_remove = false;
189+ pds->state = SERVREG_SERVICE_STATE_DOWN;
190+ }
191+
192+ mutex_lock(&pdr->status_lock);
193+ pdr->status(pds->state, pds->service_path, pdr->priv);
194+ mutex_unlock(&pdr->status_lock);
195+ }
196+ mutex_unlock(&pdr->list_lock);
197+}
198+
199+static int pdr_notifier_new_server(struct qmi_handle *qmi,
200+ struct qmi_service *svc)
201+{
202+ struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
203+ notifier_hdl);
204+ struct pdr_service *pds;
205+
206+ mutex_lock(&pdr->list_lock);
207+ list_for_each_entry(pds, &pdr->lookups, node) {
208+ if (pds->service == svc->service &&
209+ pds->instance == svc->instance) {
210+ pds->service_connected = true;
211+ pds->need_notifier_register = true;
212+ pds->addr.sq_family = AF_QIPCRTR;
213+ pds->addr.sq_node = svc->node;
214+ pds->addr.sq_port = svc->port;
215+ queue_work(pdr->notifier_wq, &pdr->notifier_work);
216+ }
217+ }
218+ mutex_unlock(&pdr->list_lock);
219+
220+ return 0;
221+}
222+
223+static void pdr_notifier_del_server(struct qmi_handle *qmi,
224+ struct qmi_service *svc)
225+{
226+ struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
227+ notifier_hdl);
228+ struct pdr_service *pds;
229+
230+ mutex_lock(&pdr->list_lock);
231+ list_for_each_entry(pds, &pdr->lookups, node) {
232+ if (pds->service == svc->service &&
233+ pds->instance == svc->instance) {
234+ pds->service_connected = false;
235+ pds->need_notifier_remove = true;
236+ pds->addr.sq_node = 0;
237+ pds->addr.sq_port = 0;
238+ queue_work(pdr->notifier_wq, &pdr->notifier_work);
239+ }
240+ }
241+ mutex_unlock(&pdr->list_lock);
242+}
243+
244+static struct qmi_ops pdr_notifier_ops = {
245+ .new_server = pdr_notifier_new_server,
246+ .del_server = pdr_notifier_del_server,
247+};
248+
249+static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
250+ u16 tid)
251+{
252+ struct servreg_set_ack_resp resp;
253+ struct servreg_set_ack_req req;
254+ struct qmi_txn txn;
255+ int ret;
256+
257+ ret = qmi_txn_init(&pdr->notifier_hdl, &txn, servreg_set_ack_resp_ei,
258+ &resp);
259+ if (ret < 0)
260+ return ret;
261+
262+ req.transaction_id = tid;
263+ strcpy(req.service_path, pds->service_path);
264+
265+ ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
266+ &txn, SERVREG_SET_ACK_REQ,
267+ SERVREG_SET_ACK_REQ_LEN,
268+ servreg_set_ack_req_ei,
269+ &req);
270+
271+ /* Skip waiting for response */
272+ qmi_txn_cancel(&txn);
273+ return ret;
274+}
275+
276+static void pdr_indack_work(struct work_struct *work)
277+{
278+ struct pdr_handle *pdr = container_of(work, struct pdr_handle,
279+ indack_work);
280+ struct pdr_list_node *ind, *tmp;
281+ struct pdr_service *pds;
282+
283+ list_for_each_entry_safe(ind, tmp, &pdr->indack_list, node) {
284+ pds = ind->pds;
285+ pdr_send_indack_msg(pdr, pds, ind->transaction_id);
286+
287+ mutex_lock(&pdr->status_lock);
288+ pds->state = ind->curr_state;
289+ pdr->status(pds->state, pds->service_path, pdr->priv);
290+ mutex_unlock(&pdr->status_lock);
291+
292+ mutex_lock(&pdr->list_lock);
293+ list_del(&ind->node);
294+ mutex_unlock(&pdr->list_lock);
295+
296+ kfree(ind);
297+ }
298+}
299+
300+static void pdr_indication_cb(struct qmi_handle *qmi,
301+ struct sockaddr_qrtr *sq,
302+ struct qmi_txn *txn, const void *data)
303+{
304+ struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
305+ notifier_hdl);
306+ const struct servreg_state_updated_ind *ind_msg = data;
307+ struct pdr_list_node *ind;
308+ struct pdr_service *pds;
309+ bool found = false;
310+
311+ if (!ind_msg || !ind_msg->service_path[0] ||
312+ strlen(ind_msg->service_path) > SERVREG_NAME_LENGTH)
313+ return;
314+
315+ mutex_lock(&pdr->list_lock);
316+ list_for_each_entry(pds, &pdr->lookups, node) {
317+ if (strcmp(pds->service_path, ind_msg->service_path))
318+ continue;
319+
320+ found = true;
321+ break;
322+ }
323+ mutex_unlock(&pdr->list_lock);
324+
325+ if (!found)
326+ return;
327+
328+ pr_info("PDR: Indication received from %s, state: 0x%x, trans-id: %d\n",
329+ ind_msg->service_path, ind_msg->curr_state,
330+ ind_msg->transaction_id);
331+
332+ ind = kzalloc(sizeof(*ind), GFP_KERNEL);
333+ if (!ind)
334+ return;
335+
336+ ind->transaction_id = ind_msg->transaction_id;
337+ ind->curr_state = ind_msg->curr_state;
338+ ind->pds = pds;
339+
340+ mutex_lock(&pdr->list_lock);
341+ list_add_tail(&ind->node, &pdr->indack_list);
342+ mutex_unlock(&pdr->list_lock);
343+
344+ queue_work(pdr->indack_wq, &pdr->indack_work);
345+}
346+
347+static struct qmi_msg_handler qmi_indication_handler[] = {
348+ {
349+ .type = QMI_INDICATION,
350+ .msg_id = SERVREG_STATE_UPDATED_IND_ID,
351+ .ei = servreg_state_updated_ind_ei,
352+ .decoded_size = sizeof(struct servreg_state_updated_ind),
353+ .fn = pdr_indication_cb,
354+ },
355+ {}
356+};
357+
358+static int pdr_get_domain_list(struct servreg_get_domain_list_req *req,
359+ struct servreg_get_domain_list_resp *resp,
360+ struct pdr_handle *pdr)
361+{
362+ struct qmi_txn txn;
363+ int ret;
364+
365+ ret = qmi_txn_init(&pdr->locator_hdl, &txn,
366+ servreg_get_domain_list_resp_ei, resp);
367+ if (ret < 0)
368+ return ret;
369+
370+ ret = qmi_send_request(&pdr->locator_hdl,
371+ &pdr->locator_addr,
372+ &txn, SERVREG_GET_DOMAIN_LIST_REQ,
373+ SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN,
374+ servreg_get_domain_list_req_ei,
375+ req);
376+ if (ret < 0) {
377+ qmi_txn_cancel(&txn);
378+ return ret;
379+ }
380+
381+ ret = qmi_txn_wait(&txn, 5 * HZ);
382+ if (ret < 0) {
383+ pr_err("PDR: %s get domain list txn wait failed: %d\n",
384+ req->service_name, ret);
385+ return ret;
386+ }
387+
388+ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
389+ pr_err("PDR: %s get domain list failed: 0x%x\n",
390+ req->service_name, resp->resp.error);
391+ return -EREMOTEIO;
392+ }
393+
394+ return 0;
395+}
396+
397+static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
398+{
399+ struct servreg_get_domain_list_resp *resp;
400+ struct servreg_get_domain_list_req req;
401+ struct servreg_location_entry *entry;
402+ int domains_read = 0;
403+ int ret, i;
404+
405+ resp = kzalloc(sizeof(*resp), GFP_KERNEL);
406+ if (!resp)
407+ return -ENOMEM;
408+
409+ /* Prepare req message */
410+ strcpy(req.service_name, pds->service_name);
411+ req.domain_offset_valid = true;
412+ req.domain_offset = 0;
413+
414+ do {
415+ req.domain_offset = domains_read;
416+ ret = pdr_get_domain_list(&req, resp, pdr);
417+ if (ret < 0)
418+ goto out;
419+
420+ for (i = domains_read; i < resp->domain_list_len; i++) {
421+ entry = &resp->domain_list[i];
422+
423+ if (strnlen(entry->name, sizeof(entry->name)) == sizeof(entry->name))
424+ continue;
425+
426+ if (!strcmp(entry->name, pds->service_path)) {
427+ pds->service_data_valid = entry->service_data_valid;
428+ pds->service_data = entry->service_data;
429+ pds->instance = entry->instance;
430+ goto out;
431+ }
432+ }
433+
434+ /* Update ret to indicate that the service is not yet found */
435+ ret = -ENXIO;
436+
437+ /* Always read total_domains from the response msg */
438+ if (resp->domain_list_len > resp->total_domains)
439+ resp->domain_list_len = resp->total_domains;
440+
441+ domains_read += resp->domain_list_len;
442+ } while (domains_read < resp->total_domains);
443+out:
444+ kfree(resp);
445+ return ret;
446+}
447+
448+static void pdr_notify_lookup_failure(struct pdr_handle *pdr,
449+ struct pdr_service *pds,
450+ int err)
451+{
452+ pr_err("PDR: service lookup for %s failed: %d\n",
453+ pds->service_name, err);
454+
455+ if (err == -ENXIO)
456+ return;
457+
458+ list_del(&pds->node);
459+ pds->state = SERVREG_LOCATOR_ERR;
460+ mutex_lock(&pdr->status_lock);
461+ pdr->status(pds->state, pds->service_path, pdr->priv);
462+ mutex_unlock(&pdr->status_lock);
463+ kfree(pds);
464+}
465+
466+static void pdr_locator_work(struct work_struct *work)
467+{
468+ struct pdr_handle *pdr = container_of(work, struct pdr_handle,
469+ locator_work);
470+ struct pdr_service *pds, *tmp;
471+ int ret = 0;
472+
473+ /* Bail out early if the SERVREG LOCATOR QMI service is not up */
474+ mutex_lock(&pdr->lock);
475+ if (!pdr->locator_init_complete) {
476+ mutex_unlock(&pdr->lock);
477+ pr_debug("PDR: SERVICE LOCATOR service not available\n");
478+ return;
479+ }
480+ mutex_unlock(&pdr->lock);
481+
482+ mutex_lock(&pdr->list_lock);
483+ list_for_each_entry_safe(pds, tmp, &pdr->lookups, node) {
484+ if (!pds->need_locator_lookup)
485+ continue;
486+
487+ ret = pdr_locate_service(pdr, pds);
488+ if (ret < 0) {
489+ pdr_notify_lookup_failure(pdr, pds, ret);
490+ continue;
491+ }
492+
493+ ret = qmi_add_lookup(&pdr->notifier_hdl, pds->service, 1,
494+ pds->instance);
495+ if (ret < 0) {
496+ pdr_notify_lookup_failure(pdr, pds, ret);
497+ continue;
498+ }
499+
500+ pds->need_locator_lookup = false;
501+ }
502+ mutex_unlock(&pdr->list_lock);
503+}
504+
505+/**
506+ * pdr_add_lookup() - register a tracking request for a PD
507+ * @pdr: PDR client handle
508+ * @service_name: service name of the tracking request
509+ * @service_path: service path of the tracking request
510+ *
511+ * Registering a pdr lookup allows for tracking the life cycle of the PD.
512+ *
513+ * Return: pdr_service object on success, ERR_PTR on failure. -EALREADY is
514+ * returned if a lookup is already in progress for the given service path.
515+ */
516+struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
517+ const char *service_name,
518+ const char *service_path)
519+{
520+ struct pdr_service *pds, *tmp;
521+ int ret;
522+
523+ if (IS_ERR_OR_NULL(pdr))
524+ return ERR_PTR(-EINVAL);
525+
526+ if (!service_name || strlen(service_name) > SERVREG_NAME_LENGTH ||
527+ !service_path || strlen(service_path) > SERVREG_NAME_LENGTH)
528+ return ERR_PTR(-EINVAL);
529+
530+ pds = kzalloc(sizeof(*pds), GFP_KERNEL);
531+ if (!pds)
532+ return ERR_PTR(-ENOMEM);
533+
534+ pds->service = SERVREG_NOTIFIER_SERVICE;
535+ strcpy(pds->service_name, service_name);
536+ strcpy(pds->service_path, service_path);
537+ pds->need_locator_lookup = true;
538+
539+ mutex_lock(&pdr->list_lock);
540+ list_for_each_entry(tmp, &pdr->lookups, node) {
541+ if (strcmp(tmp->service_path, service_path))
542+ continue;
543+
544+ mutex_unlock(&pdr->list_lock);
545+ ret = -EALREADY;
546+ goto err;
547+ }
548+
549+ list_add(&pds->node, &pdr->lookups);
550+ mutex_unlock(&pdr->list_lock);
551+
552+ schedule_work(&pdr->locator_work);
553+
554+ return pds;
555+err:
556+ kfree(pds);
557+ return ERR_PTR(ret);
558+}
559+EXPORT_SYMBOL(pdr_add_lookup);
560+
561+/**
562+ * pdr_restart_pd() - restart PD
563+ * @pdr: PDR client handle
564+ * @pds: PD service handle
565+ *
566+ * Restarts the PD tracked by the PDR client handle for a given service path.
567+ *
568+ * Return: 0 on success, negative errno on failure.
569+ */
570+int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
571+{
572+ struct servreg_restart_pd_resp resp;
573+ struct servreg_restart_pd_req req;
574+ struct sockaddr_qrtr addr;
575+ struct pdr_service *tmp;
576+ struct qmi_txn txn;
577+ int ret;
578+
579+ if (IS_ERR_OR_NULL(pdr) || IS_ERR_OR_NULL(pds))
580+ return -EINVAL;
581+
582+ mutex_lock(&pdr->list_lock);
583+ list_for_each_entry(tmp, &pdr->lookups, node) {
584+ if (tmp != pds)
585+ continue;
586+
587+ if (!pds->service_connected)
588+ break;
589+
590+ /* Prepare req message */
591+ strcpy(req.service_path, pds->service_path);
592+ addr = pds->addr;
593+ break;
594+ }
595+ mutex_unlock(&pdr->list_lock);
596+
597+ if (!req.service_path[0])
598+ return -EINVAL;
599+
600+ ret = qmi_txn_init(&pdr->notifier_hdl, &txn,
601+ servreg_restart_pd_resp_ei,
602+ &resp);
603+ if (ret < 0)
604+ return ret;
605+
606+ ret = qmi_send_request(&pdr->notifier_hdl, &addr,
607+ &txn, SERVREG_RESTART_PD_REQ,
608+ SERVREG_RESTART_PD_REQ_MAX_LEN,
609+ servreg_restart_pd_req_ei, &req);
610+ if (ret < 0) {
611+ qmi_txn_cancel(&txn);
612+ return ret;
613+ }
614+
615+ ret = qmi_txn_wait(&txn, 5 * HZ);
616+ if (ret < 0) {
617+ pr_err("PDR: %s PD restart txn wait failed: %d\n",
618+ req.service_path, ret);
619+ return ret;
620+ }
621+
622+ /* Check response if PDR is disabled */
623+ if (resp.resp.result == QMI_RESULT_FAILURE_V01 &&
624+ resp.resp.error == QMI_ERR_DISABLED_V01) {
625+ pr_err("PDR: %s PD restart is disabled: 0x%x\n",
626+ req.service_path, resp.resp.error);
627+ return -EOPNOTSUPP;
628+ }
629+
630+ /* Check the response for other error case*/
631+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
632+ pr_err("PDR: %s request for PD restart failed: 0x%x\n",
633+ req.service_path, resp.resp.error);
634+ return -EREMOTEIO;
635+ }
636+
637+ return 0;
638+}
639+EXPORT_SYMBOL(pdr_restart_pd);
640+
641+/**
642+ * pdr_handle_alloc() - initialize the PDR client handle
643+ * @status: function to be called on PD state change
644+ * @priv: handle for client's use
645+ *
646+ * Initializes the PDR client handle to allow for tracking/restart of PDs.
647+ *
648+ * Return: pdr_handle object on success, ERR_PTR on failure.
649+ */
650+struct pdr_handle *pdr_handle_alloc(void (*status)(int state,
651+ char *service_path,
652+ void *priv), void *priv)
653+{
654+ struct pdr_handle *pdr;
655+ int ret;
656+
657+ if (!status)
658+ return ERR_PTR(-EINVAL);
659+
660+ pdr = kzalloc(sizeof(*pdr), GFP_KERNEL);
661+ if (!pdr)
662+ return ERR_PTR(-ENOMEM);
663+
664+ pdr->status = status;
665+ pdr->priv = priv;
666+
667+ mutex_init(&pdr->status_lock);
668+ mutex_init(&pdr->list_lock);
669+ mutex_init(&pdr->lock);
670+
671+ INIT_LIST_HEAD(&pdr->lookups);
672+ INIT_LIST_HEAD(&pdr->indack_list);
673+
674+ INIT_WORK(&pdr->locator_work, pdr_locator_work);
675+ INIT_WORK(&pdr->notifier_work, pdr_notifier_work);
676+ INIT_WORK(&pdr->indack_work, pdr_indack_work);
677+
678+ pdr->notifier_wq = create_singlethread_workqueue("pdr_notifier_wq");
679+ if (!pdr->notifier_wq) {
680+ ret = -ENOMEM;
681+ goto free_pdr_handle;
682+ }
683+
684+ pdr->indack_wq = alloc_ordered_workqueue("pdr_indack_wq", WQ_HIGHPRI);
685+ if (!pdr->indack_wq) {
686+ ret = -ENOMEM;
687+ goto destroy_notifier;
688+ }
689+
690+ ret = qmi_handle_init(&pdr->locator_hdl,
691+ SERVREG_GET_DOMAIN_LIST_RESP_MAX_LEN,
692+ &pdr_locator_ops, NULL);
693+ if (ret < 0)
694+ goto destroy_indack;
695+
696+ ret = qmi_add_lookup(&pdr->locator_hdl, SERVREG_LOCATOR_SERVICE, 1, 1);
697+ if (ret < 0)
698+ goto release_qmi_handle;
699+
700+ ret = qmi_handle_init(&pdr->notifier_hdl,
701+ SERVREG_STATE_UPDATED_IND_MAX_LEN,
702+ &pdr_notifier_ops,
703+ qmi_indication_handler);
704+ if (ret < 0)
705+ goto release_qmi_handle;
706+
707+ return pdr;
708+
709+release_qmi_handle:
710+ qmi_handle_release(&pdr->locator_hdl);
711+destroy_indack:
712+ destroy_workqueue(pdr->indack_wq);
713+destroy_notifier:
714+ destroy_workqueue(pdr->notifier_wq);
715+free_pdr_handle:
716+ kfree(pdr);
717+
718+ return ERR_PTR(ret);
719+}
720+EXPORT_SYMBOL(pdr_handle_alloc);
721+
722+/**
723+ * pdr_handle_release() - release the PDR client handle
724+ * @pdr: PDR client handle
725+ *
726+ * Cleans up pending tracking requests and releases the underlying qmi handles.
727+ */
728+void pdr_handle_release(struct pdr_handle *pdr)
729+{
730+ struct pdr_service *pds, *tmp;
731+
732+ if (IS_ERR_OR_NULL(pdr))
733+ return;
734+
735+ mutex_lock(&pdr->list_lock);
736+ list_for_each_entry_safe(pds, tmp, &pdr->lookups, node) {
737+ list_del(&pds->node);
738+ kfree(pds);
739+ }
740+ mutex_unlock(&pdr->list_lock);
741+
742+ cancel_work_sync(&pdr->locator_work);
743+ cancel_work_sync(&pdr->notifier_work);
744+ cancel_work_sync(&pdr->indack_work);
745+
746+ destroy_workqueue(pdr->notifier_wq);
747+ destroy_workqueue(pdr->indack_wq);
748+
749+ qmi_handle_release(&pdr->locator_hdl);
750+ qmi_handle_release(&pdr->notifier_hdl);
751+
752+ kfree(pdr);
753+}
754+EXPORT_SYMBOL(pdr_handle_release);
755+
756+MODULE_LICENSE("GPL v2");
757+MODULE_DESCRIPTION("Qualcomm Protection Domain Restart helpers");
drivers/soc/qcom/pdr_internal.h+379−0
@@ -0,0 +1,379 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef __QCOM_PDR_HELPER_INTERNAL__
3+#define __QCOM_PDR_HELPER_INTERNAL__
4+
5+#include <linux/soc/qcom/pdr.h>
6+
7+#define SERVREG_LOCATOR_SERVICE 0x40
8+#define SERVREG_NOTIFIER_SERVICE 0x42
9+
10+#define SERVREG_REGISTER_LISTENER_REQ 0x20
11+#define SERVREG_GET_DOMAIN_LIST_REQ 0x21
12+#define SERVREG_STATE_UPDATED_IND_ID 0x22
13+#define SERVREG_SET_ACK_REQ 0x23
14+#define SERVREG_RESTART_PD_REQ 0x24
15+
16+#define SERVREG_DOMAIN_LIST_LENGTH 32
17+#define SERVREG_RESTART_PD_REQ_MAX_LEN 67
18+#define SERVREG_REGISTER_LISTENER_REQ_LEN 71
19+#define SERVREG_SET_ACK_REQ_LEN 72
20+#define SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN 74
21+#define SERVREG_STATE_UPDATED_IND_MAX_LEN 79
22+#define SERVREG_GET_DOMAIN_LIST_RESP_MAX_LEN 2389
23+
24+struct servreg_location_entry {
25+ char name[SERVREG_NAME_LENGTH + 1];
26+ u8 service_data_valid;
27+ u32 service_data;
28+ u32 instance;
29+};
30+
31+struct qmi_elem_info servreg_location_entry_ei[] = {
32+ {
33+ .data_type = QMI_STRING,
34+ .elem_len = SERVREG_NAME_LENGTH + 1,
35+ .elem_size = sizeof(char),
36+ .array_type = NO_ARRAY,
37+ .tlv_type = 0,
38+ .offset = offsetof(struct servreg_location_entry,
39+ name),
40+ },
41+ {
42+ .data_type = QMI_UNSIGNED_4_BYTE,
43+ .elem_len = 1,
44+ .elem_size = sizeof(u32),
45+ .array_type = NO_ARRAY,
46+ .tlv_type = 0,
47+ .offset = offsetof(struct servreg_location_entry,
48+ instance),
49+ },
50+ {
51+ .data_type = QMI_UNSIGNED_1_BYTE,
52+ .elem_len = 1,
53+ .elem_size = sizeof(u8),
54+ .array_type = NO_ARRAY,
55+ .tlv_type = 0,
56+ .offset = offsetof(struct servreg_location_entry,
57+ service_data_valid),
58+ },
59+ {
60+ .data_type = QMI_UNSIGNED_4_BYTE,
61+ .elem_len = 1,
62+ .elem_size = sizeof(u32),
63+ .array_type = NO_ARRAY,
64+ .tlv_type = 0,
65+ .offset = offsetof(struct servreg_location_entry,
66+ service_data),
67+ },
68+ {}
69+};
70+
71+struct servreg_get_domain_list_req {
72+ char service_name[SERVREG_NAME_LENGTH + 1];
73+ u8 domain_offset_valid;
74+ u32 domain_offset;
75+};
76+
77+struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
78+ {
79+ .data_type = QMI_STRING,
80+ .elem_len = SERVREG_NAME_LENGTH + 1,
81+ .elem_size = sizeof(char),
82+ .array_type = NO_ARRAY,
83+ .tlv_type = 0x01,
84+ .offset = offsetof(struct servreg_get_domain_list_req,
85+ service_name),
86+ },
87+ {
88+ .data_type = QMI_OPT_FLAG,
89+ .elem_len = 1,
90+ .elem_size = sizeof(u8),
91+ .array_type = NO_ARRAY,
92+ .tlv_type = 0x10,
93+ .offset = offsetof(struct servreg_get_domain_list_req,
94+ domain_offset_valid),
95+ },
96+ {
97+ .data_type = QMI_UNSIGNED_4_BYTE,
98+ .elem_len = 1,
99+ .elem_size = sizeof(u32),
100+ .array_type = NO_ARRAY,
101+ .tlv_type = 0x10,
102+ .offset = offsetof(struct servreg_get_domain_list_req,
103+ domain_offset),
104+ },
105+ {}
106+};
107+
108+struct servreg_get_domain_list_resp {
109+ struct qmi_response_type_v01 resp;
110+ u8 total_domains_valid;
111+ u16 total_domains;
112+ u8 db_rev_count_valid;
113+ u16 db_rev_count;
114+ u8 domain_list_valid;
115+ u32 domain_list_len;
116+ struct servreg_location_entry domain_list[SERVREG_DOMAIN_LIST_LENGTH];
117+};
118+
119+struct qmi_elem_info servreg_get_domain_list_resp_ei[] = {
120+ {
121+ .data_type = QMI_STRUCT,
122+ .elem_len = 1,
123+ .elem_size = sizeof(struct qmi_response_type_v01),
124+ .array_type = NO_ARRAY,
125+ .tlv_type = 0x02,
126+ .offset = offsetof(struct servreg_get_domain_list_resp,
127+ resp),
128+ .ei_array = qmi_response_type_v01_ei,
129+ },
130+ {
131+ .data_type = QMI_OPT_FLAG,
132+ .elem_len = 1,
133+ .elem_size = sizeof(u8),
134+ .array_type = NO_ARRAY,
135+ .tlv_type = 0x10,
136+ .offset = offsetof(struct servreg_get_domain_list_resp,
137+ total_domains_valid),
138+ },
139+ {
140+ .data_type = QMI_UNSIGNED_2_BYTE,
141+ .elem_len = 1,
142+ .elem_size = sizeof(u16),
143+ .array_type = NO_ARRAY,
144+ .tlv_type = 0x10,
145+ .offset = offsetof(struct servreg_get_domain_list_resp,
146+ total_domains),
147+ },
148+ {
149+ .data_type = QMI_OPT_FLAG,
150+ .elem_len = 1,
151+ .elem_size = sizeof(u8),
152+ .array_type = NO_ARRAY,
153+ .tlv_type = 0x11,
154+ .offset = offsetof(struct servreg_get_domain_list_resp,
155+ db_rev_count_valid),
156+ },
157+ {
158+ .data_type = QMI_UNSIGNED_2_BYTE,
159+ .elem_len = 1,
160+ .elem_size = sizeof(u16),
161+ .array_type = NO_ARRAY,
162+ .tlv_type = 0x11,
163+ .offset = offsetof(struct servreg_get_domain_list_resp,
164+ db_rev_count),
165+ },
166+ {
167+ .data_type = QMI_OPT_FLAG,
168+ .elem_len = 1,
169+ .elem_size = sizeof(u8),
170+ .array_type = NO_ARRAY,
171+ .tlv_type = 0x12,
172+ .offset = offsetof(struct servreg_get_domain_list_resp,
173+ domain_list_valid),
174+ },
175+ {
176+ .data_type = QMI_DATA_LEN,
177+ .elem_len = 1,
178+ .elem_size = sizeof(u8),
179+ .array_type = NO_ARRAY,
180+ .tlv_type = 0x12,
181+ .offset = offsetof(struct servreg_get_domain_list_resp,
182+ domain_list_len),
183+ },
184+ {
185+ .data_type = QMI_STRUCT,
186+ .elem_len = SERVREG_DOMAIN_LIST_LENGTH,
187+ .elem_size = sizeof(struct servreg_location_entry),
188+ .array_type = NO_ARRAY,
189+ .tlv_type = 0x12,
190+ .offset = offsetof(struct servreg_get_domain_list_resp,
191+ domain_list),
192+ .ei_array = servreg_location_entry_ei,
193+ },
194+ {}
195+};
196+
197+struct servreg_register_listener_req {
198+ u8 enable;
199+ char service_path[SERVREG_NAME_LENGTH + 1];
200+};
201+
202+struct qmi_elem_info servreg_register_listener_req_ei[] = {
203+ {
204+ .data_type = QMI_UNSIGNED_1_BYTE,
205+ .elem_len = 1,
206+ .elem_size = sizeof(u8),
207+ .array_type = NO_ARRAY,
208+ .tlv_type = 0x01,
209+ .offset = offsetof(struct servreg_register_listener_req,
210+ enable),
211+ },
212+ {
213+ .data_type = QMI_STRING,
214+ .elem_len = SERVREG_NAME_LENGTH + 1,
215+ .elem_size = sizeof(char),
216+ .array_type = NO_ARRAY,
217+ .tlv_type = 0x02,
218+ .offset = offsetof(struct servreg_register_listener_req,
219+ service_path),
220+ },
221+ {}
222+};
223+
224+struct servreg_register_listener_resp {
225+ struct qmi_response_type_v01 resp;
226+ u8 curr_state_valid;
227+ enum servreg_service_state curr_state;
228+};
229+
230+struct qmi_elem_info servreg_register_listener_resp_ei[] = {
231+ {
232+ .data_type = QMI_STRUCT,
233+ .elem_len = 1,
234+ .elem_size = sizeof(struct qmi_response_type_v01),
235+ .array_type = NO_ARRAY,
236+ .tlv_type = 0x02,
237+ .offset = offsetof(struct servreg_register_listener_resp,
238+ resp),
239+ .ei_array = qmi_response_type_v01_ei,
240+ },
241+ {
242+ .data_type = QMI_OPT_FLAG,
243+ .elem_len = 1,
244+ .elem_size = sizeof(u8),
245+ .array_type = NO_ARRAY,
246+ .tlv_type = 0x10,
247+ .offset = offsetof(struct servreg_register_listener_resp,
248+ curr_state_valid),
249+ },
250+ {
251+ .data_type = QMI_SIGNED_4_BYTE_ENUM,
252+ .elem_len = 1,
253+ .elem_size = sizeof(enum servreg_service_state),
254+ .array_type = NO_ARRAY,
255+ .tlv_type = 0x10,
256+ .offset = offsetof(struct servreg_register_listener_resp,
257+ curr_state),
258+ },
259+ {}
260+};
261+
262+struct servreg_restart_pd_req {
263+ char service_path[SERVREG_NAME_LENGTH + 1];
264+};
265+
266+struct qmi_elem_info servreg_restart_pd_req_ei[] = {
267+ {
268+ .data_type = QMI_STRING,
269+ .elem_len = SERVREG_NAME_LENGTH + 1,
270+ .elem_size = sizeof(char),
271+ .array_type = NO_ARRAY,
272+ .tlv_type = 0x01,
273+ .offset = offsetof(struct servreg_restart_pd_req,
274+ service_path),
275+ },
276+ {}
277+};
278+
279+struct servreg_restart_pd_resp {
280+ struct qmi_response_type_v01 resp;
281+};
282+
283+struct qmi_elem_info servreg_restart_pd_resp_ei[] = {
284+ {
285+ .data_type = QMI_STRUCT,
286+ .elem_len = 1,
287+ .elem_size = sizeof(struct qmi_response_type_v01),
288+ .array_type = NO_ARRAY,
289+ .tlv_type = 0x02,
290+ .offset = offsetof(struct servreg_restart_pd_resp,
291+ resp),
292+ .ei_array = qmi_response_type_v01_ei,
293+ },
294+ {}
295+};
296+
297+struct servreg_state_updated_ind {
298+ enum servreg_service_state curr_state;
299+ char service_path[SERVREG_NAME_LENGTH + 1];
300+ u16 transaction_id;
301+};
302+
303+struct qmi_elem_info servreg_state_updated_ind_ei[] = {
304+ {
305+ .data_type = QMI_SIGNED_4_BYTE_ENUM,
306+ .elem_len = 1,
307+ .elem_size = sizeof(u32),
308+ .array_type = NO_ARRAY,
309+ .tlv_type = 0x01,
310+ .offset = offsetof(struct servreg_state_updated_ind,
311+ curr_state),
312+ },
313+ {
314+ .data_type = QMI_STRING,
315+ .elem_len = SERVREG_NAME_LENGTH + 1,
316+ .elem_size = sizeof(char),
317+ .array_type = NO_ARRAY,
318+ .tlv_type = 0x02,
319+ .offset = offsetof(struct servreg_state_updated_ind,
320+ service_path),
321+ },
322+ {
323+ .data_type = QMI_UNSIGNED_2_BYTE,
324+ .elem_len = 1,
325+ .elem_size = sizeof(u16),
326+ .array_type = NO_ARRAY,
327+ .tlv_type = 0x03,
328+ .offset = offsetof(struct servreg_state_updated_ind,
329+ transaction_id),
330+ },
331+ {}
332+};
333+
334+struct servreg_set_ack_req {
335+ char service_path[SERVREG_NAME_LENGTH + 1];
336+ u16 transaction_id;
337+};
338+
339+struct qmi_elem_info servreg_set_ack_req_ei[] = {
340+ {
341+ .data_type = QMI_STRING,
342+ .elem_len = SERVREG_NAME_LENGTH + 1,
343+ .elem_size = sizeof(char),
344+ .array_type = NO_ARRAY,
345+ .tlv_type = 0x01,
346+ .offset = offsetof(struct servreg_set_ack_req,
347+ service_path),
348+ },
349+ {
350+ .data_type = QMI_UNSIGNED_2_BYTE,
351+ .elem_len = 1,
352+ .elem_size = sizeof(u16),
353+ .array_type = NO_ARRAY,
354+ .tlv_type = 0x02,
355+ .offset = offsetof(struct servreg_set_ack_req,
356+ transaction_id),
357+ },
358+ {}
359+};
360+
361+struct servreg_set_ack_resp {
362+ struct qmi_response_type_v01 resp;
363+};
364+
365+struct qmi_elem_info servreg_set_ack_resp_ei[] = {
366+ {
367+ .data_type = QMI_STRUCT,
368+ .elem_len = 1,
369+ .elem_size = sizeof(struct qmi_response_type_v01),
370+ .array_type = NO_ARRAY,
371+ .tlv_type = 0x02,
372+ .offset = offsetof(struct servreg_set_ack_resp,
373+ resp),
374+ .ei_array = qmi_response_type_v01_ei,
375+ },
376+ {}
377+};
378+
379+#endif
drivers/soc/qcom/qcom_aoss.c+5−1
@@ -200,7 +200,7 @@ static irqreturn_t qmp_intr(int irq, void *data) · 199 unmodified lines
200200 {
201201 struct qmp *qmp = data;
202202
203− wake_up_interruptible_all(&qmp->event);
203+ wake_up_all(&qmp->event);
204204
205205 return IRQ_HANDLED;
206206 }
@@ -225,6 +225,7 @@ static bool qmp_message_empty(struct qmp *qmp) · 18 unmodified lines
225225 static int qmp_send(struct qmp *qmp, const void *data, size_t len)
226226 {
227227 long time_left;
228+ size_t tlen;
228229 int ret;
229230
230231 if (WARN_ON(len + sizeof(u32) > qmp->size))
@@ -239,6 +240,9 @@ static int qmp_send(struct qmp *qmp, const void *data, size_t len) · 8 unmodified lines
239240 __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32),
240241 data, len / sizeof(u32));
241242 writel(len, qmp->msgram + qmp->offset);
243+
244+ /* Read back len to confirm data written in message RAM */
245+ tlen = readl(qmp->msgram + qmp->offset);
242246 qmp_kick(qmp);
243247
244248 time_left = wait_event_interruptible_timeout(qmp->event,
drivers/soc/qcom/rpmh-internal.h+1−0
@@ -110,5 +110,6 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, · 109 unmodified lines
110110 int rpmh_rsc_invalidate(struct rsc_drv *drv);
111111
112112 void rpmh_tx_done(const struct tcs_request *msg, int r);
113+int rpmh_flush(struct rpmh_ctrlr *ctrlr);
113114
114115 #endif /* __RPM_INTERNAL_H__ */
drivers/soc/qcom/rpmh-rsc.c+1−1
@@ -277,7 +277,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, · 276 unmodified lines
277277 write_tcs_cmd(drv, RSC_DRV_CMD_MSGID, tcs_id, j, msgid);
278278 write_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j, cmd->addr);
279279 write_tcs_cmd(drv, RSC_DRV_CMD_DATA, tcs_id, j, cmd->data);
280− trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
280+ trace_rpmh_send_msg_rcuidle(drv, tcs_id, j, msgid, cmd);
281281 }
282282
283283 write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete);
drivers/soc/qcom/rpmh.c+10−12
@@ -23,7 +23,7 @@ · 22 unmodified lines
2323
2424 #define RPMH_TIMEOUT_MS msecs_to_jiffies(10000)
2525
26−#define DEFINE_RPMH_MSG_ONSTACK(dev, s, q, name) \
26+#define DEFINE_RPMH_MSG_ONSTACK(device, s, q, name) \
2727 struct rpmh_request name = { \
2828 .msg = { \
2929 .state = s, \
@@ -33,7 +33,7 @@ · 3 unmodified lines
3333 }, \
3434 .cmd = { { 0 } }, \
3535 .completion = q, \
36− .dev = dev, \
36+ .dev = device, \
3737 .needs_free = false, \
3838 }
3939
@@ -427,11 +427,10 @@ static int is_req_valid(struct cache_req *req) · 387 unmodified lines
427427 req->sleep_val != req->wake_val);
428428 }
429429
430−static int send_single(const struct device *dev, enum rpmh_state state,
430+static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state,
431431 u32 addr, u32 data)
432432 {
433− DEFINE_RPMH_MSG_ONSTACK(dev, state, NULL, rpm_msg);
434− struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
433+ DEFINE_RPMH_MSG_ONSTACK(NULL, state, NULL, rpm_msg);
435434
436435 /* Wake sets are always complete and sleep sets are not */
437436 rpm_msg.msg.wait_for_compl = (state == RPMH_WAKE_ONLY_STATE);
@@ -445,7 +444,7 @@ static int send_single(const struct device *dev, enum rpmh_state state, · 7 unmodified lines
445444 /**
446445 * rpmh_flush: Flushes the buffered active and sleep sets to TCS
447446 *
448− * @dev: The device making the request
447+ * @ctrlr: controller making request to flush cached data
449448 *
450449 * Return: -EBUSY if the controller is busy, probably waiting on a response
451450 * to a RPMH request sent earlier.
@@ -454,10 +453,9 @@ static int send_single(const struct device *dev, enum rpmh_state state, · 2 unmodified lines
454453 * that is powering down the entire system. Since no other RPMH API would be
455454 * executing at this time, it is safe to run lockless.
456455 */
457−int rpmh_flush(const struct device *dev)
456+int rpmh_flush(struct rpmh_ctrlr *ctrlr)
458457 {
459458 struct cache_req *p;
460− struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
461459 int ret;
462460
463461 if (!ctrlr->dirty) {
@@ -480,11 +478,12 @@ int rpmh_flush(const struct device *dev) · 16 unmodified lines
480478 __func__, p->addr, p->sleep_val, p->wake_val);
481479 continue;
482480 }
483− ret = send_single(dev, RPMH_SLEEP_STATE, p->addr, p->sleep_val);
481+ ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr,
482+ p->sleep_val);
484483 if (ret)
485484 return ret;
486− ret = send_single(dev, RPMH_WAKE_ONLY_STATE,
487− p->addr, p->wake_val);
485+ ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr,
486+ p->wake_val);
488487 if (ret)
489488 return ret;
490489 }
@@ -493,7 +492,6 @@ int rpmh_flush(const struct device *dev) · 2 unmodified lines
493492
494493 return 0;
495494 }
496−EXPORT_SYMBOL(rpmh_flush);
497495
498496 /**
499497 * rpmh_invalidate: Invalidate all sleep and active sets
drivers/soc/qcom/socinfo.c+1−1
@@ -277,7 +277,7 @@ static int show_image_##type(struct seq_file *seq, void *p) \ · 276 unmodified lines
277277 { \
278278 struct smem_image_version *image_version = seq->private; \
279279 seq_puts(seq, image_version->type); \
280− seq_puts(seq, "\n"); \
280+ seq_putc(seq, '\n'); \
281281 return 0; \
282282 } \
283283 static int open_image_##type(struct inode *inode, struct file *file) \
drivers/soc/renesas/Kconfig+8−8
@@ -195,19 +195,19 @@ config ARCH_R8A774C0 · 194 unmodified lines
195195 This enables support for the Renesas RZ/G2E SoC.
196196
197197 config ARCH_R8A77950
198− bool
198+ bool "Renesas R-Car H3 ES1.x SoC Platform"
199+ select ARCH_RCAR_GEN3
200+ select SYSC_R8A7795
201+ help
202+ This enables support for the Renesas R-Car H3 SoC (revision 1.x).
199203
200204 config ARCH_R8A77951
201− bool
202−
203−config ARCH_R8A7795
204− bool "Renesas R-Car H3 SoC Platform"
205− select ARCH_R8A77950
206− select ARCH_R8A77951
205+ bool "Renesas R-Car H3 ES2.0+ SoC Platform"
207206 select ARCH_RCAR_GEN3
208207 select SYSC_R8A7795
209208 help
210− This enables support for the Renesas R-Car H3 SoC.
209+ This enables support for the Renesas R-Car H3 SoC (revisions 2.0 and
210+ later).
211211
212212 config ARCH_R8A77960
213213 bool "Renesas R-Car M3-W SoC Platform"
drivers/soc/renesas/rcar-sysc.h+2−2
@@ -1,5 +1,5 @@
1−/* SPDX-License-Identifier: GPL-2.0
2− *
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
33 * Renesas R-Car System Controller
44 *
55 * Copyright (C) 2016 Glider bvba
drivers/soc/renesas/renesas-soc.c+1−1
@@ -259,7 +259,7 @@ static const struct of_device_id renesas_socs[] __initconst = { · 258 unmodified lines
259259 #ifdef CONFIG_ARCH_R8A7794
260260 { .compatible = "renesas,r8a7794", .data = &soc_rcar_e2 },
261261 #endif
262−#ifdef CONFIG_ARCH_R8A7795
262+#if defined(CONFIG_ARCH_R8A77950) || defined(CONFIG_ARCH_R8A77951)
263263 { .compatible = "renesas,r8a7795", .data = &soc_rcar_h3 },
264264 #endif
265265 #ifdef CONFIG_ARCH_R8A77960
drivers/tee/tee_core.c+0−1
@@ -44,7 +44,6 @@ static struct tee_context *teedev_open(struct tee_device *teedev) · 43 unmodified lines
4444
4545 kref_init(&ctx->refcount);
4646 ctx->teedev = teedev;
47− INIT_LIST_HEAD(&ctx->list_shm);
4847 rc = teedev->desc->ops->open(ctx);
4948 if (rc)
5049 goto err;
drivers/tee/tee_private.h+2−1
@@ -37,7 +37,8 @@ struct tee_shm_pool { · 36 unmodified lines
3737 * @num_users: number of active users of this device
3838 * @c_no_user: completion used when unregistering the device
3939 * @mutex: mutex protecting @num_users and @idr
40− * @idr: register of shared memory object allocated on this device
40+ * @idr: register of user space shared memory objects allocated or
41+ * registered on this device
4142 * @pool: shared memory pool
4243 */
4344 struct tee_device {
drivers/tee/tee_shm.c+24−61
@@ -13,13 +13,13 @@ · 12 unmodified lines
1313
1414 static void tee_shm_release(struct tee_shm *shm)
1515 {
16− struct tee_device *teedev = shm->teedev;
16+ struct tee_device *teedev = shm->ctx->teedev;
1717
18− mutex_lock(&teedev->mutex);
19− idr_remove(&teedev->idr, shm->id);
20− if (shm->ctx)
21− list_del(&shm->link);
22− mutex_unlock(&teedev->mutex);
18+ if (shm->flags & TEE_SHM_DMA_BUF) {
19+ mutex_lock(&teedev->mutex);
20+ idr_remove(&teedev->idr, shm->id);
21+ mutex_unlock(&teedev->mutex);
22+ }
2323
2424 if (shm->flags & TEE_SHM_POOL) {
2525 struct tee_shm_pool_mgr *poolm;
@@ -44,8 +44,7 @@ static void tee_shm_release(struct tee_shm *shm) · 18 unmodified lines
4444 kfree(shm->pages);
4545 }
4646
47− if (shm->ctx)
48− teedev_ctx_put(shm->ctx);
47+ teedev_ctx_put(shm->ctx);
4948
5049 kfree(shm);
5150
@@ -77,7 +76,7 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) · 25 unmodified lines
7776 size_t size = vma->vm_end - vma->vm_start;
7877
7978 /* Refuse sharing shared memory provided by application */
80− if (shm->flags & TEE_SHM_REGISTER)
79+ if (shm->flags & TEE_SHM_USER_MAPPED)
8180 return -EINVAL;
8281
8382 return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT,
@@ -91,20 +90,14 @@ static const struct dma_buf_ops tee_shm_dma_buf_ops = { · 7 unmodified lines
9190 .mmap = tee_shm_op_mmap,
9291 };
9392
94−static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx,
95− struct tee_device *teedev,
96− size_t size, u32 flags)
93+struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
9794 {
95+ struct tee_device *teedev = ctx->teedev;
9896 struct tee_shm_pool_mgr *poolm = NULL;
9997 struct tee_shm *shm;
10098 void *ret;
10199 int rc;
102100
103− if (ctx && ctx->teedev != teedev) {
104− dev_err(teedev->dev.parent, "ctx and teedev mismatch\n");
105− return ERR_PTR(-EINVAL);
106− }
107−
108101 if (!(flags & TEE_SHM_MAPPED)) {
109102 dev_err(teedev->dev.parent,
110103 "only mapped allocations supported\n");
@@ -132,7 +125,6 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, · 21 unmodified lines
132125 }
133126
134127 shm->flags = flags | TEE_SHM_POOL;
135− shm->teedev = teedev;
136128 shm->ctx = ctx;
137129 if (flags & TEE_SHM_DMA_BUF)
138130 poolm = teedev->pool->dma_buf_mgr;
@@ -145,17 +137,18 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, · 6 unmodified lines
145137 goto err_kfree;
146138 }
147139
148− mutex_lock(&teedev->mutex);
149− shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
150− mutex_unlock(&teedev->mutex);
151− if (shm->id < 0) {
152− ret = ERR_PTR(shm->id);
153− goto err_pool_free;
154− }
155140
156141 if (flags & TEE_SHM_DMA_BUF) {
157142 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
158143
144+ mutex_lock(&teedev->mutex);
145+ shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
146+ mutex_unlock(&teedev->mutex);
147+ if (shm->id < 0) {
148+ ret = ERR_PTR(shm->id);
149+ goto err_pool_free;
150+ }
151+
159152 exp_info.ops = &tee_shm_dma_buf_ops;
160153 exp_info.size = shm->size;
161154 exp_info.flags = O_RDWR;
@@ -168,18 +161,16 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, · 6 unmodified lines
168161 }
169162 }
170163
171− if (ctx) {
164+ if (ctx)
172165 teedev_ctx_get(ctx);
173− mutex_lock(&teedev->mutex);
174− list_add_tail(&shm->link, &ctx->list_shm);
175− mutex_unlock(&teedev->mutex);
176− }
177166
178167 return shm;
179168 err_rem:
180− mutex_lock(&teedev->mutex);
181− idr_remove(&teedev->idr, shm->id);
182− mutex_unlock(&teedev->mutex);
169+ if (flags & TEE_SHM_DMA_BUF) {
170+ mutex_lock(&teedev->mutex);
171+ idr_remove(&teedev->idr, shm->id);
172+ mutex_unlock(&teedev->mutex);
173+ }
183174 err_pool_free:
184175 poolm->ops->free(poolm, shm);
185176 err_kfree:
@@ -188,31 +179,8 @@ err_dev_put: · 2 unmodified lines
188179 tee_device_put(teedev);
189180 return ret;
190181 }
191−
192−/**
193− * tee_shm_alloc() - Allocate shared memory
194− * @ctx: Context that allocates the shared memory
195− * @size: Requested size of shared memory
196− * @flags: Flags setting properties for the requested shared memory.
197− *
198− * Memory allocated as global shared memory is automatically freed when the
199− * TEE file pointer is closed. The @flags field uses the bits defined by
200− * TEE_SHM_* in <linux/tee_drv.h>. TEE_SHM_MAPPED must currently always be
201− * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and
202− * associated with a dma-buf handle, else driver private memory.
203− */
204−struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
205−{
206− return __tee_shm_alloc(ctx, ctx->teedev, size, flags);
207−}
208182 EXPORT_SYMBOL_GPL(tee_shm_alloc);
209183
210−struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size)
211−{
212− return __tee_shm_alloc(NULL, teedev, size, TEE_SHM_MAPPED);
213−}
214−EXPORT_SYMBOL_GPL(tee_shm_priv_alloc);
215−
216184 struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
217185 size_t length, u32 flags)
218186 {
@@ -245,7 +213,6 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 26 unmodified lines
245213 }
246214
247215 shm->flags = flags | TEE_SHM_REGISTER;
248− shm->teedev = teedev;
249216 shm->ctx = ctx;
250217 shm->id = -1;
251218 addr = untagged_addr(addr);
@@ -301,10 +268,6 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 49 unmodified lines
301268 }
302269 }
303270
304− mutex_lock(&teedev->mutex);
305− list_add_tail(&shm->link, &ctx->list_shm);
306− mutex_unlock(&teedev->mutex);
307−
308271 return shm;
309272 err:
310273 if (shm) {
include/dt-bindings/bus/ti-sysc.h+4−0
@@ -18,6 +18,10 @@ · 17 unmodified lines
1818
1919 #define SYSC_DRA7_MCAN_ENAWAKEUP (1 << 4)
2020
21+/* PRUSS sysc found on AM33xx/AM43xx/AM57xx */
22+#define SYSC_PRUSS_SUB_MWAIT (1 << 5)
23+#define SYSC_PRUSS_STANDBY_INIT (1 << 4)
24+
2125 /* SYSCONFIG STANDBYMODE/MIDLEMODE/SIDLEMODE supported by hardware */
2226 #define SYSC_IDLE_FORCE 0
2327 #define SYSC_IDLE_NO 1
include/dt-bindings/power/meson-a1-power.h+32−0
@@ -0,0 +1,32 @@
1+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
2+/*
3+ * Copyright (c) 2019 Amlogic, Inc.
4+ * Author: Jianxin Pan <jianxin.pan@amlogic.com>
5+ */
6+
7+#ifndef _DT_BINDINGS_MESON_A1_POWER_H
8+#define _DT_BINDINGS_MESON_A1_POWER_H
9+
10+#define PWRC_DSPA_ID 8
11+#define PWRC_DSPB_ID 9
12+#define PWRC_UART_ID 10
13+#define PWRC_DMC_ID 11
14+#define PWRC_I2C_ID 12
15+#define PWRC_PSRAM_ID 13
16+#define PWRC_ACODEC_ID 14
17+#define PWRC_AUDIO_ID 15
18+#define PWRC_OTP_ID 16
19+#define PWRC_DMA_ID 17
20+#define PWRC_SD_EMMC_ID 18
21+#define PWRC_RAMA_ID 19
22+#define PWRC_RAMB_ID 20
23+#define PWRC_IR_ID 21
24+#define PWRC_SPICC_ID 22
25+#define PWRC_SPIFC_ID 23
26+#define PWRC_USB_ID 24
27+#define PWRC_NIC_ID 25
28+#define PWRC_PDMIN_ID 26
29+#define PWRC_RSA_ID 27
30+#define PWRC_MAX_ID 28
31+
32+#endif
include/linux/firmware/imx/ipc.h+0−1
@@ -25,7 +25,6 @@ enum imx_sc_rpc_svc { · 24 unmodified lines
2525 IMX_SC_RPC_SVC_PAD = 6,
2626 IMX_SC_RPC_SVC_MISC = 7,
2727 IMX_SC_RPC_SVC_IRQ = 8,
28− IMX_SC_RPC_SVC_ABORT = 9
2928 };
3029
3130 struct imx_sc_rpc_msg {
include/linux/firmware/meson/meson_sm.h+2−0
@@ -12,6 +12,8 @@ enum { · 11 unmodified lines
1212 SM_EFUSE_WRITE,
1313 SM_EFUSE_USER_MAX,
1414 SM_GET_CHIP_ID,
15+ SM_A1_PWRC_SET,
16+ SM_A1_PWRC_GET,
1517 };
1618
1719 struct meson_sm_firmware;
include/linux/platform_data/ti-sysc.h+5−0
@@ -17,6 +17,7 @@ enum ti_sysc_module_type { · 16 unmodified lines
1717 TI_SYSC_OMAP4_MCASP,
1818 TI_SYSC_OMAP4_USB_HOST_FS,
1919 TI_SYSC_DRA7_MCAN,
20+ TI_SYSC_PRUSS,
2021 };
2122
2223 struct ti_sysc_cookie {
@@ -49,6 +50,9 @@ struct sysc_regbits { · 26 unmodified lines
4950 s8 emufree_shift;
5051 };
5152
53+#define SYSC_MODULE_QUIRK_PRUSS BIT(24)
54+#define SYSC_MODULE_QUIRK_DSS_RESET BIT(23)
55+#define SYSC_MODULE_QUIRK_RTC_UNLOCK BIT(22)
5256 #define SYSC_QUIRK_CLKDM_NOAUTO BIT(21)
5357 #define SYSC_QUIRK_FORCE_MSTANDBY BIT(20)
5458 #define SYSC_MODULE_QUIRK_AESS BIT(19)
@@ -141,6 +145,7 @@ struct clk; · 86 unmodified lines
141145
142146 struct ti_sysc_platform_data {
143147 struct of_dev_auxdata *auxdata;
148+ bool (*soc_type_gp)(void);
144149 int (*init_clockdomain)(struct device *dev, struct clk *fck,
145150 struct clk *ick, struct ti_sysc_cookie *cookie);
146151 void (*clkdm_deny_idle)(struct device *dev,
include/linux/soc/qcom/apr.h+1−0
@@ -85,6 +85,7 @@ struct apr_device { · 84 unmodified lines
8585 uint16_t domain_id;
8686 uint32_t version;
8787 char name[APR_NAME_SIZE];
88+ const char *service_path;
8889 spinlock_t lock;
8990 struct list_head node;
9091 };
include/linux/soc/qcom/pdr.h+29−0
@@ -0,0 +1,29 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef __QCOM_PDR_HELPER__
3+#define __QCOM_PDR_HELPER__
4+
5+#include <linux/soc/qcom/qmi.h>
6+
7+#define SERVREG_NAME_LENGTH 64
8+
9+struct pdr_service;
10+struct pdr_handle;
11+
12+enum servreg_service_state {
13+ SERVREG_LOCATOR_ERR = 0x1,
14+ SERVREG_SERVICE_STATE_DOWN = 0x0FFFFFFF,
15+ SERVREG_SERVICE_STATE_UP = 0x1FFFFFFF,
16+ SERVREG_SERVICE_STATE_EARLY_DOWN = 0x2FFFFFFF,
17+ SERVREG_SERVICE_STATE_UNINIT = 0x7FFFFFFF,
18+};
19+
20+struct pdr_handle *pdr_handle_alloc(void (*status)(int state,
21+ char *service_path,
22+ void *priv), void *priv);
23+struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
24+ const char *service_name,
25+ const char *service_path);
26+int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds);
27+void pdr_handle_release(struct pdr_handle *pdr);
28+
29+#endif
include/linux/soc/qcom/qmi.h+1−0
@@ -88,6 +88,7 @@ struct qmi_elem_info { · 87 unmodified lines
8888 #define QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 5
8989 #define QMI_ERR_INVALID_ID_V01 41
9090 #define QMI_ERR_ENCODING_V01 58
91+#define QMI_ERR_DISABLED_V01 69
9192 #define QMI_ERR_INCOMPATIBLE_STATE_V01 90
9293 #define QMI_ERR_NOT_SUPPORTED_V01 94
9394
include/linux/tee_drv.h+1−18
@@ -49,7 +49,6 @@ struct tee_shm_pool; · 48 unmodified lines
4949 */
5050 struct tee_context {
5151 struct tee_device *teedev;
52− struct list_head list_shm;
5352 void *data;
5453 struct kref refcount;
5554 bool releasing;
@@ -168,9 +167,7 @@ void tee_device_unregister(struct tee_device *teedev); · 112 unmodified lines
168167
169168 /**
170169 * struct tee_shm - shared memory object
171− * @teedev: device used to allocate the object
172− * @ctx: context using the object, if NULL the context is gone
173− * @link link element
170+ * @ctx: context using the object
174171 * @paddr: physical address of the shared memory
175172 * @kaddr: virtual address of the shared memory
176173 * @size: size of shared memory
@@ -185,9 +182,7 @@ void tee_device_unregister(struct tee_device *teedev); · 8 unmodified lines
185182 * subsystem and from drivers that implements their own shm pool manager.
186183 */
187184 struct tee_shm {
188− struct tee_device *teedev;
189185 struct tee_context *ctx;
190− struct list_head link;
191186 phys_addr_t paddr;
192187 void *kaddr;
193188 size_t size;
@@ -318,18 +313,6 @@ void *tee_get_drvdata(struct tee_device *teedev); · 124 unmodified lines
318313 */
319314 struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
320315
321−/**
322− * tee_shm_priv_alloc() - Allocate shared memory privately
323− * @dev: Device that allocates the shared memory
324− * @size: Requested size of shared memory
325− *
326− * Allocates shared memory buffer that is not associated with any client
327− * context. Such buffers are owned by TEE driver and used for internal calls.
328− *
329− * @returns a pointer to 'struct tee_shm'
330− */
331−struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size);
332−
333316 /**
334317 * tee_shm_register() - Register shared memory buffer
335318 * @ctx: Context that registers the shared memory
include/soc/fsl/dpaa2-io.h+5−1
@@ -1,7 +1,7 @@
11 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
22 /*
33 * Copyright 2014-2016 Freescale Semiconductor Inc.
4− * Copyright NXP
4+ * Copyright 2017-2019 NXP
55 *
66 */
77 #ifndef __FSL_DPAA2_IO_H
@@ -109,6 +109,10 @@ int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid, · 101 unmodified lines
109109
110110 int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid,
111111 const struct dpaa2_fd *fd);
112+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid,
113+ const struct dpaa2_fd *fd, int number_of_frame);
114+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid,
115+ const struct dpaa2_fd *fd, int number_of_frame);
112116 int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
113117 u16 qdbin, const struct dpaa2_fd *fd);
114118 int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid,
include/soc/fsl/qe/ucc_fast.h+3−3
@@ -178,10 +178,10 @@ struct ucc_fast_info { · 177 unmodified lines
178178 struct ucc_fast_private {
179179 struct ucc_fast_info *uf_info;
180180 struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */
181− u32 __iomem *p_ucce; /* a pointer to the event register in memory. */
182− u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */
181+ __be32 __iomem *p_ucce; /* a pointer to the event register in memory. */
182+ __be32 __iomem *p_uccm; /* a pointer to the mask register in memory. */
183183 #ifdef CONFIG_UGETH_TX_ON_DEMAND
184− u16 __iomem *p_utodr; /* pointer to the transmit on demand register */
184+ __be16 __iomem *p_utodr;/* pointer to the transmit on demand register */
185185 #endif
186186 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
187187 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
include/soc/fsl/qe/ucc_slow.h+6−7
@@ -184,7 +184,7 @@ struct ucc_slow_info { · 183 unmodified lines
184184 struct ucc_slow_private {
185185 struct ucc_slow_info *us_info;
186186 struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
187− struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */
187+ struct ucc_slow_pram __iomem *us_pram; /* a pointer to the parameter RAM */
188188 s32 us_pram_offset;
189189 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
190190 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
@@ -196,13 +196,12 @@ struct ucc_slow_private { · 5 unmodified lines
196196 and length for first BD in a frame */
197197 s32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */
198198 s32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */
199− struct qe_bd *confBd; /* next BD for confirm after Tx */
200− struct qe_bd *tx_bd; /* next BD for new Tx request */
201− struct qe_bd *rx_bd; /* next BD to collect after Rx */
199+ struct qe_bd __iomem *confBd; /* next BD for confirm after Tx */
200+ struct qe_bd __iomem *tx_bd; /* next BD for new Tx request */
201+ struct qe_bd __iomem *rx_bd; /* next BD to collect after Rx */
202202 void *p_rx_frame; /* accumulating receive frame */
203− u16 *p_ucce; /* a pointer to the event register in memory.
204− */
205− u16 *p_uccm; /* a pointer to the mask register in memory */
203+ __be16 __iomem *p_ucce; /* a pointer to the event register in memory */
204+ __be16 __iomem *p_uccm; /* a pointer to the mask register in memory */
206205 u16 saved_uccm; /* a saved mask for the RX Interrupt bits */
207206 #ifdef STATISTICS
208207 u32 tx_frames; /* Transmitted frames counters */
include/soc/qcom/rpmh.h+0−5
@@ -20,8 +20,6 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, · 19 unmodified lines
2020 int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
2121 const struct tcs_cmd *cmd, u32 *n);
2222
23−int rpmh_flush(const struct device *dev);
24−
2523 int rpmh_invalidate(const struct device *dev);
2624
2725 #else
@@ -40,9 +38,6 @@ static inline int rpmh_write_batch(const struct device *dev, · 12 unmodified lines
4038 const struct tcs_cmd *cmd, u32 *n)
4139 { return -ENODEV; }
4240
43−static inline int rpmh_flush(const struct device *dev)
44−{ return -ENODEV; }
45−
4641 static inline int rpmh_invalidate(const struct device *dev)
4742 { return -ENODEV; }
4843