blob: 61fe6dc9ecff2c5cf809556bd99eb7c437412c30 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* drivers/amlogic/media/enhancement/amvecm/reg_helper.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 __REG_HELPER_H
#define __REG_HELPER_H
#include "arch/vpp_regs.h"
#include "arch/ve_regs.h"
#include "arch/cm_regs.h"
#define CLR_BIT(x) (~(0x01 << (x)))
#define CLR_BITS(x, y) ((~((0x01 << (y)) - 1)) << (x))
#define SET_BIT(x) (0x01 << (x))
#define GET_BIT(x) (0x01 << (x))
#define GET_BITS(x, y) (((0x01 << (y)) - 1) << (x))
/* useful inline fucntions to handle different offset */
static inline bool cpu_after_eq_t7(void)
{
return cpu_after_eq(MESON_CPU_MAJOR_ID_T7);
}
static inline bool cpu_after_eq_tm2b(void)
{
return cpu_after_eq(MESON_CPU_MAJOR_ID_TM2);
}
static inline bool cpu_after_eq_tl1(void)
{
return cpu_after_eq(MESON_CPU_MAJOR_ID_TL1);
}
static inline bool is_sr0_reg(u32 addr)
{
return (addr >= SRSHARP0_SHARP_HVSIZE &&
addr <= SRSHARP0_PKOSHT_VSLUMA_LUT_H);
}
static inline bool is_sr1_reg(u32 addr)
{
return (addr >= SRSHARP1_SHARP_HVSIZE &&
addr <= SRSHARP1_PKOSHT_VSLUMA_LUT_H);
}
static inline bool is_lc_reg(u32 addr)
{
return (addr >= SRSHARP1_LC_INPUT_MUX &&
addr <= SRSHARP1_LC_MAP_RAM_DATA);
}
static inline bool is_sr0_dnlpv2_reg(u32 addr)
{
return (addr >= SRSHARP0_DNLP2_00 &&
addr <= SRSHARP0_DNLP2_31);
}
static inline bool is_sr1_dnlpv2_reg(u32 addr)
{
return (addr >= SRSHARP1_DNLP2_00 &&
addr <= SRSHARP1_DNLP2_31);
}
static inline u32 get_sr0_offset(void)
{
/*sr0 register shfit*/
if (cpu_after_eq_t7())
return 0x1200;
else if (cpu_after_eq_tm2b())
return 0x1200;
else if (cpu_after_eq_tl1())
return 0x0;
else if (is_meson_g12a_cpu() ||
is_meson_g12b_cpu() ||
is_meson_sm1_cpu())
return 0x0;
return 0xfffff400 /*-0xc00*/;
}
static inline u32 get_sr1_offset(void)
{
/*sr1 register shfit*/
if (cpu_after_eq_t7())
return 0x1300;
else if (cpu_after_eq_tm2b())
return 0x1300;
else if (cpu_after_eq_tl1())
return 0x0;
else if (is_meson_g12a_cpu() ||
is_meson_g12b_cpu() ||
is_meson_sm1_cpu())
return 0x0;
return 0xfffff380; /*-0xc80*/;
}
static inline u32 get_lc_offset(void)
{
/* lc register shfit*/
if (cpu_after_eq_t7())
return 0x1300;
else if (cpu_after_eq_tm2b())
return 0x1300;
return 0;
}
static inline u32 get_sr0_dnlp2_offset(void)
{
/* SHARP0_DNLP_00 shfit*/
if (cpu_after_eq_t7())
return 0x1200;
else if (cpu_after_eq_tm2b())
return 0x1200;
return 0;
}
static inline u32 get_sr1_dnlp2_offset(void)
{
/* SHARP1_DNLP_00 shfit*/
if (cpu_after_eq_t7())
return 0x1300;
else if (cpu_after_eq_tm2b())
return 0x1300;
return 0;
}
static u32 offset_addr(u32 addr)
{
if (is_sr0_reg(addr))
return addr + get_sr0_offset();
else if (is_sr1_reg(addr))
return addr + get_sr1_offset();
else if (is_sr0_dnlpv2_reg(addr))
return addr + get_sr0_dnlp2_offset();
else if (is_sr1_dnlpv2_reg(addr))
return addr + get_sr1_dnlp2_offset();
else if (is_lc_reg(addr))
return addr + get_lc_offset();
return addr;
}
static inline void WRITE_VPP_REG(u32 reg,
const u32 value)
{
aml_write_vcbus_s(offset_addr(reg), value);
}
static inline u32 READ_VPP_REG(u32 reg)
{
return aml_read_vcbus_s(offset_addr(reg));
}
static inline void WRITE_VPP_REG_EX(u32 reg,
const u32 value,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
aml_write_vcbus_s(reg, value);
}
static inline u32 READ_VPP_REG_EX(u32 reg,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
return aml_read_vcbus_s(reg);
}
static inline void WRITE_VPP_REG_BITS(u32 reg,
const u32 value,
const u32 start,
const u32 len)
{
aml_vcbus_update_bits_s(offset_addr(reg), value, start, len);
}
static inline u32 READ_VPP_REG_BITS(u32 reg,
const u32 start,
const u32 len)
{
u32 val;
u32 reg1 = offset_addr(reg);
val = ((aml_read_vcbus_s(reg1) >> (start)) & ((1L << (len)) - 1));
return val;
}
#ifndef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#define VSYNC_WR_MPEG_REG(adr, val) WRITE_VPP_REG(adr, val)
#define VSYNC_RD_MPEG_REG(adr) READ_VPP_REG(adr)
#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len) \
WRITE_VPP_REG_BITS(adr, val, start, len)
#define VSYNC_WR_MPEG_REG_VPP1(adr, val) WRITE_VCBUS_REG(adr, val)
#define VSYNC_RD_MPEG_REG_VPP1(adr) READ_VCBUS_REG(adr)
#define VSYNC_WR_MPEG_REG_BITS_VPP1(adr, val, start, len) \
WRITE_VCBUS_REG_BITS(adr, val, start, len)
#define VSYNC_WR_MPEG_REG_VPP2(adr, val) WRITE_VCBUS_REG(adr, val)
#define VSYNC_RD_MPEG_REG_VPP2(adr) READ_VCBUS_REG(adr)
#define VSYNC_WR_MPEG_REG_BITS_VPP2(adr, val, start, len) \
WRITE_VCBUS_REG_BITS(adr, val, start, len)
int VSYNC_WR_MPEG_REG_BITS_VPP_SEL(u32 adr, u32 val, u32 start, u32 len, int vpp_sel);
u32 VSYNC_RD_MPEG_REG_VPP_SEL(u32 adr, int vpp_sel);
int VSYNC_WR_MPEG_REG_VPP_SEL(u32 adr, u32 val, int vpp_sel);
#else
int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len);
u32 VSYNC_RD_MPEG_REG(u32 adr);
int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
int VSYNC_WR_MPEG_REG_BITS_VPP1(u32 adr, u32 val, u32 start, u32 len);
u32 VSYNC_RD_MPEG_REG_VPP1(u32 adr);
int VSYNC_WR_MPEG_REG_VPP1(u32 adr, u32 val);
int VSYNC_WR_MPEG_REG_BITS_VPP2(u32 adr, u32 val, u32 start, u32 len);
u32 VSYNC_RD_MPEG_REG_VPP2(u32 adr);
int VSYNC_WR_MPEG_REG_VPP2(u32 adr, u32 val);
int VSYNC_WR_MPEG_REG_BITS_VPP_SEL(u32 adr, u32 val, u32 start, u32 len, int vpp_sel);
u32 VSYNC_RD_MPEG_REG_VPP_SEL(u32 adr, int vpp_sel);
int VSYNC_WR_MPEG_REG_VPP_SEL(u32 adr, u32 val, int vpp_sel);
#endif
/* vsync for vpp_top0 */
static inline void VSYNC_WRITE_VPP_REG(u32 reg,
const u32 value)
{
VSYNC_WR_MPEG_REG(offset_addr(reg), value);
}
static inline u32 VSYNC_READ_VPP_REG(u32 reg)
{
return VSYNC_RD_MPEG_REG(offset_addr(reg));
}
static inline void VSYNC_WRITE_VPP_REG_EX(u32 reg,
const u32 value,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
VSYNC_WR_MPEG_REG(reg, value);
}
static inline u32 VSYNC_READ_VPP_REG_EX(u32 reg,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
return VSYNC_RD_MPEG_REG(reg);
}
static inline void VSYNC_WRITE_VPP_REG_BITS(u32 reg,
const u32 value,
const u32 start,
const u32 len)
{
VSYNC_WR_MPEG_REG_BITS(offset_addr(reg), value, start, len);
}
/* vsync for vpp_top1 */
static inline void VSYNC_WRITE_VPP_REG_VPP1(u32 reg,
const u32 value)
{
VSYNC_WR_MPEG_REG_VPP1(offset_addr(reg), value);
}
static inline u32 VSYNC_READ_VPP_REG_VPP1(u32 reg)
{
return VSYNC_RD_MPEG_REG_VPP1(offset_addr(reg));
}
static inline void VSYNC_WRITE_VPP_REG_EX_VPP1(u32 reg,
const u32 value,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
VSYNC_WR_MPEG_REG_VPP1(reg, value);
}
static inline u32 VSYNC_READ_VPP_REG_EX_VPP1(u32 reg,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
return VSYNC_RD_MPEG_REG_VPP1(reg);
}
static inline void VSYNC_WRITE_VPP_REG_BITS_VPP1(u32 reg,
const u32 value,
const u32 start,
const u32 len)
{
VSYNC_WR_MPEG_REG_BITS_VPP1(offset_addr(reg), value, start, len);
}
/* vsync for vpp_top2 */
static inline void VSYNC_WRITE_VPP_REG_VPP2(u32 reg,
const u32 value)
{
VSYNC_WR_MPEG_REG_VPP2(offset_addr(reg), value);
}
static inline u32 VSYNC_READ_VPP_REG_VPP2(u32 reg)
{
return VSYNC_RD_MPEG_REG_VPP2(offset_addr(reg));
}
static inline void VSYNC_WRITE_VPP_REG_EX_VPP2(u32 reg,
const u32 value,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
VSYNC_WR_MPEG_REG_VPP2(reg, value);
}
static inline u32 VSYNC_READ_VPP_REG_EX_VPP2(u32 reg,
bool add_offset)
{
if (add_offset)
reg = offset_addr(reg);
return VSYNC_RD_MPEG_REG_VPP2(reg);
}
static inline void VSYNC_WRITE_VPP_REG_BITS_VPP2(u32 reg,
const u32 value,
const u32 start,
const u32 len)
{
VSYNC_WR_MPEG_REG_BITS_VPP2(offset_addr(reg), value, start, len);
}
/* vsync for vpp_top_sel */
static inline void VSYNC_WRITE_VPP_REG_VPP_SEL(u32 reg,
const u32 value, int vpp_sel)
{
if (vpp_sel == 2)
VSYNC_WR_MPEG_REG_VPP2(offset_addr(reg), value);
else if (vpp_sel == 1)
VSYNC_WR_MPEG_REG_VPP1(offset_addr(reg), value);
else
VSYNC_WR_MPEG_REG(offset_addr(reg), value);
}
static inline u32 VSYNC_READ_VPP_REG_VPP_SEL(u32 reg, int vpp_sel)
{
if (vpp_sel == 2)
return VSYNC_RD_MPEG_REG_VPP2(offset_addr(reg));
else if (vpp_sel == 1)
return VSYNC_RD_MPEG_REG_VPP1(offset_addr(reg));
else
return VSYNC_RD_MPEG_REG(offset_addr(reg));
}
static inline void VSYNC_WRITE_VPP_REG_EX_VPP_SEL(u32 reg,
const u32 value,
bool add_offset, int vpp_sel)
{
if (add_offset)
reg = offset_addr(reg);
if (vpp_sel == 2)
VSYNC_WR_MPEG_REG_VPP2(reg, value);
else if (vpp_sel == 1)
VSYNC_WR_MPEG_REG_VPP1(reg, value);
else
VSYNC_WR_MPEG_REG(reg, value);
}
static inline u32 VSYNC_READ_VPP_REG_EX_VPP_SEL(u32 reg,
bool add_offset, int vpp_sel)
{
if (add_offset)
reg = offset_addr(reg);
if (vpp_sel == 2)
return VSYNC_RD_MPEG_REG_VPP2(reg);
else if (vpp_sel == 1)
return VSYNC_RD_MPEG_REG_VPP1(reg);
else
return VSYNC_RD_MPEG_REG(reg);
}
static inline void VSYNC_WRITE_VPP_REG_BITS_VPP_SEL(u32 reg,
const u32 value,
const u32 start,
const u32 len, int vpp_sel)
{
if (vpp_sel == 2)
VSYNC_WR_MPEG_REG_BITS_VPP2(offset_addr(reg), value, start, len);
else if (vpp_sel == 1)
VSYNC_WR_MPEG_REG_BITS_VPP1(offset_addr(reg), value, start, len);
else
VSYNC_WR_MPEG_REG_BITS(offset_addr(reg), value, start, len);
}
#endif