| // 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; |
| } |
| |