Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
0004  * Author: James.Qian.Wang <james.qian.wang@arm.com>
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 /* return 0 on success,  < 0 on no space.
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     /* GLB error */
0070     evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|");
0071     evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
0072 
0073     /* DOU error */
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     /* LPU errors or events */
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     /* LPU TBU errors*/
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     /* CU errors*/
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     /* reduce the same msg print, only print the first evt for one frame */
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 }