| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* |
| * Copyright (c) 2021, The Linux Foundation. All rights reserved. |
| * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. |
| */ |
| #ifndef __ADRENO_GEN7_GMU_H |
| #define __ADRENO_GEN7_GMU_H |
| |
| #include <linux/mailbox_client.h> |
| |
| #include "adreno_gen7_hfi.h" |
| #include "kgsl_gmu_core.h" |
| |
| struct gen7_dcvs_table { |
| u32 gpu_level_num; |
| u32 gmu_level_num; |
| struct opp_gx_desc gx_votes[MAX_GX_LEVELS]; |
| struct opp_desc cx_votes[MAX_CX_LEVELS]; |
| }; |
| |
| /** |
| * struct gen7_gmu_device - GMU device structure |
| * @ver: GMU Version information |
| * @irq: GMU interrupt number |
| * @fw_image: GMU FW image |
| * @hfi_mem: pointer to HFI shared memory |
| * @dump_mem: pointer to GMU debug dump memory |
| * @gmu_log: gmu event log memory |
| * @hfi: HFI controller |
| * @num_gpupwrlevels: number GPU frequencies in GPU freq table |
| * @num_bwlevel: number of GPU BW levels |
| * @num_cnocbwlevel: number CNOC BW levels |
| * @rpmh_votes: RPMh TCS command set for GPU, GMU voltage and bw scaling |
| * @clks: GPU subsystem clocks required for GMU functionality |
| * @wakeup_pwrlevel: GPU wake up power/DCVS level in case different |
| * than default power level |
| * @idle_level: Minimal GPU idle power level |
| * @fault_count: GMU fault count |
| * @mailbox: Messages to AOP for ACD enable/disable go through this |
| * @log_wptr_retention: Store the log wptr offset on slumber |
| */ |
| struct gen7_gmu_device { |
| struct { |
| u32 core; |
| u32 core_dev; |
| u32 pwr; |
| u32 pwr_dev; |
| u32 hfi; |
| } ver; |
| struct platform_device *pdev; |
| int irq; |
| const struct firmware *fw_image; |
| struct kgsl_memdesc *dump_mem; |
| struct kgsl_memdesc *gmu_log; |
| /** @gmu_init_scratch: Memory to store the initial HFI messages */ |
| struct kgsl_memdesc *gmu_init_scratch; |
| /** @gpu_boot_scratch: Memory to store the bootup HFI messages */ |
| struct kgsl_memdesc *gpu_boot_scratch; |
| /** @vrb: GMU virtual register bank memory */ |
| struct kgsl_memdesc *vrb; |
| /** @trace: gmu trace container */ |
| struct kgsl_gmu_trace trace; |
| struct gen7_hfi hfi; |
| struct clk_bulk_data *clks; |
| /** @num_clks: Number of entries in the @clks array */ |
| int num_clks; |
| unsigned int idle_level; |
| /** @freqs: Array of GMU frequencies */ |
| u32 freqs[GMU_MAX_PWRLEVELS]; |
| /** @vlvls: Array of GMU voltage levels */ |
| u32 vlvls[GMU_MAX_PWRLEVELS]; |
| struct kgsl_mailbox mailbox; |
| /** @gmu_globals: Array to store gmu global buffers */ |
| struct kgsl_memdesc gmu_globals[GMU_KERNEL_ENTRIES]; |
| /** @global_entries: To keep track of number of gmu buffers */ |
| u32 global_entries; |
| struct gmu_vma_entry *vma; |
| unsigned int log_wptr_retention; |
| /** @cm3_fault: whether gmu received a cm3 fault interrupt */ |
| atomic_t cm3_fault; |
| /** |
| * @itcm_shadow: Copy of the itcm block in firmware binary used for |
| * snapshot |
| */ |
| void *itcm_shadow; |
| /** @flags: Internal gmu flags */ |
| unsigned long flags; |
| /** @rscc_virt: Pointer where RSCC block is mapped */ |
| void __iomem *rscc_virt; |
| /** @domain: IOMMU domain for the kernel context */ |
| struct iommu_domain *domain; |
| /** @log_stream_enable: GMU log streaming enable. Disabled by default */ |
| bool log_stream_enable; |
| /** @log_group_mask: Allows overriding default GMU log group mask */ |
| u32 log_group_mask; |
| struct kobject log_kobj; |
| /* |
| * @perf_ddr_bw: The lowest ddr bandwidth that puts CX at a corner at |
| * which GMU can run at higher frequency. |
| */ |
| u32 perf_ddr_bw; |
| /** @rdpm_cx_virt: Pointer where the RDPM CX block is mapped */ |
| void __iomem *rdpm_cx_virt; |
| /** @rdpm_mx_virt: Pointer where the RDPM MX block is mapped */ |
| void __iomem *rdpm_mx_virt; |
| /** @num_oob_perfcntr: Number of active oob_perfcntr requests */ |
| u32 num_oob_perfcntr; |
| /** @acd_debug_val: DVM value to calibrate ACD for a level */ |
| u32 acd_debug_val; |
| /** @stats_enable: GMU stats feature enable */ |
| bool stats_enable; |
| /** @stats_mask: GMU performance countables to enable */ |
| u32 stats_mask; |
| /** @stats_interval: GMU performance counters sampling interval */ |
| u32 stats_interval; |
| /** @stats_kobj: kernel object for GMU stats directory in sysfs */ |
| struct kobject stats_kobj; |
| /** @cp_init_hdr: raw command header for cp_init */ |
| u32 cp_init_hdr; |
| /** @switch_to_unsec_hdr: raw command header for switch to unsecure packet */ |
| u32 switch_to_unsec_hdr; |
| /** @dcvs_table: Table for gpu dcvs levels */ |
| struct gen7_dcvs_table dcvs_table; |
| }; |
| |
| /* Helper function to get to gen7 gmu device from adreno device */ |
| struct gen7_gmu_device *to_gen7_gmu(struct adreno_device *adreno_dev); |
| |
| /* Helper function to get to adreno device from gen7 gmu device */ |
| struct adreno_device *gen7_gmu_to_adreno(struct gen7_gmu_device *gmu); |
| |
| /** |
| * gen7_reserve_gmu_kernel_block() - Allocate a global gmu buffer |
| * @gmu: Pointer to the gen7 gmu device |
| * @addr: Desired gmu virtual address |
| * @size: Size of the buffer in bytes |
| * @vma_id: Target gmu vma where this buffer should be mapped |
| * @align: Alignment for the GMU VA and GMU mapping size |
| * |
| * This function allocates a global gmu buffer and maps it in |
| * the desired gmu vma |
| * |
| * Return: Pointer to the memory descriptor or error pointer on failure |
| */ |
| struct kgsl_memdesc *gen7_reserve_gmu_kernel_block(struct gen7_gmu_device *gmu, |
| u32 addr, u32 size, u32 vma_id, u32 align); |
| |
| /** |
| * gen7_reserve_gmu_kernel_block_fixed() - Maps phyical resource address to gmu |
| * @gmu: Pointer to the gen7 gmu device |
| * @addr: Desired gmu virtual address |
| * @size: Size of the buffer in bytes |
| * @vma_id: Target gmu vma where this buffer should be mapped |
| * @resource: Name of the resource to get the size and address to allocate |
| * @attrs: Attributes for the mapping |
| * @align: Alignment for the GMU VA and GMU mapping size |
| * |
| * This function maps the physcial resource address to desired gmu vma |
| * |
| * Return: Pointer to the memory descriptor or error pointer on failure |
| */ |
| struct kgsl_memdesc *gen7_reserve_gmu_kernel_block_fixed(struct gen7_gmu_device *gmu, |
| u32 addr, u32 size, u32 vma_id, const char *resource, int attrs, u32 align); |
| |
| /** |
| * gen7_alloc_gmu_kernel_block() - Allocate a gmu buffer |
| * @gmu: Pointer to the gen7 gmu device |
| * @md: Pointer to the memdesc |
| * @size: Size of the buffer in bytes |
| * @vma_id: Target gmu vma where this buffer should be mapped |
| * @attrs: Attributes for the mapping |
| * |
| * This function allocates a buffer and maps it in the desired gmu vma |
| * |
| * Return: 0 on success or error code on failure |
| */ |
| int gen7_alloc_gmu_kernel_block(struct gen7_gmu_device *gmu, |
| struct kgsl_memdesc *md, u32 size, u32 vma_id, int attrs); |
| |
| /** |
| * gen7_gmu_import_buffer() - Import a gmu buffer |
| * @gmu: Pointer to the gen7 gmu device |
| * @vma_id: Target gmu vma where this buffer should be mapped |
| * @md: Pointer to the memdesc to be mapped |
| * @attrs: Attributes for the mapping |
| * @align: Alignment for the GMU VA and GMU mapping size |
| * |
| * This function imports and maps a buffer to a gmu vma |
| * |
| * Return: 0 on success or error code on failure |
| */ |
| int gen7_gmu_import_buffer(struct gen7_gmu_device *gmu, u32 vma_id, |
| struct kgsl_memdesc *md, u32 attrs, u32 align); |
| |
| /** |
| * gen7_free_gmu_block() - Free a gmu buffer |
| * @gmu: Pointer to the gen7 gmu device |
| * @md: Pointer to the memdesc that is to be freed |
| * |
| * This function frees a gmu block allocated by gen7_reserve_gmu_kernel_block() |
| */ |
| void gen7_free_gmu_block(struct gen7_gmu_device *gmu, struct kgsl_memdesc *md); |
| |
| /** |
| * gen7_build_rpmh_tables - Build the rpmh tables |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * This function creates the gpu dcvs and bw tables |
| * |
| * Return: 0 on success and negative error on failure |
| */ |
| int gen7_build_rpmh_tables(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_gx_is_on - Check if GX is on |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * This function reads pwr status registers to check if GX |
| * is on or off |
| */ |
| bool gen7_gmu_gx_is_on(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_device_probe - GEN7 GMU snapshot function |
| * @pdev: Pointer to the platform device |
| * @chipid: Chipid of the target |
| * @gpucore: Pointer to the gpucore |
| * |
| * The target specific probe function for gmu based gen7 targets. |
| */ |
| int gen7_gmu_device_probe(struct platform_device *pdev, |
| u32 chipid, const struct adreno_gpu_core *gpucore); |
| |
| /** |
| * gen7_gmu_reset - Reset and restart the gmu |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_reset(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_enable_gpu_irq - Enable gpu interrupt |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_enable_gpu_irq(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_disable_gpu_irq - Disable gpu interrupt |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_disable_gpu_irq(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_snapshot- Take snapshot for gmu targets |
| * @adreno_dev: Pointer to the adreno device |
| * @snapshot: Pointer to the snapshot structure |
| * |
| * Send an NMI to gmu if we hit a gmu fault. Then take gmu |
| * snapshot and carry on with rest of the gen7 snapshot |
| */ |
| void gen7_gmu_snapshot(struct adreno_device *adreno_dev, |
| struct kgsl_snapshot *snapshot); |
| |
| /** |
| * gen7_gmu_probe - Probe gen7 gmu resources |
| * @device: Pointer to the kgsl device |
| * @pdev: Pointer to the gmu platform device |
| * |
| * Probe the gmu and hfi resources |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_probe(struct kgsl_device *device, |
| struct platform_device *pdev); |
| |
| /** |
| * gen7_gmu_parse_fw - Parse the gmu fw binary |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_parse_fw(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_memory_init - Allocate gmu memory |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Allocates the gmu log buffer and others if ndeeded. |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_memory_init(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_aop_send_acd_state - Enable or disable acd feature in aop |
| * @gmu: Pointer to the gen7 gmu device |
| * @flag: Boolean to enable or disable acd in aop |
| * |
| * This function enables or disables gpu acd feature using mailbox |
| */ |
| void gen7_gmu_aop_send_acd_state(struct gen7_gmu_device *gmu, bool flag); |
| |
| /** |
| * gen7_gmu_load_fw - Load gmu firmware |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Loads the gmu firmware binary into TCMs and memory |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_load_fw(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_device_start - Bring gmu out of reset |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_device_start(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_hfi_start - Indicate hfi start to gmu |
| * @device: Pointer to the kgsl device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_hfi_start(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_itcm_shadow - Create itcm shadow copy for snapshot |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_itcm_shadow(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_register_config - gmu register configuration |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Program gmu regsiters based on features |
| */ |
| void gen7_gmu_register_config(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_version_info - Get gmu firmware version |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_version_info(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_irq_enable - Enable gmu interrupts |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_gmu_irq_enable(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_irq_disable - Disaable gmu interrupts |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_gmu_irq_disable(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_suspend - Hard reset the gpu and gmu |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * In case we hit a gmu fault, hard reset the gpu and gmu |
| * to recover from the fault |
| */ |
| void gen7_gmu_suspend(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_oob_set - send gmu oob request |
| * @device: Pointer to the kgsl device |
| * @req: Type of oob request as defined in enum oob_request |
| * |
| * Request gmu to keep gpu powered up till the oob is cleared |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_oob_set(struct kgsl_device *device, enum oob_request oob); |
| |
| /** |
| * gen7_gmu_oob_clear - clear an asserted oob request |
| * @device: Pointer to the kgsl device |
| * @req: Type of oob request as defined in enum oob_request |
| * |
| * Clear a previously requested oob so that gmu can power |
| * collapse the gpu |
| */ |
| void gen7_gmu_oob_clear(struct kgsl_device *device, enum oob_request oob); |
| |
| /** |
| * gen7_gmu_wait_for_lowest_idle - wait for gmu to complete ifpc |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * If ifpc is enabled, wait for gmu to put gpu into ifpc. |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_wait_for_lowest_idle(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_wait_for_idle - Wait for gmu to become idle |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_wait_for_idle(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_rscc_sleep_sequence - Trigger rscc sleep sequence |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_rscc_sleep_sequence(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_rscc_wakeup_sequence - Trigger rscc wakeup sequence |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_rscc_wakeup_sequence(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_halt_gbif - Halt CX and GX requests in GBIF |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Clear any pending GX or CX transactions in GBIF and |
| * deassert GBIF halt |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_halt_gbif(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_load_pdc_ucode - Load and enable pdc sequence |
| * @adreno_dev: Pointer to the adreno device |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_load_pdc_ucode(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_load_rsc_ucode - Load rscc sequence |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_load_rsc_ucode(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_remove - Clean up gmu probed resources |
| * @device: Pointer to the kgsl device |
| */ |
| void gen7_gmu_remove(struct kgsl_device *device); |
| |
| /** |
| * gen7_gmu_enable_clks - Enable gmu clocks |
| * @adreno_dev: Pointer to the adreno device |
| * @level: GMU frequency level |
| * |
| * Return: 0 on success or negative error on failure |
| */ |
| int gen7_gmu_enable_clks(struct adreno_device *adreno_dev, u32 level); |
| |
| /** |
| * gen7_gmu_handle_watchdog - Handle watchdog interrupt |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| void gen7_gmu_handle_watchdog(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_gmu_send_nmi - Send NMI to GMU |
| * @device: Pointer to the kgsl device |
| * @force: Boolean to forcefully send NMI irrespective of GMU state |
| */ |
| void gen7_gmu_send_nmi(struct kgsl_device *device, bool force); |
| |
| /** |
| * gen7_gmu_add_to_minidump - Register gen7_device with va minidump |
| * @adreno_dev: Pointer to the adreno device |
| */ |
| int gen7_gmu_add_to_minidump(struct adreno_device *adreno_dev); |
| |
| /** |
| * gen7_snapshot_gmu_mem - Snapshot a GMU memory descriptor |
| * @device: Pointer to the kgsl device |
| * @buf: Destination snapshot buffer |
| * @remain: Remaining size of the snapshot buffer |
| * @priv: Opaque handle |
| * |
| * Return: Number of bytes written to snapshot buffer |
| */ |
| size_t gen7_snapshot_gmu_mem(struct kgsl_device *device, |
| u8 *buf, size_t remain, void *priv); |
| |
| /** |
| * gen7_bus_ab_quantize - Calculate the AB vote that needs to be sent to GMU |
| * @adreno_dev: Handle to the adreno device |
| * @ab: ab request that needs to be scaled in MBps |
| * |
| * Returns the AB value that needs to be prefixed to bandwidth vote in kbps |
| */ |
| u32 gen7_bus_ab_quantize(struct adreno_device *adreno_dev, u32 ab); |
| |
| #endif |