377 lines
11 KiB
C
377 lines
11 KiB
C
|
/*
|
||
|
* 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__*/
|