From a4b2e6063cfeaab1160501acfb27e8618a7c693f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 15 Dec 2022 16:20:23 +0100 Subject: firmware: xilinx: Clear IOCTL_SET_SD_TAPDELAY using PM_MMIO_WRITE In case the tap delay required by Arasan SDHCI is set to 0, the current embeddedsw firmware unconditionally writes IOU_SLCR SD_ITAPDLY to 0x100 (SD0_ITAPDLYENA=1, SD0_ITAPDLYSEL=0). Previous behavior was to keep the IOU_SLCR SD_ITAPDLY set to 0x0. There is some sort of difference in the behavior between SD0_ITAPDLYENA=1/0 with the same SD0_ITAPDLYSEL=0, even though the behavior should be identical -- zero delay added to rxclk_in line. The former breaks HS200 training in low temperature conditions. Write IOU_SLCR SD_ITAPDLY register to 0 using PM_MMIO_WRITE which seem to allow unrestricted WRITE access (and PM_MMIO_READ which allows read access) to the entire address space. This way, it is possible to work around the defect in IOCTL_SET_SD_TAPDELAY design which does not permit clearing SDx_ITAPDLYENA bit. Note that the embeddedsw firmware does not permit clearing the SD_ITAPDLY SD0_ITAPDLYENA bit, this bit can only ever be set by the firmware and it is often impossible to update the possibly broken firmware. Signed-off-by: Marek Vasut Link: https://lore.kernel.org/r/20221215152023.8387-1-marex@denx.de Signed-off-by: Michal Simek --- include/linux/firmware/xlnx-zynqmp.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index b986e267d149..eb88b4ba62f9 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -79,6 +79,10 @@ #define EVENT_ERROR_PSM_ERR1 (0x28108000U) #define EVENT_ERROR_PSM_ERR2 (0x2810C000U) +/* ZynqMP SD tap delay tuning */ +#define SD_ITAPDLY 0xFF180314 +#define SD_OTAPDLYSEL 0xFF180318 + enum pm_api_cb_id { PM_INIT_SUSPEND_CB = 30, PM_ACKNOWLEDGE_CB = 31, -- cgit v1.2.3 From 33ae3d0955943ac5bacfcb6911cf7cb74822bf8c Mon Sep 17 00:00:00 2001 From: Dawei Li Date: Fri, 6 Jan 2023 23:28:03 +0800 Subject: soc: qcom: apr: make remove callback of apr driver void returned Since commit fc7a6209d571 ("bus: Make remove callback return void") forces bus_type::remove be void-returned, it doesn't make much sense for any bus based driver implementing remove callbalk to return non-void to its caller. As such, change the remove function for apr bus based drivers to return void. Signed-off-by: Dawei Li Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/TYCP286MB23232B7968D34DB8323B0F16CAFB9@TYCP286MB2323.JPNP286.PROD.OUTLOOK.COM --- include/linux/soc/qcom/apr.h | 2 +- sound/soc/qcom/qdsp6/q6core.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h index 23c5b30f3511..be98aebcb3e1 100644 --- a/include/linux/soc/qcom/apr.h +++ b/include/linux/soc/qcom/apr.h @@ -153,7 +153,7 @@ typedef struct apr_device gpr_device_t; struct apr_driver { int (*probe)(struct apr_device *sl); - int (*remove)(struct apr_device *sl); + void (*remove)(struct apr_device *sl); int (*callback)(struct apr_device *a, struct apr_resp_pkt *d); int (*gpr_callback)(struct gpr_resp_pkt *d, void *data, int op); diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c index 5358fefd4210..49cfb32cd209 100644 --- a/sound/soc/qcom/qdsp6/q6core.c +++ b/sound/soc/qcom/qdsp6/q6core.c @@ -339,7 +339,7 @@ static int q6core_probe(struct apr_device *adev) return 0; } -static int q6core_exit(struct apr_device *adev) +static void q6core_exit(struct apr_device *adev) { struct q6core *core = dev_get_drvdata(&adev->dev); @@ -350,8 +350,6 @@ static int q6core_exit(struct apr_device *adev) g_core = NULL; kfree(core); - - return 0; } #ifdef CONFIG_OF -- cgit v1.2.3 From e656cd0bcf3d2ba2eceac82b44714bf355428ec4 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 9 Jan 2023 14:05:22 +0100 Subject: soc: qcom: rmtfs: Optionally map RMTFS to more VMs Some SoCs require that RMTFS is also mapped to the NAV VM. Trying to power on the modem without that results in the whole platform crashing and forces a hard reboot within about 2 seconds. Add support for mapping the region to additional VMs, such as NAV to open a path towards enabling modem on such platforms. Signed-off-by: Loic Poulain [Konrad: reword, make conditional and flexible, add a define for NAV VMID] Signed-off-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230109130523.298971-2-konrad.dybcio@linaro.org --- drivers/soc/qcom/rmtfs_mem.c | 29 ++++++++++++++++++++++------- include/linux/qcom_scm.h | 1 + 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 0feaae357821..9d59ad509a5c 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -17,6 +17,7 @@ #include #define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1) +#define NUM_MAX_VMIDS 2 static dev_t qcom_rmtfs_mem_major; @@ -171,12 +172,12 @@ static void qcom_rmtfs_mem_release_device(struct device *dev) static int qcom_rmtfs_mem_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct qcom_scm_vmperm perms[2]; + struct qcom_scm_vmperm perms[NUM_MAX_VMIDS + 1]; struct reserved_mem *rmem; struct qcom_rmtfs_mem *rmtfs_mem; u32 client_id; - u32 vmid; - int ret; + u32 num_vmids, vmid[NUM_MAX_VMIDS]; + int ret, i; rmem = of_reserved_mem_lookup(node); if (!rmem) { @@ -226,7 +227,18 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev) goto put_device; } - ret = of_property_read_u32(node, "qcom,vmid", &vmid); + num_vmids = of_property_count_u32_elems(node, "qcom,vmid"); + if (num_vmids < 0) { + dev_err(&pdev->dev, "failed to count qcom,vmid elements: %d\n", ret); + goto remove_cdev; + } else if (num_vmids > NUM_MAX_VMIDS) { + dev_warn(&pdev->dev, + "too many VMIDs (%d) specified! Only mapping first %d entries\n", + num_vmids, NUM_MAX_VMIDS); + num_vmids = NUM_MAX_VMIDS; + } + + ret = of_property_read_u32_array(node, "qcom,vmid", vmid, num_vmids); if (ret < 0 && ret != -EINVAL) { dev_err(&pdev->dev, "failed to parse qcom,vmid\n"); goto remove_cdev; @@ -238,12 +250,15 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev) perms[0].vmid = QCOM_SCM_VMID_HLOS; perms[0].perm = QCOM_SCM_PERM_RW; - perms[1].vmid = vmid; - perms[1].perm = QCOM_SCM_PERM_RW; + + for (i = 0; i < num_vmids; i++) { + perms[i + 1].vmid = vmid[i]; + perms[i + 1].perm = QCOM_SCM_PERM_RW; + } rmtfs_mem->perms = BIT(QCOM_SCM_VMID_HLOS); ret = qcom_scm_assign_mem(rmtfs_mem->addr, rmtfs_mem->size, - &rmtfs_mem->perms, perms, 2); + &rmtfs_mem->perms, perms, num_vmids + 1); if (ret < 0) { dev_err(&pdev->dev, "assign memory failed\n"); goto remove_cdev; diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index f8335644a01a..150b72edb879 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -55,6 +55,7 @@ enum qcom_scm_ice_cipher { #define QCOM_SCM_VMID_MSS_MSA 0xF #define QCOM_SCM_VMID_WLAN 0x18 #define QCOM_SCM_VMID_WLAN_CE 0x19 +#define QCOM_SCM_VMID_NAV 0x2B #define QCOM_SCM_PERM_READ 0x4 #define QCOM_SCM_PERM_WRITE 0x2 #define QCOM_SCM_PERM_EXEC 0x1 -- cgit v1.2.3 From 45ca30eb9dfe622b00ce352cf28ee141d243254b Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 9 Jan 2023 14:05:23 +0100 Subject: dt-bindings: firmware: qcom: scm: Separate VMIDs from header to bindings The SCM VMIDs represent predefined mappings that come from the irreplaceable and non-omittable firmware that comes with every Qualcomm SoC (unless you steal engineering samples from the factory) and help clarify otherwise totally magic numbers which we are required to pass to the secure world for some parts of the SoC to work at all (with modem being the prime example). On top of that, with changes to the rmtfs binding, secure VMIDs will become useful to have in device trees for readability. Separate them out and add to include/dt-bindings. Signed-off-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230109130523.298971-3-konrad.dybcio@linaro.org --- include/dt-bindings/firmware/qcom,scm.h | 16 ++++++++++++++++ include/linux/qcom_scm.h | 7 ++----- 2 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 include/dt-bindings/firmware/qcom,scm.h (limited to 'include/linux') diff --git a/include/dt-bindings/firmware/qcom,scm.h b/include/dt-bindings/firmware/qcom,scm.h new file mode 100644 index 000000000000..1a4e68fa0744 --- /dev/null +++ b/include/dt-bindings/firmware/qcom,scm.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Linaro Ltd. + */ + +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_SCM_H +#define _DT_BINDINGS_FIRMWARE_QCOM_SCM_H + +#define QCOM_SCM_VMID_HLOS 0x3 +#define QCOM_SCM_VMID_MSS_MSA 0xF +#define QCOM_SCM_VMID_WLAN 0x18 +#define QCOM_SCM_VMID_WLAN_CE 0x19 +#define QCOM_SCM_VMID_NAV 0x2B + +#endif diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 150b72edb879..1e449a5d7f5c 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -9,6 +9,8 @@ #include #include +#include + #define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) #define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0 #define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1 @@ -51,11 +53,6 @@ enum qcom_scm_ice_cipher { QCOM_SCM_ICE_CIPHER_AES_256_CBC = 4, }; -#define QCOM_SCM_VMID_HLOS 0x3 -#define QCOM_SCM_VMID_MSS_MSA 0xF -#define QCOM_SCM_VMID_WLAN 0x18 -#define QCOM_SCM_VMID_WLAN_CE 0x19 -#define QCOM_SCM_VMID_NAV 0x2B #define QCOM_SCM_PERM_READ 0x4 #define QCOM_SCM_PERM_WRITE 0x2 #define QCOM_SCM_PERM_EXEC 0x1 -- cgit v1.2.3 From 2c3e674465e73e2f7eb52c39dc5c5e97e78e68ea Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:50:47 +0000 Subject: firmware: arm_scmi: Refactor device create/destroy helpers Refactor SCMI device create/destroy helpers: it is now possible to ask for the creation of all the currently requested devices for a whole protocol, not only for the creation of a single well-defined device. While at that, re-instate uniqueness checks on the creation of SCMI SystemPower devices. Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222185049.737625-8-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 141 ++++++++++++++++++++++++++++++++++--- drivers/firmware/arm_scmi/common.h | 8 ++- drivers/firmware/arm_scmi/driver.c | 9 ++- include/linux/scmi_protocol.h | 5 -- 4 files changed, 141 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 61113def5a9a..190999a658b2 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -7,6 +7,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -30,6 +31,9 @@ struct scmi_requested_dev { struct list_head node; }; +/* Track globally the creation of SCMI SystemPower related devices */ +static atomic_t scmi_syspower_registered = ATOMIC_INIT(0); + /** * scmi_protocol_device_request - Helper to request a device * @@ -213,11 +217,11 @@ static int scmi_match_by_id_table(struct device *dev, void *data) struct scmi_device_id *id_table = data; return sdev->protocol_id == id_table->protocol_id && - !strcmp(sdev->name, id_table->name); + (id_table->name && !strcmp(sdev->name, id_table->name)); } -struct scmi_device *scmi_child_dev_find(struct device *parent, - int prot_id, const char *name) +static struct scmi_device *scmi_child_dev_find(struct device *parent, + int prot_id, const char *name) { struct scmi_device_id id_table; struct device *dev; @@ -297,13 +301,53 @@ static void scmi_device_release(struct device *dev) kfree(to_scmi_dev(dev)); } -struct scmi_device * -scmi_device_create(struct device_node *np, struct device *parent, int protocol, - const char *name) +static void __scmi_device_destroy(struct scmi_device *scmi_dev) +{ + pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n", + of_node_full_name(scmi_dev->dev.parent->of_node), + dev_name(&scmi_dev->dev), scmi_dev->protocol_id, + scmi_dev->name); + + if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM) + atomic_set(&scmi_syspower_registered, 0); + + kfree_const(scmi_dev->name); + ida_free(&scmi_bus_id, scmi_dev->id); + device_unregister(&scmi_dev->dev); +} + +static struct scmi_device * +__scmi_device_create(struct device_node *np, struct device *parent, + int protocol, const char *name) { int id, retval; struct scmi_device *scmi_dev; + /* + * If the same protocol/name device already exist under the same parent + * (i.e. SCMI instance) just return the existent device. + * This avoids any race between the SCMI driver, creating devices for + * each DT defined protocol at probe time, and the concurrent + * registration of SCMI drivers. + */ + scmi_dev = scmi_child_dev_find(parent, protocol, name); + if (scmi_dev) + return scmi_dev; + + /* + * Ignore any possible subsequent failures while creating the device + * since we are doomed anyway at that point; not using a mutex which + * spans across this whole function to keep things simple and to avoid + * to serialize all the __scmi_device_create calls across possibly + * different SCMI server instances (parent) + */ + if (protocol == SCMI_PROTOCOL_SYSTEM && + atomic_cmpxchg(&scmi_syspower_registered, 0, 1)) { + dev_warn(parent, + "SCMI SystemPower protocol device must be unique !\n"); + return NULL; + } + scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL); if (!scmi_dev) return NULL; @@ -333,6 +377,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, if (retval) goto put_dev; + pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n", + of_node_full_name(parent->of_node), + dev_name(&scmi_dev->dev), protocol, name); + return scmi_dev; put_dev: kfree_const(scmi_dev->name); @@ -341,18 +389,85 @@ put_dev: return NULL; } -void scmi_device_destroy(struct scmi_device *scmi_dev) +/** + * scmi_device_create - A method to create one or more SCMI devices + * + * @np: A reference to the device node to use for the new device(s) + * @parent: The parent device to use identifying a specific SCMI instance + * @protocol: The SCMI protocol to be associated with this device + * @name: The requested-name of the device to be created; this is optional + * and if no @name is provided, all the devices currently known to + * be requested on the SCMI bus for @protocol will be created. + * + * This method can be invoked to create a single well-defined device (like + * a transport device or a device requested by an SCMI driver loaded after + * the core SCMI stack has been probed), or to create all the devices currently + * known to have been requested by the loaded SCMI drivers for a specific + * protocol (typically during SCMI core protocol enumeration at probe time). + * + * Return: The created device (or one of them if @name was NOT provided and + * multiple devices were created) or NULL if no device was created; + * note that NULL indicates an error ONLY in case a specific @name + * was provided: when @name param was not provided, a number of devices + * could have been potentially created for a whole protocol, unless no + * device was found to have been requested for that specific protocol. + */ +struct scmi_device *scmi_device_create(struct device_node *np, + struct device *parent, int protocol, + const char *name) { - kfree_const(scmi_dev->name); - ida_free(&scmi_bus_id, scmi_dev->id); - device_unregister(&scmi_dev->dev); + struct list_head *phead; + struct scmi_requested_dev *rdev; + struct scmi_device *scmi_dev = NULL; + + if (name) + return __scmi_device_create(np, parent, protocol, name); + + mutex_lock(&scmi_requested_devices_mtx); + phead = idr_find(&scmi_requested_devices, protocol); + /* Nothing to do. */ + if (!phead) { + mutex_unlock(&scmi_requested_devices_mtx); + return scmi_dev; + } + + /* Walk the list of requested devices for protocol and create them */ + list_for_each_entry(rdev, phead, node) { + struct scmi_device *sdev; + + sdev = __scmi_device_create(np, parent, + rdev->id_table->protocol_id, + rdev->id_table->name); + /* Report errors and carry on... */ + if (sdev) + scmi_dev = sdev; + else + pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n", + of_node_full_name(parent->of_node), + rdev->id_table->protocol_id, + rdev->id_table->name); + } + mutex_unlock(&scmi_requested_devices_mtx); + + return scmi_dev; } +EXPORT_SYMBOL_GPL(scmi_device_create); + +void scmi_device_destroy(struct device *parent, int protocol, const char *name) +{ + struct scmi_device *scmi_dev; + + scmi_dev = scmi_child_dev_find(parent, protocol, name); + if (scmi_dev) + __scmi_device_destroy(scmi_dev); +} +EXPORT_SYMBOL_GPL(scmi_device_destroy); static int __scmi_devices_unregister(struct device *dev, void *data) { struct scmi_device *scmi_dev = to_scmi_dev(dev); - scmi_device_destroy(scmi_dev); + __scmi_device_destroy(scmi_dev); return 0; } @@ -374,6 +489,10 @@ int __init scmi_bus_init(void) void __exit scmi_bus_exit(void) { + /* + * Destroy all remaining devices: just in case the drivers were + * manually unbound and at first and then the modules unloaded. + */ scmi_devices_unregister(); bus_unregister(&scmi_bus_type); ida_destroy(&scmi_bus_id); diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 07d34954c060..19726a037991 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -107,6 +107,11 @@ extern struct bus_type scmi_bus_type; #define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1 extern struct blocking_notifier_head scmi_requested_devices_nh; +struct scmi_device *scmi_device_create(struct device_node *np, + struct device *parent, int protocol, + const char *name); +void scmi_device_destroy(struct device *parent, int protocol, const char *name); + int scmi_protocol_acquire(const struct scmi_handle *handle, u8 protocol_id); void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id); @@ -168,9 +173,6 @@ struct scmi_transport_ops { bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer); }; -struct scmi_device *scmi_child_dev_find(struct device *parent, - int prot_id, const char *name); - /** * struct scmi_desc - Description of SoC integration * diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 8591b2c740c6..83a43a5f7bb4 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2091,6 +2091,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, /* Create a uniquely named, dedicated transport device for this chan */ tdev = scmi_device_create(of_node, info->dev, prot_id, name); if (!tdev) { + dev_err(info->dev, + "failed to create transport device (%s)\n", name); devm_kfree(info->dev, cinfo); return -EINVAL; } @@ -2100,7 +2102,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); if (ret) { of_node_put(of_node); - scmi_device_destroy(tdev); + scmi_device_destroy(info->dev, prot_id, name); devm_kfree(info->dev, cinfo); return ret; } @@ -2123,7 +2125,7 @@ idr_alloc: /* Destroy channel and device only if created by this call. */ if (tdev) { of_node_put(of_node); - scmi_device_destroy(tdev); + scmi_device_destroy(info->dev, prot_id, name); devm_kfree(info->dev, cinfo); } return ret; @@ -2202,10 +2204,11 @@ static int scmi_chan_destroy(int id, void *p, void *idr) struct scmi_chan_info *cinfo = p; if (cinfo->dev) { + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); struct scmi_device *sdev = to_scmi_dev(cinfo->dev); of_node_put(cinfo->dev->of_node); - scmi_device_destroy(sdev); + scmi_device_destroy(info->dev, id, sdev->name); cinfo->dev = NULL; } diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 4f765bc788ff..0ce5746a4470 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -804,11 +804,6 @@ struct scmi_device { #define to_scmi_dev(d) container_of(d, struct scmi_device, dev) -struct scmi_device * -scmi_device_create(struct device_node *np, struct device *parent, int protocol, - const char *name); -void scmi_device_destroy(struct scmi_device *scmi_dev); - struct scmi_device_id { u8 protocol_id; const char *name; -- cgit v1.2.3 From e610e81464e4e52645a0f5d259b8a9e3632db6ff Mon Sep 17 00:00:00 2001 From: "Garmin.Chang" Date: Fri, 23 Dec 2022 16:05:53 +0800 Subject: soc: mediatek: pm-domains: Add support for mt8188 Add domain control data including bus protection data size change due to more protection steps in mt8188. Signed-off-by: Garmin.Chang Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20221223080553.9397-3-Garmin.Chang@mediatek.com Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mt8188-pm-domains.h | 623 +++++++++++++++++++++++++++++++ drivers/soc/mediatek/mtk-pm-domains.c | 5 + include/linux/soc/mediatek/infracfg.h | 121 ++++++ 3 files changed, 749 insertions(+) create mode 100644 drivers/soc/mediatek/mt8188-pm-domains.h (limited to 'include/linux') diff --git a/drivers/soc/mediatek/mt8188-pm-domains.h b/drivers/soc/mediatek/mt8188-pm-domains.h new file mode 100644 index 000000000000..0692cb444ed0 --- /dev/null +++ b/drivers/soc/mediatek/mt8188-pm-domains.h @@ -0,0 +1,623 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Garmin Chang + */ + +#ifndef __SOC_MEDIATEK_MT8188_PM_DOMAINS_H +#define __SOC_MEDIATEK_MT8188_PM_DOMAINS_H + +#include "mtk-pm-domains.h" +#include + +/* + * MT8188 power domain support + */ + +static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { + [MT8188_POWER_DOMAIN_MFG0] = { + .name = "mfg0", + .sta_mask = BIT(1), + .ctl_offs = 0x300, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + }, + [MT8188_POWER_DOMAIN_MFG1] = { + .name = "mfg1", + .sta_mask = BIT(2), + .ctl_offs = 0x304, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MFG1_STEP1, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_1_MFG1_STEP3, + MT8188_TOP_AXI_PROT_EN_1_SET, + MT8188_TOP_AXI_PROT_EN_1_CLR, + MT8188_TOP_AXI_PROT_EN_1_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP4, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MFG1_STEP5, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1_STEP6, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + }, + [MT8188_POWER_DOMAIN_MFG2] = { + .name = "mfg2", + .sta_mask = BIT(3), + .ctl_offs = 0x308, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_MFG3] = { + .name = "mfg3", + .sta_mask = BIT(4), + .ctl_offs = 0x30C, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_MFG4] = { + .name = "mfg4", + .sta_mask = BIT(5), + .ctl_offs = 0x310, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_PEXTP_MAC_P0] = { + .name = "pextp_mac_p0", + .sta_mask = BIT(10), + .ctl_offs = 0x324, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_PEXTP_MAC_P0_STEP1, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_PEXTP_MAC_P0_STEP2, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_PEXTP_PHY_TOP] = { + .name = "pextp_phy_top", + .sta_mask = BIT(12), + .ctl_offs = 0x328, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_CSIRX_TOP] = { + .name = "pextp_csirx_top", + .sta_mask = BIT(17), + .ctl_offs = 0x3C4, + .pwr_sta_offs = 0x174, + .pwr_sta2nd_offs = 0x178, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_ETHER] = { + .name = "ether", + .sta_mask = BIT(1), + .ctl_offs = 0x338, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_ETHER_STEP1, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8188_POWER_DOMAIN_HDMI_TX] = { + .name = "hdmi_tx", + .sta_mask = BIT(18), + .ctl_offs = 0x37C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_HDMI_TX_STEP1, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8188_POWER_DOMAIN_ADSP_AO] = { + .name = "adsp_ao", + .sta_mask = BIT(10), + .ctl_offs = 0x35C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_ALWAYS_ON, + }, + [MT8188_POWER_DOMAIN_ADSP_INFRA] = { + .name = "adsp_infra", + .sta_mask = BIT(9), + .ctl_offs = 0x358, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP1, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ALWAYS_ON, + }, + [MT8188_POWER_DOMAIN_ADSP] = { + .name = "adsp", + .sta_mask = BIT(8), + .ctl_offs = 0x354, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP1, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8188_POWER_DOMAIN_AUDIO] = { + .name = "audio", + .sta_mask = BIT(6), + .ctl_offs = 0x34C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8188_POWER_DOMAIN_AUDIO_ASRC] = { + .name = "audio_asrc", + .sta_mask = BIT(7), + .ctl_offs = 0x350, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP1, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_VPPSYS0] = { + .name = "vppsys0", + .sta_mask = BIT(11), + .ctl_offs = 0x360, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP1, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP3, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP4, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0_STEP5, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA), + }, + }, + [MT8188_POWER_DOMAIN_VDOSYS0] = { + .name = "vdosys0", + .sta_mask = BIT(13), + .ctl_offs = 0x368, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS0_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_VDOSYS0_STEP2, + MT8188_TOP_AXI_PROT_EN_SET, + MT8188_TOP_AXI_PROT_EN_CLR, + MT8188_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0_STEP3, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA), + }, + }, + [MT8188_POWER_DOMAIN_VDOSYS1] = { + .name = "vdosys1", + .sta_mask = BIT(14), + .ctl_offs = 0x36C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VDOSYS1_STEP3, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + }, + [MT8188_POWER_DOMAIN_DP_TX] = { + .name = "dp_tx", + .sta_mask = BIT(16), + .ctl_offs = 0x374, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_DP_TX_STEP1, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_EDP_TX] = { + .name = "edp_tx", + .sta_mask = BIT(17), + .ctl_offs = 0x378, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_EDP_TX_STEP1, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR, + MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_VPPSYS1] = { + .name = "vppsys1", + .sta_mask = BIT(12), + .ctl_offs = 0x364, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS1_STEP3, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + }, + [MT8188_POWER_DOMAIN_WPE] = { + .name = "wpe", + .sta_mask = BIT(15), + .ctl_offs = 0x370, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_VDEC0] = { + .name = "vdec0", + .sta_mask = BIT(19), + .ctl_offs = 0x380, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC0_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VDEC0_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_VDEC1] = { + .name = "vdec1", + .sta_mask = BIT(20), + .ctl_offs = 0x384, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_VENC] = { + .name = "venc", + .sta_mask = BIT(22), + .ctl_offs = 0x38C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_VENC_STEP3, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_IMG_VCORE] = { + .name = "vcore", + .sta_mask = BIT(28), + .ctl_offs = 0x3A4, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_VCORE_STEP3, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + }, + [MT8188_POWER_DOMAIN_IMG_MAIN] = { + .name = "img_main", + .sta_mask = BIT(29), + .ctl_offs = 0x3A8, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP2, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_DIP] = { + .name = "dip", + .sta_mask = BIT(30), + .ctl_offs = 0x3AC, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_IPE] = { + .name = "ipe", + .sta_mask = BIT(31), + .ctl_offs = 0x3B0, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_CAM_VCORE] = { + .name = "cam_vcore", + .sta_mask = BIT(27), + .ctl_offs = 0x3A0, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_VCORE_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_1_CAM_VCORE_STEP3, + MT8188_TOP_AXI_PROT_EN_1_SET, + MT8188_TOP_AXI_PROT_EN_1_CLR, + MT8188_TOP_AXI_PROT_EN_1_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP4, + MT8188_TOP_AXI_PROT_EN_MM_SET, + MT8188_TOP_AXI_PROT_EN_MM_CLR, + MT8188_TOP_AXI_PROT_EN_MM_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_VCORE_STEP5, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + }, + [MT8188_POWER_DOMAIN_CAM_MAIN] = { + .name = "cam_main", + .sta_mask = BIT(24), + .ctl_offs = 0x394, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .bp_infracfg = { + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP1, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP2, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP3, + MT8188_TOP_AXI_PROT_EN_MM_2_SET, + MT8188_TOP_AXI_PROT_EN_MM_2_CLR, + MT8188_TOP_AXI_PROT_EN_MM_2_STA), + BUS_PROT_WR(MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP4, + MT8188_TOP_AXI_PROT_EN_2_SET, + MT8188_TOP_AXI_PROT_EN_2_CLR, + MT8188_TOP_AXI_PROT_EN_2_STA), + }, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_CAM_SUBA] = { + .name = "cam_suba", + .sta_mask = BIT(25), + .ctl_offs = 0x398, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8188_POWER_DOMAIN_CAM_SUBB] = { + .name = "cam_subb", + .sta_mask = BIT(26), + .ctl_offs = 0x39C, + .pwr_sta_offs = 0x16C, + .pwr_sta2nd_offs = 0x170, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + }, +}; + +static const struct scpsys_soc_data mt8188_scpsys_data = { + .domains_data = scpsys_domain_data_mt8188, + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8188), +}; + +#endif /* __SOC_MEDIATEK_MT8188_PM_DOMAINS_H */ diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index 474b272f9b02..ea3878bf4387 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -21,6 +21,7 @@ #include "mt8173-pm-domains.h" #include "mt8183-pm-domains.h" #include "mt8186-pm-domains.h" +#include "mt8188-pm-domains.h" #include "mt8192-pm-domains.h" #include "mt8195-pm-domains.h" @@ -579,6 +580,10 @@ static const struct of_device_id scpsys_of_match[] = { .compatible = "mediatek,mt8186-power-controller", .data = &mt8186_scpsys_data, }, + { + .compatible = "mediatek,mt8188-power-controller", + .data = &mt8188_scpsys_data, + }, { .compatible = "mediatek,mt8192-power-controller", .data = &mt8192_scpsys_data, diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h index 50804ac748bd..07f67b3d8e97 100644 --- a/include/linux/soc/mediatek/infracfg.h +++ b/include/linux/soc/mediatek/infracfg.h @@ -140,6 +140,127 @@ #define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13) #define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21) +#define MT8188_TOP_AXI_PROT_EN_SET 0x2A0 +#define MT8188_TOP_AXI_PROT_EN_CLR 0x2A4 +#define MT8188_TOP_AXI_PROT_EN_STA 0x228 +#define MT8188_TOP_AXI_PROT_EN_1_SET 0x2A8 +#define MT8188_TOP_AXI_PROT_EN_1_CLR 0x2AC +#define MT8188_TOP_AXI_PROT_EN_1_STA 0x258 +#define MT8188_TOP_AXI_PROT_EN_2_SET 0x714 +#define MT8188_TOP_AXI_PROT_EN_2_CLR 0x718 +#define MT8188_TOP_AXI_PROT_EN_2_STA 0x724 + +#define MT8188_TOP_AXI_PROT_EN_MM_SET 0x2D4 +#define MT8188_TOP_AXI_PROT_EN_MM_CLR 0x2D8 +#define MT8188_TOP_AXI_PROT_EN_MM_STA 0x2EC +#define MT8188_TOP_AXI_PROT_EN_MM_2_SET 0xDCC +#define MT8188_TOP_AXI_PROT_EN_MM_2_CLR 0xDD0 +#define MT8188_TOP_AXI_PROT_EN_MM_2_STA 0xDD8 + +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_SET 0xB84 +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_CLR 0xB88 +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_STA 0xB90 +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET 0xBCC +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR 0xBD0 +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA 0xBD8 + +#define MT8188_TOP_AXI_PROT_EN_MFG1_STEP1 BIT(11) +#define MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP2 BIT(7) +#define MT8188_TOP_AXI_PROT_EN_1_MFG1_STEP3 BIT(19) +#define MT8188_TOP_AXI_PROT_EN_2_MFG1_STEP4 BIT(5) +#define MT8188_TOP_AXI_PROT_EN_MFG1_STEP5 GENMASK(22, 21) +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1_STEP6 BIT(17) + +#define MT8188_TOP_AXI_PROT_EN_PEXTP_MAC_P0_STEP1 BIT(2) +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_PEXTP_MAC_P0_STEP2 (BIT(8) | BIT(18) | BIT(30)) +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_ETHER_STEP1 BIT(24) +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_HDMI_TX_STEP1 BIT(20) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1 GENMASK(31, 29) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP2 (GENMASK(4, 3) | BIT(28)) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP1 (GENMASK(16, 14) | BIT(23) | \ + BIT(27)) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_INFRA_STEP2 (GENMASK(19, 17) | GENMASK(26, 25)) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP1 GENMASK(11, 8) +#define MT8188_TOP_AXI_PROT_EN_2_ADSP_STEP2 GENMASK(22, 21) +#define MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1 BIT(20) +#define MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2 BIT(12) +#define MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP1 BIT(24) +#define MT8188_TOP_AXI_PROT_EN_2_AUDIO_ASRC_STEP2 BIT(13) + +#define MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP1 BIT(10) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP2 GENMASK(9, 8) +#define MT8188_TOP_AXI_PROT_EN_VPPSYS0_STEP3 BIT(23) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS0_STEP4 (BIT(1) | BIT(4) | BIT(11)) +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0_STEP5 (BIT(20)) +#define MT8188_TOP_AXI_PROT_EN_MM_VDOSYS0_STEP1 (GENMASK(18, 17) | GENMASK(21, 20)) +#define MT8188_TOP_AXI_PROT_EN_VDOSYS0_STEP2 BIT(6) +#define MT8188_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0_STEP3 BIT(21) +#define MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP1 GENMASK(31, 30) +#define MT8188_TOP_AXI_PROT_EN_MM_VDOSYS1_STEP2 BIT(22) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VDOSYS1_STEP3 BIT(10) +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_DP_TX_STEP1 BIT(23) +#define MT8188_TOP_AXI_PROT_EN_INFRA_VDNR_EDP_TX_STEP1 BIT(22) + +#define MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP1 GENMASK(6, 5) +#define MT8188_TOP_AXI_PROT_EN_MM_VPPSYS1_STEP2 BIT(23) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VPPSYS1_STEP3 BIT(18) +#define MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP1 BIT(23) +#define MT8188_TOP_AXI_PROT_EN_MM_2_WPE_STEP2 BIT(21) +#define MT8188_TOP_AXI_PROT_EN_MM_VDEC0_STEP1 BIT(13) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VDEC0_STEP2 BIT(13) +#define MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP1 BIT(14) +#define MT8188_TOP_AXI_PROT_EN_MM_VDEC1_STEP2 BIT(29) +#define MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP1 (BIT(9) | BIT(11)) +#define MT8188_TOP_AXI_PROT_EN_MM_VENC_STEP2 BIT(26) +#define MT8188_TOP_AXI_PROT_EN_MM_2_VENC_STEP3 BIT(2) +#define MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1 (BIT(1) | BIT(3)) +#define MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP2 BIT(25) +#define MT8188_TOP_AXI_PROT_EN_MM_2_IMG_VCORE_STEP3 BIT(16) +#define MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP1 GENMASK(27, 26) +#define MT8188_TOP_AXI_PROT_EN_MM_2_IMG_MAIN_STEP2 GENMASK(25, 24) +#define MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1 (BIT(2) | BIT(4)) +#define MT8188_TOP_AXI_PROT_EN_2_CAM_VCORE_STEP2 BIT(0) +#define MT8188_TOP_AXI_PROT_EN_1_CAM_VCORE_STEP3 BIT(22) +#define MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP4 BIT(24) +#define MT8188_TOP_AXI_PROT_EN_MM_2_CAM_VCORE_STEP5 BIT(17) +#define MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP1 GENMASK(31, 30) +#define MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP2 BIT(2) +#define MT8188_TOP_AXI_PROT_EN_MM_2_CAM_MAIN_STEP3 GENMASK(29, 28) +#define MT8188_TOP_AXI_PROT_EN_2_CAM_MAIN_STEP4 BIT(1) + +#define MT8188_SMI_COMMON_CLAMP_EN_STA 0x3C0 +#define MT8188_SMI_COMMON_CLAMP_EN_SET 0x3C4 +#define MT8188_SMI_COMMON_CLAMP_EN_CLR 0x3C8 + +#define MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VDO0 GENMASK(3, 1) +#define MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VPP1 GENMASK(2, 1) +#define MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1 BIT(0) + +#define MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBA_TO_VPP0 GENMASK(3, 2) +#define MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBB_TO_VDO0 GENMASK(3, 2) + +#define MT8188_SMI_LARB10_RESET_ADDR 0xC +#define MT8188_SMI_LARB11A_RESET_ADDR 0xC +#define MT8188_SMI_LARB11C_RESET_ADDR 0xC +#define MT8188_SMI_LARB12_RESET_ADDR 0xC +#define MT8188_SMI_LARB11B_RESET_ADDR 0xC +#define MT8188_SMI_LARB15_RESET_ADDR 0xC +#define MT8188_SMI_LARB16B_RESET_ADDR 0xA0 +#define MT8188_SMI_LARB17B_RESET_ADDR 0xA0 +#define MT8188_SMI_LARB16A_RESET_ADDR 0xA0 +#define MT8188_SMI_LARB17A_RESET_ADDR 0xA0 + +#define MT8188_SMI_LARB10_RESET BIT(0) +#define MT8188_SMI_LARB11A_RESET BIT(0) +#define MT8188_SMI_LARB11C_RESET BIT(0) +#define MT8188_SMI_LARB12_RESET BIT(8) +#define MT8188_SMI_LARB11B_RESET BIT(0) +#define MT8188_SMI_LARB15_RESET BIT(0) +#define MT8188_SMI_LARB16B_RESET BIT(4) +#define MT8188_SMI_LARB17B_RESET BIT(4) +#define MT8188_SMI_LARB16A_RESET BIT(4) +#define MT8188_SMI_LARB17A_RESET BIT(4) + #define MT8186_TOP_AXI_PROT_EN_SET (0x2A0) #define MT8186_TOP_AXI_PROT_EN_CLR (0x2A4) #define MT8186_TOP_AXI_PROT_EN_STA (0x228) -- cgit v1.2.3 From be234d00240cbb53d5a1fa0e58b2d14ff121dca2 Mon Sep 17 00:00:00 2001 From: "Nancy.Lin" Date: Fri, 13 Jan 2023 18:44:26 +0800 Subject: soc: mediatek: add mtk-mmsys ethdr and mdp_rdma components Add new mmsys component: ethdr_mixer and mdp_rdma. These components will use in mt8195 vdosys1. Signed-off-by: Nancy.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Tested-by: AngeloGioacchino Del Regno Tested-by: Bo-Chen Chen Link: https://lore.kernel.org/r/20230113104434.28023-4-nancy.lin@mediatek.com Signed-off-by: Matthias Brugger --- include/linux/soc/mediatek/mtk-mmsys.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index b85f66db33e1..3e4b080627c3 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -36,7 +36,16 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_DSI1, DDP_COMPONENT_DSI2, DDP_COMPONENT_DSI3, + DDP_COMPONENT_ETHDR_MIXER, DDP_COMPONENT_GAMMA, + DDP_COMPONENT_MDP_RDMA0, + DDP_COMPONENT_MDP_RDMA1, + DDP_COMPONENT_MDP_RDMA2, + DDP_COMPONENT_MDP_RDMA3, + DDP_COMPONENT_MDP_RDMA4, + DDP_COMPONENT_MDP_RDMA5, + DDP_COMPONENT_MDP_RDMA6, + DDP_COMPONENT_MDP_RDMA7, DDP_COMPONENT_MERGE0, DDP_COMPONENT_MERGE1, DDP_COMPONENT_MERGE2, -- cgit v1.2.3 From 3dd20b715c4483ae5d8ddb22cbc8e116944094e4 Mon Sep 17 00:00:00 2001 From: "Nancy.Lin" Date: Fri, 13 Jan 2023 18:44:29 +0800 Subject: soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1 Add four mmsys config APIs. The config APIs are used for config mmsys reg. Some mmsys regs need to be set according to the HW engine binding to the mmsys simultaneously. 1. mtk_mmsys_merge_async_config: config merge async width/height. async is used for cross-clock domain synchronization. 2. mtk_mmsys_hdr_confing: config hdr backend async width/height. 3. mtk_mmsys_mixer_in_config and mtk_mmsys_mixer_in_config: config mixer related settings. Signed-off-by: Nancy.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Tested-by: AngeloGioacchino Del Regno Tested-by: Bo-Chen Chen Link: https://lore.kernel.org/r/20230113104434.28023-7-nancy.lin@mediatek.com Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mt8195-mmsys.h | 6 ++++++ drivers/soc/mediatek/mtk-mmsys.c | 35 ++++++++++++++++++++++++++++++++++ include/linux/soc/mediatek/mtk-mmsys.h | 9 +++++++++ 3 files changed, 50 insertions(+) (limited to 'include/linux') diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h index fd7b455bd675..454944a9409c 100644 --- a/drivers/soc/mediatek/mt8195-mmsys.h +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -75,6 +75,12 @@ #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0 (2 << 16) #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE (3 << 16) +#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD 0xe30 +#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD 0xe70 +#define MT8195_VDO1_HDR_TOP_CFG 0xd00 +#define MT8195_VDO1_MIXER_IN1_ALPHA 0xd30 +#define MT8195_VDO1_MIXER_IN1_PAD 0xd40 + #define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN 0xf04 #define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0 1 diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 602197e95f67..2aeb739b8503 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -145,6 +145,41 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, } EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect); +void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height) +{ + mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MERGE0_ASYNC_CFG_WD + 0x10 * idx, + ~0, height << 16 | width); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_merge_async_config); + +void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height) +{ + mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_HDRBE_ASYNC_CFG_WD, ~0, + be_height << 16 | be_width); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_hdr_config); + +void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16 alpha, + u8 mode, u32 biwidth) +{ + struct mtk_mmsys *mmsys = dev_get_drvdata(dev); + + mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0, + alpha << 16 | alpha); + mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx), + alpha_sel << (19 + idx)); + mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4, + GENMASK(31, 16) | GENMASK(1, 0), biwidth << 16 | mode); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_config); + +void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap) +{ + mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4, + BIT(4), channel_swap << 4); +} +EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_channel_swap); + void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val) { struct mtk_mmsys *mmsys = dev_get_drvdata(dev); diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 3e4b080627c3..5a6753aed482 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -83,4 +83,13 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val); +void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height); + +void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height); + +void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16 alpha, + u8 mode, u32 biwidth); + +void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap); + #endif /* __MTK_MMSYS_H */ -- cgit v1.2.3 From 8af1f6b5bccb61edc40c3c00cefa7be07c1e5a91 Mon Sep 17 00:00:00 2001 From: "Nancy.Lin" Date: Fri, 13 Jan 2023 18:44:30 +0800 Subject: soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1 Add cmdq support for mtk-mmsys config API. The mmsys config register settings need to take effect with the other HW settings(like OVL_ADAPTOR...) at the same vblanking time. If we use CPU to write the mmsys reg, we can't guarantee all the settings can be written in the same vblanking time. Cmdq is used for this purpose. We prepare all the related HW settings in one cmdq packet. The first command in the packet is "wait stream done", and then following with all the HW settings. After the cmdq packet is flush to GCE HW. The GCE waits for the "stream done event" to coming and then starts flushing all the HW settings. This can guarantee all the settings flush in the same vblanking. Signed-off-by: Nancy.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: CK Hu Tested-by: AngeloGioacchino Del Regno Tested-by: Bo-Chen Chen Link: https://lore.kernel.org/r/20230113104434.28023-8-nancy.lin@mediatek.com Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-mmsys.c | 63 ++++++++++++++++++++++++---------- include/linux/soc/mediatek/mtk-mmsys.h | 15 +++++--- 2 files changed, 55 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 2aeb739b8503..a0a584f16405 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -105,12 +105,27 @@ struct mtk_mmsys { const struct mtk_mmsys_driver_data *data; spinlock_t lock; /* protects mmsys_sw_rst_b reg */ struct reset_controller_dev rcdev; + struct cmdq_client_reg cmdq_base; }; -static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val) +static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val, + struct cmdq_pkt *cmdq_pkt) { u32 tmp; +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + if (cmdq_pkt) { + if (mmsys->cmdq_base.size == 0) { + pr_err("mmsys lose gce property, failed to update mmsys bits with cmdq"); + return; + } + cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys, + mmsys->cmdq_base.offset + offset, val, + mask); + return; + } +#endif + tmp = readl_relaxed(mmsys->regs + offset); tmp = (tmp & ~mask) | (val & mask); writel_relaxed(tmp, mmsys->regs + offset); @@ -127,7 +142,7 @@ void mtk_mmsys_ddp_connect(struct device *dev, for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) mtk_mmsys_update_bits(mmsys, routes[i].addr, routes[i].mask, - routes[i].val); + routes[i].val, NULL); } EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_connect); @@ -141,42 +156,45 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) - mtk_mmsys_update_bits(mmsys, routes[i].addr, routes[i].mask, 0); + mtk_mmsys_update_bits(mmsys, routes[i].addr, routes[i].mask, 0, NULL); } EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect); -void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height) +void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height, + struct cmdq_pkt *cmdq_pkt) { mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MERGE0_ASYNC_CFG_WD + 0x10 * idx, - ~0, height << 16 | width); + ~0, height << 16 | width, cmdq_pkt); } EXPORT_SYMBOL_GPL(mtk_mmsys_merge_async_config); -void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height) +void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height, + struct cmdq_pkt *cmdq_pkt) { mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_HDRBE_ASYNC_CFG_WD, ~0, - be_height << 16 | be_width); + be_height << 16 | be_width, cmdq_pkt); } EXPORT_SYMBOL_GPL(mtk_mmsys_hdr_config); void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16 alpha, - u8 mode, u32 biwidth) + u8 mode, u32 biwidth, struct cmdq_pkt *cmdq_pkt) { struct mtk_mmsys *mmsys = dev_get_drvdata(dev); mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0, - alpha << 16 | alpha); + alpha << 16 | alpha, cmdq_pkt); mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx), - alpha_sel << (19 + idx)); + alpha_sel << (19 + idx), cmdq_pkt); mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4, - GENMASK(31, 16) | GENMASK(1, 0), biwidth << 16 | mode); + GENMASK(31, 16) | GENMASK(1, 0), biwidth << 16 | mode, cmdq_pkt); } EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_config); -void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap) +void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap, + struct cmdq_pkt *cmdq_pkt) { mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4, - BIT(4), channel_swap << 4); + BIT(4), channel_swap << 4, cmdq_pkt); } EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_channel_swap); @@ -187,20 +205,20 @@ void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val) switch (val) { case MTK_DPI_RGB888_SDR_CON: mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT, - MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_SDR_CON); + MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_SDR_CON, NULL); break; case MTK_DPI_RGB565_SDR_CON: mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT, - MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_SDR_CON); + MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_SDR_CON, NULL); break; case MTK_DPI_RGB565_DDR_CON: mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT, - MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_DDR_CON); + MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_DDR_CON, NULL); break; case MTK_DPI_RGB888_DDR_CON: default: mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT, - MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_DDR_CON); + MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_DDR_CON, NULL); break; } } @@ -215,9 +233,9 @@ static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned l spin_lock_irqsave(&mmsys->lock, flags); if (assert) - mtk_mmsys_update_bits(mmsys, mmsys->data->sw0_rst_offset, BIT(id), 0); + mtk_mmsys_update_bits(mmsys, mmsys->data->sw0_rst_offset, BIT(id), 0, NULL); else - mtk_mmsys_update_bits(mmsys, mmsys->data->sw0_rst_offset, BIT(id), BIT(id)); + mtk_mmsys_update_bits(mmsys, mmsys->data->sw0_rst_offset, BIT(id), BIT(id), NULL); spin_unlock_irqrestore(&mmsys->lock, flags); @@ -285,6 +303,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev) } mmsys->data = of_device_get_match_data(&pdev->dev); + +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0); + if (ret) + dev_dbg(dev, "No mediatek,gce-client-reg!\n"); +#endif + platform_set_drvdata(pdev, mmsys); clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver, diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 5a6753aed482..dc2963a0a0f7 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -6,6 +6,10 @@ #ifndef __MTK_MMSYS_H #define __MTK_MMSYS_H +#include +#include +#include + enum mtk_ddp_comp_id; struct device; @@ -83,13 +87,16 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val); -void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height); +void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, + int height, struct cmdq_pkt *cmdq_pkt); -void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height); +void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height, + struct cmdq_pkt *cmdq_pkt); void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16 alpha, - u8 mode, u32 biwidth); + u8 mode, u32 biwidth, struct cmdq_pkt *cmdq_pkt); -void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap); +void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap, + struct cmdq_pkt *cmdq_pkt); #endif /* __MTK_MMSYS_H */ -- cgit v1.2.3 From 40eaa8c0cbba4a27668c7e01373ccd5b38381e2f Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Mon, 23 Jan 2023 15:53:54 +0900 Subject: soc: apple: rtkit: Add apple_rtkit_idle() function This is yet another low power mode, used by DCP. Reviewed-by: Eric Curtin Reviewed-by: Sven Peter Signed-off-by: Hector Martin --- drivers/soc/apple/rtkit.c | 21 +++++++++++++++++++++ include/linux/soc/apple/rtkit.h | 5 +++++ 2 files changed, 26 insertions(+) (limited to 'include/linux') diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c index 8ec74d7539eb..efb1fa77dff2 100644 --- a/drivers/soc/apple/rtkit.c +++ b/drivers/soc/apple/rtkit.c @@ -9,6 +9,7 @@ enum { APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */ APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */ + APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */ APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */ APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */ }; @@ -881,6 +882,26 @@ int apple_rtkit_shutdown(struct apple_rtkit *rtk) } EXPORT_SYMBOL_GPL(apple_rtkit_shutdown); +int apple_rtkit_idle(struct apple_rtkit *rtk) +{ + int ret; + + /* if OFF is used here the co-processor will not wake up again */ + ret = apple_rtkit_set_ap_power_state(rtk, + APPLE_RTKIT_PWR_STATE_IDLE); + if (ret) + return ret; + + ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_IDLE); + if (ret) + return ret; + + rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_IDLE; + rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_IDLE; + return 0; +} +EXPORT_SYMBOL_GPL(apple_rtkit_idle); + int apple_rtkit_quiesce(struct apple_rtkit *rtk) { int ret; diff --git a/include/linux/soc/apple/rtkit.h b/include/linux/soc/apple/rtkit.h index c9cabb679cd1..a2446b45ed7f 100644 --- a/include/linux/soc/apple/rtkit.h +++ b/include/linux/soc/apple/rtkit.h @@ -104,6 +104,11 @@ int apple_rtkit_wake(struct apple_rtkit *rtk); */ int apple_rtkit_shutdown(struct apple_rtkit *rtk); +/* + * Put the co-processor into idle mode + */ +int apple_rtkit_idle(struct apple_rtkit *rtk); + /* * Checks if RTKit is running and ready to handle messages. */ -- cgit v1.2.3 From 4435d63f172851b57a6a0943b73a6b8055a9356f Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Sat, 21 Jan 2023 16:42:53 +0900 Subject: soc: apple: rtkit: Add a private pointer to apple_rtkit_shmem This allows downstream consumers to keep track of private data for shmem mappings. In particular, the Rust abstraction will use this to safely drop data associated with a mapping when it is unmapped. Signed-off-by: Asahi Lina Reviewed-by: Sven Peter Reviewed-by: Eric Curtin Signed-off-by: Hector Martin --- include/linux/soc/apple/rtkit.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/soc/apple/rtkit.h b/include/linux/soc/apple/rtkit.h index a2446b45ed7f..927b214ef1c6 100644 --- a/include/linux/soc/apple/rtkit.h +++ b/include/linux/soc/apple/rtkit.h @@ -22,6 +22,7 @@ * @size: Size of the shared memory buffer. * @iova: Device VA of shared memory buffer. * @is_mapped: Shared memory buffer is managed by the co-processor. + * @private: Private data pointer for the parent driver. */ struct apple_rtkit_shmem { @@ -30,6 +31,7 @@ struct apple_rtkit_shmem { size_t size; dma_addr_t iova; bool is_mapped; + void *private; }; /* -- cgit v1.2.3 From b3892860f50920ea46342d32bf51323877365082 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Sat, 21 Jan 2023 16:41:35 +0900 Subject: soc: apple: rtkit: Export non-devm init/free functions While we normally encourage devm usage by drivers, some consumers (and in particular the upcoming Rust abstractions) might want to manually manage memory. Export the raw functions to make this possible. Signed-off-by: Asahi Lina Reviewed-by: Sven Peter Reviewed-by: Eric Curtin Signed-off-by: Hector Martin --- drivers/soc/apple/rtkit.c | 15 ++++++++++----- include/linux/soc/apple/rtkit.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c index efb1fa77dff2..35ec35aa500d 100644 --- a/drivers/soc/apple/rtkit.c +++ b/drivers/soc/apple/rtkit.c @@ -699,7 +699,7 @@ static int apple_rtkit_request_mbox_chan(struct apple_rtkit *rtk) return 0; } -static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, +struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, const char *mbox_name, int mbox_idx, const struct apple_rtkit_ops *ops) { @@ -751,6 +751,7 @@ free_rtk: kfree(rtk); return ERR_PTR(ret); } +EXPORT_SYMBOL_GPL(apple_rtkit_init); static int apple_rtkit_wait_for_completion(struct completion *c) { @@ -947,10 +948,8 @@ int apple_rtkit_wake(struct apple_rtkit *rtk) } EXPORT_SYMBOL_GPL(apple_rtkit_wake); -static void apple_rtkit_free(void *data) +void apple_rtkit_free(struct apple_rtkit *rtk) { - struct apple_rtkit *rtk = data; - mbox_free_channel(rtk->mbox_chan); destroy_workqueue(rtk->wq); @@ -961,6 +960,12 @@ static void apple_rtkit_free(void *data) kfree(rtk->syslog_msg_buffer); kfree(rtk); } +EXPORT_SYMBOL_GPL(apple_rtkit_free); + +static void apple_rtkit_free_wrapper(void *data) +{ + apple_rtkit_free(data); +} struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, const char *mbox_name, int mbox_idx, @@ -973,7 +978,7 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, if (IS_ERR(rtk)) return rtk; - ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk); + ret = devm_add_action_or_reset(dev, apple_rtkit_free_wrapper, rtk); if (ret) return ERR_PTR(ret); diff --git a/include/linux/soc/apple/rtkit.h b/include/linux/soc/apple/rtkit.h index 927b214ef1c6..fc456f75c131 100644 --- a/include/linux/soc/apple/rtkit.h +++ b/include/linux/soc/apple/rtkit.h @@ -79,6 +79,25 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, const char *mbox_name, int mbox_idx, const struct apple_rtkit_ops *ops); +/* + * Non-devm version of devm_apple_rtkit_init. Must be freed with + * apple_rtkit_free. + * + * @dev: Pointer to the device node this coprocessor is assocated with + * @cookie: opaque cookie passed to all functions defined in rtkit_ops + * @mbox_name: mailbox name used to communicate with the co-processor + * @mbox_idx: mailbox index to be used if mbox_name is NULL + * @ops: pointer to rtkit_ops to be used for this co-processor + */ +struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, + const char *mbox_name, int mbox_idx, + const struct apple_rtkit_ops *ops); + +/* + * Free an instance of apple_rtkit. + */ +void apple_rtkit_free(struct apple_rtkit *rtk); + /* * Reinitialize internal structures. Must only be called with the co-processor * is held in reset. -- cgit v1.2.3 From 58ef4ece1e41ac525db3e79529909683325d85df Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 31 Jan 2023 20:18:51 -0800 Subject: soc: qcom: pmic_glink: Introduce base PMIC GLINK driver The PMIC GLINK service runs on one of the co-processors of some modern Qualcomm platforms and implements USB-C and battery managements. It uses a message based protocol over GLINK for communication with the OS, hence the name. The driver implemented provides the rpmsg device for communication and uses auxiliary bus to spawn off individual devices in respective subsystem. The auxiliary devices are spawned off from a platform_device, so that the drm_bridge is available early, to allow the DisplayPort driver to probe even before the remoteproc has spun up. Signed-off-by: Bjorn Andersson Tested-by: Konrad Dybcio # SM8350 PDX215 Reviewed-by: Neil Armstrong Tested-by: Neil Armstrong # on SM8550-MTP & SM8450-HDK Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230201041853.1934355-3-quic_bjorande@quicinc.com --- drivers/soc/qcom/Kconfig | 15 ++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/pmic_glink.c | 336 ++++++++++++++++++++++++++++++++++++ include/linux/soc/qcom/pmic_glink.h | 32 ++++ 4 files changed, 384 insertions(+) create mode 100644 drivers/soc/qcom/pmic_glink.c create mode 100644 include/linux/soc/qcom/pmic_glink.h (limited to 'include/linux') diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index ae504c43d9e7..df6ff7bf90cb 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -92,6 +92,21 @@ config QCOM_PDR_HELPERS tristate select QCOM_QMI_HELPERS +config QCOM_PMIC_GLINK + tristate "Qualcomm PMIC GLINK driver" + depends on RPMSG + depends on TYPEC + depends on DRM + select AUXILIARY_BUS + select QCOM_PDR_HELPERS + help + The Qualcomm PMIC GLINK driver provides access, over GLINK, to the + USB and battery firmware running on one of the coprocessors in + several modern Qualcomm platforms. + + Say yes here to support USB-C and battery status on modern Qualcomm + platforms. + config QCOM_QMI_HELPERS tristate depends on NET diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index d66604aff2b0..fbbd1231e554 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o +obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c new file mode 100644 index 000000000000..bb3fb57abcc6 --- /dev/null +++ b/drivers/soc/qcom/pmic_glink.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Linaro Ltd + */ +#include +#include +#include +#include +#include +#include +#include + +struct pmic_glink { + struct device *dev; + struct pdr_handle *pdr; + + struct rpmsg_endpoint *ept; + + struct auxiliary_device altmode_aux; + struct auxiliary_device ps_aux; + struct auxiliary_device ucsi_aux; + + /* serializing client_state and pdr_state updates */ + struct mutex state_lock; + unsigned int client_state; + unsigned int pdr_state; + + /* serializing clients list updates */ + struct mutex client_lock; + struct list_head clients; +}; + +static struct pmic_glink *__pmic_glink; +static DEFINE_MUTEX(__pmic_glink_lock); + +struct pmic_glink_client { + struct list_head node; + + struct pmic_glink *pg; + unsigned int id; + + void (*cb)(const void *data, size_t len, void *priv); + void (*pdr_notify)(void *priv, int state); + void *priv; +}; + +static void _devm_pmic_glink_release_client(struct device *dev, void *res) +{ + struct pmic_glink_client *client = (struct pmic_glink_client *)res; + struct pmic_glink *pg = client->pg; + + mutex_lock(&pg->client_lock); + list_del(&client->node); + mutex_unlock(&pg->client_lock); +} + +struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev, + unsigned int id, + void (*cb)(const void *, size_t, void *), + void (*pdr)(void *, int), + void *priv) +{ + struct pmic_glink_client *client; + struct pmic_glink *pg = dev_get_drvdata(dev->parent); + + client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL); + if (!client) + return ERR_PTR(-ENOMEM); + + client->pg = pg; + client->id = id; + client->cb = cb; + client->pdr_notify = pdr; + client->priv = priv; + + mutex_lock(&pg->client_lock); + list_add(&client->node, &pg->clients); + mutex_unlock(&pg->client_lock); + + devres_add(dev, client); + + return client; +} +EXPORT_SYMBOL_GPL(devm_pmic_glink_register_client); + +int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len) +{ + struct pmic_glink *pg = client->pg; + + return rpmsg_send(pg->ept, data, len); +} +EXPORT_SYMBOL_GPL(pmic_glink_send); + +static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 addr) +{ + struct pmic_glink_client *client; + struct pmic_glink_hdr *hdr; + struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev); + + if (len < sizeof(*hdr)) { + dev_warn(pg->dev, "ignoring truncated message\n"); + return 0; + } + + hdr = data; + + list_for_each_entry(client, &pg->clients, node) { + if (client->id == le32_to_cpu(hdr->owner)) + client->cb(data, len, client->priv); + } + + return 0; +} + +static void pmic_glink_aux_release(struct device *dev) {} + +static int pmic_glink_add_aux_device(struct pmic_glink *pg, + struct auxiliary_device *aux, + const char *name) +{ + struct device *parent = pg->dev; + int ret; + + aux->name = name; + aux->dev.parent = parent; + aux->dev.release = pmic_glink_aux_release; + device_set_of_node_from_dev(&aux->dev, parent); + ret = auxiliary_device_init(aux); + if (ret) + return ret; + + ret = auxiliary_device_add(aux); + if (ret) + auxiliary_device_uninit(aux); + + return ret; +} + +static void pmic_glink_del_aux_device(struct pmic_glink *pg, + struct auxiliary_device *aux) +{ + auxiliary_device_delete(aux); + auxiliary_device_uninit(aux); +} + +static void pmic_glink_state_notify_clients(struct pmic_glink *pg) +{ + struct pmic_glink_client *client; + unsigned int new_state = pg->client_state; + + if (pg->client_state != SERVREG_SERVICE_STATE_UP) { + if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept) + new_state = SERVREG_SERVICE_STATE_UP; + } else { + if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept) + new_state = SERVREG_SERVICE_STATE_DOWN; + } + + if (new_state != pg->client_state) { + list_for_each_entry(client, &pg->clients, node) + client->pdr_notify(client->priv, new_state); + pg->client_state = new_state; + } +} + +static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv) +{ + struct pmic_glink *pg = priv; + + mutex_lock(&pg->state_lock); + pg->pdr_state = state; + + pmic_glink_state_notify_clients(pg); + mutex_unlock(&pg->state_lock); +} + +static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct pmic_glink *pg = __pmic_glink; + int ret = 0; + + mutex_lock(&__pmic_glink_lock); + if (!pg) { + ret = dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n"); + goto out_unlock; + } + + dev_set_drvdata(&rpdev->dev, pg); + + mutex_lock(&pg->state_lock); + pg->ept = rpdev->ept; + pmic_glink_state_notify_clients(pg); + mutex_unlock(&pg->state_lock); + +out_unlock: + mutex_unlock(&__pmic_glink_lock); + return ret; +} + +static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev) +{ + struct pmic_glink *pg; + + mutex_lock(&__pmic_glink_lock); + pg = __pmic_glink; + if (!pg) + goto out_unlock; + + mutex_lock(&pg->state_lock); + pg->ept = NULL; + pmic_glink_state_notify_clients(pg); + mutex_unlock(&pg->state_lock); +out_unlock: + mutex_unlock(&__pmic_glink_lock); +} + +static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = { + { "PMIC_RTR_ADSP_APPS" }, + {} +}; + +static struct rpmsg_driver pmic_glink_rpmsg_driver = { + .probe = pmic_glink_rpmsg_probe, + .remove = pmic_glink_rpmsg_remove, + .callback = pmic_glink_rpmsg_callback, + .id_table = pmic_glink_rpmsg_id_match, + .drv = { + .name = "qcom_pmic_glink_rpmsg", + }, +}; + +static int pmic_glink_probe(struct platform_device *pdev) +{ + struct pdr_service *service; + struct pmic_glink *pg; + int ret; + + pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL); + if (!pg) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, pg); + + pg->dev = &pdev->dev; + + INIT_LIST_HEAD(&pg->clients); + mutex_init(&pg->client_lock); + mutex_init(&pg->state_lock); + + ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); + if (ret) + return ret; + ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); + if (ret) + goto out_release_altmode_aux; + + pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg); + if (IS_ERR(pg->pdr)) { + ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr), "failed to initialize pdr\n"); + goto out_release_aux_devices; + } + + service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd"); + if (IS_ERR(service)) { + ret = dev_err_probe(&pdev->dev, PTR_ERR(service), + "failed adding pdr lookup for charger_pd\n"); + goto out_release_pdr_handle; + } + + mutex_lock(&__pmic_glink_lock); + __pmic_glink = pg; + mutex_unlock(&__pmic_glink_lock); + + return 0; + +out_release_pdr_handle: + pdr_handle_release(pg->pdr); +out_release_aux_devices: + pmic_glink_del_aux_device(pg, &pg->ps_aux); +out_release_altmode_aux: + pmic_glink_del_aux_device(pg, &pg->altmode_aux); + + return ret; +} + +static int pmic_glink_remove(struct platform_device *pdev) +{ + struct pmic_glink *pg = dev_get_drvdata(&pdev->dev); + + pdr_handle_release(pg->pdr); + + pmic_glink_del_aux_device(pg, &pg->ps_aux); + pmic_glink_del_aux_device(pg, &pg->altmode_aux); + + mutex_lock(&__pmic_glink_lock); + __pmic_glink = NULL; + mutex_unlock(&__pmic_glink_lock); + + return 0; +} + +static const struct of_device_id pmic_glink_of_match[] = { + { .compatible = "qcom,pmic-glink", }, + {} +}; +MODULE_DEVICE_TABLE(of, pmic_glink_of_match); + +static struct platform_driver pmic_glink_driver = { + .probe = pmic_glink_probe, + .remove = pmic_glink_remove, + .driver = { + .name = "qcom_pmic_glink", + .of_match_table = pmic_glink_of_match, + }, +}; + +static int pmic_glink_init(void) +{ + platform_driver_register(&pmic_glink_driver); + register_rpmsg_driver(&pmic_glink_rpmsg_driver); + + return 0; +}; +module_init(pmic_glink_init); + +static void pmic_glink_exit(void) +{ + unregister_rpmsg_driver(&pmic_glink_rpmsg_driver); + platform_driver_unregister(&pmic_glink_driver); +}; +module_exit(pmic_glink_exit); + +MODULE_DESCRIPTION("Qualcomm PMIC GLINK driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/soc/qcom/pmic_glink.h b/include/linux/soc/qcom/pmic_glink.h new file mode 100644 index 000000000000..fd124aa18c81 --- /dev/null +++ b/include/linux/soc/qcom/pmic_glink.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Linaro Ltd + */ +#ifndef __SOC_QCOM_PMIC_GLINK_H__ +#define __SOC_QCOM_PMIC_GLINK_H__ + +struct pmic_glink; +struct pmic_glink_client; + +#define PMIC_GLINK_OWNER_BATTMGR 32778 +#define PMIC_GLINK_OWNER_USBC 32779 +#define PMIC_GLINK_OWNER_USBC_PAN 32780 + +#define PMIC_GLINK_REQ_RESP 1 +#define PMIC_GLINK_NOTIFY 2 + +struct pmic_glink_hdr { + __le32 owner; + __le32 type; + __le32 opcode; +}; + +int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len); + +struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev, + unsigned int id, + void (*cb)(const void *, size_t, void *), + void (*pdr)(void *, int), + void *priv); + +#endif -- cgit v1.2.3 From 3bf90eca76c98c55c975fa817799789b9176f9f3 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Fri, 3 Feb 2023 13:09:52 -0800 Subject: firmware: qcom_scm: Move qcom_scm.h to include/linux/firmware/qcom/ Move include/linux/qcom_scm.h to include/linux/firmware/qcom/qcom_scm.h. This removes 1 of a few remaining Qualcomm-specific headers into a more approciate subdirectory under include/. Suggested-by: Bjorn Andersson Signed-off-by: Elliot Berman Reviewed-by: Guru Das Srinagesh Acked-by: Mukesh Ojha Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230203210956.3580811-1-quic_eberman@quicinc.com --- arch/arm/mach-qcom/platsmp.c | 2 +- drivers/cpuidle/cpuidle-qcom-spm.c | 2 +- drivers/firmware/qcom_scm-legacy.c | 2 +- drivers/firmware/qcom_scm-smc.c | 2 +- drivers/firmware/qcom_scm.c | 2 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +- drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c | 2 +- drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 2 +- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 +- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 2 +- drivers/media/platform/qcom/venus/firmware.c | 2 +- drivers/misc/fastrpc.c | 2 +- drivers/mmc/host/sdhci-msm.c | 2 +- drivers/net/ipa/ipa_main.c | 2 +- drivers/net/wireless/ath/ath10k/qmi.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm.c | 2 +- drivers/remoteproc/qcom_q6v5_mss.c | 2 +- drivers/remoteproc/qcom_q6v5_pas.c | 2 +- drivers/remoteproc/qcom_wcnss.c | 2 +- drivers/soc/qcom/mdt_loader.c | 2 +- drivers/soc/qcom/ocmem.c | 2 +- drivers/soc/qcom/rmtfs_mem.c | 2 +- drivers/thermal/qcom/lmh.c | 2 +- drivers/ufs/host/ufs-qcom-ice.c | 2 +- include/linux/firmware/qcom/qcom_scm.h | 125 +++++++++++++++++++++++ include/linux/qcom_scm.h | 125 ----------------------- 27 files changed, 150 insertions(+), 150 deletions(-) create mode 100644 include/linux/firmware/qcom/qcom_scm.h delete mode 100644 include/linux/qcom_scm.h (limited to 'include/linux') diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c index 5d2f386a46d8..eca2fe0f4314 100644 --- a/arch/arm/mach-qcom/platsmp.c +++ b/arch/arm/mach-qcom/platsmp.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c index beedf22cbe78..4ac83918edf2 100644 --- a/drivers/cpuidle/cpuidle-qcom-spm.c +++ b/drivers/cpuidle/cpuidle-qcom-spm.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/firmware/qcom_scm-legacy.c b/drivers/firmware/qcom_scm-legacy.c index 9f918b9e6f8f..029e6d117cb8 100644 --- a/drivers/firmware/qcom_scm-legacy.c +++ b/drivers/firmware/qcom_scm-legacy.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index bb3235a64b8f..16cf88acfa8e 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2000323722bf..468d4d5ab550 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 660ba0db8900..d09221f97f71 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 57586c794b84..89ff978b81bb 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c index e7748461cffc..0752fe373351 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c @@ -3,7 +3,7 @@ */ #include "hdmi.h" -#include +#include #define HDCP_REG_ENABLE 0x01 #define HDCP_REG_DISABLE 0x00 diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c index 74e9ef2fd580..b5b14108e086 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include "arm-smmu.h" diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 91d404deb115..ef42329e82ce 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "arm-smmu.h" #include "arm-smmu-qcom.h" diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index 270c3d9128ba..1e0b7b2e9fbd 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 142d4c74017c..e5759d7e9ede 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index c9902a1dcf5d..04f80e754477 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 4ac8651d0b29..8ac81d57a3df 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c index 4fb92f771974..90baf7a54d9a 100644 --- a/drivers/net/ipa/ipa_main.c +++ b/drivers/net/ipa/ipa_main.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include "ipa.h" diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 3f94fbf83702..90f457b8e1fe 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 47e9a8b0d474..e0128c69bfbf 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index fddb63cffee0..da2513bb6387 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -34,7 +34,7 @@ #include "qcom_pil_info.h" #include "qcom_q6v5.h" -#include +#include #define MPSS_CRASH_REASON_SMEM 421 diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index dc6f07ca8341..d5a049669616 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 68f37296b151..9881443cb8df 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 3f11554df2f3..33dd8c315eb7 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index c92d26b73e6f..199fe9872035 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 9d59ad509a5c..2d3ee22b9249 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1) #define NUM_MAX_VMIDS 2 diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c index 4122a51e9874..f6edb12ec004 100644 --- a/drivers/thermal/qcom/lmh.c +++ b/drivers/thermal/qcom/lmh.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #define LMH_NODE_DCVS 0x44435653 #define LMH_CLUSTER0_NODE_ID 0x6370302D diff --git a/drivers/ufs/host/ufs-qcom-ice.c b/drivers/ufs/host/ufs-qcom-ice.c index 62387ccd5b30..453978877ae9 100644 --- a/drivers/ufs/host/ufs-qcom-ice.c +++ b/drivers/ufs/host/ufs-qcom-ice.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include "ufs-qcom.h" diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h new file mode 100644 index 000000000000..1e449a5d7f5c --- /dev/null +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Linaro Ltd. + */ +#ifndef __QCOM_SCM_H +#define __QCOM_SCM_H + +#include +#include +#include + +#include + +#define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) +#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0 +#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1 +#define QCOM_SCM_HDCP_MAX_REQ_CNT 5 + +struct qcom_scm_hdcp_req { + u32 addr; + u32 val; +}; + +struct qcom_scm_vmperm { + int vmid; + int perm; +}; + +enum qcom_scm_ocmem_client { + QCOM_SCM_OCMEM_UNUSED_ID = 0x0, + QCOM_SCM_OCMEM_GRAPHICS_ID, + QCOM_SCM_OCMEM_VIDEO_ID, + QCOM_SCM_OCMEM_LP_AUDIO_ID, + QCOM_SCM_OCMEM_SENSORS_ID, + QCOM_SCM_OCMEM_OTHER_OS_ID, + QCOM_SCM_OCMEM_DEBUG_ID, +}; + +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID = 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + +enum qcom_scm_ice_cipher { + QCOM_SCM_ICE_CIPHER_AES_128_XTS = 0, + QCOM_SCM_ICE_CIPHER_AES_128_CBC = 1, + QCOM_SCM_ICE_CIPHER_AES_256_XTS = 3, + QCOM_SCM_ICE_CIPHER_AES_256_CBC = 4, +}; + +#define QCOM_SCM_PERM_READ 0x4 +#define QCOM_SCM_PERM_WRITE 0x2 +#define QCOM_SCM_PERM_EXEC 0x1 +#define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE) +#define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC) + +extern bool qcom_scm_is_available(void); + +extern int qcom_scm_set_cold_boot_addr(void *entry); +extern int qcom_scm_set_warm_boot_addr(void *entry); +extern void qcom_scm_cpu_power_down(u32 flags); +extern int qcom_scm_set_remote_state(u32 state, u32 id); + +struct qcom_scm_pas_metadata { + void *ptr; + dma_addr_t phys; + ssize_t size; +}; + +extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, + size_t size, + struct qcom_scm_pas_metadata *ctx); +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); +extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, + phys_addr_t size); +extern int qcom_scm_pas_auth_and_reset(u32 peripheral); +extern int qcom_scm_pas_shutdown(u32 peripheral); +extern bool qcom_scm_pas_supported(u32 peripheral); + +extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); +extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); + +extern bool qcom_scm_restore_sec_cfg_available(void); +extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); +extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); +extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); +extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size); +extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, + u32 cp_nonpixel_size); +extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, + unsigned int *src, + const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt); + +extern bool qcom_scm_ocmem_lock_available(void); +extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size, u32 mode); +extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size); + +extern bool qcom_scm_ice_available(void); +extern int qcom_scm_ice_invalidate_key(u32 index); +extern int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, + enum qcom_scm_ice_cipher cipher, + u32 data_unit_size); + +extern bool qcom_scm_hdcp_available(void); +extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, + u32 *resp); + +extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt); +extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en); + +extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, + u64 limit_node, u32 node_id, u64 version); +extern int qcom_scm_lmh_profile_change(u32 profile_id); +extern bool qcom_scm_lmh_dcvsh_available(void); + +#endif diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h deleted file mode 100644 index 1e449a5d7f5c..000000000000 --- a/include/linux/qcom_scm.h +++ /dev/null @@ -1,125 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (C) 2015 Linaro Ltd. - */ -#ifndef __QCOM_SCM_H -#define __QCOM_SCM_H - -#include -#include -#include - -#include - -#define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) -#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0 -#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1 -#define QCOM_SCM_HDCP_MAX_REQ_CNT 5 - -struct qcom_scm_hdcp_req { - u32 addr; - u32 val; -}; - -struct qcom_scm_vmperm { - int vmid; - int perm; -}; - -enum qcom_scm_ocmem_client { - QCOM_SCM_OCMEM_UNUSED_ID = 0x0, - QCOM_SCM_OCMEM_GRAPHICS_ID, - QCOM_SCM_OCMEM_VIDEO_ID, - QCOM_SCM_OCMEM_LP_AUDIO_ID, - QCOM_SCM_OCMEM_SENSORS_ID, - QCOM_SCM_OCMEM_OTHER_OS_ID, - QCOM_SCM_OCMEM_DEBUG_ID, -}; - -enum qcom_scm_sec_dev_id { - QCOM_SCM_MDSS_DEV_ID = 1, - QCOM_SCM_OCMEM_DEV_ID = 5, - QCOM_SCM_PCIE0_DEV_ID = 11, - QCOM_SCM_PCIE1_DEV_ID = 12, - QCOM_SCM_GFX_DEV_ID = 18, - QCOM_SCM_UFS_DEV_ID = 19, - QCOM_SCM_ICE_DEV_ID = 20, -}; - -enum qcom_scm_ice_cipher { - QCOM_SCM_ICE_CIPHER_AES_128_XTS = 0, - QCOM_SCM_ICE_CIPHER_AES_128_CBC = 1, - QCOM_SCM_ICE_CIPHER_AES_256_XTS = 3, - QCOM_SCM_ICE_CIPHER_AES_256_CBC = 4, -}; - -#define QCOM_SCM_PERM_READ 0x4 -#define QCOM_SCM_PERM_WRITE 0x2 -#define QCOM_SCM_PERM_EXEC 0x1 -#define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE) -#define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC) - -extern bool qcom_scm_is_available(void); - -extern int qcom_scm_set_cold_boot_addr(void *entry); -extern int qcom_scm_set_warm_boot_addr(void *entry); -extern void qcom_scm_cpu_power_down(u32 flags); -extern int qcom_scm_set_remote_state(u32 state, u32 id); - -struct qcom_scm_pas_metadata { - void *ptr; - dma_addr_t phys; - ssize_t size; -}; - -extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, - size_t size, - struct qcom_scm_pas_metadata *ctx); -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); -extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, - phys_addr_t size); -extern int qcom_scm_pas_auth_and_reset(u32 peripheral); -extern int qcom_scm_pas_shutdown(u32 peripheral); -extern bool qcom_scm_pas_supported(u32 peripheral); - -extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); -extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); - -extern bool qcom_scm_restore_sec_cfg_available(void); -extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); -extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); -extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size); -extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, - u32 cp_nonpixel_start, - u32 cp_nonpixel_size); -extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, - unsigned int *src, - const struct qcom_scm_vmperm *newvm, - unsigned int dest_cnt); - -extern bool qcom_scm_ocmem_lock_available(void); -extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, - u32 size, u32 mode); -extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, - u32 size); - -extern bool qcom_scm_ice_available(void); -extern int qcom_scm_ice_invalidate_key(u32 index); -extern int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, - enum qcom_scm_ice_cipher cipher, - u32 data_unit_size); - -extern bool qcom_scm_hdcp_available(void); -extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, - u32 *resp); - -extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt); -extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en); - -extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, - u64 limit_node, u32 node_id, u64 version); -extern int qcom_scm_lmh_profile_change(u32 profile_id); -extern bool qcom_scm_lmh_dcvsh_available(void); - -#endif -- cgit v1.2.3