blob: d7d97d0021dcce3b9937170ae7612204639b84bd [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* drivers/amlogic/media/di_multi/di_reg_tab.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/kernel.h>
#include <linux/err.h>
#include <linux/seq_file.h>
#include <linux/amlogic/iomap.h>
#include "deinterlace.h"
#include "di_data_l.h"
#include "register.h"
#include "di_reg_v2.h"
#include "deinterlace_hw.h"
static const struct reg_t rtab_contr[] = {
/*--------------------------*/
{VD1_AFBCD0_MISC_CTRL, 20, 2, 0, "VD1_AFBCD0_MISC_CTRL",
"vd1_go_field_sel",
"0: gofile;1: post;2: pre"},
{VD1_AFBCD0_MISC_CTRL, 9, 1, 0, "",
"afbc0_mux_vpp_mad",
"afbc0 to 0:vpp; 1:di"},
{VD1_AFBCD0_MISC_CTRL, 8, 1, 0, "",
"di_mif0_en",
":mif to 0-vpp;1-di"},
/*--------------------------*/
{DI_POST_CTRL, 12, 1, 0, "DI_POST_CTRL",
"di_post_viu_link",
""},
{DI_POST_CTRL, 8, 1, 0, "",
"di_vpp_out_en",
""},
/*--------------------------*/
{VIU_MISC_CTRL0, 20, 1, 0, "VIU_MISC_CTRL0",
"?",
"?"},
{VIU_MISC_CTRL0, 18, 1, 0, "",
"Vdin0_wr_out_ctrl",
"0: nr_inp to vdin; 1: vdin wr dout"},
{VIU_MISC_CTRL0, 17, 1, 0, "",
"Afbc_inp_sel",
"0: mif to INP; 1: afbc to INP"},
{VIU_MISC_CTRL0, 16, 1, 0, "",
"di_mif0_en",
" vd1(afbc) to di post(if0) enable"},
/*--------------------------*/
{DI_IF1_GEN_REG, 0, 1, 0, "DI_IF1_GEN_REG",
"enable",
""},
/*--------------------------*/
{DI_IF1_GEN_REG3, 8, 2, 0, "DI_IF1_GEN_REG3",
"cntl_bits_mode",
"0:8bit;1:10bit 422;2:10bit 444"},
/*--------------------------*/
{DI_IF2_GEN_REG3, 8, 2, 0, "DI_IF2_GEN_REG3",
"cntl_bits_mode",
"0:8bit;1:10bit 422;2:10bit 444"},
/*--------------------------*/
{DI_IF0_GEN_REG3, 8, 2, 0, "DI_IF0_GEN_REG3",
"cntl_bits_mode",
"0:8bit;1:10bit 422;2:10bit 444"},
/*--------------------------*/
{DI_POST_GL_CTRL, 31, 1, 0, "DI_POST_GL_CTRL",
"post count enable",
""},
{DI_POST_GL_CTRL, 30, 1, 0, "",
"post count reset",
""},
{DI_POST_GL_CTRL, 16, 14, 0, "",
"total line number for post count",
""},
{DI_POST_GL_CTRL, 0, 14, 0, "",
"the line number of post frame reset",
""},
{TABLE_FLG_END, 0, 0, 0, "end", "end", ""},
};
/**********************/
/* debug register */
/**********************/
static unsigned int get_reg_bits(unsigned int val, unsigned int bstart,
unsigned int bw)
{
return((val &
(((1L << bw) - 1) << bstart)) >> (bstart));
}
//static
void dbg_reg_tab(struct seq_file *s, const struct reg_t *pregtab)
{
struct reg_t creg;
int i;
unsigned int l_add;
unsigned int val32 = 1, val;
char *bname;
char *info;
i = 0;
l_add = 0;
creg = pregtab[i];
do {
if (creg.add != l_add) {
val32 = RD(creg.add); /*RD*/
seq_printf(s, "add:0x%x = 0x%08x, %s\n",
creg.add, val32, creg.name);
l_add = creg.add;
}
val = get_reg_bits(val32, creg.bit, creg.wid); /*RD_B*/
if (creg.bname)
bname = creg.bname;
else
bname = "";
if (creg.info)
info = creg.info;
else
info = "";
seq_printf(s, "\tbit[%d,%d]:\t0x%x[%d]:\t%s:\t%s\n",
creg.bit, creg.wid, val, val, bname, info);
i++;
creg = pregtab[i];
if (i > DIMTABLE_LEN_MAX) {
pr_info("warn: too long, stop\n");
break;
}
} while (creg.add != TABLE_FLG_END);
}
int reg_con_show(struct seq_file *seq, void *v)
{
dbg_reg_tab(seq, &rtab_contr[0]);
return 0;
}
int reg_contr_show(struct seq_file *s, void *v)
{
if (DIM_IS_IC_EF(SC2)) {
if (opl1()->rtab_contr_bits_tab)
dbg_reg_tab(s, opl1()->rtab_contr_bits_tab);
else
seq_printf(s, "%s:none\n", __func__);
}
return 0;
}
static const struct reg_t rtab_cue_int[] = {
/*--------------------------*/
{NR2_CUE_CON_DIF0, 0, 32, 0x1400, "NR2_CUE_CON_DIF0",
NULL,
NULL},
{NR2_CUE_CON_DIF1, 0, 32, 0x80064, "NR2_CUE_CON_DIF1",
NULL,
NULL},
{NR2_CUE_CON_DIF2, 0, 32, 0x80064, "NR2_CUE_CON_DIF2",
NULL,
NULL},
{NR2_CUE_CON_DIF3, 0, 32, 0x80a0a, "NR2_CUE_CON_DIF3",
NULL,
NULL},
{NR2_CUE_PRG_DIF, 0, 32, 0x80a0a, "NR2_CUE_PRG_DIF",
NULL,
NULL},
{TABLE_FLG_END, 0, 0, 0, "end", "end", ""},
/*--------------------------*/
};
/************************************************
* register table
************************************************/
static bool di_g_rtab_cue(const struct reg_t **tab, unsigned int *tabsize)
{
*tab = &rtab_cue_int[0];
*tabsize = ARRAY_SIZE(rtab_cue_int);
return true;
}
static unsigned int dim_reg_read(unsigned int addr)
{
return aml_read_vcbus(addr);
}
const struct reg_acc di_pre_regset = {
.wr = DIM_DI_WR,
.rd = dim_reg_read,
.bwr = DIM_RDMA_WR_BITS,
.brd = DIM_RDMA_RD_BITS,
};
static bool di_wr_tab(const struct reg_acc *ops,
const struct reg_t *ptab, unsigned int tabsize)
{
int i;
const struct reg_t *pl;
pl = ptab;
if (!ops ||
!tabsize ||
!ptab)
return false;
for (i = 0; i < tabsize; i++) {
if (pl->add == TABLE_FLG_END ||
i > DIMTABLE_LEN_MAX) {
break;
}
if (pl->wid == 32)
ops->wr(pl->add, pl->df_val);
else
ops->bwr(pl->add, pl->df_val, pl->bit, pl->wid);
pl++;
}
return true;
}
bool dim_wr_cue_int(void)
{
const struct reg_t *ptab;
unsigned int tabsize;
di_g_rtab_cue(&ptab, &tabsize);
di_wr_tab(&di_pre_regset,
ptab,
tabsize);
//PR_INF("%s:finish\n", __func__);
return true;
}
int dim_reg_cue_int_show(struct seq_file *seq, void *v)
{
dbg_reg_tab(seq, &rtab_cue_int[0]);
return 0;
}