// SPDX-License-Identifier: GPL-2.0
/*
* (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
#include <drm/drm_atomic.h>
#include <drm/drm_print.h>
#include "komeda_dev.h"
struct komeda_str {
char *str;
u32 sz;
u32 len;
};
/* return 0 on success, < 0 on no space.
*/
__printf(2, 3)
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_EVENT_EMPTY, "EMPTY|" );
evt_sprintf(str, events & KOMEDA_EVENT_FULL, "FULL|" );
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, struct drm_device *dev)
{
u64 print_evts = 0;
static bool en_print = true ;
struct komeda_dev *mdev = dev->dev_private;
u16 const err_verbosity = mdev->err_verbosity;
u64 evts_mask = evts->global | evts->pipes[0] | evts->pipes[1];
/* reduce the same msg print, only print the first evt for one frame */
if (evts->global || is_new_frame(evts))
en_print = true ;
if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT) && !en_print)
return ;
if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
print_evts |= KOMEDA_ERR_EVENTS;
if (err_verbosity & KOMEDA_DEV_PRINT_WARN_EVENTS)
print_evts |= KOMEDA_WARN_EVENTS;
if (err_verbosity & KOMEDA_DEV_PRINT_INFO_EVENTS)
print_evts |= KOMEDA_INFO_EVENTS;
if (evts_mask & print_evts) {
char msg[256];
struct komeda_str str;
struct drm_printer p = drm_info_printer(dev->dev);
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);
if ((err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT) &&
(evts_mask & (KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS)))
drm_state_dump(dev, &p);
en_print = false ;
}
}
Messung V0.5 C=94 H=96 G=94
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland