deinterlace: add di-multi v2 [1/3]

PD#SWPL-10064

Problem:
Prepare for adding multi-di

Solution:
1. add di_local for reserved mem alloc;
2. add dil_attach_ext_api for di_api;
3. move some setting to prob;
4. add interface for di pq;

Verify:
U212

Change-Id: I023694dffabed47fd62ec3fa90b8de9302ac341e
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>

Conflicts:
	MAINTAINERS
This commit is contained in:
Jihong Sui
2019-08-05 13:33:34 +08:00
committed by Luke Go
parent 288a06b00e
commit ab73ff8a48
15 changed files with 693 additions and 11 deletions

View File

@@ -89,6 +89,7 @@ source "drivers/amlogic/media/vout/Kconfig"
source "drivers/amlogic/media/osd/Kconfig"
source "drivers/amlogic/media/osd_ext/Kconfig"
source "drivers/amlogic/media/deinterlace/Kconfig"
source "drivers/amlogic/media/di_local/Kconfig"
source "drivers/amlogic/media/vin/Kconfig"
source "drivers/amlogic/media/video_processor/Kconfig"
source "drivers/amlogic/media/enhancement/Kconfig"

View File

@@ -5,6 +5,7 @@ obj-$(CONFIG_AMLOGIC_MEDIA_FB) += osd/
obj-$(CONFIG_AMLOGIC_MEDIA_FB_EXT) += osd_ext/
obj-$(CONFIG_AMLOGIC_VOUT) += vout/
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += di_local/
obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/
obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR) += video_processor/
obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/

View File

