/*
 * drivers/amlogic/amports/decoder/decoder_bmmu_box.c
 *
 * Copyright (C) 2015 Amlogic, Inc. 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 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.
 *
 */
#define DEBUG
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/semaphore.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/kfifo.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
#include <linux/platform_device.h>

#include <linux/amlogic/media/video_sink/video_keeper.h>
#include "decoder_bmmu_box.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/codec_mm_keeper.h>

struct decoder_bmmu_box {
	int max_mm_num;
	const char *name;
	int channel_id;
	struct mutex mutex;
	struct list_head list;
	int total_size;
	int box_ref_cnt;
	int change_size_on_need_smaller;
	int align2n;		/*can overwite on idx alloc */
	int mem_flags;		/*can overwite on idx alloc */
	struct codec_mm_s *mm_list[1];
};

struct decoder_bmmu_box_mgr {
	int num;
	struct mutex mutex;
	struct list_head box_list;
};
static struct decoder_bmmu_box_mgr global_blk_mgr;
static struct decoder_bmmu_box_mgr *get_decoder_bmmu_box_mgr(void)
{
	return &global_blk_mgr;
}

static int decoder_bmmu_box_mgr_add_box(struct decoder_bmmu_box *box)
{
	struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr();

	mutex_lock(&mgr->mutex);
	list_add_tail(&box->list, &mgr->box_list);
	mutex_unlock(&mgr->mutex);
	return 0;
}

static int decoder_bmmu_box_mgr_del_box(struct decoder_bmmu_box *box)
{
	struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr();

	mutex_lock(&mgr->mutex);
	list_del(&box->list);
	mutex_unlock(&mgr->mutex);
	return 0;
}

bool decoder_bmmu_box_valide_check(void *box)
{
	struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr();
	struct decoder_bmmu_box *bmmu_box = NULL;
	bool is_valide = false;

	mutex_lock(&mgr->mutex);
	list_for_each_entry(bmmu_box, &mgr->box_list, list) {
		if (bmmu_box && bmmu_box == box) {
			is_valide = true;
			break;
		}
	}
	mutex_unlock(&mgr->mutex);

	return is_valide;
}
EXPORT_SYMBOL(decoder_bmmu_box_valide_check);

void *decoder_bmmu_box_alloc_box(const char *name,
		int channel_id, int max_num,
		int aligned, int mem_flags)
/*min_size_M:wait alloc this size*/
{
	struct decoder_bmmu_box *box;
	int size;
	int tvp_flags;
	tvp_flags = (mem_flags & CODEC_MM_FLAGS_TVP) ?
		CODEC_MM_FLAGS_TVP : 0;

	pr_debug("decoder_bmmu_box_alloc_box, tvp_flags = %x\n", tvp_flags);

	size = sizeof(struct decoder_bmmu_box) + sizeof(struct codec_mm_s *) *
		   max_num;
	box = kmalloc(size, GFP_KERNEL);
	if (!box) {
		pr_err("can't alloc decoder buffers box!!!\n");
		return NULL;
	}
	memset(box, 0, size);
	box->max_mm_num = max_num;
	box->name = name;
	box->channel_id = channel_id;
	box->align2n = aligned;
	box->mem_flags = mem_flags | tvp_flags;
	mutex_init(&box->mutex);
	INIT_LIST_HEAD(&box->list);
	decoder_bmmu_box_mgr_add_box(box);
	return (void *)box;
}
EXPORT_SYMBOL(decoder_bmmu_box_alloc_box);

int decoder_bmmu_box_alloc_idx(void *handle, int idx, int size, int aligned_2n,
							   int mem_flags)
/*align& flags if -1 user box default.*/
{
	struct decoder_bmmu_box *box = handle;
	struct codec_mm_s *mm;
	int align = aligned_2n;
	int memflags = mem_flags;

	if (!box || idx < 0 || idx >= box->max_mm_num) {
		pr_err("can't alloc bmmu box(%p),idx:%d\n",
				box, idx);
		return -1;
	}
	if (align == -1)
		align = box->align2n;
	if (memflags == -1)
		memflags = box->mem_flags;

	mutex_lock(&box->mutex);
	mm = box->mm_list[idx];
	if (mm) {
		int invalid = 0;
		int keeped = 0;

		keeped = is_codec_mm_keeped(mm);
		if (!keeped) {
			if (mm->page_count * PAGE_SIZE < size) {
				/*size is small. */
				invalid = 1;
			} else if (box->change_size_on_need_smaller &&
					   (mm->buffer_size > (size << 1))) {
				/*size is too large. */
				invalid = 2;
			} else if (mm->phy_addr & ((1 << align) - 1)) {
				/*addr is not align */
				invalid = 4;
			}
			if (invalid) {
				box->total_size -= mm->buffer_size;
				codec_mm_release(mm, box->name);
				box->mm_list[idx] = NULL;
				mm = NULL;
			}
		} else {
			box->total_size -= mm->buffer_size;
			codec_mm_release(mm, box->name);
			box->mm_list[idx] = NULL;
			mm = NULL;
		}
	}
	if (!mm) {
		mm = codec_mm_alloc(box->name, size, align, memflags);
		if (mm) {
			box->mm_list[idx] = mm;
			box->total_size += mm->buffer_size;
			mm->ins_id = box->channel_id;
			mm->ins_buffer_id = idx;
			box->box_ref_cnt++;
		}
	}
	mutex_unlock(&box->mutex);
	return mm ? 0 : -ENOMEM;
}

