123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include <linux/of_platform.h>
- #include "hw_fence_drv_priv.h"
- #include "hw_fence_drv_utils.h"
- #include "hw_fence_drv_ipc.h"
- #include "hw_fence_drv_debug.h"
- /*
- * Max size of base table with ipc mappings, with one mapping per client type with configurable
- * number of subclients
- */
- #define HW_FENCE_IPC_MAP_MAX (HW_FENCE_MAX_STATIC_CLIENTS_INDEX + \
- HW_FENCE_MAX_CLIENT_TYPE_CONFIGURABLE)
- /**
- * struct hw_fence_client_ipc_map - map client id with ipc signal for trigger.
- * @ipc_client_id_virt: virtual ipc client id for the hw-fence client.
- * @ipc_client_id_phys: physical ipc client id for the hw-fence client.
- * @ipc_signal_id: ipc signal id for the hw-fence client.
- * @update_rxq: bool to indicate if clinet uses rx-queue.
- * @send_ipc: bool to indicate if client requires ipc interrupt for signaled fences
- */
- struct hw_fence_client_ipc_map {
- int ipc_client_id_virt;
- int ipc_client_id_phys;
- int ipc_signal_id;
- bool update_rxq;
- bool send_ipc;
- };
- /**
- * struct hw_fence_clients_ipc_map_no_dpu - Table makes the 'client to signal' mapping, which
- * is used by the hw fence driver to trigger ipc signal when the hw fence is already
- * signaled.
- * This no_dpu version is for targets that do not support dpu client id
- *
- * Notes:
- * The index of this struct must match the enum hw_fence_client_id.
- * To change to a loopback signal instead of GMU, change ctx0 row to use:
- * {HW_FENCE_IPC_CLIENT_ID_APPS, 20}.
- */
- struct hw_fence_client_ipc_map hw_fence_clients_ipc_map_no_dpu[HW_FENCE_IPC_MAP_MAX] = {
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 1, true, true},/* ctrlq*/
- {HW_FENCE_IPC_CLIENT_ID_GPU_VID, HW_FENCE_IPC_CLIENT_ID_GPU_VID, 0, false, false},/* ctx0 */
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 14, false, true},/*ctl0*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 15, false, true},/*ctl1*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 16, false, true},/*ctl2*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 17, false, true},/*ctl3*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 18, false, true},/*ctl4*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 19, false, true},/*ctl5*/
- #if IS_ENABLED(CONFIG_DEBUG_FS)
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 21, true, false},/*val0*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 22, true, false},/*val1*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 23, true, false},/*val2*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 24, true, false},/*val3*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 25, true, false},/*val4*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 26, true, false},/*val5*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 27, true, false},/*val6*/
- #endif /* CONFIG_DEBUG_FS */
- };
- /**
- * struct hw_fence_clients_ipc_map - Table makes the 'client to signal' mapping, which is
- * used by the hw fence driver to trigger ipc signal when hw fence is already
- * signaled.
- * This version is for targets that support dpu client id.
- *
- * Note that the index of this struct must match the enum hw_fence_client_id
- */
- struct hw_fence_client_ipc_map hw_fence_clients_ipc_map[HW_FENCE_IPC_MAP_MAX] = {
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 1, true, true},/*ctrl q*/
- {HW_FENCE_IPC_CLIENT_ID_GPU_VID, HW_FENCE_IPC_CLIENT_ID_GPU_VID, 0, false, false},/*ctx0 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 0, false, true},/* ctl0 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 1, false, true},/* ctl1 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 2, false, true},/* ctl2 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 3, false, true},/* ctl3 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 4, false, true},/* ctl4 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_VID, 5, false, true},/* ctl5 */
- #if IS_ENABLED(CONFIG_DEBUG_FS)
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 21, true, false},/*val0*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 22, true, false},/*val1*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 23, true, false},/*val2*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 24, true, false},/*val3*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 25, true, false},/*val4*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 26, true, false},/*val5*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 27, true, false},/*val6*/
- #else
- {0, 0, 0, false, false}, /* val0 */
- {0, 0, 0, false, false}, /* val1 */
- {0, 0, 0, false, false}, /* val2 */
- {0, 0, 0, false, false}, /* val3 */
- {0, 0, 0, false, false}, /* val4 */
- {0, 0, 0, false, false}, /* val5 */
- {0, 0, 0, false, false}, /* val6 */
- #endif /* CONFIG_DEBUG_FS */
- {HW_FENCE_IPC_CLIENT_ID_IPE_VID, HW_FENCE_IPC_CLIENT_ID_IPE_VID, 0, true, true}, /* ipe */
- {HW_FENCE_IPC_CLIENT_ID_VPU_VID, HW_FENCE_IPC_CLIENT_ID_VPU_VID, 0, true, true}, /* vpu */
- };
- /**
- * struct hw_fence_clients_ipc_map_v2 - Table makes the 'client to signal' mapping, which is
- * used by the hw fence driver to trigger ipc signal when hw fence is already
- * signaled.
- * This version is for targets that support dpu client id and IPC v2.
- *
- * Note that the index of this struct must match the enum hw_fence_client_id for clients ids less
- * than HW_FENCE_MAX_STATIC_CLIENTS_INDEX.
- * For clients with configurable sub-clients, the index of this struct matches
- * HW_FENCE_MAX_STATIC_CLIENTS_INDEX + (client type index - HW_FENCE_MAX_CLIENT_TYPE_STATIC).
- */
- struct hw_fence_client_ipc_map hw_fence_clients_ipc_map_v2[HW_FENCE_IPC_MAP_MAX] = {
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 1, true, true},/*ctrlq */
- {HW_FENCE_IPC_CLIENT_ID_GPU_VID, HW_FENCE_IPC_CLIENT_ID_GPU_PID, 0, false, false},/* ctx0*/
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 0, false, true},/* ctl0 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 1, false, true},/* ctl1 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 2, false, true},/* ctl2 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 3, false, true},/* ctl3 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 4, false, true},/* ctl4 */
- {HW_FENCE_IPC_CLIENT_ID_DPU_VID, HW_FENCE_IPC_CLIENT_ID_DPU_PID, 5, false, true},/* ctl5 */
- #if IS_ENABLED(CONFIG_DEBUG_FS)
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 21, true, false},/*val0*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 22, true, false},/*val1*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 23, true, false},/*val2*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 24, true, false},/*val3*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 25, true, false},/*val4*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 26, true, false},/*val5*/
- {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_PID, 27, true, false},/*val6*/
- #else
- {0, 0, 0, false, false}, /* val0 */
- {0, 0, 0, false, false}, /* val1 */
- {0, 0, 0, false, false}, /* val2 */
- {0, 0, 0, false, false}, /* val3 */
- {0, 0, 0, false, false}, /* val4 */
- {0, 0, 0, false, false}, /* val5 */
- {0, 0, 0, false, false}, /* val6 */
- #endif /* CONFIG_DEBUG_FS */
- {HW_FENCE_IPC_CLIENT_ID_IPE_VID, HW_FENCE_IPC_CLIENT_ID_IPE_PID, 0, true, true}, /* ipe */
- {HW_FENCE_IPC_CLIENT_ID_VPU_VID, HW_FENCE_IPC_CLIENT_ID_VPU_PID, 0, true, true}, /* vpu */
- {HW_FENCE_IPC_CLIENT_ID_IFE0_VID, HW_FENCE_IPC_CLIENT_ID_IFE0_PID, 0, false, true},/* ife0*/
- {HW_FENCE_IPC_CLIENT_ID_IFE1_VID, HW_FENCE_IPC_CLIENT_ID_IFE1_PID, 0, false, true},/* ife1*/
- {HW_FENCE_IPC_CLIENT_ID_IFE2_VID, HW_FENCE_IPC_CLIENT_ID_IFE2_PID, 0, false, true},/* ife2*/
- {HW_FENCE_IPC_CLIENT_ID_IFE3_VID, HW_FENCE_IPC_CLIENT_ID_IFE3_PID, 0, false, true},/* ife3*/
- {HW_FENCE_IPC_CLIENT_ID_IFE4_VID, HW_FENCE_IPC_CLIENT_ID_IFE4_PID, 0, false, true},/* ife4*/
- {HW_FENCE_IPC_CLIENT_ID_IFE5_VID, HW_FENCE_IPC_CLIENT_ID_IFE5_PID, 0, false, true},/* ife5*/
- {HW_FENCE_IPC_CLIENT_ID_IFE6_VID, HW_FENCE_IPC_CLIENT_ID_IFE6_PID, 0, false, true},/* ife6*/
- {HW_FENCE_IPC_CLIENT_ID_IFE7_VID, HW_FENCE_IPC_CLIENT_ID_IFE7_PID, 0, false, true},/* ife7*/
- };
- int hw_fence_ipcc_get_client_virt_id(struct hw_fence_driver_data *drv_data, u32 client_id)
- {
- if (!drv_data || client_id >= drv_data->clients_num)
- return -EINVAL;
- return drv_data->ipc_clients_table[client_id].ipc_client_id_virt;
- }
- int hw_fence_ipcc_get_client_phys_id(struct hw_fence_driver_data *drv_data, u32 client_id)
- {
- if (!drv_data || client_id >= drv_data->clients_num)
- return -EINVAL;
- return drv_data->ipc_clients_table[client_id].ipc_client_id_phys;
- }
- int hw_fence_ipcc_get_signal_id(struct hw_fence_driver_data *drv_data, u32 client_id)
- {
- if (!drv_data || client_id >= drv_data->clients_num)
- return -EINVAL;
- return drv_data->ipc_clients_table[client_id].ipc_signal_id;
- }
- bool hw_fence_ipcc_needs_rxq_update(struct hw_fence_driver_data *drv_data, int client_id)
- {
- if (!drv_data || client_id >= drv_data->clients_num)
- return false;
- return drv_data->ipc_clients_table[client_id].update_rxq;
- }
- bool hw_fence_ipcc_needs_ipc_irq(struct hw_fence_driver_data *drv_data, int client_id)
- {
- if (!drv_data || client_id >= HW_FENCE_CLIENT_MAX)
- return false;
- return drv_data->ipc_clients_table[client_id].send_ipc;
- }
- /**
- * _get_ipc_phys_client_name() - Returns ipc client name from its physical id, used for debugging.
- */
- static inline char *_get_ipc_phys_client_name(u32 client_id)
- {
- switch (client_id) {
- case HW_FENCE_IPC_CLIENT_ID_APPS_PID:
- return "APPS_PID";
- case HW_FENCE_IPC_CLIENT_ID_GPU_PID:
- return "GPU_PID";
- case HW_FENCE_IPC_CLIENT_ID_DPU_PID:
- return "DPU_PID";
- case HW_FENCE_IPC_CLIENT_ID_IPE_PID:
- return "IPE_PID";
- case HW_FENCE_IPC_CLIENT_ID_VPU_PID:
- return "VPU_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE0_PID:
- return "IFE0_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE1_PID:
- return "IFE1_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE2_PID:
- return "IFE2_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE3_PID:
- return "IFE3_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE4_PID:
- return "IFE4_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE5_PID:
- return "IFE5_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE6_PID:
- return "IFE6_PID";
- case HW_FENCE_IPC_CLIENT_ID_IFE7_PID:
- return "IFE7_PID";
- }
- return "UNKNOWN_PID";
- }
- /**
- * _get_ipc_virt_client_name() - Returns ipc client name from its virtual id, used for debugging.
- */
- static inline char *_get_ipc_virt_client_name(u32 client_id)
- {
- switch (client_id) {
- case HW_FENCE_IPC_CLIENT_ID_APPS_VID:
- return "APPS_VID";
- case HW_FENCE_IPC_CLIENT_ID_GPU_VID:
- return "GPU_VID";
- case HW_FENCE_IPC_CLIENT_ID_DPU_VID:
- return "DPU_VID";
- case HW_FENCE_IPC_CLIENT_ID_IPE_VID:
- return "IPE_VID";
- case HW_FENCE_IPC_CLIENT_ID_VPU_VID:
- return "VPU_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE0_VID:
- return "IFE0_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE1_VID:
- return "IFE1_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE2_VID:
- return "IFE2_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE3_VID:
- return "IFE3_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE4_VID:
- return "IFE4_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE5_VID:
- return "IFE5_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE6_VID:
- return "IFE6_VID";
- case HW_FENCE_IPC_CLIENT_ID_IFE7_VID:
- return "IFE7_VID";
- }
- return "UNKNOWN_VID";
- }
- void hw_fence_ipcc_trigger_signal(struct hw_fence_driver_data *drv_data,
- u32 tx_client_pid, u32 rx_client_vid, u32 signal_id)
- {
- void __iomem *ptr;
- u32 val;
- /* Send signal */
- ptr = IPC_PROTOCOLp_CLIENTc_SEND(drv_data->ipcc_io_mem, drv_data->protocol_id,
- tx_client_pid);
- val = (rx_client_vid << 16) | signal_id;
- HWFNC_DBG_IRQ("Sending ipcc from %s (%d) to %s (%d) signal_id:%d [wr:0x%x to off:0x%pK]\n",
- _get_ipc_phys_client_name(tx_client_pid), tx_client_pid,
- _get_ipc_virt_client_name(rx_client_vid), rx_client_vid,
- signal_id, val, ptr);
- HWFNC_DBG_H("Write:0x%x to RegOffset:0x%pK\n", val, ptr);
- writel_relaxed(val, ptr);
- /* Make sure value is written */
- wmb();
- }
- static int _hw_fence_ipcc_init_map_with_configurable_clients(struct hw_fence_driver_data *drv_data,
- struct hw_fence_client_ipc_map *base_table)
- {
- int i, j, map_idx;
- size_t size;
- size = drv_data->clients_num * sizeof(struct hw_fence_client_ipc_map);
- drv_data->ipc_clients_table = kzalloc(size, GFP_KERNEL);
- if (!drv_data->ipc_clients_table)
- return -ENOMEM;
- /* copy mappings for static hw fence clients */
- size = HW_FENCE_MAX_STATIC_CLIENTS_INDEX * sizeof(struct hw_fence_client_ipc_map);
- memcpy(drv_data->ipc_clients_table, base_table, size);
- /* initialize mappings for ipc clients with configurable number of hw fence clients */
- map_idx = HW_FENCE_MAX_STATIC_CLIENTS_INDEX;
- for (i = 0; i < HW_FENCE_MAX_CLIENT_TYPE_CONFIGURABLE; i++) {
- int client_type = HW_FENCE_MAX_CLIENT_TYPE_STATIC + i;
- int clients_num = drv_data->hw_fence_client_types[client_type].clients_num;
- for (j = 0; j < clients_num; j++) {
- /* this should never happen if drv_data->clients_num is correct */
- if (map_idx >= drv_data->clients_num) {
- HWFNC_ERR("%s clients_num:%lu exceeds drv_data->clients_num:%lu\n",
- drv_data->hw_fence_client_types[client_type].name,
- clients_num, drv_data->clients_num);
- return -EINVAL;
- }
- drv_data->ipc_clients_table[map_idx] =
- base_table[HW_FENCE_MAX_STATIC_CLIENTS_INDEX + i];
- drv_data->ipc_clients_table[map_idx].ipc_signal_id = j;
- map_idx++;
- }
- }
- return 0;
- }
- /**
- * _hw_fence_ipcc_hwrev_init() - Initializes internal driver struct with corresponding ipcc data,
- * according to the ipcc hw revision.
- * @drv_data: driver data.
- * @hwrev: ipcc hw revision.
- */
- static int _hw_fence_ipcc_hwrev_init(struct hw_fence_driver_data *drv_data, u32 hwrev)
- {
- int ret = 0;
- switch (hwrev) {
- case HW_FENCE_IPCC_HW_REV_100:
- drv_data->ipcc_client_vid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->ipcc_client_pid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->protocol_id = HW_FENCE_IPC_COMPUTE_L1_PROTOCOL_ID_LAHAINA;
- drv_data->ipc_clients_table = hw_fence_clients_ipc_map_no_dpu;
- HWFNC_DBG_INIT("ipcc protocol_id: Lahaina\n");
- break;
- case HW_FENCE_IPCC_HW_REV_110:
- drv_data->ipcc_client_vid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->ipcc_client_pid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->protocol_id = HW_FENCE_IPC_COMPUTE_L1_PROTOCOL_ID_WAIPIO;
- drv_data->ipc_clients_table = hw_fence_clients_ipc_map_no_dpu;
- HWFNC_DBG_INIT("ipcc protocol_id: Waipio\n");
- break;
- case HW_FENCE_IPCC_HW_REV_170:
- drv_data->ipcc_client_vid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->ipcc_client_pid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->protocol_id = HW_FENCE_IPC_COMPUTE_L1_PROTOCOL_ID_KALAMA;
- drv_data->ipc_clients_table = hw_fence_clients_ipc_map;
- HWFNC_DBG_INIT("ipcc protocol_id: Kalama\n");
- break;
- case HW_FENCE_IPCC_HW_REV_203:
- drv_data->ipcc_client_vid = HW_FENCE_IPC_CLIENT_ID_APPS_VID;
- drv_data->ipcc_client_pid = HW_FENCE_IPC_CLIENT_ID_APPS_PID;
- drv_data->protocol_id = HW_FENCE_IPC_FENCE_PROTOCOL_ID_PINEAPPLE; /* Fence */
- ret = _hw_fence_ipcc_init_map_with_configurable_clients(drv_data,
- hw_fence_clients_ipc_map_v2);
- HWFNC_DBG_INIT("ipcc protocol_id: Pineapple\n");
- break;
- default:
- return -1;
- }
- return ret;
- }
- int hw_fence_ipcc_enable_signaling(struct hw_fence_driver_data *drv_data)
- {
- void __iomem *ptr;
- u32 val;
- int ret;
- HWFNC_DBG_H("enable ipc +\n");
- /**
- * Attempt to read the ipc version from dt, if not available, then attempt
- * to read from the registers.
- */
- ret = of_property_read_u32(drv_data->dev->of_node, "qcom,hw-fence-ipc-ver", &val);
- if (ret || !val) {
- /* if no device tree prop, attempt to get the version from the registers*/
- HWFNC_DBG_H("missing hw fences ipc-ver entry or invalid ret:%d val:%d\n", ret, val);
- /* Read IPC Version from Client=0x8 (apps) for protocol=2 (compute_l1) */
- val = readl_relaxed(IPC_PROTOCOLp_CLIENTc_VERSION(drv_data->ipcc_io_mem,
- HW_FENCE_IPC_COMPUTE_L1_PROTOCOL_ID_LAHAINA,
- HW_FENCE_IPC_CLIENT_ID_APPS_VID));
- HWFNC_DBG_INIT("ipcc version:0x%x\n", val);
- }
- if (_hw_fence_ipcc_hwrev_init(drv_data, val)) {
- HWFNC_ERR("ipcc protocol id not supported\n");
- return -EINVAL;
- }
- /* Enable compute l1 (protocol_id = 2) */
- val = 0x00000000;
- ptr = IPC_PROTOCOLp_CLIENTc_CONFIG(drv_data->ipcc_io_mem, drv_data->protocol_id,
- drv_data->ipcc_client_pid);
- HWFNC_DBG_H("Write:0x%x to RegOffset:0x%pK\n", val, ptr);
- writel_relaxed(val, ptr);
- /* Enable Client-Signal pairs from APPS(NS) (0x8) to APPS(NS) (0x8) */
- val = 0x000080000;
- ptr = IPC_PROTOCOLp_CLIENTc_RECV_SIGNAL_ENABLE(drv_data->ipcc_io_mem, drv_data->protocol_id,
- drv_data->ipcc_client_pid);
- HWFNC_DBG_H("Write:0x%x to RegOffset:0x%pK\n", val, ptr);
- writel_relaxed(val, ptr);
- HWFNC_DBG_H("enable ipc -\n");
- return 0;
- }
- #ifdef HW_DPU_IPCC
- int hw_fence_ipcc_enable_dpu_signaling(struct hw_fence_driver_data *drv_data)
- {
- struct hw_fence_client_ipc_map *hw_fence_client;
- bool protocol_enabled = false;
- void __iomem *ptr;
- u32 val;
- int i;
- HWFNC_DBG_H("enable dpu ipc +\n");
- if (!drv_data || !drv_data->protocol_id || !drv_data->ipc_clients_table) {
- HWFNC_ERR("invalid drv data\n");
- return -1;
- }
- HWFNC_DBG_H("ipcc_io_mem:0x%lx\n", (u64)drv_data->ipcc_io_mem);
- HWFNC_DBG_H("Initialize dpu signals\n");
- /* Enable Client-Signal pairs from DPU (25) to APPS(NS) (8) */
- for (i = 0; i < drv_data->clients_num; i++) {
- hw_fence_client = &drv_data->ipc_clients_table[i];
- /* skip any client that is not a dpu client */
- if (hw_fence_client->ipc_client_id_virt != HW_FENCE_IPC_CLIENT_ID_DPU_VID)
- continue;
- if (!protocol_enabled) {
- /*
- * First DPU client will enable the protocol for dpu, e.g. compute l1
- * (protocol_id = 2) or fencing protocol, depending on the target, for the
- * dpu client (vid = 25, pid = 9).
- * Sets bit(1) to clear when RECV_ID is read
- */
- val = 0x00000001;
- ptr = IPC_PROTOCOLp_CLIENTc_CONFIG(drv_data->ipcc_io_mem,
- drv_data->protocol_id, hw_fence_client->ipc_client_id_phys);
- HWFNC_DBG_H("Write:0x%x to RegOffset:0x%lx\n", val, (u64)ptr);
- writel_relaxed(val, ptr);
- protocol_enabled = true;
- }
- /* Enable signals for dpu client */
- HWFNC_DBG_H("dpu client:%d vid:%d pid:%d signal:%d\n", i,
- hw_fence_client->ipc_client_id_virt, hw_fence_client->ipc_client_id_phys,
- hw_fence_client->ipc_signal_id);
- /* Enable input apps-signal for dpu */
- val = (HW_FENCE_IPC_CLIENT_ID_APPS_VID << 16) |
- (hw_fence_client->ipc_signal_id & 0xFFFF);
- ptr = IPC_PROTOCOLp_CLIENTc_RECV_SIGNAL_ENABLE(drv_data->ipcc_io_mem,
- drv_data->protocol_id, hw_fence_client->ipc_client_id_phys);
- HWFNC_DBG_H("Write:0x%x to RegOffset:0x%lx\n", val, (u64)ptr);
- writel_relaxed(val, ptr);
- }
- HWFNC_DBG_H("enable dpu ipc -\n");
- return 0;
- }
- #endif /* HW_DPU_IPCC */
|