/*
 * Qualcomm Technologies HIDMA debug file
 *
 * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/pm_runtime.h>

#include "hidma.h"

static void hidma_ll_chstats(struct seq_file *s, void *llhndl, u32 tre_ch)
{
	struct hidma_lldev *lldev = llhndl;
	struct hidma_tre *tre;
	u32 length;
	dma_addr_t src_start;
	dma_addr_t dest_start;
	u32 *tre_local;

	if (tre_ch >= lldev->nr_tres) {
		dev_err(lldev->dev, "invalid TRE number in chstats:%d", tre_ch);
		return;
	}
	tre = &lldev->trepool[tre_ch];
	seq_printf(s, "------Channel %d -----\n", tre_ch);
	seq_printf(s, "allocated=%d\n", atomic_read(&tre->allocated));
	seq_printf(s, "queued = 0x%x\n", tre->queued);
	seq_printf(s, "err_info = 0x%x\n", tre->err_info);
	seq_printf(s, "err_code = 0x%x\n", tre->err_code);
	seq_printf(s, "status = 0x%x\n", tre->status);
	seq_printf(s, "idx = 0x%x\n", tre->idx);
	seq_printf(s, "dma_sig = 0x%x\n", tre->dma_sig);
	seq_printf(s, "dev_name=%s\n", tre->dev_name);
	seq_printf(s, "callback=%p\n", tre->callback);
	seq_printf(s, "data=%p\n", tre->data);
	seq_printf(s, "tre_index = 0x%x\n", tre->tre_index);

	tre_local = &tre->tre_local[0];
	src_start = tre_local[HIDMA_TRE_SRC_LOW_IDX];
	src_start = ((u64) (tre_local[HIDMA_TRE_SRC_HI_IDX]) << 32) + src_start;
	dest_start = tre_local[HIDMA_TRE_DEST_LOW_IDX];
	dest_start += ((u64) (tre_local[HIDMA_TRE_DEST_HI_IDX]) << 32);
	length = tre_local[HIDMA_TRE_LEN_IDX];

	seq_printf(s, "src=%pap\n", &src_start);
	seq_printf(s, "dest=%pap\n", &dest_start);
	seq_printf(s, "length = 0x%x\n", length);
}

static void hidma_ll_devstats(struct seq_file *s, void *llhndl)
{
	struct hidma_lldev *lldev = llhndl;

	seq_puts(s, "------Device -----\n");
	seq_printf(s, "lldev init = 0x%x\n", lldev->initialized);
	seq_printf(s, "trch_state = 0x%x\n", lldev->trch_state);
	seq_printf(s, "evch_state = 0x%x\n", lldev->evch_state);
	seq_printf(s, "chidx = 0x%x\n", lldev->chidx);
	seq_printf(s, "nr_tres = 0x%x\n", lldev->nr_tres);
	seq_printf(s, "trca=%p\n", lldev->trca);
	seq_printf(s, "tre_ring=%p\n", lldev->tre_ring);
	seq_printf(s, "tre_ring_handle=%pap\n", &lldev->tre_dma);
	seq_printf(s, "tre_ring_size = 0x%x\n", lldev->tre_ring_size);
	seq_printf(s, "tre_processed_off = 0x%x\n", lldev->tre_processed_off);
	seq_printf(s, "pending_tre_count=%d\n",
			atomic_read(&lldev->pending_tre_count));
	seq_printf(s, "evca=%p\n", lldev->evca);
	seq_printf(s, "evre_ring=%p\n", lldev->evre_ring);
	seq_printf(s, "evre_ring_handle=%pap\n", &lldev->evre_dma);
	seq_printf(s, "evre_ring_size = 0x%x\n", lldev->evre_ring_size);
	seq_printf(s, "evre_processed_off = 0x%x\n", lldev->evre_processed_off);
	seq_printf(s, "tre_write_offset = 0x%x\n", lldev->tre_write_offset);
}

/*
 * hidma_chan_stats: display HIDMA channel statistics
 *
 * Display the statistics for the current HIDMA virtual channel device.
 */