int decoder_bmmu_box_free_idx(void *handle, int idx)
{
	struct decoder_bmmu_box *box = handle;
	struct codec_mm_s *mm;

	if (!box || idx < 0 || idx >= box->max_mm_num) {
		pr_err("can't free idx of box(%p),idx:%d  in (%d-%d)\n",
				box, idx, 0,
			   box ? (box->max_mm_num - 1) : 0);
		return -1;
	}
	mutex_lock(&box->mutex);
	mm = box->mm_list[idx];
	if (mm) {
		box->total_size -= mm->buffer_size;
		codec_mm_release(mm, box->name);
		box->mm_list[idx] = NULL;
		mm = NULL;
		box->box_ref_cnt--;
	}
	mutex_unlock(&box->mutex);
	return 0;
}
EXPORT_SYMBOL(decoder_bmmu_box_free_idx);

int decoder_bmmu_box_free(void *handle)
{
	struct decoder_bmmu_box *box = handle;
	struct codec_mm_s *mm;
	int i;

	if (!box) {
		pr_err("can't free box of NULL box!\n");
		return -1;
	}
	mutex_lock(&box->mutex);
	for (i = 0; i < box->max_mm_num; i++) {
		mm = box->mm_list[i];
		if (mm) {
			codec_mm_release(mm, box->name);
			box->mm_list[i] = NULL;
		}
	}
	mutex_unlock(&box->mutex);
	decoder_bmmu_box_mgr_del_box(box);
	kfree(box);
	return 0;
}
EXPORT_SYMBOL(decoder_bmmu_box_free);

void decoder_bmmu_try_to_release_box(void *handle)
{
	struct decoder_bmmu_box *box = handle;
	bool is_keep = false;
	int i;

	if (!box || box->box_ref_cnt)
		return;

	mutex_lock(&box->mutex);
	for (i = 0; i < box->max_mm_num; i++) {
		if (box->mm_list[i]) {
			is_keep = true;
			break;
		}
	}
	mutex_unlock(&box->mutex);

	if (!is_keep) {
		decoder_bmmu_box_mgr_del_box(box);
		kfree(box);
	}
}
EXPORT_SYMBOL(decoder_bmmu_try_to_release_box);

void *decoder_bmmu_box_get_mem_handle(void *box_handle, int idx)
{
	struct decoder_bmmu_box *box = box_handle;

	if (!box || idx < 0 || idx >= box->max_mm_num)
		return NULL;
	return box->mm_list[idx];
}
EXPORT_SYMBOL(decoder_bmmu_box_get_mem_handle);

int decoder_bmmu_box_get_mem_size(void *box_handle, int idx)
{
	struct decoder_bmmu_box *box = box_handle;
	int size = 0;

	if (!box || idx < 0 || idx >= box->max_mm_num)
		return 0;
	mutex_lock(&box->mutex);
	if (box->mm_list[idx] != NULL)
		size = box->mm_list[idx]->buffer_size;
	mutex_unlock(&box->mutex);
	return size;
}


unsigned long decoder_bmmu_box_get_phy_addr(void *box_handle, int idx)
{
	struct decoder_bmmu_box *box = box_handle;
	struct codec_mm_s *mm;

	if (!box || idx < 0 || idx >= box->max_mm_num)
		return 0;
	mm = box->mm_list[idx];
	if (!mm)
		return 0;
	return mm->phy_addr;
}
EXPORT_SYMBOL(decoder_bmmu_box_get_phy_addr);

