linux/drivers/gpu/host1x/hw/debug_hw_1x06.c
<<
>>
Prefs
   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-2017 NVIDIA Corporation
   7 */
   8
   9#include "../dev.h"
  10#include "../debug.h"
  11#include "../cdma.h"
  12#include "../channel.h"
  13
  14static 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 = 0, dmaend = 0;
  20        u32 dmaput, dmaget, dmactrl;
  21        u32 offset, class;
  22        u32 ch_stat;
  23
  24#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && HOST1X_HW >= 6
  25        dmastart = host1x_ch_readl(ch, HOST1X_CHANNEL_DMASTART_HI);
  26        dmastart <<= 32;
  27#endif
  28        dmastart |= host1x_ch_readl(ch, HOST1X_CHANNEL_DMASTART);
  29
  30#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && HOST1X_HW >= 6
  31        dmaend = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAEND_HI);
  32        dmaend <<= 32;
  33#endif
  34        dmaend |= host1x_ch_readl(ch, HOST1X_CHANNEL_DMAEND);
  35
  36        dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT);
  37        dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET);
  38        dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL);
  39        offset = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_OFFSET);
  40        class = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CLASS);
  41        ch_stat = host1x_ch_readl(ch, HOST1X_CHANNEL_CHANNELSTAT);
  42
  43        host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev));
  44
  45        if (dmactrl & HOST1X_CHANNEL_DMACTRL_DMASTOP ||
  46            !ch->cdma.push_buffer.mapped) {
  47                host1x_debug_output(o, "inactive\n\n");
  48                return;
  49        }
  50
  51        if (class == HOST1X_CLASS_HOST1X && offset == HOST1X_UCLASS_WAIT_SYNCPT)
  52                host1x_debug_output(o, "waiting on syncpt\n");
  53        else
  54                host1x_debug_output(o, "active class %02x, offset %04x\n",
  55                                    class, offset);
  56
  57        host1x_debug_output(o, "DMASTART %pad, DMAEND %pad\n", &dmastart, &dmaend);
  58        host1x_debug_output(o, "DMAPUT %08x DMAGET %08x DMACTL %08x\n",
  59                            dmaput, dmaget, dmactrl);
  60        host1x_debug_output(o, "CHANNELSTAT %02x\n", ch_stat);
  61
  62        show_channel_gathers(o, cdma);
  63        host1x_debug_output(o, "\n");
  64}
  65
  66static void host1x_debug_show_channel_fifo(struct host1x *host,
  67                                           struct host1x_channel *ch,
  68                                           struct output *o)
  69{
  70#if HOST1X_HW <= 6
  71        u32 rd_ptr, wr_ptr, start, end;
  72        u32 payload = INVALID_PAYLOAD;
  73        unsigned int data_count = 0;
  74#endif
  75        u32 val;
  76
  77        host1x_debug_output(o, "%u: fifo:\n", ch->id);
  78
  79        val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_STAT);
  80        host1x_debug_output(o, "CMDFIFO_STAT %08x\n", val);
  81        if (val & HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY) {
  82                host1x_debug_output(o, "[empty]\n");
  83                return;
  84        }
  85
  86        val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_RDATA);
  87        host1x_debug_output(o, "CMDFIFO_RDATA %08x\n", val);
  88
  89#if HOST1X_HW <= 6
  90        /* Peek pointer values are invalid during SLCG, so disable it */
  91        host1x_hypervisor_writel(host, 0x1, HOST1X_HV_ICG_EN_OVERRIDE);
  92
  93        val = 0;
  94        val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
  95        val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
  96        host1x_hypervisor_writel(host, val, HOST1X_HV_CMDFIFO_PEEK_CTRL);
  97
  98        val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_PEEK_PTRS);
  99        rd_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(val);
 100        wr_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(val);
 101
 102        val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_SETUP(ch->id));
 103        start = HOST1X_HV_CMDFIFO_SETUP_BASE_V(val);
 104        end = HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(val);
 105
 106        do {
 107                val = 0;
 108                val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
 109                val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
 110                val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(rd_ptr);
 111                host1x_hypervisor_writel(host, val,
 112                                         HOST1X_HV_CMDFIFO_PEEK_CTRL);
 113
 114                val = host1x_hypervisor_readl(host,
 115                                              HOST1X_HV_CMDFIFO_PEEK_READ);
 116
 117                if (!data_count) {
 118                        host1x_debug_output(o, "%03x 0x%08x: ",
 119                                            rd_ptr - start, val);
 120                        data_count = show_channel_command(o, val, &payload);
 121                } else {
 122                        host1x_debug_cont(o, "%08x%s", val,
 123                                          data_count > 1 ? ", " : "])\n");
 124                        data_count--;
 125                }
 126
 127                if (rd_ptr == end)
 128                        rd_ptr = start;
 129                else
 130                        rd_ptr++;
 131        } while (rd_ptr != wr_ptr);
 132
 133        if (data_count)
 134                host1x_debug_cont(o, ", ...])\n");
 135        host1x_debug_output(o, "\n");
 136
 137        host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL);
 138        host1x_hypervisor_writel(host, 0x0, HOST1X_HV_ICG_EN_OVERRIDE);
 139#endif
 140}
 141
 142static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
 143{
 144        /* TODO */
 145}
 146