From d7601393dce0e11ab823fe530e8d5f2277b5fdc0 Mon Sep 17 00:00:00 2001 From: Krishna chaitanya chundru Date: Fri, 16 Jun 2023 10:27:03 +0530 Subject: [PATCH 01/14] bus: mhi: Fix potential out-of-bound access In mhi_sat_isvalid_header function if the length is less than the size of header then there can be out-of-bound access. So fix the len check in the function. Change-Id: I80f1556557b1bf2f30c07f6377bd6e3db48712b3 Signed-off-by: Krishna chaitanya chundru --- drivers/bus/mhi/devices/mhi_satellite.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/devices/mhi_satellite.c b/drivers/bus/mhi/devices/mhi_satellite.c index f7c6c07c30ab..2e33051d910a 100644 --- a/drivers/bus/mhi/devices/mhi_satellite.c +++ b/drivers/bus/mhi/devices/mhi_satellite.c @@ -357,7 +357,8 @@ static struct mhi_sat_device *find_sat_dev_by_id( static bool mhi_sat_isvalid_header(struct sat_header *hdr, int len) { /* validate payload size */ - if (len >= sizeof(*hdr) && (len != hdr->payload_size + sizeof(*hdr))) + if ((len < sizeof(*hdr)) || + (len >= sizeof(*hdr) && (len != hdr->payload_size + sizeof(*hdr)))) return false; /* validate SAT IPC version */ From 1ffd957fcf66db0bef7d2aee180bcde5d14d02ee Mon Sep 17 00:00:00 2001 From: Srinivasarao Pathipati Date: Wed, 28 Feb 2024 12:26:45 +0530 Subject: [PATCH 02/14] Revert LLCC changes reverting below llcc changes cc1a1dcb411fe soc: qcom: llcc: Handle a second device without data corruption 813fdddde20fd soc: qcom: Rename llcc-slice to llcc-qcom 077010717b52f soc: qcom: llcc cleanup to get rid of sdm845 specific driver file Change-Id: Ia3588add7e8884d2b05fd770253c98afad41adf5 Signed-off-by: kamasali Satyanarayan Signed-off-by: Srinivasarao Pathipati --- drivers/soc/qcom/Kconfig | 1177 ++++++++++++++++- drivers/soc/qcom/Makefile | 105 +- drivers/soc/qcom/llcc-sdm845.c | 100 ++ .../soc/qcom/{llcc-qcom.c => llcc-slice.c} | 153 ++- include/linux/soc/qcom/llcc-qcom.h | 76 +- 5 files changed, 1517 insertions(+), 94 deletions(-) create mode 100644 drivers/soc/qcom/llcc-sdm845.c rename drivers/soc/qcom/{llcc-qcom.c => llcc-slice.c} (77%) diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 600083cfc1f2..145b60079b23 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -17,7 +17,7 @@ config QCOM_AOSS_QMP Subsystem (AOSS) using Qualcomm Messaging Protocol (QMP). config QCOM_COMMAND_DB - tristate "Qualcomm Command DB" + tristate "Qualcomm Technologies, Inc. Command DB driver" depends on ARCH_QCOM || COMPILE_TEST depends on OF_RESERVED_MEM help @@ -26,6 +26,47 @@ config QCOM_COMMAND_DB resource on a RPM-hardened platform must use this database to get SoC specific identifier and information for the shared resources. +config QCOM_MEM_OFFLINE + bool "Dynamic Memory Region Offline driver" + depends on MEMORY_HOTPLUG + help + Add support for DDR Self-Refresh power management through the dynamic + memory offline framework. This driver interfaces between the memory + hotplug subsystem and AOP which hot adds or removes memory blocks and + controls the start/stop of self-refresh of these DDR regions. This + helps reduce power consumption during idle mode of the system. + If unsure, say N + +config BUG_ON_HW_MEM_ONLINE_FAIL + bool "Trigger a BUG when HW memory online fails" + depends on QCOM_MEM_OFFLINE + help + Select this option if kernel should BUG when the hardware + onlining of memory hotplug blocks fails. This helps to catch + online failures much quicker and avoids the later side effects + of such memory online failures. + If unsure, say N + +config OVERRIDE_MEMORY_LIMIT + bool "Override memory limit set by the kernel boot parameter" + depends on QCOM_MEM_OFFLINE + help + Override any memory limit set by the kernel boot parameter with + limit set by mem-offline dt entry so that memory offline framework + can initialize remaining memory with movable pages for memory + hot-plugging. + If unsure, say N + +config QCOM_MEM_BUF + bool "Qualcomm Technologies, Inc. Memory Buffer Sharing Driver" + depends on HH_MSGQ && HH_RM_DRV && ION_MSM_HEAPS + help + Add support for lending memory from one virtual machine to another. + This driver communicates with the hypervisor, as well as other + virtual machines, to request and lend memory from and to VMs + respectively. + If unsure, say N + config QCOM_GENI_SE tristate "QCOM GENI Serial Engine Driver" depends on ARCH_QCOM || COMPILE_TEST @@ -35,6 +76,16 @@ config QCOM_GENI_SE driver is also used to manage the common aspects of multiple Serial Engines present in the QUP. +config OVERRIDE_MEMORY_LIMIT + bool "Override memory limit set by the kernel boot parameter" + depends on QCOM_MEM_OFFLINE + help + Override any memory limit set by the kernel boot parameter with + limit set by mem-offline dt entry so that memory offline framework + can initialize remaining memory with movable pages for memory + hot-plugging. + If unsure, say N + config QCOM_GLINK_SSR tristate "Qualcomm Glink SSR driver" depends on RPMSG @@ -44,6 +95,39 @@ config QCOM_GLINK_SSR implements the SSR protocol for notifying the remote processor about neighboring subsystems going up or down. +config MSM_SPSS_UTILS + depends on MSM_PIL + tristate "Secure Processor Utilities" + help + spss-utils driver selects Secure Processor firmware file name.name + The firmware file name for dev, test or production is selected + based on two fuses.fuses + Different file name is used for differnt SPSS HW versions,versions + because the SPSS firmware size is too small to support multiple + HW versions. + +config MSM_QBT_HANDLER + tristate "Event Handler for QTI Ultrasonic Fingerprint Sensor" + help + This driver acts as a interrupt handler, where the interrupt is generated + by the QTI Ultrasonic Fingerprint Sensor. It queues the events for each + interrupt in an event queue and notifies the userspace to read the events + from the queue. It also creates an input device to send key events such as + KEY_POWER, KEY_HOME. + +config QCOM_PROXY_OF_CONSUMER + tristate "Qualcomm Technologies, Inc. OF proxy consumer driver" + help + A target may contain multiple defconfigs, but only one device-tree + configuration. Such a target may have device-drivers that are + only enabled in a particular defconfig, while disabled in the + others. For the kernel that boots up with disabled configuration, + since the device-tree node exists, the of_devlink logic expects + the driver to be probed, which is not possible. As a result, the + sync-state remains incomplete. + This proxy consumer driver shows a proxy-presence of the main + driver to satisfy the sync-state. + config QCOM_GSBI tristate "QCOM General Serial Bus Interface" depends on ARCH_QCOM || COMPILE_TEST @@ -53,20 +137,140 @@ config QCOM_GSBI functions for connecting the underlying serial UART, SPI, and I2C devices to the output pins. +config QCOM_IPCC + tristate "Qualcomm Technologies, Inc. IPCC driver" + depends on MAILBOX + help + Qualcomm Technologies, Inc. IPCC driver for MSM devices. The drivers + acts as an interrupt controller for the clients interested in + talking to the IPCC (inbound-communication). On the other hand, the + driver also provides a mailbox channel for outbound-communications. + Say Y here to compile the driver as a part of kernel or M to compile + as a module. + +config QCOM_RIMPS + tristate "Qualcomm Technologies, Inc. Rimps driver" + depends on MAILBOX + help + Qualcomm Technologies, Inc. RIMPS driver for MSM devices. This driver + acts as a mailbox controller to do doorbell between Apss and Rimps + subsystem. Say yes here to enable rx and tx channel between both + the subsystems. + If unsure, say n. + config QCOM_LLCC tristate "Qualcomm Technologies, Inc. LLCC driver" depends on ARCH_QCOM || COMPILE_TEST select REGMAP_MMIO help Qualcomm Technologies, Inc. platform specific - Last Level Cache Controller(LLCC) driver for platforms such as, - SDM845. This provides interfaces to clients that use the LLCC. - Say yes here to enable LLCC slice driver. + Last Level Cache Controller(LLCC) driver. This provides interfaces + to clients that use the LLCC. Say yes here to enable LLCC slice + driver. + +config QCOM_LAHAINA_LLCC + tristate "Qualcomm Technologies, Inc. LAHAINA LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for Lahaina platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_SDXLEMUR_LLCC + tristate "Qualcomm Technologies, Inc. SDXLEMUR LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for SDXLEMUR platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_SHIMA_LLCC + tristate "Qualcomm Technologies, Inc. SHIMA LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for Shima platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_YUPIK_LLCC + tristate "Qualcomm Technologies, Inc. YUPIK LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for Yupik platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_SM8150_LLCC + tristate "Qualcomm Technologies, Inc. SM8150 LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for SM8150 platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_SDMSHRIKE_LLCC + tristate "Qualcomm Technologies, Inc. SDMSHRIKE LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for SDMSHRIKE platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. + +config QCOM_SM6150_LLCC + tristate "Qualcomm Technologies, Inc. SM6150 LLCC driver" + depends on QCOM_LLCC + help + Say yes here to enable the LLCC driver for SM6150. This is provides + data required to configure LLCC so that clients can start using the + LLCC slices. + If unsure, say n. + +config QCOM_SDM845_LLCC + tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver" + depends on QCOM_LLCC + help + Say yes here to enable the LLCC driver for SDM845. This provides + data required to configure LLCC so that clients can start using the + LLCC slices. + +config QCOM_LLCC_PERFMON + tristate "Qualcomm Technologies, Inc. LLCC Perfmon driver" + depends on QCOM_LLCC + help + This option enables driver for LLCC Performance monitor block. Using + this various events in different LLCC sub ports can be monitored. + This is used for performance and debug activity and exports sysfs + interface. sysfs interface is used to configure and dump the LLCC + performance events. + +config QCOM_DIREWOLF_LLCC + tristate "Qualcomm Technologies, Inc. Direwolf LLCC driver" + depends on QCOM_LLCC + help + Say y or m here to enable the LLCC driver for Direwolf platform. + This provides data required to configure LLCC so that clients + can start using the LLCC slices. + If unsure, say n. config QCOM_MDT_LOADER tristate select QCOM_SCM +config QPNP_PBS + tristate "PBS trigger support for QPNP PMIC" + depends on SPMI + help + This driver supports configuring software PBS trigger event through PBS + RAM on Qualcomm Technologies, Inc. QPNP PMICs. This module provides + the APIs to the client drivers that wants to send the PBS trigger + event to the PBS RAM. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 @@ -77,11 +281,156 @@ config QCOM_PM modes. It interface with various system drivers to put the cores in low power modes. +config MSM_PIL + tristate "Peripheral image loader" + select FW_LOADER + help + Some peripherals' firmware need to be loaded into memory before + they can be brought out of reset. The Peripheral Image Loader (PIL) + framework is used to achive this. The driver relays the lower-level + functionalities such as, authenticating the images, performing the + reset of the peripheral, and so on to the drivers that are registered + with it. + + Say 'y' or 'm' to support these devices. + +config MSM_SUBSYSTEM_RESTART + tristate "MSM Subsystem Restart" + select MSM_PIL + select QCOM_QMI_HELPERS + help + This option enables the MSM subsystem restart framework. + + The MSM subsystem restart framework provides support to boot, + shutdown, and restart subsystems with a reference counted API. + It also extends the APIs to add support for MSM System Monitor + using the QMI layer. These APIs may be used for sending events + or passing commands. + Moreover, the framework also notifies userspace of transitions + between these states via sysfs. + +config MSM_QUIN_SUBSYSTEM_NOTIF_VIRT + tristate "MSM QUIN Subsystem Notif Virt" + select MSM_SUBSYSTEM_RESTART + help + This option enables the virtual MSM subsystem notification + framework for the QUIN platform. + + The virtual MSM subsystem notif framework provides support for + a subsystem to notify its clients of its state, when the clients + are in a different virtual machine domain than the subsystem. + +config SETUP_SSR_NOTIF_TIMEOUTS + bool "Set timeouts on SSR sysmon notifications and notifier callbacks" + help + Setup timers prior to initiating communication between + subsystems through sysmon, and prior to sending notifications + to drivers in the kernel that have registered callbacks with the + subsystem notifier framework for a particular subsystem. This + is a debugging feature. + +config SSR_SYSMON_NOTIF_TIMEOUT + depends on SETUP_SSR_NOTIF_TIMEOUTS + int "SSR Sysmon notifications timeout in ms" + default 10000 + help + The amount of time, in milliseconds, that should elapse between + the start and end of sysmon SSR notifications, before a warning + is emitted. + +config SSR_SUBSYS_NOTIF_TIMEOUT + depends on SETUP_SSR_NOTIF_TIMEOUTS + int "SSR Subsystem notifier timeout in ms" + default 10000 + help + The amount of time, in milliseconds, that should elapse between + the start and end of SSR notifications through the subsystem + notifier, before a warning is emitted. + +config PANIC_ON_SSR_NOTIF_TIMEOUT + bool "Trigger kernel panic when notification timeout expires" + depends on SETUP_SSR_NOTIF_TIMEOUTS + help + This is a debug feature where a kernel panic is triggered when + communication between subsystems through sysmon is taking too + long. This scneario can happen if the peripheral has died and + is no longer responsive. + Also trigger a kernel panic if invoking the callbacks registered + with a particular subsystem's notifications by the subsystem + notifier framework is taking too long. + +config MSM_PIL_SSR_GENERIC + tristate "MSM Subsystem Boot Support" + depends on MSM_SUBSYSTEM_RESTART + help + Support for booting and shutting down MSM Subsystem processors. + This driver also monitors the SMSM status bits and the watchdog + interrupt for the subsystem and restarts it on a watchdog bite + or a fatal error. Subsystems include LPASS, Venus, VPU, WCNSS and + BCSS. + +config MSM_PIL_MSS_QDSP6V5 + tristate "MSS QDSP6v5 (Hexagon) Boot Support" + depends on MSM_PIL && MSM_SUBSYSTEM_RESTART + help + Support for booting and shutting down QDSP6v5 (Hexagon) processors + in modem subsystems. If you would like to make or receive phone + calls then say Y here. + If unsure, say N. + +config MSM_SERVICE_LOCATOR + tristate "Service Locator" + select QCOM_QMI_HELPERS + help + The Service Locator provides a library to retrieve location + information given a service identifier. Location here translates + to what process domain exports the service, and which subsystem + that process domain will execute in. + +config MSM_SERVICE_NOTIFIER + tristate "Service Notifier" + depends on MSM_SERVICE_LOCATOR && MSM_SUBSYSTEM_RESTART + help + The Service Notifier provides a library for a kernel client to + register for state change notifications regarding a remote service. + A remote service here refers to a process providing certain services + like audio, the identifier for which is provided by the service + locator. + +config MSM_BOOT_STATS + tristate "Use MSM boot stats reporting" + help + Use this to report msm boot stats such as bootloader throughput, + display init, total boot time. + This figures are reported in mpm sleep clock cycles and have a + resolution of 31 bits as 1 bit is used as an overflow check. + +config QGKI_MSM_BOOT_TIME_MARKER + bool "Use MSM boot time marker reporting" + depends on MSM_BOOT_STATS && QGKI + help + Use this to mark msm boot kpi for measurement. + An instrumentation for boot time measurement. + To create an entry, call "place_marker" function. + At userspace, write marker name to "/sys/kernel/boot_kpi/kpi_values" + config QCOM_QMI_HELPERS tristate depends on ARCH_QCOM || COMPILE_TEST depends on NET +source "drivers/soc/qcom/memshare/Kconfig" + +config QCOM_QFPROM_SYS + tristate "Qualcomm Technologies, Inc. QFPROM_SYS driver " + depends on QCOM_QFPROM + help + Qualcomm Technologies, Inc. QFPROM_SYS driver. The QFPROM SYS driver + provides access to the child nodes of QFPROM to user space. The cell + values are exported as sysfs entries. + + Say y here to enable QFPROM SYS support. + config QCOM_RMTFS_MEM tristate "Qualcomm Remote Filesystem memory driver" depends on ARCH_QCOM @@ -94,9 +443,17 @@ config QCOM_RMTFS_MEM Say y here if you intend to boot the modem remoteproc. +config MSM_CORE_HANG_DETECT + tristate "MSM Core Hang Detection Support" + help + This enables the core hang detection module. It causes SoC + reset on core hang detection and collects the core context + for hang. By using sysfs entries core hang detection can be + enabled or disabled dynamically. + config QCOM_RPMH tristate "Qualcomm RPM-Hardened (RPMH) Communication" - depends on ARCH_QCOM && ARM64 || COMPILE_TEST + depends on ARCH_QCOM || COMPILE_TEST help Support for communication with the hardened-RPM blocks in Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an @@ -104,6 +461,14 @@ config QCOM_RPMH of hardware components aggregate requests for these resources and help apply the aggregated state on the resource. +config QCOM_RPMH_QGKI_DEBUG + bool "Enhance RPMh debug for QGKI variants" + depends on QCOM_RPMH + help + Adding debug prints increases latency of handling RPMh requests. This + is specially notable during the boot process. Let's selectively remove + some tracing that are more informative than an actual error. + config QCOM_RPMHPD tristate "Qualcomm RPMh Power domain driver" depends on QCOM_RPMH && QCOM_COMMAND_DB @@ -113,6 +478,14 @@ config QCOM_RPMHPD value to RPMh which then translates it into corresponding voltage for the voltage rail. +config QCOM_RUN_QUEUE_STATS + bool "Enable collection and exporting of QTI Run Queue stats to userspace" + help + This option enables the driver to periodically collecting the statistics + of kernel run queue information and calculate the load of the system. + This information is exported to usespace via sysfs entries and userspace + algorithms uses info and decide when to turn on/off the cpu cores. + config QCOM_RPMPD bool "Qualcomm RPM Power domain driver" depends on QCOM_SMD_RPM=y @@ -146,6 +519,39 @@ config QCOM_SMD_RPM Say M here if you want to include support for the Qualcomm RPM as a module. This will build a module called "qcom-smd-rpm". +config MSM_SPM + bool "Driver support for SPM and AVS wrapper hardware" + help + Enables the support for SPM and AVS wrapper hardware on MSMs. SPM + hardware is used to manage the processor power during sleep. The + driver allows configuring SPM to allow different low power modes for + both core and L2. + +config MSM_L2_SPM + bool "SPM support for L2 cache" + help + Enable SPM driver support for L2 cache. Some MSM chipsets allow + control of L2 cache low power mode with a Subsystem Power manager. + Enabling this driver allows configuring L2 SPM for low power modes + on supported chipsets. + +config QCOM_MEMORY_DUMP_V2 + tristate "QCOM Memory Dump V2 Support" + help + This enables memory dump feature. It allows various client + subsystems to register respective dump regions. At the time + of deadlocks or cpu hangs these dump regions are captured to + give a snapshot of the system at the time of the crash. + +config MSM_REMOTEQDSS + bool "Allow debug tools to enable events on other processors" + depends on QCOM_SCM && DEBUG_FS + help + Other onchip processors/execution environments may support debug + events. Provide a sysfs interface for debug tools to dynamically + enable/disable these events. Interface located in + /sys/class/remoteqdss. + config QCOM_SMEM_STATE bool @@ -184,6 +590,71 @@ config QCOM_WCNSS_CTRL Client driver for the WCNSS_CTRL SMD channel, used to download nv firmware to a newly booted WCNSS chip. +config QCOM_DCC_V2 + bool "Qualcomm Technologies Data Capture and Compare enigne support for V2" + help + This option enables driver for Data Capture and Compare engine. DCC + driver provides interface to configure DCC block and read back + captured data from DCC's internal SRAM. + +config QCOM_MINIDUMP + tristate "QCOM Minidump Support" + depends on QCOM_SMEM && POWER_RESET_MSM + help + This enables minidump feature. It allows various clients to + register to dump their state at system bad state (panic/WDT,etc.,). + Minidump would dump all registered entries, only when DLOAD mode + is enabled. + +config QCOM_DYN_MINIDUMP_STACK + bool "QTI Dynamic Minidump Stack Registration Support" + depends on QCOM_MINIDUMP + help + This enables minidump dynamic current stack registration feature. + It allows current task stack to be available in minidump, for cases + where CPU is unable to register it from IPI_CPU_STOP. The stack data + can be used to unwind stack frames. + +config QCOM_MINIDUMP_FTRACE + bool "QCOM Minidump Support" + depends on QGKI && QCOM_MINIDUMP + help + This enables ftrace buffer registration in minidump table. + This allows dumping ftrace buffer content as part of + minidump dumps. + +config QCOM_MINIDUMP_PANIC_DUMP + bool "QCOM Minidump Panic dumps Support" + depends on QGKI && QCOM_MINIDUMP + help + This enables various dumps collection in minidump table, + on panic. + +config QCOM_MINIDUMP_PANIC_CPU_CONTEXT + bool "QCOM Minidump Panic dumps Support" + depends on ARM64 && QCOM_MINIDUMP_PANIC_DUMP + help + This enables cpu context collection in minidump table, + on panic. + +config MINIDUMP_MAX_ENTRIES + int "Minidump Maximum num of entries" + default 200 + depends on QCOM_MINIDUMP + help + This defines maximum number of entries to be allocated for application + subsytem in Minidump table. + +config QCOM_MICRODUMP + tristate "Qualcomm Technologies, Inc. Microdump Support" + depends on MSM_SUBSYSTEM_RESTART + depends on QCOM_SMEM + help + This enables microdump feature. It collects + crash data from SMEM whenever modem subsytem + crashes and stores it under /dev to expose + to user space. + config QCOM_APR tristate "Qualcomm APR Bus (Asynchronous Packet Router)" depends on ARCH_QCOM || COMPILE_TEST @@ -193,4 +664,700 @@ config QCOM_APR application processor and QDSP6. APR is used by audio driver to configure QDSP6 ASM, ADM and AFE modules. + +config QCOM_SECURE_BUFFER + tristate "Helper functions for secure buffers through TZ" + depends on QCOM_SCM + help + Enable for targets that need to call into TZ to secure + memory buffers. This ensures that only the correct clients can + use this memory and no unauthorized access is made to the + buffer. + +config QCOM_GLINK_PKT + tristate "Enable device interface for GLINK packet channels" + depends on QCOM_GLINK || RPMSG_QCOM_GLINK_SLATECOM + help + G-link packet driver provides the interface for the userspace + clients to communicate over G-Link via device nodes. + This enable the userspace clients to read and write to + some glink packets channel. + +source "drivers/soc/qcom/hab/Kconfig" +source "drivers/soc/qcom/hgsl/Kconfig" + +config MSM_PERFORMANCE + tristate "msm performance driver to support userspace fmin/fmax request" + help + This driver can restrict max freq or min freq of cpu cluster + when requested by the userspace by changing the cpufreq policy + fmin and fmax. The user space can request the cpu freq change by + writing cpu#:freq values + +config QTI_PLH + bool "Qualcomm Technologies Inc. RIMPS PLH interface" + depends on ARM_SCMI_PROTOCOL && MSM_PERFORMANCE + default n + help + Interface between RIMPS PLH and userspace. + + This interface is responsible for handling the communication + with RIMPS PLH such as passing tunables, enable and disable. + +config MSM_PERFORMANCE_QGKI + bool "Enable QGKI features" + depends on QGKI + help + This option enables full functionality of MSM_PERFORMANCE for + QGKI flavor. This is not defined in GKI builds wherein the driver + offers minimal functionality of changing the min and max frequency + of a given cluster. The user space can request the cpu freq change + by writing cpu#:freq values + +config QMP_DEBUGFS_CLIENT + bool "Debugfs Client to communicate with AOP using QMP protocol" + depends on DEBUG_FS + help + This options enables a driver which allows clients to send messages + to Alway On processor using QMP transport. Users can echo a message + into an exposed debugfs node to send to AOP. The driver expects the + passed in string argument to be formatted correctly for AOP to read. + +config QSEE_IPC_IRQ_BRIDGE + tristate "QSEE IPC Interrupt Bridge" + help + This module enables bridging an Inter-Processor Communication(IPC) + interrupt from a remote subsystem directed towards + Qualcomm Technologies, Inc. Secure Execution Environment(QSEE) to + userspace. The interrupt will be propagated through a character device + that userspace clients can poll on. + +config QCOM_SMP2P_SLEEPSTATE + tristate "SMP2P Sleepstate notifier" + depends on QCOM_SMP2P + help + When this option is enabled, notifications are sent to remote procs + for the power state changes on the local processor. The notifications + are sent through the smp2p framework. This driver can also receive + notifications from the remote to prevent suspend on the local + processor. + +config SENSORS_SSC + tristate "Enable Sensors Driver Support for SSC" + depends on MSM_SUBSYSTEM_RESTART + help + Say y or m here to enable Snapdragon Sensor Core(SSC) + support for Qualcomm Technologies, Inc SoCs. SSC is used for + exercising sensor use-cases. This driver loads firmware files + for SSC and also does time synchronization with DSP clock. + +config QSEE_IPC_IRQ + tristate "QSEE interrupt manager" + help + The QSEE IPC IRQ controller manages the interrupts from the QTI + secure execution environment. This interrupt controller will use + the registers in the spcs region to mask and clear interrupts. + Clients can use this driver to avoid adding common interrupt handling + code. + +config QCOM_GLINK + tristate "GLINK Probe Helper" + depends on RPMSG_QCOM_GLINK_SMEM + help + This enables the GLINK Probe module. This is designed to set up + other edges in the system. It will initialize all the transports for + all the edges present in the device. + Say M if you want to enable this module. + +config MSM_GLINK_SSR + tristate "MSM GLINK SSR" + depends on RPMSG + help + The GLINK RPMSG Plugin is currently designed to plugin with the + remote proc framework as a subdev. This module is responsible + for creating the glink transports when remote proc is disabled. This + will be used for drivers on MSMs. + Say M if you want to enable this + +config QTI_PMIC_GLINK + tristate "Enable support for PMIC GLINK" + depends on QCOM_GLINK + help + The PMIC Glink driver provides the interface for clients to + communicate over GLink for sending and receiving data to charger + firmware that runs on a remote subsystem like DSP which supports + charging and gauging. + This enables clients to read and write battery charging parameters. + +config QTI_PMIC_GLINK_CLIENT_DEBUG + depends on QTI_PMIC_GLINK && DEBUG_FS + bool "Enable debugfs features in PMIC GLINK client drivers" + help + This option enables the generation of debugfs files in PMIC GLINK + client drivers that are strictly meant for internal debugging only. + Writing to these debug files changes key physical parameters of a + system, which may lead to instability. Therefore, this option should + never be enabled on production devices. + +config QTI_BATTERY_GLINK_DEBUG + tristate "Enable support for QTI battery glink debug driver" + depends on QTI_PMIC_GLINK + help + Qualcomm Technologies, Inc. battery glink debug driver helps to + obtain debug information for battery charging and gauging over PMIC + Glink from charger and gauging firmware running on a remote subsystem + (e.g. DSP). + +config QTI_ALTMODE_GLINK + tristate "Type-C alternate mode over GLINK" + depends on QTI_PMIC_GLINK + help + The Qualcomm Technologies, Inc. Type-C alternate mode driver provides + an interface for Type-C alternate mode clients to receive data such + as Pin Assignment Notifications from the Type-C stack running on a + remote subsystem (e.g. DSP) via the PMIC GLINK interface. + +config QTI_PMIC_PON_LOG + tristate "PMIC PON log parser driver" + help + The PMIC PON log driver parses PMIC power-on, power-off, and fault + information out of a binary log stored in the SDAM memory found on + some Qualcomm Technologies, Inc. PMIC devices. This driver is useful + when debugging unexpected power-off scenarios. + +config MSM_CDSP_LOADER + tristate "CDSP loader support" + help + This enables the CDSP loader driver that loads the CDSP + firmware images and brings the compute DSP out of reset + for platforms that have one. + Say M if you want to enable this module. + +config QGKI + bool "Enable for QGKI or debug variant" + help + When this flag is enabled, it is safe to assume that the build + is a Non GKI build. It can be either QGKI build or a debug + build. This does not differentiate a QGKI and a debug build. + This flag is absent if the build is a GKI build. If this flag is + enabled, all the ABI compatibilities are not applicable. + +config MSM_PM + bool + select MSM_IDLE_STATS if DEBUG_FS + select QTI_SYSTEM_PM if QCOM_RPMH + select QTI_SYSTEM_PM_RPM if MSM_RPM_SMD && QGKI && QCOM_MPM + bool "Qualcomm Technologies, Inc. (QTI) Power Management Drivers" + help + Platform specific power driver to manage cores and l2 low power + modes. It interface with various system driver and put the cores + into low power modes. It implements OS initiated scheme and + determines last CPU to call into PSCI for cluster Low power + modes. + +config QTI_SYSTEM_PM + bool + +config QTI_SYSTEM_PM_RPM + bool + +config MSM_PM_LEGACY + depends on PM + select MSM_IDLE_STATS if DEBUG_FS + select CPU_IDLE_MULTIPLE_DRIVERS + bool "Qualcomm Technologies, Inc. (QTI) platform specific Legacy PM driver" + help + Platform specific legacy power driver to manage + cores and l2 low power modes. It interface with + various system driver and put the cores into + low power modes. + +config QTI_PLH_SCMI_CLIENT + tristate "Qualcomm Technologies Inc. SCMI client driver for PLH" + depends on QTI_PLH + default n + help + SCMI client driver registers itself with SCMI framework for PLH + vendor protocol, and also registers with the plh interface driver + msm_performance. + + This driver deliver the PLH vendor protocol handle to interface + driver, and interface driver will use this handle to communicate + with RIMPS PLH. + +config QTI_HW_MEMLAT + tristate "Qualcomm Technologies Inc. RIMPS memlat interface driver" + depends on PERF_EVENTS + default n + help + Interface driver between RIMPS memlat and userspace. + + This driver is responsible for handling the communication with + RIMPS memlat such as setting up PMU events, passing tunables, frequency + table, PMU counters and saving the values of PMU counters during LPM and + hotplug. + +config QTI_HW_NUM_AMU + int + default 7 if ARCH_LAHAINA && QTI_HW_MEMLAT + default 5 if ARCH_HOLI && QTI_HW_MEMLAT + default 5 + +config QTI_HW_NUM_PMU + int + default 6 if (ARCH_LAHAINA || ARCH_HOLI) && QTI_HW_MEMLAT + default 6 + +config QTI_HW_MEMLAT_SCMI_CLIENT + tristate "Qualcomm Technologies Inc. SCMI client driver for HW MEMLAT" + depends on QTI_HW_MEMLAT + default n + help + SCMI client driver registers itself with SCMI framework for memlat + vendor protocol, and also registers with the memlat hw interface + driver. + + This driver deliver the memlat vendor protocol handle to interface + driver, and interface driver will use this handle to communicate with + memlat HW. + +config QTI_HW_MEMLAT_LOG + tristate "Qualcomm Technologies Inc. HW MEMLAT Logging" + depends on IPC_LOGGING && QCOM_RIMPS + default n + help + Memlat hw logging driver, this driver has the infra to collect logs + generated in MEMLAT HW and log the buffers. + + This driver register with IPC_Logging framework, to have dedicated + buffer for memlat hw device. + +if (MSM_PM || MSM_PM_LEGACY) +menuconfig MSM_IDLE_STATS + bool "Collect idle statistics" + help + Collect cores various low power mode idle statistics + and export them in proc/msm_pm_stats. User can read + this data and determine what low power modes and how + many times cores have entered into LPM modes. + +if MSM_IDLE_STATS + +config MSM_IDLE_STATS_FIRST_BUCKET + int "First bucket time" + default 62500 + help + Upper time limit in nanoseconds of first bucket. + +config MSM_IDLE_STATS_BUCKET_SHIFT + int "Bucket shift" + default 2 + +config MSM_IDLE_STATS_BUCKET_COUNT + int "Bucket count" + default 10 + +config MSM_SUSPEND_STATS_FIRST_BUCKET + int "First bucket time for suspend" + default 1000000000 + help + Upper time limit in nanoseconds of first bucket of the + histogram. This is for collecting statistics on suspend. + +endif # MSM_IDLE_STATS +endif # MSM_PM || MSM_PM_LEGACY + +config QTI_RPM_STATS_LOG + tristate "Qualcomm Technologies RPM Stats Driver" + help + This option enables a driver which reads RPM messages from a shared + memory location. These messages provide statistical information about + the low power modes that RPM enters. The drivers outputs the message + via a sysfs node. + +config QCOM_SUBSYSTEM_SLEEP_STATS + tristate "Qualcomm Technologies, Inc. Subsystem sleep stats driver" + depends on QCOM_SMEM + help + This driver is IOCTL implementation to get the subsystem stats data + from SMEM. Stats information such as sleep count, last entered at, + last exited at and accumulated duration can be read from + userspace with ioctl. + +config QTI_DDR_STATS_LOG + tristate "Qualcomm Technologies Inc (QTI) DDR Stats Driver" + depends on QCOM_RPMH + help + This option enables a driver which reads DDR statistical information + from AOP shared memory location such as DDR low power modes and DDR + frequency residency and counts. The driver outputs information using + sysfs. + +config QTI_SYS_PM_VX + tristate "Qualcomm Technologies Inc (QTI) System PM Violators Driver" + depends on QMP_DEBUGFS_CLIENT + help + This option enables debug subystems that prevent system low power + modes. The user sends a QMP message to AOP to record subsystems + preventing deeper system low power modes. The data is stored in the + MSGRAM by AOP and read and reported in the debugfs by this driver. + +config MSM_JTAGV8 + bool "Debug and ETM trace support across power collapse for ARMv8" + default y if CORESIGHT_SOURCE_ETM4X + depends on QCOM_SCM=y + help + Enables support for debugging (specifically breakpoints) and ETM + processor tracing across power collapse both for JTag and OS hosted + software running on ARMv8 target. Enabling this will ensure debug + and ETM registers are saved and restored across power collapse. + If unsure, say 'N' here to avoid potential power, performance and + memory penalty. + +config QCOM_FSA4480_I2C + bool "Fairchild FSA4480 chip with I2C" + select REGMAP_I2C + depends on I2C + depends on AUDIO_QGKI + help + Support for the Fairchild FSA4480 IC switch chip controlled + using I2C. This driver provides common support + for accessing the device, switching between USB and Audio + modes, changing orientation. + +config QCOM_SOC_SLEEP_STATS + tristate "Qualcomm Technologies, Inc. (QTI) SoC sleep stats driver" + help + Qualcomm Technologies Inc (QTI) SoC sleep stats driver to read + the shared memory exported by the remote processor related to + various SoC level low power modes statistics and export to sysfs + interface. + +config QCOM_CDSP_RM + tristate "CDSP request manager" + depends on QCOM_GLINK + help + This driver serves CDSP requests for CPU L3 clock and CPU QoS thus + improving CDSP performance. Using this driver, CDSP can set appropriate + CPU L3 clock for improving IO-Coherent throughput and opt for QoS mode + to improve RPC latency. The driver also registers cooling devices for + CDSP subsystem and implements Cx ipeak limit management. + +config CDSPRM_VTCM_DYNAMIC_DEBUG + bool "Enable for VTCM parition test enablement" + help + The VTCM dynamic debug flag is used to enable the vtcm partition test + feature from the debugfs node from cdsprm driver.When the test is + enabled, the vtcm partition details are sent to the CDSP via rpmsg + channel. + +config QCOM_SYSMON_SUBSYSTEM_STATS + tristate "Qualcomm Technologies SysMon DSP subsystem stats" + depends on QCOM_SMEM + help + sysMon subsystem stats driver exposes API to query DSP + subsystem's load and power statistics stored in SMEM. + SMEM region for each DSP subsystem is updated periodically + by the respective subsystem. Power stats gets updated after + DSP clock change event. + +config QCOM_WDT_CORE + tristate "Qualcomm Technologies, Inc. Watchdog Support" + depends on ARCH_QCOM + help + This enables the watchdog framework for Qualcomm Technologies, Inc. + devices. It causes a kernel panic if the watchdog times out. It allows + for the detection of cpu hangs and deadlocks. It does not run during the + bootup process, so it will not catch any early lockups. Enabling this + only enables the framework, an individual Qualcomm Technologies, Inc. + watchdog module must be loaded along with this for watchdog + functionality. + +config QCOM_CX_IPEAK + tristate "Common driver to handle Cx iPeak limitation" + help + Cx ipeak HW module is used to limit the current drawn by various + subsystem blocks on Cx power rail. Each client needs to set their + bit in tcsr register if it is going to cross its own threshold. + If all clients are going to cross their thresholds then Cx ipeak + hw module will raise an interrupt to cDSP block to throttle cDSP fmax. + +config QCOM_SOC_WATCHDOG + tristate "Qualcomm Technologies, Inc. Soc Watchdog" + depends on QCOM_WDT_CORE + help + This enables the Qualcomm Technologies, Inc. watchdog module for the + Soc. It provides an interface to perform watchdog actions such as + setting the bark/bite time and also petting the hardware watchdog. To + utilize this the Qualcomm Technologies, Inc. watchdog framework must + also be enabled. + +config QCOM_IRQ_STAT + bool "QCOM IRQ stats" + depends on QGKI && QCOM_WDT_CORE + help + This give irq stats for top hitter at + watchdog pet, watchdog bark and kernel panics. + This provides additional debug information + for irq counts on cpu and ipi counts. + +config QCOM_INITIAL_LOGBUF + bool "QCOM save initial log_buf" + depends on QGKI && QCOM_WDT_CORE + help + This enables to keep copy of initial log_buf + of minimum 512KB from bootup. It can help in + debugging issues which are manifestation + of failure during initial bootup. + +config QCOM_FORCE_WDOG_BITE_ON_PANIC + bool "QCOM force watchdog bite on panic" + depends on QCOM_WDT_CORE + help + This forces a watchdog bite when the device restarts + due to a kernel panic. On certain MSM SoCs, + this provides additional debugging + information. + +config QCOM_WDOG_BITE_EARLY_PANIC + bool "QCOM early panic watchdog bite" + depends on QCOM_WDT_CORE && QCOM_FORCE_WDOG_BITE_ON_PANIC + help + This forces a watchdog bite early in panic sequence. On certain + MSM SoCs, this provides us additional debugging information at the + context of the crash. If this option is disabled, then bite occurs + later in panic, which permits more of the restart sequence to run + (e.g. more dmesg to flushed to console). + +config QCOM_WATCHDOG_BARK_TIME + depends on QCOM_WDT_CORE + int "Qualcomm Technologies, Inc. Watchdog bark time in ms" + default 11000 + range 11000 11000 + help + The amount of time, in milliseconds, that should elapse after + a watchdog timer reset before a bark interrupt is sent from the + watchdog. + +config QCOM_WATCHDOG_PET_TIME + depends on QCOM_WDT_CORE + int "Qualcomm Technologies, Inc. Watchdog pet time in ms" + default 9360 + range 9360 9360 + help + The amount of time, in milliseconds, that should elapse before + a watchdog pet is initiated to reset the watchdog timer to 0. + +config QCOM_WATCHDOG_IPI_PING + depends on QCOM_WDT_CORE + bool "Qualcomm Technologies, Inc. Watchdog ipi ping" + default y + help + This boolean flag gives the watchdog driver the ability to send a + keep-alive ping to other cpu's if it is set to 1. Otherwise, when + it is set to 0 no keep alive pings will be sent. + +config QCOM_WATCHDOG_WAKEUP_ENABLE + depends on QCOM_WDT_CORE + bool "Qualcomm Technologies, Inc. Watchdog wakeup enable" + default y + help + This boolean flag allows the non secure watchdog counter to freeze + and unfreeze automatically across the system suspend and resume + path. + +config QCOM_WATCHDOG_USERSPACE_PET + depends on QCOM_WDT_CORE + bool "Qualcomm Technologies, Inc. Watchdog user pet enable" + default n + help + This boolean flag allows enabling the userspace-watchdog feature. + This feature requires userspace to pet the watchdog every in an + interval that matches the time set in the pet-time config. + The feature is supported through device sysfs files. + +config MSM_SPCOM + depends on QCOM_GLINK + tristate "Secure Processor Communication over RPMSG" + help + SPCOM driver allows loading Secure Processor Applications and sending + messages to Secure Processor Applications. SPCOM implements logic of RPMSG + client of SPSS edge. SPCOM provides interface to both user space app and + kernel driver. It is using glink as the transport layer, which provides + multiple logical channels over single physical channel. The physical layer + is based on shared memory and interrupts. SPCOM provides clients/server API + although currently only one client/server is allowed per logical channel. + +config QCOM_EUD + tristate "QTI Embedded USB Debugger (EUD)" + depends on ARCH_QCOM + select SERIAL_CORE + help + The EUD (Embedded USB Debugger) is a mini-USB hub implemented + on chip to support the USB-based debug and trace capabilities. + This module enables support for Qualcomm Technologies, Inc. + Embedded USB Debugger (EUD). + If unsure, say N. + +config QCOM_SMCINVOKE + tristate "Secure QSEE Support" + help + Enable SMCInvoke driver which supports capability based secure + communication between QTI Secure Execution Environment (QSEE) + and high level operating system. It exposes APIs for both + userspace and kernel clients. + +config QCOM_GUESTVM + tristate "Enable Guest VM to be loaded by PIL" + help + This driver invokes Peripheral Image Loader to load images of + any guest Virtual Machine (VM). It also communicates with the + Resource Manager driver to start the boot of VMs once it has + successfully loaded the VM images in the designated memory. + +config QCOM_HYP_CORE_CTL + bool "CPU reservation scheme for Hypervisor" + depends on QCOM_GUESTVM && SCHED_WALT + help + This driver reserve the specified CPUS by isolating them. The reserved + CPUs can be assigned to the other guest OS by the hypervisor. + An offline CPU is considered as a reserved CPU since this OS can't use + it. + +config QTI_CRYPTO_COMMON + tristate "Enable common crypto functionality used for FBE" + depends on SCSI_UFS_CRYPTO_QTI + help + Say 'Y' to enable the common crypto implementation to be used by + different storage layers such as UFS and EMMC for file based hardware + encryption. This library implements API to program and evict + keys using Trustzone or Hardware Key Manager. + +config QTI_CRYPTO_TZ + tristate "Enable Trustzone to be used for FBE" + depends on QTI_CRYPTO_COMMON + help + Say 'Y' to enable routing crypto requests to Trustzone while + performing hardware based file encryption. This means keys are + programmed and managed through SCM calls to TZ where ICE driver + will configure keys. + +config QTI_CRYPTO_FDE + tristate "Enable common crypto functionality used for FDE" + depends on QTI_CRYPTO_COMMON + help + Say 'Y' to enable hardware Full Disk Encryption implementation to be used by + different storage layers such as UFS. Enabling the FDE will reserve one slot + of KSM(Key Slot Manager) for the FDE. Making one less slot available for FBE + (File based encryption) in case both encryption mechanism are enabled on device. + +config QTI_CRYPTO_VIRTUALIZATION + tristate "Enable hypervysor to be used for FBE" + depends on FS_ENCRYPTION_INLINE_CRYPT + depends on MSM_HAB + help + Say 'Y' to enable routing of crypto requests to different operating + system in virtualized environment. Driver uses a hardware abstraction(hab) + layer where the APIs exposed by that operationg systems are used to send + requests to perform the hardware crypto operation. + +config QTI_HW_KEY_MANAGER + tristate "Enable QTI Hardware Key Manager for storage encryption" + default n + help + Say 'Y' to enable the hardware key manager driver used to operate + and access key manager hardware block. This is used to interface with + HWKM hardware to perform key operations from the kernel which will + be used for storage encryption. + +config QCOM_RTIC + bool "Enable Qualcomm Technologies, Inc. RTIC feature" + depends on QGKI + default y if QGKI + help + This option enables QCOM Real Time Integrity Check feature. This + will trigger RTIC kernel MP.s (measurement parameters) generation + during the kernel build. + +config RENAME_BLOCK_DEVICE + tristate "Rename block device node in /dev" + default n + help + Say 'Y' to to rename the block device node assigned by generic + driver to a name that is needed. This is used for rename block + device names created by default as sda1, sda2 etc. to the + names system is needed.this is applicable for block devices only. + +config QCOM_ADSP_MANUAL_VOTE + bool "Send commands to ADSP to unvote/vote during Suspend/resume" + help + This driver is used to manually release and acquire the ADSP vote from + APPS processor during system suspend and resume. + This driver sends message over QMI to the service which is running on + ADSP. + +config MSM_SLATECOM + bool "Provide APIs to communicate with Slate chipset" + help + SLATECOM is a thin layer above SPI. It is used whithin a SoC for + communication between G-Link/slate_com_dev and Slate processor over SPI. + This handle the interrupts raised by BG and notify the G-link with + interrupt event and event data. + +config MSM_SLATECOM_INTERFACE + tristate "Driver support for Slate Communication" + depends on MSM_SLATECOM + help + Create a slate_com_dev device node for user space communication. + Single user space client can open device node for communication + from hardware. Hardware will provide access to read + registers and read/write AHB memory in the device. + +config QCOM_AOP_SET_DDR + tristate "Sysfs to communicate with AOP using QMP protocol" + help + This options enables a driver which allows clients to send messages + to Alway On processor using QMP transport. Users can echo a frequency + into an exposed sysfs node to send to AOP. The driver expects the Cap + frequency of DDR based on SKU. + +config DUMP_XBL_LOG + bool "print xbl log on console from fs" + help + This driver is used to capture xbl log from reserved memory region + defined separately in each device tree and print on console when user + requests. User can perform below command to print xbl log stored in + reserved memory region: + cat /sys/module/xbl_log/xbl_log + +config MSM_SEB + tristate "Provide APIs to send and receive events from Slate chipset" + help + SEB(Slate event bridge) communicates to Slate over rpmsg driver to + send or receive events from Slate. The button events received from + Slate are send to input framework. The driver provides functionality + for a client to register a callback to receive events from a group. + +config MSM_SEB_RPMSG + tristate "Provide support for slate event GLINK channel" + depends on MSM_SEB + help + SEB_RPMSG informs SEB driver if GLINK channel has been + opened by remote processor. It doesn't maintain state machine + and is probed when Slate opens channel and removed when the + channel is closed by remote processor. + +config SDX_EXT_IPC + tristate "QCOM external ipc driver" + help + This enables the module to help modem communicate with external + Application processor connected to Qualcomm Technologies, Inc + modem chipset. The modem and APQ can understand each other's + state by reading ipc gpios. + + If unsure, say N. + +source "drivers/soc/qcom/icnss2/Kconfig" + +source "drivers/soc/qcom/gnsssirf/Kconfig" endmenu diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 2559fe948ce0..6bd8d4a71359 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -7,20 +7,123 @@ obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o obj-$(CONFIG_QCOM_PM) += spm.o +obj-$(CONFIG_MSM_PIL) += peripheral-loader.o +obj-$(CONFIG_MSM_SUBSYSTEM_RESTART) += subsystem_restart.o +obj-$(CONFIG_MSM_CDSP_LOADER) += qdsp6v2/ +subsystem_restart-y := msm_subsystem_restart.o subsystem_notif.o ramdump.o sysmon-qmi.o +obj-$(CONFIG_MSM_QUIN_SUBSYSTEM_NOTIF_VIRT) += subsystem_notif_virt.o +obj-$(CONFIG_MSM_PIL_SSR_GENERIC) += subsys-pil-tz.o +obj-$(CONFIG_MSM_PIL_MSS_QDSP6V5) += pil-q6v5.o pil-msa.o pil-q6v5-mss.o +obj-$(CONFIG_MSM_SERVICE_NOTIFIER) += service-notifier.o +obj-$(CONFIG_MSM_SERVICE_LOCATOR) += service-locator.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o +obj-$(CONFIG_MEM_SHARE_QMI_SERVICE) += memshare/ obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o qcom_rpmh-y += rpmh-rsc.o qcom_rpmh-y += rpmh.o +obj-$(CONFIG_QCOM_SOC_SLEEP_STATS) += soc_sleep_stats.o +obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o obj-$(CONFIG_QCOM_SMEM) += smem.o +obj-$(CONFIG_MSM_PM_LEGACY) += pm-boot.o msm-pm.o +obj-$(CONFIG_MSM_SPM) += msm-spm.o spm_devices.o obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o obj-$(CONFIG_QCOM_SMP2P) += smp2p.o +obj-$(CONFIG_QCOM_SUBSYSTEM_SLEEP_STATS) += subsystem_sleep_stats.o +obj-$(CONFIG_QSEE_IPC_IRQ_BRIDGE) += qsee_ipc_irq_bridge.o obj-$(CONFIG_QCOM_SMSM) += smsm.o +obj-$(CONFIG_MSM_CORE_HANG_DETECT) += core_hang_detect.o +obj-$(CONFIG_QCOM_SECURE_BUFFER) += secure_buffer.o obj-$(CONFIG_QCOM_SOCINFO) += socinfo.o +obj-$(CONFIG_QCOM_PROXY_OF_CONSUMER) += qcom_proxy_of_consumer.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o +obj-$(CONFIG_QCOM_IPCC) += qcom_ipcc.o +obj-$(CONFIG_QCOM_RIMPS) += qcom_rimps.o +obj-$(CONFIG_QCOM_RUN_QUEUE_STATS) += rq_stats.o obj-$(CONFIG_QCOM_APR) += apr.o -obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o +obj-$(CONFIG_QCOM_LLCC) += qcom_llcc.o +qcom_llcc-y += llcc-slice.o llcc-tcm.o +obj-$(CONFIG_QCOM_LAHAINA_LLCC) += llcc-lahaina.o +obj-$(CONFIG_QCOM_SDXLEMUR_LLCC) += llcc-sdxlemur.o +obj-$(CONFIG_QCOM_SHIMA_LLCC) += llcc-shima.o +obj-$(CONFIG_QCOM_YUPIK_LLCC) += llcc-yupik.o +obj-$(CONFIG_QCOM_SM8150_LLCC) += llcc-sm8150.o +obj-$(CONFIG_QCOM_SDMSHRIKE_LLCC) += llcc-sdmshrike.o +obj-$(CONFIG_QCOM_SM6150_LLCC) += llcc-sm6150.o +obj-$(CONFIG_QCOM_DIREWOLF_LLCC) += llcc-direwolf.o +obj-$(CONFIG_QCOM_MINIDUMP) += msm_minidump.o minidump_log.o +obj-$(CONFIG_QCOM_MEM_OFFLINE) += mem-offline.o +obj-$(CONFIG_QCOM_MEM_BUF) += mem-buf.o mem_buf_dma_buf.o +obj-$(CONFIG_QCOM_MEMORY_DUMP_V2) += memory_dump_v2.o +obj-$(CONFIG_QCOM_DCC_V2) += dcc_v2.o +obj-$(CONFIG_MSM_JTAGV8) += jtagv8.o jtagv8-etm.o +obj-$(CONFIG_QCOM_SMCINVOKE) += smcinvoke.o +obj-$(CONFIG_QCOM_MICRODUMP) += microdump_collector.o +obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o +obj-$(CONFIG_QCOM_LLCC_PERFMON) += llcc_perfmon.o obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o +obj-$(CONFIG_QMP_DEBUGFS_CLIENT) += qmp-debugfs-client.o +obj-$(CONFIG_QCOM_SMP2P_SLEEPSTATE) += smp2p_sleepstate.o +obj-$(CONFIG_SENSORS_SSC) += sensors_ssc.o +obj-$(CONFIG_QCOM_GLINK_PKT) += glink_pkt.o +obj-$(CONFIG_QSEE_IPC_IRQ) += qsee_ipc_irq.o +obj-$(CONFIG_QCOM_GLINK) += glink_probe.o +obj-$(CONFIG_MSM_GLINK_SSR) += msm_glink_ssr.o +obj-$(CONFIG_QTI_PMIC_GLINK) += pmic_glink.o +obj-$(CONFIG_QTI_BATTERY_GLINK_DEBUG) += qti_battery_debug.o +obj-$(CONFIG_QTI_ALTMODE_GLINK) += altmode-glink.o +obj-$(CONFIG_QTI_PMIC_PON_LOG) += pmic-pon-log.o +obj-$(CONFIG_QTI_DDR_STATS_LOG) += ddr_stats.o +obj-$(CONFIG_QTI_SYSTEM_PM) += system_pm.o +obj-$(CONFIG_QTI_SYSTEM_PM_RPM) += system_pm_rpm.o +obj-$(CONFIG_MSM_REMOTEQDSS) += remoteqdss.o +obj-$(CONFIG_MSM_SPSS_UTILS) += spss_utils.o +obj-$(CONFIG_MSM_IDLE_STATS) += lpm-stats.o +obj-$(CONFIG_MSM_PERFORMANCE) += msm_performance.o +obj-$(CONFIG_QTI_RPM_STATS_LOG) += rpmh_master_stat.o +ifdef CONFIG_MSM_RPM_SMD +obj-$(CONFIG_QTI_RPM_STATS_LOG) += rpm_master_stat.o +endif +obj-$(CONFIG_QPNP_PBS) += qpnp-pbs.o +obj-$(CONFIG_MSM_SPCOM) += spcom.o +obj-$(CONFIG_QCOM_CDSP_RM) += cdsprm.o +obj-$(CONFIG_QCOM_FSA4480_I2C) += fsa4480-i2c.o +obj-$(CONFIG_QCOM_EUD) += eud.o +obj-$(CONFIG_QCOM_GUESTVM) += guestvm_loader.o +obj-$(CONFIG_QCOM_HYP_CORE_CTL) += hyp_core_ctl.o +obj-$(CONFIG_MSM_QBT_HANDLER) += qbt_handler.o +obj-$(CONFIG_QTI_CRYPTO_COMMON) += crypto-qti-common.o +obj-$(CONFIG_QTI_CRYPTO_TZ) += crypto-qti-tz.o +obj-$(CONFIG_QTI_CRYPTO_VIRTUALIZATION) += crypto-qti-virt.o +obj-$(CONFIG_QTI_HW_KEY_MANAGER) += hwkm.o crypto-qti-hwkm.o +obj-$(CONFIG_QCOM_WDT_CORE) += qcom_wdt_core.o +obj-$(CONFIG_QCOM_SOC_WATCHDOG) += qcom_soc_wdt.o +obj-$(CONFIG_MSM_HAB) += hab/ +obj-$(CONFIG_QCOM_HGSL) += hgsl/ +obj-$(CONFIG_SDX_EXT_IPC) += sdx_ext_ipc.o +ifdef CONFIG_DEBUG_FS +obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o +endif +obj-$(CONFIG_QTI_SYS_PM_VX) += sys_pm_vx.o +obj-$(CONFIG_ICNSS2) += icnss2/ +obj-$(CONFIG_QTI_PLH_SCMI_CLIENT) += plh_scmi.o +obj-$(CONFIG_QCOM_SYSMON_SUBSYSTEM_STATS) += sysmon_subsystem_stats.o +obj-$(CONFIG_QTI_HW_MEMLAT_SCMI_CLIENT) += memlat_scmi.o +obj-$(CONFIG_QTI_HW_MEMLAT) += rimps_memlat.o +obj-$(CONFIG_QTI_HW_MEMLAT_LOG) += rimps_log.o +obj-$(CONFIG_QCOM_QFPROM_SYS) += qfprom-sys.o +obj-$(CONFIG_RENAME_BLOCK_DEVICE) += rename_block_device.o +obj-$(CONFIG_QCOM_ADSP_MANUAL_VOTE) += adsp_vote_qmi.o adsp_lpm_voting_v01.o +obj-$(CONFIG_MSM_SLATECOM) += slatecom_spi.o +obj-$(CONFIG_MSM_SLATECOM_INTERFACE) += slatecom_interface.o +obj-$(CONFIG_QCOM_AOP_SET_DDR) += aop-set-ddr.o +obj-$(CONFIG_CPU_V7) += idle-v7.o +obj-$(CONFIG_DUMP_XBL_LOG) += dump_boot_log.o +obj-$(CONFIG_QCOM_CX_IPEAK) += cx_ipeak.o +# GNSS driver +obj-$(CONFIG_GNSS_SIRF) += gnsssirf/ +obj-$(CONFIG_MSM_SEB) += slate_events_bridge.o +obj-$(CONFIG_MSM_SEB_RPMSG) += slate_events_bridge_rpmsg.o diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c new file mode 100644 index 000000000000..86600d97c36d --- /dev/null +++ b/drivers/soc/qcom/llcc-sdm845.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * + */ + +#include +#include +#include +#include +#include + +/* + * SCT(System Cache Table) entry contains of the following members: + * usecase_id: Unique id for the client's use case + * slice_id: llcc slice id for each client + * max_cap: The maximum capacity of the cache slice provided in KB + * priority: Priority of the client used to select victim line for replacement + * fixed_size: Boolean indicating if the slice has a fixed capacity + * bonus_ways: Bonus ways are additional ways to be used for any slice, + * if client ends up using more than reserved cache ways. Bonus + * ways are allocated only if they are not reserved for some + * other client. + * res_ways: Reserved ways for the cache slice, the reserved ways cannot + * be used by any other client than the one its assigned to. + * cache_mode: Each slice operates as a cache, this controls the mode of the + * slice: normal or TCM(Tightly Coupled Memory) + * probe_target_ways: Determines what ways to probe for access hit. When + * configured to 1 only bonus and reserved ways are probed. + * When configured to 0 all ways in llcc are probed. + * dis_cap_alloc: Disable capacity based allocation for a client + * retain_on_pc: If this bit is set and client has maintained active vote + * then the ways assigned to this client are not flushed on power + * collapse. + * activate_on_init: Activate the slice immediately after the SCT is programmed + */ +#define SCT_ENTRY(uid, sid, mc, p, fs, bway, rway, cmod, ptw, dca, rp, a) \ + { \ + .usecase_id = uid, \ + .slice_id = sid, \ + .max_cap = mc, \ + .priority = p, \ + .fixed_size = fs, \ + .bonus_ways = bway, \ + .res_ways = rway, \ + .cache_mode = cmod, \ + .probe_target_ways = ptw, \ + .dis_cap_alloc = dca, \ + .retain_on_pc = rp, \ + .activate_on_init = a, \ + } + +static struct llcc_slice_config sdm845_data[] = { + SCT_ENTRY(LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1), + SCT_ENTRY(LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0), + SCT_ENTRY(LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1), + SCT_ENTRY(LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0), + SCT_ENTRY(LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0), +}; + +static int sdm845_qcom_llcc_remove(struct platform_device *pdev) +{ + return qcom_llcc_remove(pdev); +} + +static int sdm845_qcom_llcc_probe(struct platform_device *pdev) +{ + return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data)); +} + +static const struct of_device_id sdm845_qcom_llcc_of_match[] = { + { .compatible = "qcom,sdm845-llcc", }, + { } +}; + +static struct platform_driver sdm845_qcom_llcc_driver = { + .driver = { + .name = "sdm845-llcc", + .of_match_table = sdm845_qcom_llcc_of_match, + }, + .probe = sdm845_qcom_llcc_probe, + .remove = sdm845_qcom_llcc_remove, +}; +module_platform_driver(sdm845_qcom_llcc_driver); + +MODULE_DESCRIPTION("QCOM sdm845 LLCC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-slice.c similarity index 77% rename from drivers/soc/qcom/llcc-qcom.c rename to drivers/soc/qcom/llcc-slice.c index 431b214975c8..bf5ec56a6395 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * */ @@ -11,12 +11,11 @@ #include #include #include -#include #include #include #include #include -#include +#include #define ACTIVATE BIT(0) #define DEACTIVATE BIT(1) @@ -45,28 +44,17 @@ #define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) #define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) -#define BANK_OFFSET_STRIDE 0x80000 +#define LLCC_TRP_C_AS_NC 0x22890 +#define LLCC_TRP_NC_AS_C 0x22894 +#define LLCC_FEAC_C_AS_NC 0x35030 +#define LLCC_FEAC_NC_AS_C 0x35034 +#define LLCC_TRP_WRSC_EN 0x21F20 +#define LLCC_WRSC_SCID_EN(n) BIT(n) -static struct llcc_slice_config sdm845_data[] = { - { LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 }, - { LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, - { LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, - { LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0 }, - { LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0 }, - { LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0 }, - { LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1 }, - { LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, - { LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0 }, - { LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0 }, - { LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 }, -}; +#define LLCC_TRP_PCB_ACT 0x21F04 +#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21F00 + +#define BANK_OFFSET_STRIDE 0x80000 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; @@ -273,9 +261,16 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) u32 attr0_val; u32 max_cap_cacheline; u32 sz; + u32 pcb = 0; + u32 cad = 0; + u32 wren = 0; int ret = 0; const struct llcc_slice_config *llcc_table; struct llcc_slice_desc desc; + bool cap_based_alloc_and_pwr_collapse = + drv_data->cap_based_alloc_and_pwr_collapse; + int v2_ver = of_device_is_compatible(pdev->dev.of_node, + "qcom,llcc-v2"); sz = drv_data->cfg_size; llcc_table = drv_data->cfg; @@ -315,6 +310,32 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) attr0_val); if (ret) return ret; + + if (v2_ver) { + wren |= llcc_table[i].write_scid_en << + llcc_table[i].slice_id; + ret = regmap_write(drv_data->bcast_regmap, + LLCC_TRP_WRSC_EN, wren); + if (ret) + return ret; + } + + if (cap_based_alloc_and_pwr_collapse) { + cad |= llcc_table[i].dis_cap_alloc << + llcc_table[i].slice_id; + ret = regmap_write(drv_data->bcast_regmap, + LLCC_TRP_SCID_DIS_CAP_ALLOC, cad); + if (ret) + return ret; + + pcb |= llcc_table[i].retain_on_pc << + llcc_table[i].slice_id; + ret = regmap_write(drv_data->bcast_regmap, + LLCC_TRP_PCB_ACT, pcb); + if (ret) + return ret; + } + if (llcc_table[i].activate_on_init) { desc.slice_id = llcc_table[i].slice_id; ret = llcc_slice_activate(&desc); @@ -323,12 +344,13 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) return ret; } -static int qcom_llcc_remove(struct platform_device *pdev) +int qcom_llcc_remove(struct platform_device *pdev) { /* Set the global pointer to a error code to avoid referencing it */ drv_data = ERR_PTR(-ENODEV); return 0; } +EXPORT_SYMBOL_GPL(qcom_llcc_remove); static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, const char *name) @@ -348,16 +370,14 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config); } -static int qcom_llcc_probe(struct platform_device *pdev, - const struct llcc_slice_config *llcc_cfg, u32 sz) +int qcom_llcc_probe(struct platform_device *pdev, + const struct llcc_slice_config *llcc_cfg, u32 sz) { u32 num_banks; struct device *dev = &pdev->dev; int ret, i; - struct platform_device *llcc_edac; - - if (!IS_ERR(drv_data)) - return -EBUSY; + struct platform_device *llcc_edac, *llcc_perfmon; + struct device_node *tcm_memory_node; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) { @@ -373,7 +393,10 @@ static int qcom_llcc_probe(struct platform_device *pdev, drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, "llcc_broadcast_base"); - if (IS_ERR(drv_data->bcast_regmap)) { + + if (PTR_ERR(drv_data->bcast_regmap) == -ENODEV) + drv_data->bcast_regmap = drv_data->regmap; + else if (IS_ERR(drv_data->bcast_regmap)) { ret = PTR_ERR(drv_data->bcast_regmap); goto err; } @@ -398,6 +421,10 @@ static int qcom_llcc_probe(struct platform_device *pdev, goto err; } + drv_data->cap_based_alloc_and_pwr_collapse = + of_property_read_bool(pdev->dev.of_node, + "cap-based-alloc-and-pwr-collapse"); + for (i = 0; i < num_banks; i++) drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; @@ -415,48 +442,42 @@ static int qcom_llcc_probe(struct platform_device *pdev, platform_set_drvdata(pdev, drv_data); ret = qcom_llcc_cfg_program(pdev); - if (ret) + if (ret) { + pr_err("llcc configuration failed!!\n"); goto err; + } drv_data->ecc_irq = platform_get_irq(pdev, 0); - if (drv_data->ecc_irq >= 0) { - llcc_edac = platform_device_register_data(&pdev->dev, - "qcom_llcc_edac", -1, drv_data, - sizeof(*drv_data)); - if (IS_ERR(llcc_edac)) - dev_err(dev, "Failed to register llcc edac driver\n"); + llcc_edac = platform_device_register_data(&pdev->dev, + "qcom_llcc_edac", -1, drv_data, + sizeof(*drv_data)); + if (IS_ERR(llcc_edac)) + dev_err(dev, "Failed to register llcc edac driver\n"); + + llcc_perfmon = platform_device_register_data(&pdev->dev, + "qcom_llcc_perfmon", -1, + drv_data, sizeof(*drv_data)); + if (IS_ERR(llcc_perfmon)) + dev_err(dev, "Failed to register llcc perfmon device\n"); + + tcm_memory_node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (tcm_memory_node) { + ret = qcom_llcc_tcm_probe(pdev, llcc_cfg, sz, tcm_memory_node); + if (ret) { + dev_err(dev, "Failed to probe TCM manager\n"); + goto err_dereg; + } } return 0; + +err_dereg: + platform_device_unregister(llcc_edac); + platform_device_unregister(llcc_perfmon); err: drv_data = ERR_PTR(-ENODEV); return ret; } - -static int sdm845_qcom_llcc_remove(struct platform_device *pdev) -{ - return qcom_llcc_remove(pdev); -} - -static int sdm845_qcom_llcc_probe(struct platform_device *pdev) -{ - return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data)); -} - -static const struct of_device_id sdm845_qcom_llcc_of_match[] = { - { .compatible = "qcom,sdm845-llcc", }, - { } -}; - -static struct platform_driver sdm845_qcom_llcc_driver = { - .driver = { - .name = "sdm845-llcc", - .of_match_table = sdm845_qcom_llcc_of_match, - }, - .probe = sdm845_qcom_llcc_probe, - .remove = sdm845_qcom_llcc_remove, -}; -module_platform_driver(sdm845_qcom_llcc_driver); - -MODULE_DESCRIPTION("QCOM sdm845 LLCC driver"); +EXPORT_SYMBOL_GPL(qcom_llcc_probe); MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller"); diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index d5cad6f7953c..a65033f5a75c 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * */ @@ -16,6 +16,7 @@ #define LLCC_AUDIO 6 #define LLCC_MDMHPGRW 7 #define LLCC_MDM 8 +#define LLCC_MDMHW 9 #define LLCC_CMPT 10 #define LLCC_GPUHTW 11 #define LLCC_GPU 12 @@ -26,6 +27,19 @@ #define LLCC_MDMHPFX 20 #define LLCC_MDMPNG 21 #define LLCC_AUDHW 22 +#define LLCC_NPU 23 +#define LLCC_WLNHW 24 +#define LLCC_PIMEM 25 +#define LLCC_DRE 26 +#define LLCC_CVP 28 +#define LLCC_MDMVPE 29 +#define LLCC_APTCM 30 +#define LLCC_WRTCH 31 +#define LLCC_CVPFW 32 +#define LLCC_CPUSS1 33 +#define LLCC_CMPT1 34 +#define LLCC_CPUHWT 36 +#define LLCC_MDMCLD2 37 /** * llcc_slice_desc - Cache slice descriptor @@ -39,27 +53,19 @@ struct llcc_slice_desc { /** * llcc_slice_config - Data associated with the llcc slice - * @usecase_id: Unique id for the client's use case - * @slice_id: llcc slice id for each client - * @max_cap: The maximum capacity of the cache slice provided in KB - * @priority: Priority of the client used to select victim line for replacement - * @fixed_size: Boolean indicating if the slice has a fixed capacity - * @bonus_ways: Bonus ways are additional ways to be used for any slice, - * if client ends up using more than reserved cache ways. Bonus - * ways are allocated only if they are not reserved for some - * other client. - * @res_ways: Reserved ways for the cache slice, the reserved ways cannot - * be used by any other client than the one its assigned to. - * @cache_mode: Each slice operates as a cache, this controls the mode of the - * slice: normal or TCM(Tightly Coupled Memory) - * @probe_target_ways: Determines what ways to probe for access hit. When - * configured to 1 only bonus and reserved ways are probed. - * When configured to 0 all ways in llcc are probed. - * @dis_cap_alloc: Disable capacity based allocation for a client - * @retain_on_pc: If this bit is set and client has maintained active vote - * then the ways assigned to this client are not flushed on power - * collapse. - * @activate_on_init: Activate the slice immediately after it is programmed + * @usecase_id: usecase id for which the llcc slice is used + * @slice_id: llcc slice id assigned to each slice + * @max_cap: maximum capacity of the llcc slice + * @priority: priority of the llcc slice + * @fixed_size: whether the llcc slice can grow beyond its size + * @bonus_ways: bonus ways associated with llcc slice + * @res_ways: reserved ways associated with llcc slice + * @cache_mode: mode of the llcc slice + * @probe_target_ways: Probe only reserved and bonus ways on a cache miss + * @dis_icap_alloc: Disable capacity based allocation + * @write_scid_en: Enables write cache support for a given scid. + * @retain_on_pc: Retain through power collapse + * @activate_on_init: activate the slice on init */ struct llcc_slice_config { u32 usecase_id; @@ -72,6 +78,7 @@ struct llcc_slice_config { u32 cache_mode; u32 probe_target_ways; bool dis_cap_alloc; + bool write_scid_en; bool retain_on_pc; bool activate_on_init; }; @@ -100,6 +107,7 @@ struct llcc_drv_data { unsigned long *bitmap; u32 *offsets; int ecc_irq; + bool cap_based_alloc_and_pwr_collapse; }; /** @@ -163,6 +171,20 @@ int llcc_slice_activate(struct llcc_slice_desc *desc); */ int llcc_slice_deactivate(struct llcc_slice_desc *desc); +/** + * qcom_llcc_probe - program the sct table + * @pdev: platform device pointer + * @table: soc sct table + * @sz: Size of the config table + */ +int qcom_llcc_probe(struct platform_device *pdev, + const struct llcc_slice_config *table, u32 sz); + +/** + * qcom_llcc_remove - remove the sct table + * @pdev: Platform device pointer + */ +int qcom_llcc_remove(struct platform_device *pdev); #else static inline struct llcc_slice_desc *llcc_slice_getd(u32 uid) { @@ -192,6 +214,16 @@ static inline int llcc_slice_deactivate(struct llcc_slice_desc *desc) { return -EINVAL; } +static inline int qcom_llcc_probe(struct platform_device *pdev, + const struct llcc_slice_config *table, u32 sz) +{ + return -ENODEV; +} + +static inline int qcom_llcc_remove(struct platform_device *pdev) +{ + return -ENODEV; +} #endif #endif From ab0f86134fcb5d4e066dffcc6e1684138e96337d Mon Sep 17 00:00:00 2001 From: Kaushal Hooda Date: Tue, 20 Jun 2023 11:06:00 +0530 Subject: [PATCH 03/14] rpmsg: slatecom: maintain rx_size to read For cmd close_ack or open request where rx_size is being incrementing with respect to offset might lead to out of bound read from rx_data. Decrease rx_size as we process commands. Change-Id: I492eadcbebb78386fc20f744eb9ad8db4a2914fc Signed-off-by: Kaushal Hooda --- drivers/rpmsg/qcom_glink_slatecom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_slatecom.c b/drivers/rpmsg/qcom_glink_slatecom.c index d57adfa3c92f..79e241a04ce5 100644 --- a/drivers/rpmsg/qcom_glink_slatecom.c +++ b/drivers/rpmsg/qcom_glink_slatecom.c @@ -1935,7 +1935,7 @@ static void glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_da case SLATECOM_CMD_CLOSE_ACK: glink_slatecom_rx_defer(glink, rx_data + offset - sizeof(*msg), - rx_size + offset - sizeof(*msg), 0); + rx_size - offset + sizeof(*msg), 0); break; case SLATECOM_CMD_RX_INTENT_REQ: glink_slatecom_handle_intent_req(glink, param1, param2); @@ -1948,7 +1948,7 @@ static void glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_da name = rx_data + offset; glink_slatecom_rx_defer(glink, rx_data + offset - sizeof(*msg), - rx_size + offset - sizeof(*msg), + rx_size - offset + sizeof(*msg), ALIGN(name_len, SLATECOM_ALIGNMENT)); offset += ALIGN(name_len, SLATECOM_ALIGNMENT); From 0950011ce6a06720105c0849bb35e33492d629e7 Mon Sep 17 00:00:00 2001 From: Ajit Kumar Date: Mon, 21 Aug 2023 12:36:55 +0530 Subject: [PATCH 04/14] soc: qcom: add out of bound check for AON fifo Add out of bound check while parsing the SPI slave-to-master fifo. Change-Id: I14f707307fa277b2f8a7b543d3cc5e9ebac885db Signed-off-by: Ajit Kumar --- drivers/soc/qcom/slatecom_spi.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/slatecom_spi.c b/drivers/soc/qcom/slatecom_spi.c index de30f47a1288..a728ba43c90f 100644 --- a/drivers/soc/qcom/slatecom_spi.c +++ b/drivers/soc/qcom/slatecom_spi.c @@ -303,7 +303,7 @@ void slatecom_slatedown_handler(void) } EXPORT_SYMBOL(slatecom_slatedown_handler); -static void parse_fifo(uint8_t *data, union slatecom_event_data_type *event_data) +static void parse_fifo(uint8_t *data, uint16_t data_len, union slatecom_event_data_type *event_data) { uint16_t p_len; uint8_t sub_id; @@ -314,11 +314,16 @@ static void parse_fifo(uint8_t *data, union slatecom_event_data_type *event_data struct event_list *data_list; while (*data != '\0') { - + if (data_len < HED_EVENT_ID_LEN) + break; event_id = *((uint16_t *) data); data = data + HED_EVENT_ID_LEN; + data_len = data_len - HED_EVENT_ID_LEN; + if (data_len < HED_EVENT_SIZE_LEN) + break; p_len = *((uint16_t *) data); data = data + HED_EVENT_SIZE_LEN; + data_len = data_len - HED_EVENT_SIZE_LEN; if (event_id == 0xFFFE) { @@ -346,8 +351,14 @@ static void parse_fifo(uint8_t *data, union slatecom_event_data_type *event_data send_event(SLATECOM_EVENT_TO_MASTER_FIFO_USED, event_data); } + } else if (event_id == 0xc8) { + data = data + 12; + data_len = data_len - 12; + pr_err("Packet Received = 0x%X, len = %u\n", event_id, p_len); } + data = data + p_len; + data_len = data_len - p_len; } if (!list_empty(&pr_lst_hd)) queue_work(wq, &input_work); @@ -451,7 +462,8 @@ static void send_back_notification(uint32_t slav_status_reg, if (!ret) { augmnt_fifo((uint8_t *)ptr, master_fifo_used*SLATE_SPI_WORD_SIZE); - parse_fifo((uint8_t *)ptr, &event_data); + parse_fifo((uint8_t *)ptr, + master_fifo_used*SLATE_SPI_WORD_SIZE, &event_data); } kfree(ptr); } From 920dbdcff741e685247c257d2733bd962599709e Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Mon, 8 Aug 2022 15:02:02 +0530 Subject: [PATCH 05/14] defconfig: arm64: Disable trimming non-whitelisted symbols Disable trimming of non-whitelisted symbols for all defconfigs. Change-Id: I11f8c5a2835b79cad31ff36e04f618f22c22e84b Signed-off-by: Vivek Kumar Signed-off-by: Srinivasarao Pathipati --- arch/arm64/configs/vendor/autogvm_GKI.config | 3 --- arch/arm64/configs/vendor/bengal_GKI.config | 3 --- arch/arm64/configs/vendor/gen3auto_GKI.config | 4 +--- arch/arm64/configs/vendor/holi_GKI.config | 4 +--- arch/arm64/configs/vendor/lahaina_GKI.config | 4 +--- arch/arm64/configs/vendor/sdmsteppeauto_GKI.config | 3 --- 6 files changed, 3 insertions(+), 18 deletions(-) diff --git a/arch/arm64/configs/vendor/autogvm_GKI.config b/arch/arm64/configs/vendor/autogvm_GKI.config index 92f8a3709d5a..a716ab4c5de6 100644 --- a/arch/arm64/configs/vendor/autogvm_GKI.config +++ b/arch/arm64/configs/vendor/autogvm_GKI.config @@ -3,9 +3,6 @@ CONFIG_COMMON_CLK_QCOM=m CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_PROXY_CONSUMER=m CONFIG_REGULATOR_STUB=m -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_PINCTRL_SM8150=m CONFIG_PINCTRL_SDMSHRIKE=m CONFIG_PINCTRL_SM6150=m diff --git a/arch/arm64/configs/vendor/bengal_GKI.config b/arch/arm64/configs/vendor/bengal_GKI.config index 63ae85ce8a27..16b3f591f3f0 100644 --- a/arch/arm64/configs/vendor/bengal_GKI.config +++ b/arch/arm64/configs/vendor/bengal_GKI.config @@ -1,9 +1,6 @@ CONFIG_ARCH_QCOM=y CONFIG_ARCH_SCUBA=y CONFIG_ARCH_BENGAL=y -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_PINCTRL_SCUBA=m CONFIG_QCOM_RPMH=m CONFIG_QCOM_COMMAND_DB=m diff --git a/arch/arm64/configs/vendor/gen3auto_GKI.config b/arch/arm64/configs/vendor/gen3auto_GKI.config index 999dd7f0d345..b3bcb58db3c2 100644 --- a/arch/arm64/configs/vendor/gen3auto_GKI.config +++ b/arch/arm64/configs/vendor/gen3auto_GKI.config @@ -9,9 +9,6 @@ CONFIG_REGULATOR_PROXY_CONSUMER=m CONFIG_REGULATOR_REFGEN=m CONFIG_REGULATOR_RPMH=m CONFIG_REGULATOR_STUB=m -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_PINCTRL_SM8150=m CONFIG_PINCTRL_SDMSHRIKE=m CONFIG_PINCTRL_SLPI=m @@ -140,3 +137,4 @@ CONFIG_CNSS_GENL=m CONFIG_QRTR_MHI=m CONFIG_UIO_MSM_SHAREDMEM=m CONFIG_INCREMENTAL_FS=m +# CONFIG_TRIM_UNUSED_KSYMS is not set diff --git a/arch/arm64/configs/vendor/holi_GKI.config b/arch/arm64/configs/vendor/holi_GKI.config index 031730e79137..b3dac1f70c31 100644 --- a/arch/arm64/configs/vendor/holi_GKI.config +++ b/arch/arm64/configs/vendor/holi_GKI.config @@ -1,8 +1,5 @@ CONFIG_ARCH_QCOM=y CONFIG_ARCH_HOLI=y -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_QCOM_RPMH=m CONFIG_QCOM_RPMHPD=m CONFIG_QCOM_COMMAND_DB=m @@ -234,3 +231,4 @@ CONFIG_SM_DISPCC_BLAIR=m CONFIG_SM_DEBUGCC_BLAIR=m CONFIG_QCOM_CX_IPEAK=m CONFIG_LEDS_AW2016=m +# CONFIG_TRIM_UNUSED_KSYMS is not set diff --git a/arch/arm64/configs/vendor/lahaina_GKI.config b/arch/arm64/configs/vendor/lahaina_GKI.config index 1d1ab64c11df..70314edcbd6d 100644 --- a/arch/arm64/configs/vendor/lahaina_GKI.config +++ b/arch/arm64/configs/vendor/lahaina_GKI.config @@ -1,9 +1,6 @@ CONFIG_ARCH_QCOM=y CONFIG_ARCH_LAHAINA=y CONFIG_ARCH_SHIMA=y -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_QCOM_RPMH=m CONFIG_QCOM_RPMHPD=m CONFIG_QCOM_COMMAND_DB=m @@ -252,3 +249,4 @@ CONFIG_REGULATOR_QPNP_LCDB=m CONFIG_LEDS_QPNP_VIBRATOR_LDO=m CONFIG_BACKLIGHT_QCOM_SPMI_WLED=m # CONFIG_CFG80211_CRDA_SUPPORT is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set diff --git a/arch/arm64/configs/vendor/sdmsteppeauto_GKI.config b/arch/arm64/configs/vendor/sdmsteppeauto_GKI.config index 1f02ec38f3e7..d758880b0c83 100644 --- a/arch/arm64/configs/vendor/sdmsteppeauto_GKI.config +++ b/arch/arm64/configs/vendor/sdmsteppeauto_GKI.config @@ -8,9 +8,6 @@ CONFIG_REGULATOR_PROXY_CONSUMER=m CONFIG_REGULATOR_REFGEN=m CONFIG_REGULATOR_RPMH=m CONFIG_REGULATOR_STUB=m -CONFIG_TRIM_UNUSED_KSYMS=y -CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal" -CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y CONFIG_PINCTRL_SM6150=m CONFIG_PINCTRL_SDMSHRIKE=m CONFIG_HEADER_TEST=y From 91292d8e2db61cd9028e1c2fa02a9151a0e0e98c Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Mon, 29 Jan 2024 12:30:12 +0530 Subject: [PATCH 06/14] soc: qcom: msm_minidump: Configurable Encryption support Some regions registered cannot be encrypted in minidump due to some HW limitations on sdxlemur. To work around this, make the encryption of minidump regions configurable. Change-Id: Ibd0899ecaacfda4bd8f05ce0b8eef05c731c18e3 Signed-off-by: Rohit Agarwal Signed-off-by: Sayan Dey --- arch/arm/configs/vendor/sdxlemur.config | 1 + drivers/soc/qcom/Kconfig | 10 ++++++++++ drivers/soc/qcom/msm_minidump.c | 9 +++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/vendor/sdxlemur.config b/arch/arm/configs/vendor/sdxlemur.config index a816f4605758..59549a3b7aae 100644 --- a/arch/arm/configs/vendor/sdxlemur.config +++ b/arch/arm/configs/vendor/sdxlemur.config @@ -513,3 +513,4 @@ CONFIG_ANDROID_BINDERFS=y CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder" # CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set CONFIG_IPC_LOG_MINIDUMP_BUFFERS=16 +# CONFIG_QCOM_MINIDUMP_ENCRYPT is not set diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 145b60079b23..33674ebaf5da 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -645,6 +645,16 @@ config MINIDUMP_MAX_ENTRIES This defines maximum number of entries to be allocated for application subsytem in Minidump table. +config QCOM_MINIDUMP_ENCRYPT + bool "QCOM Minidump Encryption Required" + depends on QCOM_MINIDUMP + default y + help + This adds a support to decide whether the regions in minidump + table should be encrypted or not. By default, encryption is done + by the boot firmware and the decision for encryption is taken by + the subsystems. + config QCOM_MICRODUMP tristate "Qualcomm Technologies, Inc. Microdump Support" depends on MSM_SUBSYSTEM_RESTART diff --git a/drivers/soc/qcom/msm_minidump.c b/drivers/soc/qcom/msm_minidump.c index 4b4b81647688..0419749a0a17 100644 --- a/drivers/soc/qcom/msm_minidump.c +++ b/drivers/soc/qcom/msm_minidump.c @@ -570,8 +570,13 @@ static int __init msm_minidump_init(void) minidump_table.revision = md_global_toc->md_revision; md_ss_toc = &md_global_toc->md_ss_toc[MD_SS_HLOS_ID]; - md_ss_toc->encryption_status = MD_SS_ENCR_NONE; - md_ss_toc->encryption_required = MD_SS_ENCR_REQ; + if (IS_ENABLED(CONFIG_QCOM_MINIDUMP_ENCRYPT)) { + md_ss_toc->encryption_status = MD_SS_ENCR_NONE; + md_ss_toc->encryption_required = MD_SS_ENCR_REQ; + } else { + md_ss_toc->encryption_status = MD_SS_ENCR_DONE; + md_ss_toc->encryption_required = MD_SS_ENCR_NOTREQ; + } minidump_table.md_ss_toc = md_ss_toc; minidump_table.md_regions = kzalloc((MAX_NUM_ENTRIES * From 7ddb61a6ac27c795177021b05f60377482043222 Mon Sep 17 00:00:00 2001 From: Kaushal Hooda Date: Fri, 2 Jun 2023 20:21:06 +0530 Subject: [PATCH 07/14] rpmsg: slatecom: out of bound read from process_cmd When dereferencing "rx_data" as type "glink_slatecom_msg" , we didn't check if "rx_data" has enough room to hold that type. The "rx_size" is read from slate to master fifo and if received rx_size is less then "glink_slatecom_msg" then it could lead to heap out of bounds read. If received rx_size is less then the expected glink_slatecom_msg then return back as a bad message. Change-Id: Idde757ee70c7c88c22e4f036e6da0280e3b385d0 Signed-off-by: Kaushal Hooda --- drivers/rpmsg/qcom_glink_slatecom.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_slatecom.c b/drivers/rpmsg/qcom_glink_slatecom.c index d57adfa3c92f..18ae3934aa15 100644 --- a/drivers/rpmsg/qcom_glink_slatecom.c +++ b/drivers/rpmsg/qcom_glink_slatecom.c @@ -1900,7 +1900,7 @@ static void glink_slatecom_handle_rx_done(struct glink_slatecom *glink, mutex_unlock(&channel->intent_lock); } -static void glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_data, +static int glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_data, u32 rx_size) { struct glink_slatecom_msg *msg; @@ -1909,12 +1909,18 @@ static void glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_da unsigned int param3; unsigned int param4; unsigned int cmd; - int offset = 0; - int ret; + u32 offset = 0; + int ret = 0; u16 name_len; char *name; while (offset < rx_size) { + if (rx_size - offset < sizeof(struct glink_slatecom_msg)) { + ret = -EBADMSG; + GLINK_ERR(glink, "%s: Error %d process cmd\n", __func__, ret); + return ret; + } + msg = (struct glink_slatecom_msg *)(rx_data + offset); offset += sizeof(*msg); @@ -1997,6 +2003,7 @@ static void glink_slatecom_process_cmd(struct glink_slatecom *glink, void *rx_da break; } } + return ret; } /** From 1babb91a340d41e42ec8856039d6448573eb9f2d Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Wed, 6 Mar 2024 23:41:05 +0530 Subject: [PATCH 08/14] msm: eva: User after free fix in msm_cvp_mark_user_persist Update buffer ktid inside mutex protetion. Change-Id: I86767eb60e1f78e373233c0f64c3b5a2249cba0e Signed-off-by: Gopireddy Arunteja Reddy --- drivers/media/platform/msm/cvp/msm_cvp_buf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/cvp/msm_cvp_buf.c b/drivers/media/platform/msm/cvp/msm_cvp_buf.c index 9b9dbd456c42..995c111edb7d 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_buf.c +++ b/drivers/media/platform/msm/cvp/msm_cvp_buf.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_cvp_common.h" @@ -643,9 +644,10 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { if (pbuf->ownership == CLIENT) { - if (pbuf->fd == buf->fd && - pbuf->size == buf->size) + if (pbuf->fd == buf->fd && pbuf->size == buf->size) { buf->fd = pbuf->smem->device_addr; + pbuf->ktid = ktid; + } rc = 1; break; } @@ -657,7 +659,6 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, rc = -EFAULT; break; } - pbuf->ktid = ktid; rc = 0; } return rc; From 7ba19e773bf36bbe8244f377cae4176bb893b5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 26 Sep 2023 10:32:29 +0200 Subject: [PATCH 09/14] soc: qcom: llcc: Handle a second device without data corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f1a1bc8775b26345aba2be278118999e7f661d3d ] Usually there is only one llcc device. But if there were a second, even a failed probe call would modify the global drv_data pointer. So check if drv_data is valid before overwriting it. Change-Id: Ie9bcc0686959b0c3bfb740963eed3ba399ed735e Signed-off-by: Uwe Kleine-König Fixes: a3134fb09e0b ("drivers: soc: Add LLCC driver") Git-commit: cc1a1dcb411fe224f48553cfdcdfe6e61395b69c Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Link: https://lore.kernel.org/r/20230926083229.2073890-1-u.kleine-koenig@pengutronix.de Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Signed-off-by: kamasali Satyanarayan --- drivers/soc/qcom/llcc-slice.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c index bf5ec56a6395..38acab027dbb 100644 --- a/drivers/soc/qcom/llcc-slice.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -379,6 +379,9 @@ int qcom_llcc_probe(struct platform_device *pdev, struct platform_device *llcc_edac, *llcc_perfmon; struct device_node *tcm_memory_node; + if (!IS_ERR(drv_data)) + return -EBUSY; + drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) { ret = -ENOMEM; From 8c44843e9f2bb2626ae189c83551e09b5cb24e4a Mon Sep 17 00:00:00 2001 From: Fakruddin Vohra Date: Tue, 12 Mar 2024 18:32:25 +0530 Subject: [PATCH 10/14] msm: ipa3: change variable name for indication of rx tlv format wlan cannot have hsp in there traces so need to change variable name. Change-Id: I49ff72b3e446600b42064b02d33b409f55e327d0 Signed-off-by: Fakruddin Vohra --- include/linux/ipa_wdi3.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/ipa_wdi3.h b/include/linux/ipa_wdi3.h index 8fbd994cb26a..ffd7298e1d08 100644 --- a/include/linux/ipa_wdi3.h +++ b/include/linux/ipa_wdi3.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018 - 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 - 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 - 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _IPA_WDI3_H_ @@ -73,7 +73,7 @@ typedef void (*ipa_wdi_mesh_ast_notifier_cb)(void *priv, unsigned long data); * @wdi_notify: bw notification cb * inst_id: Instance ID * @ast_update: AST update needed or not. - * @is_hsp: need to identify if attach is hsp/pine. + * @rx_tlv_format: need to identify rx tlv format hsp(1)/pine(0). */ struct ipa_wdi_init_in_params { enum ipa_wdi_version wdi_version; @@ -85,6 +85,7 @@ struct ipa_wdi_init_in_params { int inst_id; bool ast_update; bool is_hsp; + u8 rx_tlv_format; }; /** From 5dbe477bb7c24716676135a877f4c5e811c2cb89 Mon Sep 17 00:00:00 2001 From: Himansu Nayak Date: Thu, 1 Feb 2024 11:58:00 +0530 Subject: [PATCH 11/14] msm_ipa: new structure for tunnel design for uC 1. structures for tunnels according to new HPS. 2. Action to taken per vlan mapped to each pdn. 3. structure for untag pppoe packet over eogre. 4. structure for single tag packet over eogre. 5. structure for double tag + pppoe packet over mpls tunnel. 6. new ioctl structure for uC. Change-Id: I7c7769c42070c91bc595baff662f2430d12b0da7 Signed-off-by: Himansu Nayak --- include/uapi/linux/msm_ipa.h | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index dcd4980ea987..0abf3da4beac 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -152,6 +152,8 @@ #define IPA_IOCTL_SET_EXT_ROUTER_MODE 95 #define IPA_IOCTL_ADD_DEL_DSCP_PCP_MAPPING 96 #define IPA_IOCTL_SEND_VLAN_MUXID_MAPPING 97 +#define IPA_IOCTL_SEND_TUNNEL_TEMPLATE_INFO 98 +#define IPA_IOCTL_QUERY_TUNNEL_FEATURE 99 /** * max size of the header to be inserted */ @@ -1776,6 +1778,104 @@ struct ipa_ioc_mux_mapping_table { struct singletag_mux_map_entry map_entries[MAX_VLAN_CONFIGURE]; }; +/* Feature Type Supported Design*/ +/* Cache all Design Support with Regular HPS for both EoGRE and MPLSoGRE tunnel */ +#define DEFAULT_FEATURE 0x00 +/* EoGRE to support Single Tag packet with new HPS */ +#define SINGLE_TAG_FEATURE 0x01 +/* MPLSoGRE to support Double Tag packet with new HPS */ +#define DOUBLE_TAG_FEATURE 0x02 +/* EoGRE to support UnTag packet with new HPS */ +#define UNTAG_FEATURE 0x03 + +/* l2 header is adjusted for every hwp_pkt_next_action */ +/* uc evaluate l2 header length and send packet to exception */ +#define SW_PATH_ADJ_L2_EXCEPTION 0x00 +/* uc evaluate l2 header length and send packet to 2nd pass */ +#define HW_PATH_ADJ_L2_RESUME_2ND_PASS 0x01 +/* uc evaluate l2 header length, update the metadata and send packet to 2nd pass */ +#define HW_PATH_ADJ_L2_METADATA_UPDATE_RESUME_2ND_PASS 0x02 +/* uc evaluate l2 header length, add outer header and send packet to 2nd pass */ +#define HW_PATH_ADJ_L2_ADD_TUNNEL_RESUME_2ND_PASS 0x03 +/* uc evaluate l2 header, update metadata, add outer header and send packet to 2nd pass */ +#define HW_PATH_ADJ_L2_ADD_TUNNEL_WITH_METADATA_UPDATE_RESUME_2ND_PASS 0x04 + +/* untagged packet configuration */ +struct untag_pkt_config_t { + /* packet action that should follow untag packet */ + uint32_t action_configured; + /* pdn from which untag packet should transfer */ + uint8_t mux_id; + /* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */ + uint8_t is_v6_options_hdr_present; + uint16_t pad0; /*for alignment*/ + /* lower 32 bit of tunnel header address */ + uint32_t *tunnel_template_addr; + uint32_t pad1; /*for alignment*/ +} __packed; + + +/* vlanid - action - tunnel_id - mux_id */ +struct singletag_mux_mapping_table_t { + /* multi tunnel purpose */ + uint16_t vlan_id_start; + uint16_t vlan_id_end; + uint32_t action_configured; + /* pdn from which untag packet should transfer */ + uint8_t mux_id; + /* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */ + uint8_t is_v6_options_hdr_present; + uint16_t pad0; /*for alignment*/ + uint32_t *tunnel_template_addr; +} __packed; + +struct doubletag_mux_mapping_table_t { + /* multi tunnel purpose */ + uint16_t stag_id_start; + uint16_t stag_id_end; + uint16_t ctag_id_start; + uint16_t ctag_id_end; + uint32_t action_configured; + /* pdn from which untag packet should transfer */ + uint8_t mux_id; + /* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */ + uint8_t is_v6_options_hdr_present; + uint16_t pad0; /*for alignment*/ + uint32_t *tunnel_template_addr; + uint32_t pad1; /*for alignment*/ +} __packed; + +/* max template side pass to uc */ +#define MAX_TEMPLATE_SIZE 64 +/* max number of tunnel to support ie: per PDN two tunnel (2*8)*/ +#define MAX_TUNNEL_SUPPORT 16 + +/* configuration table */ +struct tunnel_protocols_config_table_t { + struct untag_pkt_config_t untagged_mapping_table; + uint8_t num_of_single_tag_configs; + uint8_t pad0; /*for alignment*/ + uint16_t pad1; /*for alignment*/ + uint32_t pad2; /*for alignment*/ + /* table for single tag pkt */ + struct singletag_mux_mapping_table_t singletag_mux_mapping_table[MAX_TUNNEL_SUPPORT]; + uint8_t num_of_double_tag_configs; + uint8_t pad3; /*for alignment*/ + uint16_t pad4; /*for alignment*/ + uint32_t pad5; /*for alignment*/ + /* table for double tag pkt */ + struct doubletag_mux_mapping_table_t doubletag_mux_mapping_table[MAX_TUNNEL_SUPPORT]; +}; + +/* ioctl tunnel configuration table */ + +struct ipa_ioc_tunnel_template_info { + uint8_t template_header[MAX_TEMPLATE_SIZE]; + uint32_t template_len; + uint32_t template_type; + /*tunnel configuration table*/ + struct tunnel_protocols_config_table_t tunnel_config; +}; /** * struct ipa_exception @@ -4103,6 +4203,14 @@ struct ipa_ioc_dscp_pcp_map_info { IPA_IOCTL_SEND_VLAN_MUXID_MAPPING, \ struct ipa_ioc_mux_mapping_table) +#define IPA_IOC_SEND_TUNNEL_TEMPLATE_INFO _IOW(IPA_IOC_MAGIC, \ + IPA_IOCTL_SEND_TUNNEL_TEMPLATE_INFO, \ + struct ipa_ioc_tunnel_template_info) + + +#define IPA_IOC_QUERY_TUNNEL_FEATURE _IOW(IPA_IOC_MAGIC, \ + IPA_IOCTL_QUERY_TUNNEL_FEATURE, \ + uint8_t) /* * unique magic number of the Tethering bridge ioctls From 65757a25d1ac447ba75fc2038529a6618aecd18d Mon Sep 17 00:00:00 2001 From: Mehul Raninga Date: Fri, 15 Mar 2024 10:24:28 +0530 Subject: [PATCH 12/14] slimbus: qcom-ngd-ctrl: Avoid accessing deallocated stack The functions qcom_slim_ngd_xfer_msg and qcom_slim_ngd_xfer_msg_sync declare a local completion variable called done. However, this variable is accessed beyond the scope of these functions. To address this issue: 1. Instead of keeping done as a local variable, move it to qcom_slim_ngd_ctrl. 2. Initialize done during the probe phase. 3. Use this variable for handling transfer and synchronization messages. Change-Id: If97b71e2db730ab21bfd07479d2737b0546e1f8e Signed-off-by: Mehul Raninga --- drivers/slimbus/qcom-ngd-ctrl.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 09ecd1fb24ae..2244923532f2 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. // Copyright (c) 2018, Linaro Limited +// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. #include #include @@ -156,6 +157,8 @@ struct qcom_slim_ngd_ctrl { struct completion reconf; struct work_struct m_work; struct workqueue_struct *mwq; + struct completion xfer_done; + struct completion sync_done; spinlock_t tx_buf_lock; enum qcom_slim_ngd_state state; dma_addr_t rx_phys_base; @@ -768,7 +771,6 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, { struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(sctrl->dev); DECLARE_COMPLETION_ONSTACK(tx_sent); - DECLARE_COMPLETION_ONSTACK(done); int ret, timeout, i; u8 wbuf[SLIM_MSGQ_BUF_LEN]; u8 rbuf[SLIM_MSGQ_BUF_LEN]; @@ -777,6 +779,8 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, u8 la = txn->la; bool usr_msg = false; + reinit_completion(&ctrl->xfer_done); + if (txn->mt == SLIM_MSG_MT_CORE && (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION && txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) @@ -824,7 +828,7 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT) wbuf[i++] = txn->msg->wbuf[1]; - txn->comp = &done; + txn->comp = &ctrl->xfer_done; ret = slim_alloc_txn_tid(sctrl, txn); if (ret) { dev_err(ctrl->dev, "Unable to allocate TID\n"); @@ -876,7 +880,7 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, } if (usr_msg) { - timeout = wait_for_completion_timeout(&done, HZ); + timeout = wait_for_completion_timeout(&ctrl->xfer_done, HZ); if (!timeout) { dev_err(sctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc, txn->mt); @@ -890,18 +894,21 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl, static int qcom_slim_ngd_xfer_msg_sync(struct slim_controller *ctrl, struct slim_msg_txn *txn) { - DECLARE_COMPLETION_ONSTACK(done); + struct qcom_slim_ngd_ctrl *dev = + container_of(ctrl, struct qcom_slim_ngd_ctrl, ctrl); int ret, timeout; + reinit_completion(&dev->sync_done); + pm_runtime_get_sync(ctrl->dev); - txn->comp = &done; + txn->comp = &dev->sync_done; ret = qcom_slim_ngd_xfer_msg(ctrl, txn); if (ret) return ret; - timeout = wait_for_completion_timeout(&done, HZ); + timeout = wait_for_completion_timeout(&dev->sync_done, HZ); if (!timeout) { dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc, txn->mt); @@ -1460,6 +1467,9 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) init_completion(&ctrl->reconf); init_completion(&ctrl->qmi.qmi_comp); + init_completion(&ctrl->xfer_done); + init_completion(&ctrl->sync_done); + platform_driver_register(&qcom_slim_ngd_driver); return of_qcom_slim_ngd_register(dev, ctrl); } From e46fa2494859f4774f64d067816eedcf10d767d6 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Mon, 12 Feb 2024 11:46:37 +0530 Subject: [PATCH 13/14] mmc: sdhci-msm: Disable partial_init and clk-scaling to avoid RED error As part of partial_init, after tuning when we're enabling CQE (Command Queue Engine) mode, driver sends CMD44 (QUEUED_TASK_PARAM), and the response received for this is illegal command error. This is a temporary fix to avoid RED (Response Error Detected) error until power and performance impact is analyzed with disabling partial_init and clk-scaling. Change-Id: I97833e60399d43a611342ef17a82639c9b7ea5be Signed-off-by: Sachin Gupta Signed-off-by: Sarthak Garg Signed-off-by: Ram Prakash Gupta --- drivers/mmc/core/mmc.c | 48 ++++++++++++++++++++++-------------- drivers/mmc/host/sdhci-msm.c | 14 ++++++++++- include/linux/mmc/host.h | 1 + 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 11b00688aaa6..89b9a32b6201 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2259,6 +2259,7 @@ static int mmc_cache_card_ext_csd(struct mmc_host *host) return 0; } +#if defined(CONFIG_SDC_QTI) static int mmc_test_awake_ext_csd(struct mmc_host *host) { int err; @@ -2273,7 +2274,6 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host) } /* only compare read/write fields that the sw changes */ -#if defined(CONFIG_SDC_QTI) pr_debug("%s: %s: type(cached:current) cmdq(%d:%d) cache_ctrl(%d:%d) bus_width (%d:%d) timing(%d:%d)\n", mmc_hostname(host), __func__, card->ext_csd.raw_ext_csd_cmdq, @@ -2292,12 +2292,12 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host) ext_csd[EXT_CSD_BUS_WIDTH]) && (card->ext_csd.raw_ext_csd_hs_timing == ext_csd[EXT_CSD_HS_TIMING])); -#endif kfree(ext_csd); return err; } +#endif static int _mmc_suspend(struct mmc_host *host, bool is_suspend) { @@ -2305,11 +2305,13 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : EXT_CSD_POWER_OFF_LONG; #if defined(CONFIG_SDC_QTI) - err = mmc_suspend_clk_scaling(host); - if (err) { - pr_err("%s: %s: fail to suspend clock scaling (%d)\n", - mmc_hostname(host), __func__, err); - return err; + if (!host->partial_init_broken) { + err = mmc_suspend_clk_scaling(host); + if (err) { + pr_err("%s: %s: fail to suspend clock scaling (%d)\n", + mmc_hostname(host), __func__, err); + return err; + } } #endif mmc_log_string(host, "Enter\n"); @@ -2328,8 +2330,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) if (mmc_can_sleep(host->card)) { #if defined(CONFIG_SDC_QTI) memcpy(&host->cached_ios, &host->ios, sizeof(host->cached_ios)); + if (!host->partial_init_broken) #endif - mmc_cache_card_ext_csd(host); + mmc_cache_card_ext_csd(host); } if (mmc_can_sleep(host->card)) err = mmc_sleepawake(host, true); @@ -2351,24 +2354,21 @@ out: return err; } +#if defined(CONFIG_SDC_QTI) static int mmc_partial_init(struct mmc_host *host) { int err = 0; struct mmc_card *card = host->card; -#if defined(CONFIG_SDC_QTI) mmc_set_bus_width(host, host->cached_ios.bus_width); mmc_set_timing(host, host->cached_ios.timing); if (host->cached_ios.enhanced_strobe) { -#endif host->ios.enhanced_strobe = true; if (host->ops->hs400_enhanced_strobe) host->ops->hs400_enhanced_strobe(host, &host->ios); -#if defined(CONFIG_SDC_QTI) } mmc_set_clock(host, host->cached_ios.clock); mmc_set_bus_mode(host, host->cached_ios.bus_mode); -#endif if (!mmc_card_hs400es(card) && (mmc_card_hs200(card) || mmc_card_hs400(card))) { @@ -2396,6 +2396,7 @@ static int mmc_partial_init(struct mmc_host *host) out: return err; } +#endif /* * Suspend callback @@ -2440,14 +2441,23 @@ static int _mmc_resume(struct mmc_host *host) if (mmc_can_sleep(host->card)) { err = mmc_sleepawake(host, false); - if (!err) - err = mmc_partial_init(host); + +#if defined(CONFIG_SDC_QTI) + if (!err) { + if (host->partial_init_broken) + err = mmc_init_card(host, host->card->ocr, host->card); + else + err = mmc_partial_init(host); + } else pr_err("%s: %s: awake failed (%d), fallback to full init\n", mmc_hostname(host), __func__, err); +#endif } +#if defined(CONFIG_SDC_QTI) if (err) +#endif err = mmc_init_card(host, host->card->ocr, host->card); mmc_card_clr_suspended(host->card); @@ -2458,10 +2468,12 @@ out: mmc_release_host(host); #if defined(CONFIG_SDC_QTI) - err = mmc_resume_clk_scaling(host); - if (err) - pr_err("%s: %s: fail to resume clock scaling (%d)\n", - mmc_hostname(host), __func__, err); + if (!host->partial_init_broken) { + err = mmc_resume_clk_scaling(host); + if (err) + pr_err("%s: %s: fail to resume clock scaling (%d)\n", + mmc_hostname(host), __func__, err); + } out: #endif mmc_log_string(host, "Exit err %d\n", err); diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 91cc197d5e20..302a77938787 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -3,6 +3,7 @@ * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver * * Copyright (c) 2013-2014,2020. The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1869,6 +1870,12 @@ static bool sdhci_msm_populate_pdata(struct device *dev, if (sdhci_msm_dt_parse_hsr_info(dev, msm_host)) goto out; +#if defined(CONFIG_SDC_QTI) + msm_host->mmc->partial_init_broken = + of_property_read_bool(dev->of_node, + "qcom,partial_init_broken"); +#endif + if (!sdhci_msm_dt_get_array(dev, "qcom,ice-clk-rates", &ice_clk_table, &ice_clk_table_len, 0)) { if (ice_clk_table && ice_clk_table_len) { @@ -4268,6 +4275,11 @@ static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host) { msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM; msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; + +#if defined(CONFIG_SDC_QTI) + if (!msm_host->mmc->partial_init_broken) + msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE; +#endif } static int sdhci_msm_probe(struct platform_device *pdev) @@ -4546,8 +4558,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) #if defined(CONFIG_SDC_QTI) host->timeout_clk_div = 4; - msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE; #endif + sdhci_msm_setup_pm(pdev, msm_host); host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 38cfd8faa2d2..af6bc6f7bfd4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -597,6 +597,7 @@ struct mmc_host { bool hsq_enabled; #if defined(CONFIG_SDC_QTI) bool need_hw_reset; + bool partial_init_broken; #endif #if defined(CONFIG_SDC_QTI) From 3396e5da3621e8495f9f8d823d00786e3f2cf0f0 Mon Sep 17 00:00:00 2001 From: Jilai Wang Date: Thu, 25 Jan 2024 11:41:04 -0500 Subject: [PATCH 14/14] msm: npu v1: Fix OOB issue in IPC between driver and firmware We shoudn't trust the data from firmware, and need to validate all content before using them. Change-Id: I39b58f3d482931a932dab7ca4b8cc3e4d9086b36 Signed-off-by: Jilai Wang --- drivers/media/platform/msm/npu/npu_common.h | 6 -- drivers/media/platform/msm/npu/npu_debugfs.c | 70 ------------------- drivers/media/platform/msm/npu/npu_host_ipc.c | 46 +++++++++--- .../media/platform/msm/npu/npu_hw_access.c | 46 ------------ .../media/platform/msm/npu/npu_hw_access.h | 3 - drivers/media/platform/msm/npu/npu_mgr.c | 60 ++-------------- 6 files changed, 43 insertions(+), 188 deletions(-) diff --git a/drivers/media/platform/msm/npu/npu_common.h b/drivers/media/platform/msm/npu/npu_common.h index 18d896c98e96..1f18e052cc62 100644 --- a/drivers/media/platform/msm/npu/npu_common.h +++ b/drivers/media/platform/msm/npu/npu_common.h @@ -94,12 +94,6 @@ struct npu_debugfs_ctx { struct dentry *root; uint32_t reg_off; uint32_t reg_cnt; - uint8_t *log_buf; - struct mutex log_lock; - uint32_t log_num_bytes_buffered; - uint32_t log_read_index; - uint32_t log_write_index; - uint32_t log_buf_size; }; struct npu_debugfs_reg_ctx { diff --git a/drivers/media/platform/msm/npu/npu_debugfs.c b/drivers/media/platform/msm/npu/npu_debugfs.c index 18c8df0a4bb0..c813f3657b03 100644 --- a/drivers/media/platform/msm/npu/npu_debugfs.c +++ b/drivers/media/platform/msm/npu/npu_debugfs.c @@ -27,8 +27,6 @@ */ static int npu_debug_open(struct inode *inode, struct file *file); static int npu_debug_release(struct inode *inode, struct file *file); -static ssize_t npu_debug_log_read(struct file *file, - char __user *user_buf, size_t count, loff_t *ppos); static ssize_t npu_debug_ctrl_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos); @@ -38,13 +36,6 @@ static ssize_t npu_debug_ctrl_write(struct file *file, */ static struct npu_device *g_npu_dev; -static const struct file_operations npu_log_fops = { - .open = npu_debug_open, - .release = npu_debug_release, - .read = npu_debug_log_read, - .write = NULL, -}; - static const struct file_operations npu_ctrl_fops = { .open = npu_debug_open, .release = npu_debug_release, @@ -69,47 +60,6 @@ static int npu_debug_release(struct inode *inode, struct file *file) return 0; } -/* ------------------------------------------------------------------------- - * Function Implementations - DebugFS Log - * ------------------------------------------------------------------------- - */ -static ssize_t npu_debug_log_read(struct file *file, - char __user *user_buf, size_t count, loff_t *ppos) -{ - size_t len = 0; - struct npu_device *npu_dev = file->private_data; - struct npu_debugfs_ctx *debugfs; - - pr_debug("npu_dev %pK %pK\n", npu_dev, g_npu_dev); - npu_dev = g_npu_dev; - debugfs = &npu_dev->debugfs_ctx; - - /* mutex log lock */ - mutex_lock(&debugfs->log_lock); - - if (debugfs->log_num_bytes_buffered != 0) { - len = min(debugfs->log_num_bytes_buffered, - debugfs->log_buf_size - debugfs->log_read_index); - len = min(count, len); - if (copy_to_user(user_buf, (debugfs->log_buf + - debugfs->log_read_index), len)) { - pr_err("%s failed to copy to user\n", __func__); - mutex_unlock(&debugfs->log_lock); - return -EFAULT; - } - debugfs->log_read_index += len; - if (debugfs->log_read_index == debugfs->log_buf_size) - debugfs->log_read_index = 0; - - debugfs->log_num_bytes_buffered -= len; - *ppos += len; - } - - /* mutex log unlock */ - mutex_unlock(&debugfs->log_lock); - - return len; -} /* ------------------------------------------------------------------------- * Function Implementations - DebugFS Control @@ -193,12 +143,6 @@ int npu_debugfs_init(struct npu_device *npu_dev) return -ENODEV; } - if (!debugfs_create_file("log", 0644, debugfs->root, - npu_dev, &npu_log_fops)) { - pr_err("debugfs_create_file log fail\n"); - goto err; - } - if (!debugfs_create_file("ctrl", 0644, debugfs->root, npu_dev, &npu_ctrl_fops)) { pr_err("debugfs_create_file ctrl fail\n"); @@ -235,14 +179,6 @@ int npu_debugfs_init(struct npu_device *npu_dev) goto err; } - debugfs->log_num_bytes_buffered = 0; - debugfs->log_read_index = 0; - debugfs->log_write_index = 0; - debugfs->log_buf_size = NPU_LOG_BUF_SIZE; - debugfs->log_buf = kzalloc(debugfs->log_buf_size, GFP_KERNEL); - if (!debugfs->log_buf) - goto err; - mutex_init(&debugfs->log_lock); return 0; @@ -255,12 +191,6 @@ void npu_debugfs_deinit(struct npu_device *npu_dev) { struct npu_debugfs_ctx *debugfs = &npu_dev->debugfs_ctx; - debugfs->log_num_bytes_buffered = 0; - debugfs->log_read_index = 0; - debugfs->log_write_index = 0; - debugfs->log_buf_size = 0; - kfree(debugfs->log_buf); - if (!IS_ERR_OR_NULL(debugfs->root)) { debugfs_remove_recursive(debugfs->root); debugfs->root = NULL; diff --git a/drivers/media/platform/msm/npu/npu_host_ipc.c b/drivers/media/platform/msm/npu/npu_host_ipc.c index 940a35d9ada8..2dc80c2c2784 100644 --- a/drivers/media/platform/msm/npu/npu_host_ipc.c +++ b/drivers/media/platform/msm/npu/npu_host_ipc.c @@ -33,15 +33,16 @@ struct npu_queue_tuple { uint32_t size; uint32_t hdr; + uint32_t start_offset; }; -static const struct npu_queue_tuple npu_q_setup[6] = { - { 1024, IPC_QUEUE_CMD_HIGH_PRIORITY | TX_HDR_TYPE | RX_HDR_TYPE }, - { 4096, IPC_QUEUE_APPS_EXEC | TX_HDR_TYPE | RX_HDR_TYPE }, - { 4096, IPC_QUEUE_DSP_EXEC | TX_HDR_TYPE | RX_HDR_TYPE }, - { 4096, IPC_QUEUE_APPS_RSP | TX_HDR_TYPE | RX_HDR_TYPE }, - { 4096, IPC_QUEUE_DSP_RSP | TX_HDR_TYPE | RX_HDR_TYPE }, - { 1024, IPC_QUEUE_LOG | TX_HDR_TYPE | RX_HDR_TYPE }, +static struct npu_queue_tuple npu_q_setup[6] = { + { 1024, IPC_QUEUE_CMD_HIGH_PRIORITY | TX_HDR_TYPE | RX_HDR_TYPE, 0}, + { 4096, IPC_QUEUE_APPS_EXEC | TX_HDR_TYPE | RX_HDR_TYPE, 0}, + { 4096, IPC_QUEUE_DSP_EXEC | TX_HDR_TYPE | RX_HDR_TYPE, 0}, + { 4096, IPC_QUEUE_APPS_RSP | TX_HDR_TYPE | RX_HDR_TYPE, 0}, + { 4096, IPC_QUEUE_DSP_RSP | TX_HDR_TYPE | RX_HDR_TYPE, 0}, + { 1024, IPC_QUEUE_LOG | TX_HDR_TYPE | RX_HDR_TYPE, 0}, }; /* ------------------------------------------------------------------------- @@ -111,6 +112,7 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev) /* queue is active */ q_hdr->qhdr_status = 0x01; q_hdr->qhdr_start_offset = cur_start_offset; + npu_q_setup[q_idx].start_offset = cur_start_offset; q_size = npu_q_setup[q_idx].size; q_hdr->qhdr_type = npu_q_setup[q_idx].hdr; /* in bytes */ @@ -212,6 +214,18 @@ static int ipc_queue_read(struct npu_device *npu_dev, /* Read the queue */ MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); + + if (queue.qhdr_type != npu_q_setup[target_que].hdr || + queue.qhdr_q_size != npu_q_setup[target_que].size || + queue.qhdr_read_idx >= queue.qhdr_q_size || + queue.qhdr_write_idx >= queue.qhdr_q_size || + queue.qhdr_start_offset != + npu_q_setup[target_que].start_offset) { + pr_err("Invalid Queue header\n"); + status = -EIO; + goto exit; + } + /* check if queue is empty */ if (queue.qhdr_read_idx == queue.qhdr_write_idx) { /* @@ -235,8 +249,10 @@ static int ipc_queue_read(struct npu_device *npu_dev, target_que, packet_size); - if (packet_size == 0) { - status = -EPERM; + if ((packet_size == 0) || + (packet_size > NPU_IPC_BUF_LENGTH)) { + pr_err("Invalid packet size %d\n", packet_size); + status = -EINVAL; goto exit; } new_read_idx = queue.qhdr_read_idx + packet_size; @@ -306,6 +322,18 @@ static int ipc_queue_write(struct npu_device *npu_dev, MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); + + if (queue.qhdr_type != npu_q_setup[target_que].hdr || + queue.qhdr_q_size != npu_q_setup[target_que].size || + queue.qhdr_read_idx >= queue.qhdr_q_size || + queue.qhdr_write_idx >= queue.qhdr_q_size || + queue.qhdr_start_offset != + npu_q_setup[target_que].start_offset) { + pr_err("Invalid Queue header\n"); + status = -EIO; + goto exit; + } + packet_size = (*(uint32_t *)packet); if (packet_size == 0) { /* assign failed status and return */ diff --git a/drivers/media/platform/msm/npu/npu_hw_access.c b/drivers/media/platform/msm/npu/npu_hw_access.c index 3b7a420a1d11..113407d34a21 100644 --- a/drivers/media/platform/msm/npu/npu_hw_access.c +++ b/drivers/media/platform/msm/npu/npu_hw_access.c @@ -442,49 +442,3 @@ void subsystem_put_local(void *sub_system_handle) return subsystem_put(sub_system_handle); } -/* ------------------------------------------------------------------------- - * Functions - Log - * ------------------------------------------------------------------------- - */ -void npu_process_log_message(struct npu_device *npu_dev, uint32_t *message, - uint32_t size) -{ - struct npu_debugfs_ctx *debugfs = &npu_dev->debugfs_ctx; - - /* mutex log lock */ - mutex_lock(&debugfs->log_lock); - - if ((debugfs->log_num_bytes_buffered + size) > - debugfs->log_buf_size) { - /* No more space, invalidate it all and start over */ - debugfs->log_read_index = 0; - debugfs->log_write_index = size; - debugfs->log_num_bytes_buffered = size; - memcpy(debugfs->log_buf, message, size); - } else { - if ((debugfs->log_write_index + size) > - debugfs->log_buf_size) { - /* Wrap around case */ - uint8_t *src_addr = (uint8_t *)message; - uint8_t *dst_addr = NULL; - uint32_t remaining_to_end = debugfs->log_buf_size - - debugfs->log_write_index + 1; - dst_addr = debugfs->log_buf + debugfs->log_write_index; - memcpy(dst_addr, src_addr, remaining_to_end); - src_addr = &(src_addr[remaining_to_end]); - dst_addr = debugfs->log_buf; - memcpy(dst_addr, src_addr, size-remaining_to_end); - debugfs->log_write_index = size-remaining_to_end; - } else { - memcpy((debugfs->log_buf + debugfs->log_write_index), - message, size); - debugfs->log_write_index += size; - if (debugfs->log_write_index == debugfs->log_buf_size) - debugfs->log_write_index = 0; - } - debugfs->log_num_bytes_buffered += size; - } - - /* mutex log unlock */ - mutex_unlock(&debugfs->log_lock); -} diff --git a/drivers/media/platform/msm/npu/npu_hw_access.h b/drivers/media/platform/msm/npu/npu_hw_access.h index 311f4fb84870..06ed0e6d132d 100644 --- a/drivers/media/platform/msm/npu/npu_hw_access.h +++ b/drivers/media/platform/msm/npu/npu_hw_access.h @@ -83,7 +83,4 @@ void npu_disable_sys_cache(struct npu_device *npu_dev); void *subsystem_get_local(char *sub_system); void subsystem_put_local(void *sub_system_handle); -void npu_process_log_message(struct npu_device *npu_dev, uint32_t *msg, - uint32_t size); - #endif /* _NPU_HW_ACCESS_H*/ diff --git a/drivers/media/platform/msm/npu/npu_mgr.c b/drivers/media/platform/msm/npu/npu_mgr.c index f36aff27ccc5..6b017934f985 100644 --- a/drivers/media/platform/msm/npu/npu_mgr.c +++ b/drivers/media/platform/msm/npu/npu_mgr.c @@ -20,11 +20,6 @@ * Defines * ------------------------------------------------------------------------- */ -#define LOG_MSG_HEADER_SIZE 20 -#define LOG_MSG_START_MSG_INDEX 5 -#define LOG_MSG_TOTAL_SIZE_INDEX 0 -#define LOG_MSG_MSG_ID_INDEX 1 - #define NPU_FW_TIMEOUT_POLL_INTERVAL_MS 10 #define NPU_FW_TIMEOUT_MS 1000 @@ -48,9 +43,7 @@ static void free_network(struct npu_host_ctx *ctx, struct npu_client *client, static int network_get(struct npu_network *network); static int network_put(struct npu_network *network); static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg); -static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg); static void host_session_msg_hdlr(struct npu_device *npu_dev); -static void host_session_log_hdlr(struct npu_device *npu_dev); static int host_error_hdlr(struct npu_device *npu_dev, bool force); static int npu_send_network_cmd(struct npu_device *npu_dev, struct npu_network *network, void *cmd_ptr); @@ -391,7 +384,6 @@ static void host_irq_wq(struct work_struct *work) if (host_error_hdlr(npu_dev, false)) return; - host_session_log_hdlr(npu_dev); host_session_msg_hdlr(npu_dev); } @@ -768,6 +760,12 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) } pr_debug("network id : %llu\n", network->id); + if (exe_rsp_pkt->header.size < sizeof(*exe_rsp_pkt)) { + pr_err("invalid packet header size, header.size: %d\n", + exe_rsp_pkt->header.size); + network_put(network); + break; + } stats_size = exe_rsp_pkt->header.size - sizeof(*exe_rsp_pkt); pr_debug("stats_size %d:%d\n", exe_rsp_pkt->header.size, stats_size); @@ -986,52 +984,6 @@ skip_read_msg: kfree(msg); } -static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg) -{ - uint32_t msg_id; - uint32_t *log_msg; - uint32_t size; - - msg_id = msg[LOG_MSG_MSG_ID_INDEX]; - size = msg[LOG_MSG_TOTAL_SIZE_INDEX] - LOG_MSG_HEADER_SIZE; - - switch (msg_id) { - case NPU_IPC_MSG_EVENT_NOTIFY: - /* Process the message */ - log_msg = &(msg[LOG_MSG_START_MSG_INDEX]); - npu_process_log_message(npu_dev, log_msg, size); - break; - default: - pr_err("unsupported log response received %d\n", msg_id); - break; - } -} - -static void host_session_log_hdlr(struct npu_device *npu_dev) -{ - uint32_t *msg; - struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; - - msg = kzalloc(sizeof(uint32_t) * NPU_IPC_BUF_LENGTH, GFP_KERNEL); - - if (!msg) - return; - - mutex_lock(&host_ctx->lock); - if (host_ctx->fw_state == FW_DISABLED) { - pr_warn("handle npu session msg when FW is disabled\n"); - goto skip_read_msg; - } - - while (npu_host_ipc_read_msg(npu_dev, IPC_QUEUE_LOG, msg) == 0) { - pr_debug("received from log queue\n"); - log_msg_proc(npu_dev, msg); - } - -skip_read_msg: - mutex_unlock(&host_ctx->lock); - kfree(msg); -} /* ------------------------------------------------------------------------- * Function Definitions - Functionality