/*
   forward-vdma.h - VideoDMA driver for SoftLab-NSK Forward video boards

   Copyright (C) 2017 - 2024 SoftLab-NSK <forward@softlab.tv>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   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.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef FORWARD_VDMA_H
#define FORWARD_VDMA_H

#include "forward.h"
#include <linux/pm_qos.h>

struct forward_vdma_region {
	void *owner;
	u32 vdma_address;
	u32 size;
	struct list_head item;
};

struct forward_vdma {
	struct forward_dev *dev;
	bool dma44bit;
	struct pm_qos_request qos;

	unsigned int map_size;
	u32 *map;
	dma_addr_t map_addr;

	u32 *descriptors;

	struct page **pages;

	unsigned long *rw_bitmap;
	unsigned long *user_bitmap;

	u32 *dummy_rd;
	dma_addr_t dummy_rd_addr;
	u32 *dummy_wr;
	dma_addr_t dummy_wr_addr;

	struct list_head regions;

	spinlock_t lock, rlock;
};

int forward_vdma_probe(struct forward_dev *dev);
void forward_vdma_remove(struct forward_dev *dev);

void forward_vdma_enable(struct forward_dev *dev);
void forward_vdma_disable(struct forward_dev *dev);

int forward_vdma_init_region(struct forward_vdma *vdma, u64 vdma_address, size_t size, bool read);

int forward_vdma_get_region(struct forward_vdma *vdma, void *owner, u64 vdma_address, size_t size);
int forward_vdma_put_region(struct forward_vdma *vdma, void *owner, u64 vdma_address);
void forward_vdma_put_all_regions(struct forward_vdma *vdma, void *owner);

int forward_vdma_map_user_buf(struct forward_vdma *vdma, void *owner, void __user *address,
			      u64 vdma_address, size_t size, bool read);
int forward_vdma_map_kernel_buf(struct forward_vdma *vdma, void *owner, void *address,
				u64 vdma_address, size_t size, bool read);

int forward_vdma_unmap_buf(struct forward_vdma *vdma, void *owner, u64 vdma_address, size_t size);

void forward_vdma_sync_buf(struct forward_vdma *vdma, void *owner, u64 vdma_address, size_t size);

void forward_vdma_debug_show_map(struct forward_vdma *vdma);

#endif