@@ -66,6 +66,8 @@
#include "deinterlace_dbg.h"
#include "nr_downscale.h"
#include "di_pps.h"
#include "di_pqa.h"
#define CREATE_TRACE_POINTS
#include "deinterlace_trace.h"
@@ -409,6 +411,7 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val,
VSYNC_WR_MPEG_REG_BITS(addr, val, start, len);
}
#if 0
unsigned int DI_POST_REG_RD(unsigned int addr)
{
if (IS_ERR_OR_NULL(de_devp))
@@ -432,6 +435,35 @@ int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
}
EXPORT_SYMBOL(DI_POST_WR_REG_BITS);
#else
static unsigned int lDI_POST_REG_RD(unsigned int addr)
{
if (IS_ERR_OR_NULL(de_devp))
return 0;
if (de_devp->flags & DI_SUSPEND_FLAG) {
pr_err("[DI] REG 0x%x access prohibited.\n", addr);
return 0;
}
return VSYNC_RD_MPEG_REG(addr);
}
static int lDI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
{
if (IS_ERR_OR_NULL(de_devp))
return 0;
if (de_devp->flags & DI_SUSPEND_FLAG) {
pr_err("[DI] REG 0x%x access prohibited.\n", adr);
return -1;
}
return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
}
static const struct di_ext_ops di_ext = {
.di_post_reg_rd = lDI_POST_REG_RD,
.di_post_wr_reg_bits = lDI_POST_WR_REG_BITS,
};
#endif
/**********************************/
/*****************************
@@ -677,7 +709,7 @@ static int __init di_read_canvas_reverse(char *str)
{
unsigned char *ptr = str;
pr_dbg("%s: bootargs is %s.\n", __func__, str);
di_pr_info("%s: bootargs is %s.\n", __func__, str);
if (strstr(ptr, "1")) {
invert_top_bot |= 0x1;
overturn = true;
@@ -8007,6 +8039,7 @@ show_frame_format(struct device *dev,
}
static DEVICE_ATTR(frame_format, 0444, show_frame_format, NULL);
#if 0 /*move to di_local.c*/
static int __init rmem_di_device_init(struct reserved_mem *rmem,
struct device *dev)
{
@@ -8037,6 +8070,7 @@ static void rmem_di_device_release(struct reserved_mem *rmem,
di_devp->mem_size = 0;
}
}
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
unsigned int RDMA_RD_BITS(unsigned int adr, unsigned int start,
unsigned int len)
@@ -8185,6 +8219,7 @@ static void set_di_flag(void)
mtn_int_combing_glbmot();
}
#if 0 /*move to di_local.c*/
static const struct reserved_mem_ops rmem_di_ops = {
.device_init = rmem_di_device_init,
.device_release = rmem_di_device_release,
@@ -8202,7 +8237,7 @@ static int __init rmem_di_setup(struct reserved_mem *rmem)
return 0;
}
RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup);
#endif
static void di_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev)
{
@@ -8254,6 +8289,23 @@ static int di_probe(struct platform_device *pdev)
int ret = 0;
struct di_dev_s *di_devp = NULL;
di_pr_info("%s:\n", __func__);
#if 1 /*move from init*/
ret = alloc_chrdev_region(&di_devno, 0, DI_COUNT, DEVICE_NAME);
if (ret < 0) {
pr_err("%s: failed to allocate major number\n", __func__);
goto fail_alloc_cdev_region;
}
di_pr_info("%s: major %d\n", __func__, MAJOR(di_devno));
di_clsp = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(di_clsp)) {
ret = PTR_ERR(di_clsp);
pr_err("%s: failed to create class\n", __func__);
goto fail_class_create;
}
#endif
di_devp = kmalloc(sizeof(struct di_dev_s), GFP_KERNEL);
if (!di_devp) {
pr_err("%s fail to allocate memory.\n", __func__);
@@ -8440,7 +8492,9 @@ static int di_probe(struct platform_device *pdev)
di_debugfs_init(); /*2018-07-18 add debugfs*/
di_patch_post_update_mc_sw(DI_MC_SW_IC, true);
pr_info("%s:ok\n", __func__);
dil_attach_ext_api(&di_ext);
di_pr_info("%s:ok\n", __func__);
return ret;
fail_cdev_add:
@@ -8448,13 +8502,20 @@ fail_cdev_add:
kfree(di_devp);
fail_kmalloc_dev:
#if 1 /*move from init*/
class_destroy(di_clsp);
fail_class_create:
unregister_chrdev_region(di_devno, DI_COUNT);
fail_alloc_cdev_region:
return ret;
#endif
}
static int di_remove(struct platform_device *pdev)
{
struct di_dev_s *di_devp = NULL;
di_pr_info("%s:\n", __func__);
di_devp = platform_get_drvdata(pdev);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
@@ -8505,11 +8566,17 @@ static int di_remove(struct platform_device *pdev)
}
device_destroy(di_clsp, di_devno);
#if 1 /*move from exit*/
class_destroy(di_clsp);
di_debugfs_exit();
unregister_chrdev_region(di_devno, DI_COUNT);
#endif
kfree(di_devp);
/* free drvdata */
dev_set_drvdata(&pdev->dev, NULL);
platform_set_drvdata(pdev, NULL);
di_pr_info("%s:ok\n", __func__);
return 0;
}
@@ -8656,7 +8723,7 @@ static int __init di_module_init(void)
int ret = 0;
di_pr_info("%s ok.\n", __func__);
#if 0 /*move to prob*/
ret = alloc_chrdev_region(&di_devno, 0, DI_COUNT, DEVICE_NAME);
if (ret < 0) {
pr_err("%s: failed to allocate major number\n", __func__);
@@ -8669,26 +8736,30 @@ static int __init di_module_init(void)
pr_err("%s: failed to create class\n", __func__);
goto fail_class_create;
}
#endif
ret = platform_driver_register(&di_driver);
if (ret != 0) {
pr_err("%s: failed to register driver\n", __func__);
goto fail_pdrv_register;
return -ENODEV;//goto fail_pdrv_register;
}
return 0;
#if 0 /*move to prob*/
fail_pdrv_register:
class_destroy(di_clsp);
fail_class_create:
unregister_chrdev_region(di_devno, DI_COUNT);
fail_alloc_cdev_region:
return ret;
#endif
}
static void __exit di_module_exit(void)
{
#if 0 /*move to remove*/
class_destroy(di_clsp);
di_debugfs_exit();
unregister_chrdev_region(di_devno, DI_COUNT);
#endif
platform_driver_unregister(&di_driver);
}

