mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
drm/komeda: Adds error event print functionality
Adds to print the event message when error happens and the same event will not be printed until next vsync. Changes since v2: 1. Refine komeda_sprintf(); 2. Not using STR_SZ macro for the string size in komeda_print_events(). Changes since v1: 1. Handling the event print by CONFIG_KOMEDA_ERROR_PRINT; 2. Changing the max string size to 256. Signed-off-by: Lowry Li (Arm Technology China) <lowry.li@arm.com> Reviewed-by: Mihail Atanassov <mihail.atanassov@arm.com> Reviewed-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com> Signed-off-by: james qian wang (Arm Technology China) <james.qian.wang@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/1564738954-6101-1-git-send-email-lowry.li@arm.com
This commit is contained in:
parent
62afb4ad42
commit
4d74b25ee3
5 changed files with 167 additions and 0 deletions
|
@ -12,3 +12,9 @@ config DRM_KOMEDA
|
|||
Processor driver. It supports the D71 variants of the hardware.
|
||||
|
||||
If compiled as a module it will be called komeda.
|
||||
|
||||
config DRM_KOMEDA_ERROR_PRINT
|
||||
bool "Enable komeda error print"
|
||||
depends on DRM_KOMEDA
|
||||
help
|
||||
Choose this option to enable error printing.
|
||||
|
|
|
@ -22,4 +22,6 @@ komeda-y += \
|
|||
d71/d71_dev.o \
|
||||
d71/d71_component.o
|
||||
|
||||
komeda-$(CONFIG_DRM_KOMEDA_ERROR_PRINT) += komeda_event.o
|
||||
|
||||
obj-$(CONFIG_DRM_KOMEDA) += komeda.o
|
||||
|
|
|
@ -40,6 +40,17 @@
|
|||
#define KOMEDA_ERR_TTNG BIT_ULL(30)
|
||||
#define KOMEDA_ERR_TTF BIT_ULL(31)
|
||||
|
||||
#define KOMEDA_ERR_EVENTS \
|
||||
(KOMEDA_EVENT_URUN | KOMEDA_EVENT_IBSY | KOMEDA_EVENT_OVR |\
|
||||
KOMEDA_ERR_TETO | KOMEDA_ERR_TEMR | KOMEDA_ERR_TITR |\
|
||||
KOMEDA_ERR_CPE | KOMEDA_ERR_CFGE | KOMEDA_ERR_AXIE |\
|
||||
KOMEDA_ERR_ACE0 | KOMEDA_ERR_ACE1 | KOMEDA_ERR_ACE2 |\
|
||||
KOMEDA_ERR_ACE3 | KOMEDA_ERR_DRIFTTO | KOMEDA_ERR_FRAMETO |\
|
||||
KOMEDA_ERR_ZME | KOMEDA_ERR_MERR | KOMEDA_ERR_TCF |\
|
||||
KOMEDA_ERR_TTNG | KOMEDA_ERR_TTF)
|
||||
|
||||
#define KOMEDA_WARN_EVENTS KOMEDA_ERR_CSCE
|
||||
|
||||
/* malidp device id */
|
||||
enum {
|
||||
MALI_D71 = 0,
|
||||
|
@ -207,4 +218,8 @@ void komeda_dev_destroy(struct komeda_dev *mdev);
|
|||
|
||||
struct komeda_dev *dev_to_mdev(struct device *dev);
|
||||
|
||||
#ifdef CONFIG_DRM_KOMEDA_ERROR_PRINT
|
||||
void komeda_print_events(struct komeda_events *evts);
|
||||
#endif
|
||||
|
||||
#endif /*_KOMEDA_DEV_H_*/
|
||||
|
|
140
drivers/gpu/drm/arm/display/komeda/komeda_event.c
Normal file
140
drivers/gpu/drm/arm/display/komeda/komeda_event.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
// 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_print.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
|
@ -47,6 +47,10 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
|
|||
memset(&evts, 0, sizeof(evts));
|
||||
status = mdev->funcs->irq_handler(mdev, &evts);
|
||||
|
||||
#ifdef CONFIG_DRM_KOMEDA_ERROR_PRINT
|
||||
komeda_print_events(&evts);
|
||||
#endif
|
||||
|
||||
/* Notify the crtc to handle the events */
|
||||
for (i = 0; i < kms->n_crtcs; i++)
|
||||
komeda_crtc_handle_event(&kms->crtcs[i], &evts);
|
||||
|
|
Loading…
Reference in a new issue