2019-08-02 09:43:10 +00:00
// SPDX-License-Identifier: GPL-2.0
/*
* ( C ) COPYRIGHT 2019 ARM Limited . All rights reserved .
* Author : James . Qian . Wang < james . qian . wang @ arm . com >
*
*/
2019-11-07 11:42:36 +00:00
# include <drm/drm_atomic.h>
2019-08-02 09:43:10 +00:00
# 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.
*/
2019-11-14 10:04:37 +00:00
__printf ( 2 , 3 )
2019-08-02 09:43:10 +00:00
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| " ) ;
2019-12-12 07:27:55 +00:00
evt_sprintf ( str , events & KOMEDA_EVENT_EMPTY , " EMPTY| " ) ;
evt_sprintf ( str , events & KOMEDA_EVENT_FULL , " FULL| " ) ;
2019-08-02 09:43:10 +00:00
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 ) ;
}
2019-11-07 11:42:28 +00:00
void komeda_print_events ( struct komeda_events * evts , struct drm_device * dev )
2019-08-02 09:43:10 +00:00
{
2019-11-07 11:42:28 +00:00
u64 print_evts = 0 ;
2019-08-02 09:43:10 +00:00
static bool en_print = true ;
2019-11-07 11:42:28 +00:00
struct komeda_dev * mdev = dev - > dev_private ;
u16 const err_verbosity = mdev - > err_verbosity ;
2019-11-07 11:42:36 +00:00
u64 evts_mask = evts - > global | evts - > pipes [ 0 ] | evts - > pipes [ 1 ] ;
2019-08-02 09:43:10 +00:00
/* reduce the same msg print, only print the first evt for one frame */
if ( evts - > global | | is_new_frame ( evts ) )
en_print = true ;
2019-11-07 11:42:44 +00:00
if ( ! ( err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT ) & & ! en_print )
2019-08-02 09:43:10 +00:00
return ;
2019-11-07 11:42:28 +00:00
if ( err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS )
print_evts | = KOMEDA_ERR_EVENTS ;
2019-11-07 11:42:40 +00:00
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 ;
2019-11-07 11:42:28 +00:00
2019-11-07 11:42:36 +00:00
if ( evts_mask & print_evts ) {
2019-08-02 09:43:10 +00:00
char msg [ 256 ] ;
struct komeda_str str ;
2019-11-07 11:42:36 +00:00
struct drm_printer p = drm_info_printer ( dev - > dev ) ;
2019-08-02 09:43:10 +00:00
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 ) ;
2019-11-07 11:42:36 +00:00
if ( ( err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT ) & &
( evts_mask & ( KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS ) ) )
drm_state_dump ( dev , & p ) ;
2019-08-02 09:43:10 +00:00
en_print = false ;
}
}