159 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.4 * Author: James.Qian.Wang <james.qian.wang@arm.com>5 *6 */7#include <drm/drm_atomic.h>8#include <drm/drm_print.h>9 10#include "komeda_dev.h"11 12struct komeda_str {13 char *str;14 u32 sz;15 u32 len;16};17 18/* return 0 on success, < 0 on no space.19 */20__printf(2, 3)21static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)22{23 va_list args;24 int num, free_sz;25 int err;26 27 free_sz = str->sz - str->len - 1;28 if (free_sz <= 0)29 return -ENOSPC;30 31 va_start(args, fmt);32 33 num = vsnprintf(str->str + str->len, free_sz, fmt, args);34 35 va_end(args);36 37 if (num < free_sz) {38 str->len += num;39 err = 0;40 } else {41 str->len = str->sz - 1;42 err = -ENOSPC;43 }44 45 return err;46}47 48static void evt_sprintf(struct komeda_str *str, u64 evt, const char *msg)49{50 if (evt)51 komeda_sprintf(str, msg);52}53 54static void evt_str(struct komeda_str *str, u64 events)55{56 if (events == 0ULL) {57 komeda_sprintf(str, "None");58 return;59 }60 61 evt_sprintf(str, events & KOMEDA_EVENT_VSYNC, "VSYNC|");62 evt_sprintf(str, events & KOMEDA_EVENT_FLIP, "FLIP|");63 evt_sprintf(str, events & KOMEDA_EVENT_EOW, "EOW|");64 evt_sprintf(str, events & KOMEDA_EVENT_MODE, "OP-MODE|");65 66 evt_sprintf(str, events & KOMEDA_EVENT_URUN, "UNDERRUN|");67 evt_sprintf(str, events & KOMEDA_EVENT_OVR, "OVERRUN|");68 69 /* GLB error */70 evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|");71 evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");72 73 /* DOU error */74 evt_sprintf(str, events & KOMEDA_ERR_DRIFTTO, "DRIFTTO|");75 evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");76 evt_sprintf(str, events & KOMEDA_ERR_TETO, "TETO|");77 evt_sprintf(str, events & KOMEDA_ERR_CSCE, "CSCE|");78 79 /* LPU errors or events */80 evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|");81 evt_sprintf(str, events & KOMEDA_EVENT_EMPTY, "EMPTY|");82 evt_sprintf(str, events & KOMEDA_EVENT_FULL, "FULL|");83 evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|");84 evt_sprintf(str, events & KOMEDA_ERR_ACE0, "ACE0|");85 evt_sprintf(str, events & KOMEDA_ERR_ACE1, "ACE1|");86 evt_sprintf(str, events & KOMEDA_ERR_ACE2, "ACE2|");87 evt_sprintf(str, events & KOMEDA_ERR_ACE3, "ACE3|");88 89 /* LPU TBU errors*/90 evt_sprintf(str, events & KOMEDA_ERR_TCF, "TCF|");91 evt_sprintf(str, events & KOMEDA_ERR_TTNG, "TTNG|");92 evt_sprintf(str, events & KOMEDA_ERR_TITR, "TITR|");93 evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");94 evt_sprintf(str, events & KOMEDA_ERR_TTF, "TTF|");95 96 /* CU errors*/97 evt_sprintf(str, events & KOMEDA_ERR_CPE, "COPROC|");98 evt_sprintf(str, events & KOMEDA_ERR_ZME, "ZME|");99 evt_sprintf(str, events & KOMEDA_ERR_CFGE, "CFGE|");100 evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");101 102 if (str->len > 0 && (str->str[str->len - 1] == '|')) {103 str->str[str->len - 1] = 0;104 str->len--;105 }106}107 108static bool is_new_frame(struct komeda_events *a)109{110 return (a->pipes[0] | a->pipes[1]) &111 (KOMEDA_EVENT_FLIP | KOMEDA_EVENT_EOW);112}113 114void komeda_print_events(struct komeda_events *evts, struct drm_device *dev)115{116 u64 print_evts = 0;117 static bool en_print = true;118 struct komeda_dev *mdev = dev->dev_private;119 u16 const err_verbosity = mdev->err_verbosity;120 u64 evts_mask = evts->global | evts->pipes[0] | evts->pipes[1];121 122 /* reduce the same msg print, only print the first evt for one frame */123 if (evts->global || is_new_frame(evts))124 en_print = true;125 if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT) && !en_print)126 return;127 128 if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)129 print_evts |= KOMEDA_ERR_EVENTS;130 if (err_verbosity & KOMEDA_DEV_PRINT_WARN_EVENTS)131 print_evts |= KOMEDA_WARN_EVENTS;132 if (err_verbosity & KOMEDA_DEV_PRINT_INFO_EVENTS)133 print_evts |= KOMEDA_INFO_EVENTS;134 135 if (evts_mask & print_evts) {136 char msg[256];137 struct komeda_str str;138 struct drm_printer p = drm_info_printer(dev->dev);139 140 str.str = msg;141 str.sz = sizeof(msg);142 str.len = 0;143 144 komeda_sprintf(&str, "gcu: ");145 evt_str(&str, evts->global);146 komeda_sprintf(&str, ", pipes[0]: ");147 evt_str(&str, evts->pipes[0]);148 komeda_sprintf(&str, ", pipes[1]: ");149 evt_str(&str, evts->pipes[1]);150 151 DRM_ERROR("err detect: %s\n", msg);152 if ((err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT) &&153 (evts_mask & (KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS)))154 drm_state_dump(dev, &p);155 156 en_print = false;157 }158}159