1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2010 Google, Inc. 4 * Author: Erik Gilling <konkers@android.com> 5 * 6 * Copyright (C) 2011-2013 NVIDIA Corporation 7 */ 8 9 #include "../dev.h" 10 #include "../debug.h" 11 #include "../cdma.h" 12 #include "../channel.h" 13 14 static void host1x_debug_show_channel_cdma(struct host1x *host, 15 struct host1x_channel *ch, 16 struct output *o) 17 { 18 struct host1x_cdma *cdma = &ch->cdma; 19 dma_addr_t dmastart, dmaend; 20 u32 dmaput, dmaget, dmactrl; 21 u32 cbstat, cbread; 22 u32 val, base, baseval; 23 24 dmastart = host1x_ch_readl(ch, HOST1X_CHANNEL_DMASTART); 25 dmaend = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAEND); 26 dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT); 27 dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET); 28 dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL); 29 cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id)); 30 cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id)); 31 32 host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev)); 33 34 if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) || 35 !ch->cdma.push_buffer.mapped) { 36 host1x_debug_output(o, "inactive\n\n"); 37 return; 38 } 39 40 if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X && 41 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == 42 HOST1X_UCLASS_WAIT_SYNCPT) 43 host1x_debug_output(o, "waiting on syncpt %d val %d\n", 44 cbread >> 24, cbread & 0xffffff); 45 else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == 46 HOST1X_CLASS_HOST1X && 47 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == 48 HOST1X_UCLASS_WAIT_SYNCPT_BASE) { 49 base = (cbread >> 16) & 0xff; 50 baseval = 51 host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base)); 52 val = cbread & 0xffff; 53 host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n", 54 cbread >> 24, baseval + val, base, 55 baseval, val); 56 } else 57 host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n", 58 HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat), 59 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat), 60 cbread); 61 62 host1x_debug_output(o, "DMASTART %pad, DMAEND %pad\n", &dmastart, &dmaend); 63 host1x_debug_output(o, "DMAPUT %08x DMAGET %08x DMACTL %08x\n", 64 dmaput, dmaget, dmactrl); 65 host1x_debug_output(o, "CBREAD %08x CBSTAT %08x\n", cbread, cbstat); 66 67 show_channel_gathers(o, cdma); 68 host1x_debug_output(o, "\n"); 69 } 70 71 static void host1x_debug_show_channel_fifo(struct host1x *host, 72 struct host1x_channel *ch, 73 struct output *o) 74 { 75 u32 val, rd_ptr, wr_ptr, start, end; 76 unsigned int data_count = 0; 77 78 host1x_debug_output(o, "%u: fifo:\n", ch->id); 79 80 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT); 81 host1x_debug_output(o, "FIFOSTAT %08x\n", val); 82 if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) { 83 host1x_debug_output(o, "[empty]\n"); 84 return; 85 } 86 87 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 88 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | 89 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id), 90 HOST1X_SYNC_CFPEEK_CTRL); 91 92 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS); 93 rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val); 94 wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val); 95 96 val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id)); 97 start = HOST1X_SYNC_CF_SETUP_BASE_V(val); 98 end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val); 99 100 do { 101 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 102 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | 103 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) | 104 HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr), 105 HOST1X_SYNC_CFPEEK_CTRL); 106 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); 107 108 if (!data_count) { 109 host1x_debug_output(o, "%08x: ", val); 110 data_count = show_channel_command(o, val, NULL); 111 } else { 112 host1x_debug_cont(o, "%08x%s", val, 113 data_count > 1 ? ", " : "])\n"); 114 data_count--; 115 } 116 117 if (rd_ptr == end) 118 rd_ptr = start; 119 else 120 rd_ptr++; 121 } while (rd_ptr != wr_ptr); 122 123 if (data_count) 124 host1x_debug_cont(o, ", ...])\n"); 125 host1x_debug_output(o, "\n"); 126 127 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 128 } 129 130 static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) 131 { 132 unsigned int i; 133 134 host1x_debug_output(o, "---- mlocks ----\n"); 135 136 for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) { 137 u32 owner = 138 host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i)); 139 if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner)) 140 host1x_debug_output(o, "%u: locked by channel %u\n", 141 i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner)); 142 else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner)) 143 host1x_debug_output(o, "%u: locked by cpu\n", i); 144 else 145 host1x_debug_output(o, "%u: unlocked\n", i); 146 } 147 148 host1x_debug_output(o, "\n"); 149 } 150