tegrakernel/kernel/nvidia/drivers/video/tegra/dc/nvdisp/nvdisp_priv.h

169 lines
4.5 KiB
C

/*
* nvidia/drivers/video/tegra/nvdisp/nvdisp_priv.h
*
* Copyright (c) 2014-2018, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 __DRIVERS_VIDEO_TEGRA_NVDISP_NVDISP_PRIV_H
#define __DRIVERS_VIDEO_TEGRA_NVDISP_NVDISP_PRIV_H
#include <dc_priv_defs.h>
#include <trace/events/display.h>
#include <linux/tegra-powergate.h>
#include "hw_win_nvdisp.h"
#include "dc_priv.h"
#include <uapi/video/tegra_dc_ext.h>
/* TODO: move to device tree */
#define BASE_ADDRESS_DC_A_WINC 0x00000a00
#define BASE_ADDRESS_DC_A_WIN 0x00000b80
#define BASE_ADDRESS_DC_A_WINBUF 0x00000bc0
#define BASE_ADDRESS_DC_B_WINC 0x00000d00
#define BASE_ADDRESS_DC_B_WIN 0x00000e80
#define BASE_ADDRESS_DC_B_WINBUF 0x00000ec0
#define BASE_ADDRESS_DC_C_WINC 0x00001000
#define BASE_ADDRESS_DC_C_WIN 0x00001180
#define BASE_ADDRESS_DC_C_WINBUF 0x000011c0
#define BASE_ADDRESS_DC_D_WINC 0x00001300
#define BASE_ADDRESS_DC_D_WIN 0x00001480
#define BASE_ADDRESS_DC_D_WINBUF 0x000014c0
#define BASE_ADDRESS_DC_E_WINC 0x00001600
#define BASE_ADDRESS_DC_E_WIN 0x00001780
#define BASE_ADDRESS_DC_E_WINBUF 0x000017c0
#define BASE_ADDRESS_DC_F_WINC 0x00001900
#define BASE_ADDRESS_DC_F_WIN 0x00001a80
#define BASE_ADDRESS_DC_F_WINBUF 0x00001ac0
static u32 BASE_ADDRESS_DC_WIN_WINC[] = {
BASE_ADDRESS_DC_A_WINC,
BASE_ADDRESS_DC_B_WINC,
BASE_ADDRESS_DC_C_WINC,
BASE_ADDRESS_DC_D_WINC,
BASE_ADDRESS_DC_E_WINC,
BASE_ADDRESS_DC_F_WINC,
};
static u32 BASE_ADDRESS_DC_WIN_WIN[] = {
BASE_ADDRESS_DC_A_WIN,
BASE_ADDRESS_DC_B_WIN,
BASE_ADDRESS_DC_C_WIN,
BASE_ADDRESS_DC_D_WIN,
BASE_ADDRESS_DC_E_WIN,
BASE_ADDRESS_DC_F_WIN,
};
static u32 BASE_ADDRESS_DC_WIN_WINBUF[] = {
BASE_ADDRESS_DC_A_WINBUF,
BASE_ADDRESS_DC_B_WINBUF,
BASE_ADDRESS_DC_C_WINBUF,
BASE_ADDRESS_DC_D_WINBUF,
BASE_ADDRESS_DC_E_WINBUF,
BASE_ADDRESS_DC_F_WINBUF,
};
enum {
NVDISP_DEGAMMA_NONE,
NVDISP_DEGAMMA_SRGB,
NVDISP_DEGAMMA_YUV_8_10,
NVDISP_DEGAMMA_YUV_12,
};
#define NVDISP_WIN_ADDR(head, win, word_offset) \
nvdisp_win_offset(win, word_offset) << 2
/* convert window indirect to window direct offsets within a head */
static u32 nvdisp_win_offset(const u32 win, const u32 word_offset)
{
if (word_offset >= win_base_addr_dc_winbuf_r()) /* WINBUF */
return (word_offset - win_base_addr_dc_winbuf_r()) +
BASE_ADDRESS_DC_WIN_WINBUF[win];
else if (word_offset >= win_base_addr_dc_win_r()) /* WIN */
return (word_offset - win_base_addr_dc_win_r()) +
BASE_ADDRESS_DC_WIN_WIN[win];
else if (word_offset >= win_base_addr_dc_winc_r()) /* WINC */
return (word_offset - win_base_addr_dc_winc_r()) +
BASE_ADDRESS_DC_WIN_WINC[win];
else
pr_err("bad window address 0x%x, win %u\n", word_offset, win);
return 0;
}
static inline u32 nvdisp_win_read(struct tegra_dc_win *win, u32 off)
{
u32 ret;
u32 reg;
struct tegra_dc *dc = win->dc;
/* assuming we create three instances of dc for the three heads */
reg = NVDISP_WIN_ADDR(dc->ctrl_num, win->idx, off);
ret = readl(dc->base + reg);
trace_display_readl(dc, ret, dc->base + reg);
return ret;
}
static inline void nvdisp_win_write(struct tegra_dc_win *win, u32 val, u32 off)
{
u32 reg;
struct tegra_dc *dc = win->dc;
reg = NVDISP_WIN_ADDR(dc->ctrl_num, win->idx, off);
trace_display_writel(dc, val, dc->base + reg);
writel(val, dc->base + reg);
}
static inline bool tegra_dc_is_yuv_12bpc(int fmt)
{
switch (tegra_dc_fmt(fmt)) {
case TEGRA_DC_EXT_FMT_T_Y12___U12___V12_N420:
case TEGRA_DC_EXT_FMT_T_Y12___U12___V12_N444:
case TEGRA_DC_EXT_FMT_T_Y12___V12U12_N420:
case TEGRA_DC_EXT_FMT_T_Y12___U12V12_N422:
case TEGRA_DC_EXT_FMT_T_Y12___U12V12_N422R:
case TEGRA_DC_EXT_FMT_T_Y12___U12V12_N444:
case TEGRA_DC_EXT_FMT_T_Y12___U12V12_N420:
case TEGRA_DC_EXT_FMT_T_Y12___V12U12_N422:
case TEGRA_DC_EXT_FMT_T_Y12___V12U12_N422R:
case TEGRA_DC_EXT_FMT_T_Y12___V12U12_N444:
case TEGRA_DC_EXT_FMT_T_Y12___V12___U12_N420:
case TEGRA_DC_EXT_FMT_T_Y12___V12___U12_N444:
return true;
default:
return false;
}
return false;
}
void nvdisp_clock_init(struct tegra_dc *dc);
dma_addr_t __attribute__((weak))
nvdisp_t19x_get_addr_flag(struct tegra_dc_win *win);
void tegra_nvdisp_crc_region_init(void);
#endif