void *decoder_bmmu_box_get_virt_addr(void *box_handle, int idx)
{
	struct decoder_bmmu_box *box = box_handle;
	struct codec_mm_s *mm;

	if (!box || idx < 0 || idx >= box->max_mm_num)
		return NULL;
	mm = box->mm_list[idx];
	if (!mm)
		return 0;
	return codec_mm_phys_to_virt(mm->phy_addr);
}

/*flags: &0x1 for wait,*/
int decoder_bmmu_box_check_and_wait_size(int size, int flags, int mem_flags)
{
	if ((flags & BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER) &&
		codec_mm_get_free_size() < size) {
		pr_err("CMA force free keep,for size = %d\n", size);
		/*need free others?
		 */
		try_free_keep_video(1);
	}

	return codec_mm_enough_for_size(size,
			flags & BMMU_ALLOC_FLAGS_WAIT, mem_flags);
}

int decoder_bmmu_box_alloc_idx_wait(
	void *handle, int idx,
	int size, int aligned_2n,
	int mem_flags,
	int wait_flags)
{
	int have_space;
	int ret = -1;
	int keeped = 0;

	if (decoder_bmmu_box_get_mem_size(handle, idx) >= size) {
		struct decoder_bmmu_box *box = handle;
		struct codec_mm_s *mm;
		mutex_lock(&box->mutex);
		mm = box->mm_list[idx];
		keeped = is_codec_mm_keeped(mm);
		mutex_unlock(&box->mutex);

		if (!keeped)
			return 0;/*have alloced memery before.*/
	}
	have_space = decoder_bmmu_box_check_and_wait_size(
					size,
					wait_flags,
					mem_flags);
	if (have_space) {
		ret = decoder_bmmu_box_alloc_idx(handle,
				idx, size, aligned_2n, mem_flags);
		if (ret == -ENOMEM) {
			pr_info("bmmu alloc idx fail, try free keep video.\n");
			try_free_keep_video(1);
		}
	} else {
		try_free_keep_video(1);
		ret = -ENOMEM;
	}
	return ret;
}
EXPORT_SYMBOL(decoder_bmmu_box_alloc_idx_wait);

int decoder_bmmu_box_alloc_buf_phy(
	void *handle, int idx,
	int size, unsigned char *driver_name,
	unsigned long *buf_phy_addr)
{
	struct decoder_bmmu_box *bmmu_box = (struct decoder_bmmu_box *)handle;

	if (bmmu_box == NULL)
		return -EINVAL;

	if (!decoder_bmmu_box_check_and_wait_size(
			size,
			1, bmmu_box->mem_flags)) {
		pr_info("%s not enough buf for buf_idx = %d\n",
					driver_name, idx);
		return	-ENOMEM;
	}
	if (!decoder_bmmu_box_alloc_idx_wait(
			handle,
			idx,
			size,
			-1,
			bmmu_box->mem_flags,
			BMMU_ALLOC_FLAGS_WAITCLEAR)) {
		*buf_phy_addr =
			decoder_bmmu_box_get_phy_addr(
			handle,
			idx);
		/*
		 *pr_info("%s malloc buf_idx = %d addr = %ld size = %d\n",
		 *	driver_name, idx, *buf_phy_addr, size);
		 */
		} else {
			pr_info("%s malloc failed  %d\n", driver_name, idx);
			return -ENOMEM;
	}

	return 0;
}
EXPORT_SYMBOL(decoder_bmmu_box_alloc_buf_phy);

int decoder_bmmu_box_add_callback_func(
	void *handle, int idx,
	void *cb)
{
	struct decoder_bmmu_box *box = handle;
	struct codec_mm_s *mm;

	if (!box || idx < 0 || idx >= box->max_mm_num)
		return 0;

	mutex_lock(&box->mutex);
	mm = box->mm_list[idx];
	codec_mm_add_release_callback(mm, (struct codec_mm_cb_s *)cb);
	mutex_unlock(&box->mutex);

	return 0;
}
EXPORT_SYMBOL(decoder_bmmu_box_add_callback_func);

static int decoder_bmmu_box_dump(struct decoder_bmmu_box *box, void *buf,
								 int size)
{
	char *pbuf = buf;
	char sbuf[512];
	int tsize = 0;
	int s;
	int i;

	if (!buf) {
		pbuf = sbuf;
		size = 512;
	}
#define BUFPRINT(args...) \
	do {\
		s = snprintf(pbuf, size - tsize, args);\
		tsize += s;\
		pbuf += s; \
	} while (0)

	for (i = 0; i < box->max_mm_num; i++) {
		struct codec_mm_s *mm = box->mm_list[i];
		if (buf && (size - tsize) < 256) {
			BUFPRINT("\n\t**NOT END**\n");
			break;
		}
		if (mm) {
			BUFPRINT("code mem[%d]:%p, addr=%p, size=%d,from=%d\n",
					 i,
					 (void *)mm,
					 (void *)mm->phy_addr,
					 mm->buffer_size,
					 mm->from_flags);
			if (!buf) {
				pr_info("%s", sbuf);
				pbuf = sbuf;
			}
		}
	}
#undef BUFPRINT

	return tsize;
}

