lineage_kernel_xcoverpro/drivers/media/platform/exynos/scaler/scaler-regs.h

377 lines
11 KiB
C
Executable File

/*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Register header file for Exynos Scaler driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __SCALER_REGS_H__
#define __SCALER_REGS_H__
#include "scaler.h"
/* Status */
#define SCALER_STATUS 0x00
/* Configuration */
#define SCALER_CFG 0x04
#define SCALER_CFG_DRCG_EN (1 << 31)
#define SCALER_CFG_CORE_BYP_EN (1 << 29)
#define SCALER_CFG_SRAM_CG_EN (1 << 28)
#define SCALER_CFG_FILL_EN (1 << 24)
#define SCALER_CFG_BL_DIV_ALPHA_EN (1 << 17)
#define SCALER_CFG_BLEND_EN (1 << 16)
#define SCALER_CFG_CSC_Y_OFFSET_SRC (1 << 10)
#define SCALER_CFG_BURST_WR (1 << 8)
#define SCALER_CFG_BURST_RD (1 << 7)
#define SCALER_CFG_CSC_Y_OFFSET_DST (1 << 9)
#define SCALER_CFG_STOP_REQ (1 << 3)
#define SCALER_CFG_RESET_OKAY (1 << 2)
#define SCALER_CFG_SOFT_RST (1 << 1)
#define SCALER_CFG_START_CMD (1 << 0)
/* Interrupt */
#define SCALER_INT_EN 0x08
#define SCALER_INT_EN_FRAME_END (1 << 0)
#define SCALER_INT_EN_ALL 0x807fffff
#define SCALER_INT_EN_ALL_v3 0x82ffffff
#define SCALER_INT_EN_ALL_v4 0xb2ffffff
#define SCALER_INT_OK(status) ((status) == SCALER_INT_EN_FRAME_END)
#define SCALER_INT_STATUS 0x0c
#define SCALER_INT_STATUS_FRAME_END (1 << 0)
#define SCALER_SRC_CFG 0x10
/* Source Image Configuration */
#define SCALER_CFG_TILE_EN (1 << 10)
#define SCALER_CFG_VHALF_PHASE_EN (1 << 9)
#define SCALER_CFG_BIG_ENDIAN (1 << 8)
#define SCALER_CFG_10BIT_P010 (1 << 7)
#define SCALER_CFG_10BIT_S10 (2 << 7)
#define SCALER_CFG_SWAP_MASK (3 << 5)
#define SCALER_CFG_BYTE_SWAP (1 << 5)
#define SCALER_CFG_HWORD_SWAP (2 << 5)
#define SCALER_CFG_BYTE_HWORD_SWAP (3 << 5)
#define SCALER_CFG_FMT_MASK (0x1f << 0)
#define SCALER_CFG_FMT_YCBCR420_2P (0 << 0)
#define SCALER_CFG_FMT_YUYV (0xa << 0)
#define SCALER_CFG_FMT_UYVY (0xb << 0)
#define SCALER_CFG_FMT_YVYU (9 << 0)
#define SCALER_CFG_FMT_YCBCR422_2P (2 << 0)
#define SCALER_CFG_FMT_YCBCR444_2P (3 << 0)
#define SCALER_CFG_FMT_RGB565 (4 << 0)
#define SCALER_CFG_FMT_ARGB1555 (5 << 0)
#define SCALER_CFG_FMT_ARGB4444 (0xc << 0)
#define SCALER_CFG_FMT_ARGB8888 (6 << 0)
#define SCALER_CFG_FMT_RGBA8888 (0xe << 0)
#define SCALER_CFG_FMT_P_ARGB8888 (7 << 0)
#define SCALER_CFG_FMT_L8A8 (0xd << 0)
#define SCALER_CFG_FMT_L8 (0xf << 0)
#define SCALER_CFG_FMT_YCRCB420_2P (0x10 << 0)
#define SCALER_CFG_FMT_YCRCB422_2P (0x12 << 0)
#define SCALER_CFG_FMT_YCRCB444_2P (0x13 << 0)
#define SCALER_CFG_FMT_YCBCR420_3P (0x14 << 0)
#define SCALER_CFG_FMT_YCBCR422_3P (0x16 << 0)
#define SCALER_CFG_FMT_YCBCR444_3P (0x17 << 0)
/* Source Y Base Address */
#define SCALER_SRC_Y_BASE 0x14
#define SCALER_SRC_CB_BASE 0x18
#define SCALER_SRC_CR_BASE 0x294
#define SCALER_SRC_SPAN 0x1c
#define SCALER_SRC_CSPAN_MASK (0xffff << 16)
#define SCALER_SRC_YSPAN_MASK (0xffff << 0)
#define SCALER_SRC_Y_POS 0x20
#define SCALER_SRC_WH 0x24
#define SCALER_SRC_PRESC_WH 0x2C
#define SCALER_SRC_C_POS 0x28
#define SCALER_DST_CFG 0x30
#define SCALER_DST_Y_BASE 0x34
#define SCALER_DST_CB_BASE 0x38
#define SCALER_DST_CR_BASE 0x298
#define SCALER_DST_SPAN 0x3c
#define SCALER_DST_CSPAN_MASK (0xffff << 16)
#define SCALER_DST_YSPAN_MASK (0xffff << 0)
#define SCALER_DST_WH 0x40
#define SCALER_DST_POS 0x44
#define SCALER_H_RATIO 0x50
#define SCALER_V_RATIO 0x54
#define SCALER_ROT_CFG 0x58
#define SCALER_ROT_MASK (3 << 0)
#define SCALER_FLIP_MASK (3 << 2)
#define SCALER_FLIP_X_EN (1 << 3)
#define SCALER_FLIP_Y_EN (1 << 2)
#define SCALER_ROT_90 (1 << 0)
#define SCALER_ROT_180 (2 << 0)
#define SCALER_ROT_270 (3 << 0)
#define SCALER_LAT_CON 0x5c
#define SCALER_YHCOEF 0x60
#define SCALER_YVCOEF 0xf0
#define SCALER_CHCOEF 0x140
#define SCALER_CVCOEF 0x1d0
#define SCALER_CSC_COEF00 0x220
#define SCALER_CSC_COEF10 0x224
#define SCALER_CSC_COEF20 0x228
#define SCALER_CSC_COEF01 0x22c
#define SCALER_CSC_COEF11 0x230
#define SCALER_CSC_COEF21 0x234
#define SCALER_CSC_COEF02 0x238
#define SCALER_CSC_COEF12 0x23c
#define SCALER_CSC_COEF22 0x240
#define SCALER_CSC_COEF_MASK (0xffff << 0)
#define SCALER_DITH_CFG 0x250
#define SCALER_DITH_R_MASK (7 << 6)
#define SCALER_DITH_G_MASK (7 << 3)
#define SCALER_DITH_B_MASK (7 << 0)
#define SCALER_DITH_R_SHIFT (6)
#define SCALER_DITH_G_SHIFT (3)
#define SCALER_DITH_B_SHIFT (0)
#define SCALER_DITH_SRC_INV (1 << 1)
#define SCALER_DITH_DST_EN (1 << 0)
#define SCALER_VER 0x260
#define SCALER_CRC_COLOR01 0x270
#define SCALER_CRC_COLOR23 0x274
#define SCALER_CYCLE_COUNT 0x278
#define SCALER_SRC_BLEND_COLOR 0x280
#define SCALER_SRC_BLEND_ALPHA 0x284
#define SCALER_DST_BLEND_COLOR 0x288
#define SCALER_DST_BLEND_ALPHA 0x28c
#define SCALER_SEL_INV_MASK (1 << 31)
#define SCALER_SEL_MASK (2 << 29)
#define SCALER_OP_SEL_INV_MASK (1 << 28)
#define SCALER_OP_SEL_MASK (0xf << 24)
#define SCALER_SEL_INV_SHIFT (31)
#define SCALER_SEL_SHIFT (29)
#define SCALER_OP_SEL_INV_SHIFT (28)
#define SCALER_OP_SEL_SHIFT (24)
#define SCALER_SRC_2BIT_Y_BASE 0x280
#define SCALER_SRC_2BIT_C_BASE 0x284
#define SCALER_SRC_2BIT_SPAN 0x288
#define SCALER_SRC_2BIT_YSPAN_MASK (0x7fff << 0)
#define SCALER_SRC_2BIT_CSPAN_MASK (0x7fff << 16)
#define SCALER_DST_2BIT_Y_BASE 0x2A0
#define SCALER_DST_2BIT_C_BASE 0x2A4
#define SCALER_DST_2BIT_SPAN 0x2A8
#define SCALER_DST_2BIT_YSPAN_MASK (0x7fff << 0)
#define SCALER_DST_2BIT_CSPAN_MASK (0x7fff << 16)
#define SCALER_FILL_COLOR 0x290
#define SCALER_TIMEOUT_CTRL 0x2c0
#define SCALER_TIMEOUT_CNT 0x2c4
#define SCALER_CLK_REQ 0x2cc
#define SCALER_SRC_YH_INIT_PHASE 0x2d0
#define SCALER_SRC_YV_INIT_PHASE 0x2d4
#define SCALER_SRC_CH_INIT_PHASE 0x2d8
#define SCALER_SRC_CV_INIT_PHASE 0x2dc
/* macros to make words to SFR */
#define SCALER_VAL_WH(w, h) (((w) & 0x3FFF) << 16) | ((h) & 0x3FFF)
#define SCALER_VAL_SRC_POS(l, t) (((l) & 0x3FFF) << 18) | (((t) & 0x3FFF) << 2)
#define SCALER_VAL_DST_POS(l, t) (((l) & 0x3FFF) << 16) | ((t) & 0x3FFF)
static inline void sc_hwset_clk_request(struct sc_dev *sc, bool enable)
{
if (sc->version >= SCALER_VERSION(5, 0, 1))
__raw_writel(enable ? 1 : 0, sc->regs + SCALER_CLK_REQ);
}
static inline void sc_hwset_src_pos(struct sc_dev *sc, __s32 left, __s32 top,
unsigned int chshift, unsigned int cvshift)
{
/* SRC pos have fractional part of 2 bits which is not used */
__raw_writel(SCALER_VAL_SRC_POS(left, top),
sc->regs + SCALER_SRC_Y_POS);
__raw_writel(SCALER_VAL_SRC_POS(left >> chshift, top >> cvshift),
sc->regs + SCALER_SRC_C_POS);
}
static inline void sc_hwset_src_wh(struct sc_dev *sc, __s32 width, __s32 height,
unsigned int pre_h_ratio, unsigned int pre_v_ratio,
unsigned int chshift, unsigned int cvshift)
{
__s32 pre_width = round_down(width >> pre_h_ratio, 1 << chshift);
__s32 pre_height = round_down(height >> pre_v_ratio, 1 << cvshift);
sc_dbg("width %d, height %d\n", pre_width, pre_height);
if (sc->variant->prescale) {
/*
* crops the width and height if the pre-scaling result violates
* the width/height constraints:
* - result width or height is not a natural number
* - result width or height violates the constrains
* of YUV420/422
*/
width = pre_width << pre_h_ratio;
height = pre_height << pre_v_ratio;
__raw_writel(SCALER_VAL_WH(width, height),
sc->regs + SCALER_SRC_PRESC_WH);
}
__raw_writel(SCALER_VAL_WH(pre_width, pre_height),
sc->regs + SCALER_SRC_WH);
}
static inline void sc_hwset_dst_pos(struct sc_dev *sc, __s32 left, __s32 top)
{
__raw_writel(SCALER_VAL_DST_POS(left, top), sc->regs + SCALER_DST_POS);
}
static inline void sc_hwset_dst_wh(struct sc_dev *sc, __s32 width, __s32 height)
{
__raw_writel(SCALER_VAL_WH(width, height), sc->regs + SCALER_DST_WH);
}
static inline void sc_hwset_hratio(struct sc_dev *sc, u32 ratio, u32 pre_ratio)
{
__raw_writel((pre_ratio << 28) | ratio, sc->regs + SCALER_H_RATIO);
}
static inline void sc_hwset_vratio(struct sc_dev *sc, u32 ratio, u32 pre_ratio)
{
__raw_writel((pre_ratio << 28) | ratio, sc->regs + SCALER_V_RATIO);
}
static inline void sc_hwset_flip_rotation(struct sc_dev *sc, u32 flip_rot_cfg)
{
__raw_writel(flip_rot_cfg & 0xF, sc->regs + SCALER_ROT_CFG);
}
static inline void sc_hwset_int_en(struct sc_dev *sc)
{
unsigned int val;
if (sc->version < SCALER_VERSION(3, 0, 0))
val = SCALER_INT_EN_ALL;
else if (sc->version < SCALER_VERSION(4, 0, 1) ||
sc->version == SCALER_VERSION(4, 2, 0))
val = SCALER_INT_EN_ALL_v3;
else
val = SCALER_INT_EN_ALL_v4;
__raw_writel(val, sc->regs + SCALER_INT_EN);
}
static inline void sc_clear_aux_power_cfg(struct sc_dev *sc)
{
/* Clearing all power saving features */
__raw_writel(__raw_readl(sc->regs + SCALER_CFG) & ~SCALER_CFG_DRCG_EN,
sc->regs + SCALER_CFG);
}
static inline void sc_hwset_bus_idle(struct sc_dev *sc)
{
if (sc->version == SCALER_VERSION(5, 0, 1)) {
int cnt = 1000;
__raw_writel(SCALER_CFG_STOP_REQ, sc->regs + SCALER_CFG);
while (cnt-- > 0)
if (__raw_readl(sc->regs + SCALER_CFG)
& SCALER_CFG_RESET_OKAY)
break;
WARN_ON(cnt <= 0);
}
}
static inline void sc_hwset_init(struct sc_dev *sc)
{
unsigned long cfg;
sc_hwset_bus_idle(sc);
#ifdef SC_NO_SOFTRST
cfg = (SCALER_CFG_CSC_Y_OFFSET_SRC | SCALER_CFG_CSC_Y_OFFSET_DST);
#else
cfg = SCALER_CFG_SOFT_RST;
#endif
writel(cfg, sc->regs + SCALER_CFG);
if (sc->version >= SCALER_VERSION(3, 0, 1))
__raw_writel(
__raw_readl(sc->regs + SCALER_CFG) | SCALER_CFG_DRCG_EN,
sc->regs + SCALER_CFG);
if (sc->version >= SCALER_VERSION(4, 0, 1) &&
sc->version != SCALER_VERSION(4, 2, 0)) {
__raw_writel(
__raw_readl(sc->regs + SCALER_CFG) | SCALER_CFG_BURST_RD,
sc->regs + SCALER_CFG);
__raw_writel(
__raw_readl(sc->regs + SCALER_CFG) & ~SCALER_CFG_BURST_WR,
sc->regs + SCALER_CFG);
}
}
static inline void sc_hwset_soft_reset(struct sc_dev *sc)
{
sc_hwset_bus_idle(sc);
writel(SCALER_CFG_SOFT_RST, sc->regs + SCALER_CFG);
}
static inline void sc_hwset_start(struct sc_dev *sc)
{
unsigned long cfg = __raw_readl(sc->regs + SCALER_CFG);
cfg |= SCALER_CFG_START_CMD;
if (sc->version >= SCALER_VERSION(3, 0, 1)) {
cfg |= SCALER_CFG_CORE_BYP_EN;
cfg |= SCALER_CFG_SRAM_CG_EN;
}
writel(cfg, sc->regs + SCALER_CFG);
}
u32 sc_hwget_and_clear_irq_status(struct sc_dev *sc);
#define SCALER_FRACT_VAL(x) (x << (20 - SC_CROP_FRACT_MULTI))
#define SCALER_INIT_PHASE_VAL(i, f) (((i) & 0xf << 20) | \
((SCALER_FRACT_VAL(f)) & 0xfffff))
static inline void sc_hwset_src_init_phase(struct sc_dev *sc, struct sc_init_phase *ip)
{
if (ip->yh) {
__raw_writel(SCALER_INIT_PHASE_VAL(0, ip->yh),
sc->regs + SCALER_SRC_YH_INIT_PHASE);
__raw_writel(SCALER_INIT_PHASE_VAL(0, ip->ch),
sc->regs + SCALER_SRC_CH_INIT_PHASE);
sc_dbg("initial phase value is yh 0x%x, ch 0x%x\n",
SCALER_FRACT_VAL(ip->yh), SCALER_FRACT_VAL(ip->ch));
}
if (ip->yv) {
__raw_writel(SCALER_INIT_PHASE_VAL(0, ip->yv),
sc->regs + SCALER_SRC_YV_INIT_PHASE);
__raw_writel(SCALER_INIT_PHASE_VAL(0, ip->cv),
sc->regs + SCALER_SRC_CV_INIT_PHASE);
sc_dbg("initial phase value is yv 0x%x, cv 0x%x\n",
SCALER_FRACT_VAL(ip->yv), SCALER_FRACT_VAL(ip->cv));
}
}
void sc_hwset_polyphase_hcoef(struct sc_dev *sc,
unsigned int yratio, unsigned int cratio, unsigned int filter);
void sc_hwset_polyphase_vcoef(struct sc_dev *sc,
unsigned int yratio, unsigned int cratio, unsigned int filter);
#endif /*__SCALER_REGS_H__*/