View File

@@ -25,9 +25,8 @@
#include <linux/clk.h>
#include <linux/atomic.h>
#include "deinterlace_hw.h"
#include "pulldown_drv.h"
#include "nr_drv.h"
#include "../di_local/di_local.h"
/*trigger_pre_di_process param*/
#define TRIGGER_PRE_BY_PUT 'p'
#define TRIGGER_PRE_BY_DE_IRQ 'i'
@@ -454,6 +453,7 @@ u32 di_requeset_afbc(u32 onoff);
extern bool di_wr_cue_int(void);
extern int reg_cue_int_show(struct seq_file *seq, void *v);
bool dil_attach_ext_api(const struct di_ext_ops *di_api);
/*---------------------*/
struct di_buf_s *get_di_buf(int queue_idx, int *start_pos);

View File

@@ -18,7 +18,7 @@
#ifndef _DI_HW_H
#define _DI_HW_H
#include <linux/amlogic/media/amvecm/amvecm.h>
#include "pulldown_drv.h"
#include "di_pqa.h"
#include "nr_drv.h"
/* if post size < 80, filter of ei can't work */

View File

@@ -41,6 +41,7 @@
#include "register.h"
#include "deinterlace_mtn.h"
#include "di_pqa.h"
#define MAX_NUM_DI_REG 32
#define GXTVBB_REG_START 12
static unsigned int combing_setting_registers[MAX_NUM_DI_REG] = {
@@ -812,3 +813,26 @@ int adaptive_combing_fixing(
#ifdef DEBUG_SUPPORT
module_param_named(cmb_adpset_cnt, cmb_adpset_cnt, int, 0644);
#endif
static const struct mtn_op_s di_ops_mtn = {
.mtn_int_combing_glbmot = mtn_int_combing_glbmot,
.adpative_combing_exit = adpative_combing_exit,
.fix_tl1_1080i_sawtooth_patch = fix_tl1_1080i_sawtooth_patch,
.adaptive_combing_fixing = adaptive_combing_fixing,
.adpative_combing_config = adpative_combing_config,
/*.module_para = dim_seq_file_module_para_mtn,*/
};
bool di_attach_ops_mtn(const struct mtn_op_s **ops)
{
#if 0
if (!ops)
return false;
memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
#else
*ops = &di_ops_mtn;
#endif
return true;
}
EXPORT_SYMBOL(di_attach_ops_mtn);

View File

@@ -26,6 +26,7 @@
#include "register_nr4.h"
#include "detect3d.h"
#include "di_pqa.h"
/*******************Local defines**********************/
#define DET3D_REG_NUM 9
/* the number of total register */
@@ -442,3 +443,23 @@ MODULE_PARM_DESC(chessbd_vrate, "\n the chessboard 3d fmt vertical rate\n");
module_param(det3d_debug, bool, 0644);
MODULE_PARM_DESC(det3d_debug, "\n print the information of 3d detection\n");
static const struct detect3d_op_s di_ops_3d = {
.det3d_config = det3d_config,
.det3d_fmt_detect = det3d_fmt_detect,
/*.module_para = dim_seq_file_module_para_3d,*/
};
bool di_attach_ops_3d(const struct detect3d_op_s **ops)
{
#if 0
if (!ops)
return false;
memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
#else
*ops = &di_ops_3d;
#endif
return true;
}
EXPORT_SYMBOL(di_attach_ops_3d);

View File

@@ -0,0 +1,131 @@
/*
* drivers/amlogic/media/deinterlace/di_pqa.h
*
* Copyright (C) 2017 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.
*
*/
#ifndef __DI_PQA_H__
#define __DI_PQA_H__
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/device.h>
#include "../deinterlace/pulldown_drv.h"
#include "../deinterlace/deinterlace_mtn.h"
#if 0 /*move from pulldown_drv.h to di_pq.h*/
enum pulldown_mode_e {
PULL_DOWN_BLEND_0 = 0,/* buf1=dup[0] */
PULL_DOWN_BLEND_2 = 1,/* buf1=dup[2] */
PULL_DOWN_MTN = 2,/* mtn only */
PULL_DOWN_BUF1 = 3,/* do wave with dup[0] */
PULL_DOWN_EI = 4,/* ei only */
PULL_DOWN_NORMAL = 5,/* normal di */
PULL_DOWN_NORMAL_2 = 6,/* di */
};
struct pulldown_vof_win_s {
unsigned short win_vs;
unsigned short win_ve;
enum pulldown_mode_e blend_mode;
};
struct pulldown_detected_s {
enum pulldown_mode_e global_mode;
struct pulldown_vof_win_s regs[4];
};
#endif
#if 0 /*move from deinterlace_mtn.h*/
struct combing_status_s {
unsigned int frame_diff_avg;
unsigned int cmb_row_num;
unsigned int field_diff_rate;
int like_pulldown22_flag;
unsigned int cur_level;
};
#endif
/**************************
* pulldown
*************************/
struct pulldown_op_s {
unsigned char (*init)(unsigned short width, unsigned short height);
unsigned int (*detection)(struct pulldown_detected_s *res,
struct combing_status_s *cmb_sts,
bool reverse,
struct vframe_s *vf);
void (*vof_win_vshift)(struct pulldown_detected_s *wins,
unsigned short v_offset);
int (*module_para)(struct seq_file *seq);
void (*prob)(struct device *dev);
void (*remove)(struct device *dev);
};
bool di_attach_ops_pulldown(const struct pulldown_op_s **ops);
/**************************
* detect3d
*************************/
struct detect3d_op_s {
void (*det3d_config)(bool flag);
enum tvin_trans_fmt (*det3d_fmt_detect)(void);
int (*module_para)(struct seq_file *seq);
};
bool di_attach_ops_3d(const struct detect3d_op_s **ops);
/**************************
* nr_drv
*************************/
struct nr_op_s {
void (*nr_hw_init)(void);
void (*nr_gate_control)(bool gate);
void (*nr_drv_init)(struct device *dev);
void (*nr_drv_uninit)(struct device *dev);
void (*nr_process_in_irq)(void);
void (*nr_all_config)(unsigned short nCol, unsigned short nRow,
unsigned short type);
bool (*set_nr_ctrl_reg_table)(unsigned int addr, unsigned int value);
void (*cue_int)(void);
void (*adaptive_cue_adjust)(unsigned int frame_diff,
unsigned int field_diff);
int (*module_para)(struct seq_file *seq);
};
bool di_attach_ops_nr(const struct nr_op_s **ops);
/**************************
* deinterlace_mtn
*************************/
struct mtn_op_s {
void (*mtn_int_combing_glbmot)(void);
void (*adpative_combing_exit)(void);
void (*fix_tl1_1080i_sawtooth_patch)(void);
int (*adaptive_combing_fixing)(
struct combing_status_s *cmb_status,
unsigned int field_diff, unsigned int frame_diff,
int bit_mode);
/*adpative_combing_config*/
struct combing_status_s *
(*adpative_combing_config)(unsigned int width,
unsigned int height,
enum vframe_source_type_e src_type,
bool prog,
enum tvin_sig_fmt_e fmt);
int (*module_para)(struct seq_file *seq);
};
bool di_attach_ops_mtn(const struct mtn_op_s **ops);
#endif /*__DI_PQA_H__*/

View File

@@ -27,6 +27,7 @@
#include "register_nr4.h"
#include "nr_drv.h"
#include "deinterlace.h"
#include "di_pqa.h"
static DNR_PRM_t dnr_param;
static struct NR_PARM_s nr_param;
@@ -1343,3 +1344,31 @@ void nr_drv_init(struct device *dev)
else
dnr_dm_en = false;
}
static const struct nr_op_s di_ops_nr = {
.nr_hw_init = nr_hw_init,
.nr_gate_control = nr_gate_control,
.nr_drv_init = nr_drv_init,
.nr_drv_uninit = nr_drv_uninit,
.nr_process_in_irq = nr_process_in_irq,
.nr_all_config = nr_all_config,
.set_nr_ctrl_reg_table = set_nr_ctrl_reg_table,
.cue_int = cue_int,
.adaptive_cue_adjust = adaptive_cue_adjust,
/*.module_para = dim_seq_file_module_para_nr,*/
};
bool di_attach_ops_nr(const struct nr_op_s **ops)
{
#if 0
if (!ops)
return false;
memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
#else
*ops = &di_ops_nr;
#endif
return true;
}
EXPORT_SYMBOL(di_attach_ops_nr);

View File

@@ -22,6 +22,7 @@
#include "deinterlace_hw.h"
#include "deinterlace_dbg.h"
#include "di_pqa.h"
static unsigned int field_diff_rate;
static unsigned int flm22_sure_num = 100;
@@ -534,3 +535,26 @@ module_param_named(flm22_sure_num, flm22_sure_num, uint, 0644);
module_param_named(flm22_glbpxlnum_rat, flm22_glbpxlnum_rat, uint, 0644);
module_param_named(flag_di_weave, flag_di_weave, int, 0644);
#endif
static const struct pulldown_op_s di_pd_ops = {
.init = pulldown_init, /*call when size change*/
.detection = pulldown_detection, /*call after pre nrwrite*/
.vof_win_vshift = pulldown_vof_win_vshift, /*in post process*/
/*.module_para = dim_seq_file_module_para_pulldown,*/ /*for debug*/
.prob = pd_device_files_add, /*prob*/
.remove = pd_device_files_del, /*remove*/
};
bool di_attach_ops_pulldown(const struct pulldown_op_s **ops)
{
#if 0
if (!ops)
return false;
memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
#else
*ops = &di_pd_ops;
#endif
return true;
}
EXPORT_SYMBOL(di_attach_ops_pulldown);

View File

@@ -17,8 +17,8 @@
#ifndef _DI_PULLDOWN_H
#define _DI_PULLDOWN_H
#include "film_mode_fmw/film_vof_soft.h"
#include "deinterlace_mtn.h"
#include "../deinterlace/film_mode_fmw/film_vof_soft.h"
#include "../deinterlace/deinterlace_mtn.h"
#define MAX_VOF_WIN_NUM 4

View File

@@ -0,0 +1,15 @@
#
# Deinterlace driver configuration
#
menu "DI_LOCAL driver"
config AMLOGIC_MEDIA_DEINTERLACE
tristate "DI_LOCAL driver"
default n
help
Select to enable AMLOGIC DEINTERLACE driver
process interlace source need three continueed fields,
wave progressive source with two interlace fields from
one progreesive fields
endmenu

View File

@@ -0,0 +1,12 @@
# # Makefile for the Post Process Manager device #
ifeq ($(TARGET_BUILD_VARIANT),userdebug)
ccflags-y := -D DEBUG_SUPPORT
ccflags-y := -DDEBUG
else
ccflags-y := -DDEBUG
endif
CFLAGS_dil.o := -I$(src)
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += dil.o
dil-objs += di_local.o
#ccflags-y += -Idrivers/amlogic/media/deinterlace/

View File

@@ -0,0 +1,327 @@
/*
* drivers/amlogic/media/di_local/di_local.c
*
* Copyright (C) 2017 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.
*
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/semaphore.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/major.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/proc_fs.h>
#include <linux/list.h>
#include <linux/of_reserved_mem.h>
#include <linux/of_irq.h>
#include <linux/uaccess.h>
#include <linux/of_fdt.h>
/*for di_ext_ops*/
/*#include <linux/amlogic/media/video_sink/video.h> */
#include "di_local.h"
/***************************************
* deinterlace in linux kernel
**************************************/
#define DEVICE_NAME "di_local"
/*#define CLASS_NAME "dev_pl_demo" */
#define DEV_COUNT 1
#define PR_ERR(fmt, args ...) pr_err("dil:err:"fmt, ## args)
#define PR_WARN(fmt, args ...) pr_err("dil:warn:"fmt, ## args)
#define PR_INF(fmt, args ...) pr_info("dil:"fmt, ## args)
struct dil_dev_s {
struct platform_device *pdev;
unsigned long mem_start;
unsigned int mem_size;
unsigned int flg_map;/*?*/
};
static struct dil_dev_s *pdv;
static const struct di_ext_ops *dil_api; //temp
/***************************************
* di api for other module *
**************************************/
bool dil_attach_ext_api(const struct di_ext_ops *di_api)
{
#if 0
if (!di_api) {
PR_ERR("%s:null\n", __func__);
return false;
}
memcpy(di_api, &di_ext, sizeof(struct di_ext_ops));
#else
dil_api = di_api;
#endif
return true;
}
EXPORT_SYMBOL(dil_attach_ext_api);
unsigned int DI_POST_REG_RD(unsigned int addr)
{
#if 0
if (IS_ERR_OR_NULL(de_devp))
return 0;
if (de_devp->flags & DI_SUSPEND_FLAG) {
pr_err("[DI] REG 0x%x access prohibited.\n", addr);
return 0;
}
return VSYNC_RD_MPEG_REG(addr);
#endif
if (dil_api && dil_api->di_post_reg_rd)
return dil_api->di_post_reg_rd(addr);
PR_ERR("%s:not attach\n", __func__);
return 0;
}
EXPORT_SYMBOL(DI_POST_REG_RD);
int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
{
#if 0
if (IS_ERR_OR_NULL(de_devp))
return 0;
if (de_devp->flags & DI_SUSPEND_FLAG) {
pr_err("[DI] REG 0x%x access prohibited.\n", adr);
return -1;
}
return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
#endif
if (dil_api && dil_api->di_post_wr_reg_bits)
return dil_api->di_post_wr_reg_bits(adr, val, start, len);
PR_ERR("%s:not attach\n", __func__);
return 0;
}
EXPORT_SYMBOL(DI_POST_WR_REG_BITS);
/***************************************
* reserved mem for di *
**************************************/
void dil_get_rev_mem(unsigned long *mstart, unsigned int *msize)
{
if (pdv) {
*mstart = pdv->mem_start;
*msize = pdv->mem_size;
} else {
*mstart = 0;
*msize = 0;
}
}
EXPORT_SYMBOL(dil_get_rev_mem);
void dil_get_flg(unsigned int *flg)
{
if (pdv)
*flg = pdv->flg_map;
else
*flg = 0;
}
EXPORT_SYMBOL(dil_get_flg);
/***************************************
* reserved mem for di *
**************************************/
static int __init rmem_dil_init(struct reserved_mem *rmem,
struct device *dev)
{
struct dil_dev_s *devp = dev_get_drvdata(dev);
if (devp) {
devp->mem_start = rmem->base;
devp->mem_size = rmem->size;
if (!of_get_flat_dt_prop(rmem->fdt_node, "no-map", NULL))
devp->flg_map = 1;
#if 0
o_size = rmem->size / DI_CHANNEL_NUB;
for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
di_set_mem_info(ch,
di_devp->mem_start + (o_size * ch),
o_size);
PR_INF("rmem:ch[%d]:start:0x%lx, size:%uB\n",
ch,
(di_devp->mem_start + (o_size * ch)),
o_size);
}
#endif
PR_INF("%s:0x%lx, size %uMB.\n",
__func__,
devp->mem_start, (devp->mem_size >> 20));
return 0;
}
PR_ERR("%s:no devp\n", __func__);
return 1;
}
static void rmem_dil_release(struct reserved_mem *rmem,
struct device *dev)
{
struct dil_dev_s *devp = dev_get_drvdata(dev);
if (devp) {
devp->mem_start = 0;
devp->mem_size = 0;
}
PR_INF("%s:ok\n", __func__);
}
static const struct reserved_mem_ops rmem_di_ops = {
.device_init = rmem_dil_init,
.device_release = rmem_dil_release,
};
static int __init rmem_dil_setup(struct reserved_mem *rmem)
{
rmem->ops = &rmem_di_ops;
/* rmem->priv = cma; */
PR_INF("%s %pa, size %ld MiB\n",
__func__,
&rmem->base, (unsigned long)rmem->size / SZ_1M);
return 0;
}
RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_dil_setup);
/***************************************
*
***************************************/
static int dil_probe(struct platform_device *pdev)
{
int ret = 0;
PR_INF("%s.\n", __func__);
/*alloc data*/
pdv = kzalloc(sizeof(*pdv), GFP_KERNEL);
if (!pdv) {
PR_ERR("%s fail to alloc pdv.\n", __func__);
return -ENOMEM;/*goto fail_alloc_data;*/
}
pdv->pdev = pdev;
platform_set_drvdata(pdev, pdv);
ret = of_reserved_mem_device_init(&pdev->dev);
if (ret != 0)
PR_INF("%s no reserved mem.\n", __func__);
PR_INF("%s ok.\n", __func__);
return 0;
}
static int dil_remove(struct platform_device *pdev)
{
PR_INF("%s.\n", __func__);
/*data*/
kfree(pdv);
PR_INF("%s ok.\n", __func__);
return 0;
}
static void dil_shutdown(struct platform_device *pdev)
{
PR_INF("%s.\n", __func__);
}
static const struct of_device_id dil_match[] = {
{
.compatible = "amlogic, di-local",
.data = NULL,
},
{},
};
static struct platform_driver dev_driver_tab = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
.of_match_table = dil_match,
},
.probe = dil_probe,
.remove = dil_remove,
.shutdown = dil_shutdown,
};
#if 1
static int __init dil_init(void)
{
PR_INF("%s.\n", __func__);
if (platform_driver_register(&dev_driver_tab)) {
PR_ERR("%s: can't register\n", __func__);
return -ENODEV;
}
PR_INF("%s ok.\n", __func__);
return 0;
}
static void __exit dil_exit(void)
{
platform_driver_unregister(&dev_driver_tab);
PR_INF("%s: ok.\n", __func__);
}
module_init(dil_init);
module_exit(dil_exit);
MODULE_DESCRIPTION("AMLOGIC DI_LOCAL driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("4.0.0");
#else
int dil_init(void)
{
PR_INF("%s.\n", __func__);
if (platform_driver_register(&dev_driver_tab)) {
PR_ERR("%s: can't register\n", __func__);
return -ENODEV;
}
PR_INF("%s ok.\n", __func__);
return 0;
}
void dil_exit(void)
{
platform_driver_unregister(&dev_driver_tab);
PR_INF("%s: ok.\n", __func__);
}
#endif

View File

@@ -0,0 +1,26 @@
/*
* drivers/amlogic/media/di_local/di_local.h
*
* Copyright (C) 2017 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.
*
*/
#ifndef __DI_LOCAL_H__
#define __DI_LOCAL_H__
struct di_ext_ops {
unsigned int (*di_post_reg_rd)(unsigned int addr);
int (*di_post_wr_reg_bits)(u32 adr, u32 val, u32 start, u32 len);
};
#endif /*__DI_LOCAL_H__*/