static int hidma_chan_stats(struct seq_file *s, void *unused)
{
	struct hidma_chan *mchan = s->private;
	struct hidma_desc *mdesc;
	struct hidma_dev *dmadev = mchan->dmadev;

	pm_runtime_get_sync(dmadev->ddev.dev);
	seq_printf(s, "paused=%u\n", mchan->paused);
	seq_printf(s, "dma_sig=%u\n", mchan->dma_sig);
	seq_puts(s, "prepared\n");
	list_for_each_entry(mdesc, &mchan->prepared, node)
		hidma_ll_chstats(s, mchan->dmadev->lldev, mdesc->tre_ch);

	seq_puts(s, "active\n");
	list_for_each_entry(mdesc, &mchan->active, node)
		hidma_ll_chstats(s, mchan->dmadev->lldev, mdesc->tre_ch);

	seq_puts(s, "completed\n");
	list_for_each_entry(mdesc, &mchan->completed, node)
		hidma_ll_chstats(s, mchan->dmadev->lldev, mdesc->tre_ch);

	hidma_ll_devstats(s, mchan->dmadev->lldev);
	pm_runtime_mark_last_busy(dmadev->ddev.dev);
	pm_runtime_put_autosuspend(dmadev->ddev.dev);
	return 0;
}

/*
 * hidma_dma_info: display HIDMA device info
 *
 * Display the info for the current HIDMA device.
 */
static int hidma_dma_info(struct seq_file *s, void *unused)
{
	struct hidma_dev *dmadev = s->private;
	resource_size_t sz;

	seq_printf(s, "nr_descriptors=%d\n", dmadev->nr_descriptors);
	seq_printf(s, "dev_trca=%p\n", &dmadev->dev_trca);
	seq_printf(s, "dev_trca_phys=%pa\n", &dmadev->trca_resource->start);
	sz = resource_size(dmadev->trca_resource);
	seq_printf(s, "dev_trca_size=%pa\n", &sz);
	seq_printf(s, "dev_evca=%p\n", &dmadev->dev_evca);
	seq_printf(s, "dev_evca_phys=%pa\n", &dmadev->evca_resource->start);
	sz = resource_size(dmadev->evca_resource);
	seq_printf(s, "dev_evca_size=%pa\n", &sz);
	return 0;
}

static int hidma_chan_stats_open(struct inode *inode, struct file *file)
{
	return single_open(file, hidma_chan_stats, inode->i_private);
}

static int hidma_dma_info_open(struct inode *inode, struct file *file)
{
	return single_open(file, hidma_dma_info, inode->i_private);
}

static const struct file_operations hidma_chan_fops = {
	.open = hidma_chan_stats_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static const struct file_operations hidma_dma_fops = {
	.open = hidma_dma_info_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

void hidma_debug_uninit(struct hidma_dev *dmadev)
{
	debugfs_remove_recursive(dmadev->debugfs);
}

int hidma_debug_init(struct hidma_dev *dmadev)
{
	int rc = 0;
	int chidx = 0;
	struct list_head *position = NULL;

	dmadev->debugfs = debugfs_create_dir(dev_name(dmadev->ddev.dev), NULL);
	if (!dmadev->debugfs) {
		rc = -ENODEV;
		return rc;
	}

	/* walk through the virtual channel list */
	list_for_each(position, &dmadev->ddev.channels) {
		struct hidma_chan *chan;

		chan = list_entry(position, struct hidma_chan,
				  chan.device_node);
		sprintf(chan->dbg_name, "chan%d", chidx);
		chan->debugfs = debugfs_create_dir(chan->dbg_name,
						   dmadev->debugfs);
		if (!chan->debugfs) {
			rc = -ENOMEM;
			goto cleanup;
		}
		chan->stats = debugfs_create_file("stats", S_IRUGO,
						  chan->debugfs, chan,
						  &hidma_chan_fops);
		if (!chan->stats) {
			rc = -ENOMEM;
			goto cleanup;
		}
		chidx++;
	}

	dmadev->stats = debugfs_create_file("stats", S_IRUGO,
					    dmadev->debugfs, dmadev,
					    &hidma_dma_fops);
	if (!dmadev->stats) {
		rc = -ENOMEM;
		goto cleanup;
	}

	return 0;
cleanup:
	hidma_debug_uninit(dmadev);
	return rc;
}
