14d74b25eSLowry Li (Arm Technology China) // SPDX-License-Identifier: GPL-2.0
24d74b25eSLowry Li (Arm Technology China) /*
34d74b25eSLowry Li (Arm Technology China)  * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
44d74b25eSLowry Li (Arm Technology China)  * Author: James.Qian.Wang <james.qian.wang@arm.com>
54d74b25eSLowry Li (Arm Technology China)  *
64d74b25eSLowry Li (Arm Technology China)  */
739338934SMihail Atanassov #include <drm/drm_atomic.h>
84d74b25eSLowry Li (Arm Technology China) #include <drm/drm_print.h>
94d74b25eSLowry Li (Arm Technology China) 
104d74b25eSLowry Li (Arm Technology China) #include "komeda_dev.h"
114d74b25eSLowry Li (Arm Technology China) 
124d74b25eSLowry Li (Arm Technology China) struct komeda_str {
134d74b25eSLowry Li (Arm Technology China) 	char *str;
144d74b25eSLowry Li (Arm Technology China) 	u32 sz;
154d74b25eSLowry Li (Arm Technology China) 	u32 len;
164d74b25eSLowry Li (Arm Technology China) };
174d74b25eSLowry Li (Arm Technology China) 
184d74b25eSLowry Li (Arm Technology China) /* return 0 on success,  < 0 on no space.
194d74b25eSLowry Li (Arm Technology China)  */
2081fa149bSjames qian wang (Arm Technology China) __printf(2, 3)
komeda_sprintf(struct komeda_str * str,const char * fmt,...)214d74b25eSLowry Li (Arm Technology China) static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
224d74b25eSLowry Li (Arm Technology China) {
234d74b25eSLowry Li (Arm Technology China) 	va_list args;
244d74b25eSLowry Li (Arm Technology China) 	int num, free_sz;
254d74b25eSLowry Li (Arm Technology China) 	int err;
264d74b25eSLowry Li (Arm Technology China) 
274d74b25eSLowry Li (Arm Technology China) 	free_sz = str->sz - str->len - 1;
284d74b25eSLowry Li (Arm Technology China) 	if (free_sz <= 0)
294d74b25eSLowry Li (Arm Technology China) 		return -ENOSPC;
304d74b25eSLowry Li (Arm Technology China) 
314d74b25eSLowry Li (Arm Technology China) 	va_start(args, fmt);
324d74b25eSLowry Li (Arm Technology China) 
334d74b25eSLowry Li (Arm Technology China) 	num = vsnprintf(str->str + str->len, free_sz, fmt, args);
344d74b25eSLowry Li (Arm Technology China) 
354d74b25eSLowry Li (Arm Technology China) 	va_end(args);
364d74b25eSLowry Li (Arm Technology China) 
374d74b25eSLowry Li (Arm Technology China) 	if (num < free_sz) {
384d74b25eSLowry Li (Arm Technology China) 		str->len += num;
394d74b25eSLowry Li (Arm Technology China) 		err = 0;
404d74b25eSLowry Li (Arm Technology China) 	} else {
414d74b25eSLowry Li (Arm Technology China) 		str->len = str->sz - 1;
424d74b25eSLowry Li (Arm Technology China) 		err = -ENOSPC;
434d74b25eSLowry Li (Arm Technology China) 	}
444d74b25eSLowry Li (Arm Technology China) 
454d74b25eSLowry Li (Arm Technology China) 	return err;
464d74b25eSLowry Li (Arm Technology China) }
474d74b25eSLowry Li (Arm Technology China) 
evt_sprintf(struct komeda_str * str,u64 evt,const char * msg)484d74b25eSLowry Li (Arm Technology China) static void evt_sprintf(struct komeda_str *str, u64 evt, const char *msg)
494d74b25eSLowry Li (Arm Technology China) {
504d74b25eSLowry Li (Arm Technology China) 	if (evt)
514d74b25eSLowry Li (Arm Technology China) 		komeda_sprintf(str, msg);
524d74b25eSLowry Li (Arm Technology China) }
534d74b25eSLowry Li (Arm Technology China) 
evt_str(struct komeda_str * str,u64 events)544d74b25eSLowry Li (Arm Technology China) static void evt_str(struct komeda_str *str, u64 events)
554d74b25eSLowry Li (Arm Technology China) {
564d74b25eSLowry Li (Arm Technology China) 	if (events == 0ULL) {
574d74b25eSLowry Li (Arm Technology China) 		komeda_sprintf(str, "None");
584d74b25eSLowry Li (Arm Technology China) 		return;
594d74b25eSLowry Li (Arm Technology China) 	}
604d74b25eSLowry Li (Arm Technology China) 
614d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_VSYNC, "VSYNC|");
624d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_FLIP, "FLIP|");
634d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_EOW, "EOW|");
644d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_MODE, "OP-MODE|");
654d74b25eSLowry Li (Arm Technology China) 
664d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_URUN, "UNDERRUN|");
674d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_OVR, "OVERRUN|");
684d74b25eSLowry Li (Arm Technology China) 
694d74b25eSLowry Li (Arm Technology China) 	/* GLB error */
704d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|");
714d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
724d74b25eSLowry Li (Arm Technology China) 
734d74b25eSLowry Li (Arm Technology China) 	/* DOU error */
744d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_DRIFTTO, "DRIFTTO|");
754d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
764d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TETO, "TETO|");
774d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_CSCE, "CSCE|");
784d74b25eSLowry Li (Arm Technology China) 
794d74b25eSLowry Li (Arm Technology China) 	/* LPU errors or events */
804d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|");
818f902dbdSjames qian wang (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_EMPTY, "EMPTY|");
828f902dbdSjames qian wang (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_EVENT_FULL, "FULL|");
834d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|");
844d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_ACE0, "ACE0|");
854d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_ACE1, "ACE1|");
864d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_ACE2, "ACE2|");
874d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_ACE3, "ACE3|");
884d74b25eSLowry Li (Arm Technology China) 
894d74b25eSLowry Li (Arm Technology China) 	/* LPU TBU errors*/
904d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TCF, "TCF|");
914d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TTNG, "TTNG|");
924d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TITR, "TITR|");
934d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");
944d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TTF, "TTF|");
954d74b25eSLowry Li (Arm Technology China) 
964d74b25eSLowry Li (Arm Technology China) 	/* CU errors*/
974d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_CPE, "COPROC|");
984d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_ZME, "ZME|");
994d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_CFGE, "CFGE|");
1004d74b25eSLowry Li (Arm Technology China) 	evt_sprintf(str, events & KOMEDA_ERR_TEMR, "TEMR|");
1014d74b25eSLowry Li (Arm Technology China) 
1024d74b25eSLowry Li (Arm Technology China) 	if (str->len > 0 && (str->str[str->len - 1] == '|')) {
1034d74b25eSLowry Li (Arm Technology China) 		str->str[str->len - 1] = 0;
1044d74b25eSLowry Li (Arm Technology China) 		str->len--;
1054d74b25eSLowry Li (Arm Technology China) 	}
1064d74b25eSLowry Li (Arm Technology China) }
1074d74b25eSLowry Li (Arm Technology China) 
is_new_frame(struct komeda_events * a)1084d74b25eSLowry Li (Arm Technology China) static bool is_new_frame(struct komeda_events *a)
1094d74b25eSLowry Li (Arm Technology China) {
1104d74b25eSLowry Li (Arm Technology China) 	return (a->pipes[0] | a->pipes[1]) &
1114d74b25eSLowry Li (Arm Technology China) 	       (KOMEDA_EVENT_FLIP | KOMEDA_EVENT_EOW);
1124d74b25eSLowry Li (Arm Technology China) }
1134d74b25eSLowry Li (Arm Technology China) 
komeda_print_events(struct komeda_events * evts,struct drm_device * dev)1148894cd58SMihail Atanassov void komeda_print_events(struct komeda_events *evts, struct drm_device *dev)
1154d74b25eSLowry Li (Arm Technology China) {
1168894cd58SMihail Atanassov 	u64 print_evts = 0;
1174d74b25eSLowry Li (Arm Technology China) 	static bool en_print = true;
1188894cd58SMihail Atanassov 	struct komeda_dev *mdev = dev->dev_private;
1198894cd58SMihail Atanassov 	u16 const err_verbosity = mdev->err_verbosity;
12039338934SMihail Atanassov 	u64 evts_mask = evts->global | evts->pipes[0] | evts->pipes[1];
1214d74b25eSLowry Li (Arm Technology China) 
1224d74b25eSLowry Li (Arm Technology China) 	/* reduce the same msg print, only print the first evt for one frame */
1234d74b25eSLowry Li (Arm Technology China) 	if (evts->global || is_new_frame(evts))
1244d74b25eSLowry Li (Arm Technology China) 		en_print = true;
125f8fbe33bSMihail Atanassov 	if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT) && !en_print)
1264d74b25eSLowry Li (Arm Technology China) 		return;
1274d74b25eSLowry Li (Arm Technology China) 
1288894cd58SMihail Atanassov 	if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
1298894cd58SMihail Atanassov 		print_evts |= KOMEDA_ERR_EVENTS;
1304039f029SMihail Atanassov 	if (err_verbosity & KOMEDA_DEV_PRINT_WARN_EVENTS)
1314039f029SMihail Atanassov 		print_evts |= KOMEDA_WARN_EVENTS;
1324039f029SMihail Atanassov 	if (err_verbosity & KOMEDA_DEV_PRINT_INFO_EVENTS)
1334039f029SMihail Atanassov 		print_evts |= KOMEDA_INFO_EVENTS;
1348894cd58SMihail Atanassov 
13539338934SMihail Atanassov 	if (evts_mask & print_evts) {
1364d74b25eSLowry Li (Arm Technology China) 		char msg[256];
1374d74b25eSLowry Li (Arm Technology China) 		struct komeda_str str;
13839338934SMihail Atanassov 		struct drm_printer p = drm_info_printer(dev->dev);
1394d74b25eSLowry Li (Arm Technology China) 
1404d74b25eSLowry Li (Arm Technology China) 		str.str = msg;
1414d74b25eSLowry Li (Arm Technology China) 		str.sz  = sizeof(msg);
1424d74b25eSLowry Li (Arm Technology China) 		str.len = 0;
1434d74b25eSLowry Li (Arm Technology China) 
1444d74b25eSLowry Li (Arm Technology China) 		komeda_sprintf(&str, "gcu: ");
1454d74b25eSLowry Li (Arm Technology China) 		evt_str(&str, evts->global);
1464d74b25eSLowry Li (Arm Technology China) 		komeda_sprintf(&str, ", pipes[0]: ");
1474d74b25eSLowry Li (Arm Technology China) 		evt_str(&str, evts->pipes[0]);
1484d74b25eSLowry Li (Arm Technology China) 		komeda_sprintf(&str, ", pipes[1]: ");
1494d74b25eSLowry Li (Arm Technology China) 		evt_str(&str, evts->pipes[1]);
1504d74b25eSLowry Li (Arm Technology China) 
1514d74b25eSLowry Li (Arm Technology China) 		DRM_ERROR("err detect: %s\n", msg);
15239338934SMihail Atanassov 		if ((err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT) &&
15339338934SMihail Atanassov 		    (evts_mask & (KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS)))
15439338934SMihail Atanassov 			drm_state_dump(dev, &p);
1554d74b25eSLowry Li (Arm Technology China) 
1564d74b25eSLowry Li (Arm Technology China) 		en_print = false;
1574d74b25eSLowry Li (Arm Technology China) 	}
1584d74b25eSLowry Li (Arm Technology China) }
159