static int decoder_bmmu_box_dump_all(void *buf, int size)
{
	struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr();
	char *pbuf = buf;
	char sbuf[512];
	int tsize = 0;
	int s;
	int i;
	struct list_head *head, *list;

	if (!buf) {
		pbuf = sbuf;
		size = 512;
	}
#define BUFPRINT(args...) \
	do {\
		s = snprintf(pbuf, size - tsize, args);\
		tsize += s;\
		pbuf += s; \
	} while (0)

	mutex_lock(&mgr->mutex);
	head = &mgr->box_list;
	list = head->next;
	i = 0;
	while (list != head) {
		struct decoder_bmmu_box *box;

		box = list_entry(list, struct decoder_bmmu_box, list);
		BUFPRINT("box[%d]: %s, %splayer_id:%d, max_num:%d, size:%d\n",
				 i, box->name,
				 (box->mem_flags & CODEC_MM_FLAGS_TVP) ?
				 "TVP mode " : "",
				 box->channel_id,
				 box->max_mm_num,
				 box->total_size);
		if (buf) {
			s = decoder_bmmu_box_dump(box, pbuf, size - tsize);
			if (s > 0) {
				tsize += s;
				pbuf += s;
			}
		} else {
			pr_info("%s", sbuf);
			pbuf = sbuf;
			tsize += decoder_bmmu_box_dump(box, NULL, 0);
		}
		list = list->next;
		i++;
	}
	mutex_unlock(&mgr->mutex);

#undef BUFPRINT
	if (!buf)
		pr_info("%s", sbuf);
	return tsize;
}

static ssize_t box_dump_show(struct class *class, struct class_attribute *attr,
							 char *buf)
{
	ssize_t ret = 0;

	ret = decoder_bmmu_box_dump_all(buf, PAGE_SIZE);
	return ret;
}

static ssize_t debug_show(struct class *class,
		struct class_attribute *attr,
		char *buf)
{
	ssize_t size = 0;
	size += sprintf(buf, "box debug help:\n");
	size += sprintf(buf + size, "echo n > debug\n");
	size += sprintf(buf + size, "n==0: clear all debugs)\n");
	size += sprintf(buf + size,
	"n=1: dump all box\n");

	return size;
}

static ssize_t debug_store(struct class *class,
		struct class_attribute *attr,
		const char *buf, size_t size)
{
	unsigned val;
	ssize_t ret;
	val = -1;
	ret = sscanf(buf, "%d", &val);
	if (ret != 1)
		return -EINVAL;
	switch (val) {
	case 1:
		decoder_bmmu_box_dump_all(NULL , 0);
		break;
	default:
		pr_err("unknow cmd! %d\n", val);
	}
	return size;

}

static CLASS_ATTR_RO(box_dump);
static CLASS_ATTR_RW(debug);

static struct attribute *decoder_bmmu_box_class_attrs[] = {
	&class_attr_box_dump.attr,
	&class_attr_debug.attr,
	NULL
};

ATTRIBUTE_GROUPS(decoder_bmmu_box_class);

static struct class decoder_bmmu_box_class = {
	.name = "decoder_bmmu_box",
	.class_groups = decoder_bmmu_box_class_groups,
};

int decoder_bmmu_box_init(void)
{
	int r;

	memset(&global_blk_mgr, 0, sizeof(global_blk_mgr));
	INIT_LIST_HEAD(&global_blk_mgr.box_list);
	mutex_init(&global_blk_mgr.mutex);
	r = class_register(&decoder_bmmu_box_class);
	return r;
}
EXPORT_SYMBOL(decoder_bmmu_box_init);

void decoder_bmmu_box_exit(void)
{
	class_unregister(&decoder_bmmu_box_class);
	pr_info("dec bmmu box exit.\n");
}

#if 0
static int __init decoder_bmmu_box_init(void)
{
	int r;

	memset(&global_blk_mgr, 0, sizeof(global_blk_mgr));
	INIT_LIST_HEAD(&global_blk_mgr.box_list);
	mutex_init(&global_blk_mgr.mutex);
	r = class_register(&decoder_bmmu_box_class);
	return r;
}

module_init(decoder_bmmu_box_init);
#endif
