0001
0002
0003
0004
0005
0006
0007 #include <drm/drm_atomic.h>
0008 #include <drm/drm_print.h>
0009
0010 #include "komeda_dev.h"
0011
0012 struct komeda_str {
0013 char *str;
0014 u32 sz;
0015 u32 len;
0016 };
0017
0018
0019
0020 __printf(2, 3)
0021 static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
0022 {
0023 va_list args;
0024 int num, free_sz;
0025 int err;
0026
0027 free_sz = str->sz - str->len - 1;
0028 if (free_sz <= 0)
0029 return -ENOSPC;
0030
0031 va_start(args, fmt);
0032
0033 num = vsnprintf(str->str + str->len, free_sz, fmt, args);
0034
0035 va_end(args);
0036
0037 if (num < free_sz) {
0038 str->len += num;
0039 err = 0;
0040 } else {
0041 str->len = str->sz - 1;
0042 err = -ENOSPC;
0043 }
0044
0045 return err;
0046 }
0047
0048 static void evt_sprintf(struct komeda_str *str, u64 evt, const char *msg)
0049 {
0050 if (evt)
0051 komeda_sprintf(str, msg);
0052 }
0053
0054 static void evt_str(struct komeda_str *str, u64 events)
0055 {
0056 if (events == 0ULL) {
0057 komeda_sprintf(str, "None");
0058 return;
0059 }
0060
0061 evt_sprintf(str, events & KOMEDA_EVENT_VSYNC, "VSYNC|");
0062 evt_sprintf(str, events & KOMEDA_EVENT_FLIP, "FLIP|");
0063 evt_sprintf(str, events & KOMEDA_EVENT_EOW, "EOW|");
0064 evt_sprintf(str, events & KOMEDA_EVENT_MODE, "OP-MODE|");
0065
0066 evt_sprintf(str, events & KOMEDA_EVENT_URUN, "UNDERRUN|");
0067 evt_sprintf(str, events & KOMEDA_EVENT_OVR, "OVERRUN|");
0068
0069
0070 evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|");
0071 evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
0072
0073
0074 evt_sprintf(str, events & KOMEDA_ERR_DRIFTTO, "DRIFTTO|");
0075 evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
0076 evt_sprintf(str, events & KOMEDA_ERR_TETO, "TETO|");
0077 evt_sprintf(str, events & KOMEDA_ERR_CSCE, "CSCE|");
0078
0079
0080 evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|");
0081 evt_sprintf(str, events & KOMEDA_EVENT_EMPTY, "EMPTY|");
0082 evt_sprintf(str, events & KOMEDA_EVENT_FULL, "FULL|");
0083 evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|");
0084 evt_sprintf(str, events & KOMEDA_ERR_ACE0, "ACE0|");
0085 evt_sprintf(str, events & KOMEDA_ERR_ACE1, "ACE1|");
0086 evt_sprintf(str, events & KOMEDA_ERR_ACE2, "ACE2|");
0087 evt_sprintf(str, events & KOMEDA_ERR_ACE3, "ACE3|");
0088
0089
0090 evt_sprintf(str, events & KOMEDA_ERR_TCF, "TCF|");
0091 evt_sprintf(str, events & KOMEDA_ERR_TTNG, "TTNG|");
0092 evt_sprintf(str, events & KOMEDA_ERR_TITR, "TITR|");
0093 evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");
0094 evt_sprintf(str, events & KOMEDA_ERR_TTF, "TTF|");
0095
0096
0097 evt_sprintf(str, events & KOMEDA_ERR_CPE, "COPROC|");
0098 evt_sprintf(str, events & KOMEDA_ERR_ZME, "ZME|");
0099 evt_sprintf(str, events & KOMEDA_ERR_CFGE, "CFGE|");
0100 evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");
0101
0102 if (str->len > 0 && (str->str[str->len - 1] == '|')) {
0103 str->str[str->len - 1] = 0;
0104 str->len--;
0105 }
0106 }
0107
0108 static bool is_new_frame(struct komeda_events *a)
0109 {
0110 return (a->pipes[0] | a->pipes[1]) &
0111 (KOMEDA_EVENT_FLIP | KOMEDA_EVENT_EOW);
0112 }
0113
0114 void komeda_print_events(struct komeda_events *evts, struct drm_device *dev)
0115 {
0116 u64 print_evts = 0;
0117 static bool en_print = true;
0118 struct komeda_dev *mdev = dev->dev_private;
0119 u16 const err_verbosity = mdev->err_verbosity;
0120 u64 evts_mask = evts->global | evts->pipes[0] | evts->pipes[1];
0121
0122
0123 if (evts->global || is_new_frame(evts))
0124 en_print = true;
0125 if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT) && !en_print)
0126 return;
0127
0128 if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
0129 print_evts |= KOMEDA_ERR_EVENTS;
0130 if (err_verbosity & KOMEDA_DEV_PRINT_WARN_EVENTS)
0131 print_evts |= KOMEDA_WARN_EVENTS;
0132 if (err_verbosity & KOMEDA_DEV_PRINT_INFO_EVENTS)
0133 print_evts |= KOMEDA_INFO_EVENTS;
0134
0135 if (evts_mask & print_evts) {
0136 char msg[256];
0137 struct komeda_str str;
0138 struct drm_printer p = drm_info_printer(dev->dev);
0139
0140 str.str = msg;
0141 str.sz = sizeof(msg);
0142 str.len = 0;
0143
0144 komeda_sprintf(&str, "gcu: ");
0145 evt_str(&str, evts->global);
0146 komeda_sprintf(&str, ", pipes[0]: ");
0147 evt_str(&str, evts->pipes[0]);
0148 komeda_sprintf(&str, ", pipes[1]: ");
0149 evt_str(&str, evts->pipes[1]);
0150
0151 DRM_ERROR("err detect: %s\n", msg);
0152 if ((err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT) &&
0153 (evts_mask & (KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS)))
0154 drm_state_dump(dev, &p);
0155
0156 en_print = false;
0157 }
0158 }