// SPDX-License-Identifier: GPL-2.0 /* * (C) COPYRIGHT 2019 ARM Limited. All rights reserved. * Author: James.Qian.Wang * */ #include #include "komeda_dev.h" struct komeda_str { char *str; u32 sz; u32 len; }; /* return 0 on success, < 0 on no space. */ static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...) { va_list args; int num, free_sz; int err; free_sz = str->sz - str->len - 1; if (free_sz <= 0) return -ENOSPC; va_start(args, fmt); num = vsnprintf(str->str + str->len, free_sz, fmt, args); va_end(args); if (num < free_sz) { str->len += num; err = 0; } else { str->len = str->sz - 1; err = -ENOSPC; } return err; } static void evt_sprintf(struct komeda_str *str, u64 evt, const char *msg) { if (evt) komeda_sprintf(str, msg); } static void evt_str(struct komeda_str *str, u64 events) { if (events == 0ULL) { komeda_sprintf(str, "None"); return; } evt_sprintf(str, events & KOMEDA_EVENT_VSYNC, "VSYNC|"); evt_sprintf(str, events & KOMEDA_EVENT_FLIP, "FLIP|"); evt_sprintf(str, events & KOMEDA_EVENT_EOW, "EOW|"); evt_sprintf(str, events & KOMEDA_EVENT_MODE, "OP-MODE|"); evt_sprintf(str, events & KOMEDA_EVENT_URUN, "UNDERRUN|"); evt_sprintf(str, events & KOMEDA_EVENT_OVR, "OVERRUN|"); /* GLB error */ evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|"); evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|"); /* DOU error */ evt_sprintf(str, events & KOMEDA_ERR_DRIFTTO, "DRIFTTO|"); evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|"); evt_sprintf(str, events & KOMEDA_ERR_TETO, "TETO|"); evt_sprintf(str, events & KOMEDA_ERR_CSCE, "CSCE|"); /* LPU errors or events */ evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|"); evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|"); evt_sprintf(str, events & KOMEDA_ERR_ACE0, "ACE0|"); evt_sprintf(str, events & KOMEDA_ERR_ACE1, "ACE1|"); evt_sprintf(str, events & KOMEDA_ERR_ACE2, "ACE2|"); evt_sprintf(str, events & KOMEDA_ERR_ACE3, "ACE3|"); /* LPU TBU errors*/ evt_sprintf(str, events & KOMEDA_ERR_TCF, "TCF|"); evt_sprintf(str, events & KOMEDA_ERR_TTNG, "TTNG|"); evt_sprintf(str, events & KOMEDA_ERR_TITR, "TITR|"); evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|"); evt_sprintf(str, events & KOMEDA_ERR_TTF, "TTF|"); /* CU errors*/ evt_sprintf(str, events & KOMEDA_ERR_CPE, "COPROC|"); evt_sprintf(str, events & KOMEDA_ERR_ZME, "ZME|"); evt_sprintf(str, events & KOMEDA_ERR_CFGE, "CFGE|"); evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|"); if (str->len > 0 && (str->str[str->len - 1] == '|')) { str->str[str->len - 1] = 0; str->len--; } } static bool is_new_frame(struct komeda_events *a) { return (a->pipes[0] | a->pipes[1]) & (KOMEDA_EVENT_FLIP | KOMEDA_EVENT_EOW); } void komeda_print_events(struct komeda_events *evts) { u64 print_evts = KOMEDA_ERR_EVENTS; static bool en_print = true; /* reduce the same msg print, only print the first evt for one frame */ if (evts->global || is_new_frame(evts)) en_print = true; if (!en_print) return; if ((evts->global | evts->pipes[0] | evts->pipes[1]) & print_evts) { char msg[256]; struct komeda_str str; str.str = msg; str.sz = sizeof(msg); str.len = 0; komeda_sprintf(&str, "gcu: "); evt_str(&str, evts->global); komeda_sprintf(&str, ", pipes[0]: "); evt_str(&str, evts->pipes[0]); komeda_sprintf(&str, ", pipes[1]: "); evt_str(&str, evts->pipes[1]); DRM_ERROR("err detect: %s\n", msg); en_print = false; } }