2019-05-19 15:51:43 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2016-11-10 15:29:37 +01:00
/*
* Copyright ( C ) 2016 BayLibre , SAS
* Author : Neil Armstrong < narmstrong @ baylibre . com >
* Copyright ( C ) 2015 Amlogic , Inc . All rights reserved .
*/
2019-07-16 08:42:02 +02:00
# include <linux/export.h>
# include <drm/drm_modes.h>
2016-11-10 15:29:37 +01:00
# include "meson_drv.h"
2019-07-16 08:42:02 +02:00
# include "meson_registers.h"
2016-11-10 15:29:37 +01:00
# include "meson_venc.h"
# include "meson_vpp.h"
2017-04-04 14:15:29 +02:00
/**
* DOC : Video Encoder
*
2016-11-10 15:29:37 +01:00
* VENC Handle the pixels encoding to the output formats .
* We handle the following encodings :
2017-04-04 14:15:29 +02:00
*
2016-11-10 15:29:37 +01:00
* - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
* - TMDS / HDMI Encoding via ENCI_DIV and ENCP
* - Setup of more clock rates for HDMI modes
2017-04-04 14:15:26 +02:00
*
* What is missing :
2017-04-04 14:15:29 +02:00
*
2016-11-10 15:29:37 +01:00
* - LCD Panel encoding via ENCL
* - TV Panel encoding via ENCT
2017-04-04 14:15:26 +02:00
*
* VENC paths :
2017-04-04 14:15:29 +02:00
*
* . . code : :
*
* _____ _____ ____________________
* vd1 - - - | | - | | | VENC / - - - - - - - - - | - - - - VDAC
* vd2 - - - | VIU | - | VPP | - | - - - - - ENCI / - ENCI_DVI - | - |
* osd1 - - | | - | | | \ | X - - HDMI - TX
* osd2 - - | _____ | - | _____ | | | \ - ENCP - - ENCP_DVI - | - |
* | | |
* | \ - - ENCL - - - - - - - - - - - | - - - - LVDS
* | ____________________ |
2017-04-04 14:15:26 +02:00
*
* The ENCI is designed for PAl or NTSC encoding and can go through the VDAC
* directly for CVBS encoding or through the ENCI_DVI encoder for HDMI .
* The ENCP is designed for Progressive encoding but can also generate
* 1080 i interlaced pixels , and was initialy desined to encode pixels for
* VDAC to output RGB ou YUV analog outputs .
* It ' s output is only used through the ENCP_DVI encoder for HDMI .
* The ENCL LVDS encoder is not implemented .
*
* The ENCI and ENCP encoders needs specially defined parameters for each
* supported mode and thus cannot be determined from standard video timings .
*
* The ENCI end ENCP DVI encoders are more generic and can generate any timings
* from the pixel data generated by ENCI or ENCP , so can use the standard video
* timings are source for HW parameters .
2016-11-10 15:29:37 +01:00
*/
2017-01-02 16:14:15 +01:00
/* HHI Registers */
2018-11-22 17:01:03 +01:00
# define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
2017-01-02 16:14:15 +01:00
# define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
2019-06-24 16:48:57 +02:00
# define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
2017-01-02 16:14:15 +01:00
# define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
2019-06-24 16:48:57 +02:00
# define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
2017-01-02 16:14:15 +01:00
# define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
2016-11-10 15:29:37 +01:00
struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
. mode_tag = MESON_VENC_MODE_CVBS_PAL ,
. hso_begin = 3 ,
. hso_end = 129 ,
. vso_even = 3 ,
. vso_odd = 260 ,
. macv_max_amp = 7 ,
. video_prog_mode = 0xff ,
. video_mode = 0x13 ,
. sch_adjust = 0x28 ,
. yc_delay = 0x343 ,
. pixel_start = 251 ,
. pixel_end = 1691 ,
. top_field_line_start = 22 ,
. top_field_line_end = 310 ,
. bottom_field_line_start = 23 ,
. bottom_field_line_end = 311 ,
. video_saturation = 9 ,
. video_contrast = 0 ,
. video_brightness = 0 ,
. video_hue = 0 ,
. analog_sync_adj = 0x8080 ,
} ;
struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
. mode_tag = MESON_VENC_MODE_CVBS_NTSC ,
. hso_begin = 5 ,
. hso_end = 129 ,
. vso_even = 3 ,
. vso_odd = 260 ,
. macv_max_amp = 0xb ,
. video_prog_mode = 0xf0 ,
. video_mode = 0x8 ,
. sch_adjust = 0x20 ,
. yc_delay = 0x333 ,
. pixel_start = 227 ,
. pixel_end = 1667 ,
. top_field_line_start = 18 ,
. top_field_line_end = 258 ,
. bottom_field_line_start = 19 ,
. bottom_field_line_end = 259 ,
. video_saturation = 18 ,
. video_contrast = 3 ,
. video_brightness = 0 ,
. video_hue = 0 ,
. analog_sync_adj = 0x9c00 ,
} ;
2017-04-04 14:15:26 +02:00
union meson_hdmi_venc_mode {
struct {
unsigned int mode_tag ;
unsigned int hso_begin ;
unsigned int hso_end ;
unsigned int vso_even ;
unsigned int vso_odd ;
unsigned int macv_max_amp ;
unsigned int video_prog_mode ;
unsigned int video_mode ;
unsigned int sch_adjust ;
unsigned int yc_delay ;
unsigned int pixel_start ;
unsigned int pixel_end ;
unsigned int top_field_line_start ;
unsigned int top_field_line_end ;
unsigned int bottom_field_line_start ;
unsigned int bottom_field_line_end ;
} enci ;
struct {
unsigned int dvi_settings ;
unsigned int video_mode ;
unsigned int video_mode_adv ;
unsigned int video_prog_mode ;
bool video_prog_mode_present ;
unsigned int video_sync_mode ;
bool video_sync_mode_present ;
unsigned int video_yc_dly ;
bool video_yc_dly_present ;
unsigned int video_rgb_ctrl ;
bool video_rgb_ctrl_present ;
unsigned int video_filt_ctrl ;
bool video_filt_ctrl_present ;
unsigned int video_ofld_voav_ofst ;
bool video_ofld_voav_ofst_present ;
unsigned int yfp1_htime ;
unsigned int yfp2_htime ;
unsigned int max_pxcnt ;
unsigned int hspuls_begin ;
unsigned int hspuls_end ;
unsigned int hspuls_switch ;
unsigned int vspuls_begin ;
unsigned int vspuls_end ;
unsigned int vspuls_bline ;
unsigned int vspuls_eline ;
unsigned int eqpuls_begin ;
bool eqpuls_begin_present ;
unsigned int eqpuls_end ;
bool eqpuls_end_present ;
unsigned int eqpuls_bline ;
bool eqpuls_bline_present ;
unsigned int eqpuls_eline ;
bool eqpuls_eline_present ;
unsigned int havon_begin ;
unsigned int havon_end ;
unsigned int vavon_bline ;
unsigned int vavon_eline ;
unsigned int hso_begin ;
unsigned int hso_end ;
unsigned int vso_begin ;
unsigned int vso_end ;
unsigned int vso_bline ;
unsigned int vso_eline ;
bool vso_eline_present ;
unsigned int sy_val ;
bool sy_val_present ;
unsigned int sy2_val ;
bool sy2_val_present ;
unsigned int max_lncnt ;
} encp ;
} ;
union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
. enci = {
. hso_begin = 5 ,
. hso_end = 129 ,
. vso_even = 3 ,
. vso_odd = 260 ,
2019-06-24 16:49:12 +02:00
. macv_max_amp = 0xb ,
2017-04-04 14:15:26 +02:00
. video_prog_mode = 0xf0 ,
. video_mode = 0x8 ,
. sch_adjust = 0x20 ,
. yc_delay = 0 ,
. pixel_start = 227 ,
. pixel_end = 1667 ,
. top_field_line_start = 18 ,
. top_field_line_end = 258 ,
. bottom_field_line_start = 19 ,
. bottom_field_line_end = 259 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
. enci = {
. hso_begin = 3 ,
. hso_end = 129 ,
. vso_even = 3 ,
. vso_odd = 260 ,
2019-06-24 16:49:12 +02:00
. macv_max_amp = 0x7 ,
2017-04-04 14:15:26 +02:00
. video_prog_mode = 0xff ,
. video_mode = 0x13 ,
. sch_adjust = 0x28 ,
. yc_delay = 0x333 ,
. pixel_start = 251 ,
. pixel_end = 1691 ,
. top_field_line_start = 22 ,
. top_field_line_end = 310 ,
. bottom_field_line_start = 23 ,
. bottom_field_line_end = 311 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
. encp = {
. dvi_settings = 0x21 ,
. video_mode = 0x4000 ,
. video_mode_adv = 0x9 ,
. video_prog_mode = 0 ,
. video_prog_mode_present = true ,
. video_sync_mode = 7 ,
. video_sync_mode_present = true ,
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x2052 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 244 ,
. yfp2_htime = 1630 ,
. max_pxcnt = 1715 ,
. hspuls_begin = 0x22 ,
. hspuls_end = 0xa0 ,
. hspuls_switch = 88 ,
. vspuls_begin = 0 ,
. vspuls_end = 1589 ,
. vspuls_bline = 0 ,
. vspuls_eline = 5 ,
. havon_begin = 249 ,
. havon_end = 1689 ,
. vavon_bline = 42 ,
. vavon_eline = 521 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 3 ,
. hso_end = 5 ,
. vso_begin = 3 ,
. vso_end = 5 ,
. vso_bline = 0 ,
/* vso_eline */
. sy_val = 8 ,
. sy_val_present = true ,
. sy2_val = 0x1d8 ,
. sy2_val_present = true ,
. max_lncnt = 524 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
. encp = {
. dvi_settings = 0x21 ,
. video_mode = 0x4000 ,
. video_mode_adv = 0x9 ,
. video_prog_mode = 0 ,
. video_prog_mode_present = true ,
. video_sync_mode = 7 ,
. video_sync_mode_present = true ,
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x52 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 235 ,
. yfp2_htime = 1674 ,
. max_pxcnt = 1727 ,
. hspuls_begin = 0 ,
. hspuls_end = 0x80 ,
. hspuls_switch = 88 ,
. vspuls_begin = 0 ,
. vspuls_end = 1599 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 235 ,
. havon_end = 1674 ,
. vavon_bline = 44 ,
. vavon_eline = 619 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 0x80 ,
. hso_end = 0 ,
. vso_begin = 0 ,
. vso_end = 5 ,
. vso_bline = 0 ,
/* vso_eline */
. sy_val = 8 ,
. sy_val_present = true ,
. sy2_val = 0x1d8 ,
. sy2_val_present = true ,
. max_lncnt = 624 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
. encp = {
. dvi_settings = 0x2029 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x19 ,
/* video_prog_mode */
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
/* video_filt_ctrl */
/* video_ofld_voav_ofst */
. yfp1_htime = 648 ,
. yfp2_htime = 3207 ,
. max_pxcnt = 3299 ,
. hspuls_begin = 80 ,
. hspuls_end = 240 ,
. hspuls_switch = 80 ,
. vspuls_begin = 688 ,
. vspuls_end = 3248 ,
. vspuls_bline = 4 ,
. vspuls_eline = 8 ,
. havon_begin = 648 ,
. havon_end = 3207 ,
. vavon_bline = 29 ,
. vavon_eline = 748 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 256 ,
. hso_end = 168 ,
. vso_begin = 168 ,
. vso_end = 256 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 749 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
. encp = {
. dvi_settings = 0x202d ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x19 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
. video_sync_mode = 0x407 ,
. video_sync_mode_present = true ,
. video_yc_dly = 0 ,
. video_yc_dly_present = true ,
/* video_rgb_ctrl */
/* video_filt_ctrl */
/* video_ofld_voav_ofst */
. yfp1_htime = 648 ,
. yfp2_htime = 3207 ,
. max_pxcnt = 3959 ,
. hspuls_begin = 80 ,
. hspuls_end = 240 ,
. hspuls_switch = 80 ,
. vspuls_begin = 688 ,
. vspuls_end = 3248 ,
. vspuls_bline = 4 ,
. vspuls_eline = 8 ,
. havon_begin = 648 ,
. havon_end = 3207 ,
. vavon_bline = 29 ,
. vavon_eline = 748 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 128 ,
. hso_end = 208 ,
. vso_begin = 128 ,
. vso_end = 128 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 749 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
. encp = {
. dvi_settings = 0x2029 ,
. video_mode = 0x5ffc ,
. video_mode_adv = 0x19 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
. video_sync_mode = 0x207 ,
. video_sync_mode_present = true ,
/* video_yc_dly */
/* video_rgb_ctrl */
/* video_filt_ctrl */
. video_ofld_voav_ofst = 0x11 ,
. video_ofld_voav_ofst_present = true ,
. yfp1_htime = 516 ,
. yfp2_htime = 4355 ,
. max_pxcnt = 4399 ,
. hspuls_begin = 88 ,
. hspuls_end = 264 ,
. hspuls_switch = 88 ,
. vspuls_begin = 440 ,
. vspuls_end = 2200 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 516 ,
. havon_end = 4355 ,
. vavon_bline = 20 ,
. vavon_eline = 559 ,
. eqpuls_begin = 2288 ,
. eqpuls_begin_present = true ,
. eqpuls_end = 2464 ,
. eqpuls_end_present = true ,
. eqpuls_bline = 0 ,
. eqpuls_bline_present = true ,
. eqpuls_eline = 4 ,
. eqpuls_eline_present = true ,
. hso_begin = 264 ,
. hso_end = 176 ,
. vso_begin = 88 ,
. vso_end = 88 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
. encp = {
. dvi_settings = 0x202d ,
. video_mode = 0x5ffc ,
. video_mode_adv = 0x19 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
. video_sync_mode = 0x7 ,
. video_sync_mode_present = true ,
/* video_yc_dly */
/* video_rgb_ctrl */
/* video_filt_ctrl */
. video_ofld_voav_ofst = 0x11 ,
. video_ofld_voav_ofst_present = true ,
. yfp1_htime = 526 ,
. yfp2_htime = 4365 ,
. max_pxcnt = 5279 ,
. hspuls_begin = 88 ,
. hspuls_end = 264 ,
. hspuls_switch = 88 ,
. vspuls_begin = 440 ,
. vspuls_end = 2200 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 526 ,
. havon_end = 4365 ,
. vavon_bline = 20 ,
. vavon_eline = 559 ,
. eqpuls_begin = 2288 ,
. eqpuls_begin_present = true ,
. eqpuls_end = 2464 ,
. eqpuls_end_present = true ,
. eqpuls_bline = 0 ,
. eqpuls_bline_present = true ,
. eqpuls_eline = 4 ,
. eqpuls_eline_present = true ,
. hso_begin = 142 ,
. hso_end = 230 ,
. vso_begin = 142 ,
. vso_end = 142 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
. encp = {
. dvi_settings = 0xd ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x18 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
. video_sync_mode = 0x7 ,
. video_sync_mode_present = true ,
. video_yc_dly = 0 ,
. video_yc_dly_present = true ,
. video_rgb_ctrl = 2 ,
. video_rgb_ctrl_present = true ,
. video_filt_ctrl = 0x1052 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 271 ,
. yfp2_htime = 2190 ,
. max_pxcnt = 2749 ,
. hspuls_begin = 44 ,
. hspuls_end = 132 ,
. hspuls_switch = 44 ,
. vspuls_begin = 220 ,
. vspuls_end = 2140 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 271 ,
. havon_end = 2190 ,
. vavon_bline = 41 ,
. vavon_eline = 1120 ,
/* eqpuls_begin */
/* eqpuls_end */
. eqpuls_bline = 0 ,
. eqpuls_bline_present = true ,
. eqpuls_eline = 4 ,
. eqpuls_eline_present = true ,
. hso_begin = 79 ,
. hso_end = 123 ,
. vso_begin = 79 ,
. vso_end = 79 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
. encp = {
. dvi_settings = 0x1 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x18 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x1052 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 140 ,
. yfp2_htime = 2060 ,
. max_pxcnt = 2199 ,
. hspuls_begin = 2156 ,
. hspuls_end = 44 ,
. hspuls_switch = 44 ,
. vspuls_begin = 140 ,
. vspuls_end = 2059 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 148 ,
. havon_end = 2067 ,
. vavon_bline = 41 ,
. vavon_eline = 1120 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 44 ,
. hso_end = 2156 ,
. vso_begin = 2100 ,
. vso_end = 2164 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
. encp = {
. dvi_settings = 0xd ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x18 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
. video_sync_mode = 0x7 ,
. video_sync_mode_present = true ,
. video_yc_dly = 0 ,
. video_yc_dly_present = true ,
. video_rgb_ctrl = 2 ,
. video_rgb_ctrl_present = true ,
/* video_filt_ctrl */
/* video_ofld_voav_ofst */
. yfp1_htime = 271 ,
. yfp2_htime = 2190 ,
. max_pxcnt = 2639 ,
. hspuls_begin = 44 ,
. hspuls_end = 132 ,
. hspuls_switch = 44 ,
. vspuls_begin = 220 ,
. vspuls_end = 2140 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 271 ,
. havon_end = 2190 ,
. vavon_bline = 41 ,
. vavon_eline = 1120 ,
/* eqpuls_begin */
/* eqpuls_end */
. eqpuls_bline = 0 ,
. eqpuls_bline_present = true ,
. eqpuls_eline = 4 ,
. eqpuls_eline_present = true ,
. hso_begin = 79 ,
. hso_end = 123 ,
. vso_begin = 79 ,
. vso_end = 79 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
. encp = {
. dvi_settings = 0x1 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x18 ,
. video_prog_mode = 0x100 ,
. video_prog_mode_present = true ,
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x1052 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 140 ,
. yfp2_htime = 2060 ,
. max_pxcnt = 2199 ,
. hspuls_begin = 2156 ,
. hspuls_end = 44 ,
. hspuls_switch = 44 ,
. vspuls_begin = 140 ,
. vspuls_end = 2059 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 148 ,
. havon_end = 2067 ,
. vavon_bline = 41 ,
. vavon_eline = 1120 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 44 ,
. hso_end = 2156 ,
. vso_begin = 2100 ,
. vso_end = 2164 ,
. vso_bline = 0 ,
. vso_eline = 5 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 1124 ,
} ,
} ;
2018-11-06 10:35:09 +01:00
union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
. encp = {
. dvi_settings = 0x1 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x8 ,
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x1000 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 140 ,
. yfp2_htime = 140 + 3840 ,
. max_pxcnt = 3840 + 1660 - 1 ,
. hspuls_begin = 2156 + 1920 ,
. hspuls_end = 44 ,
. hspuls_switch = 44 ,
. vspuls_begin = 140 ,
. vspuls_end = 2059 + 1920 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 148 ,
. havon_end = 3987 ,
. vavon_bline = 89 ,
. vavon_eline = 2248 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 44 ,
. hso_end = 2156 + 1920 ,
. vso_begin = 2100 + 1920 ,
. vso_end = 2164 + 1920 ,
. vso_bline = 51 ,
. vso_eline = 53 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 2249 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
. encp = {
. dvi_settings = 0x1 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x8 ,
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x1000 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 140 ,
. yfp2_htime = 140 + 3840 ,
. max_pxcnt = 3840 + 1440 - 1 ,
. hspuls_begin = 2156 + 1920 ,
. hspuls_end = 44 ,
. hspuls_switch = 44 ,
. vspuls_begin = 140 ,
. vspuls_end = 2059 + 1920 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 148 ,
. havon_end = 3987 ,
. vavon_bline = 89 ,
. vavon_eline = 2248 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 44 ,
. hso_end = 2156 + 1920 ,
. vso_begin = 2100 + 1920 ,
. vso_end = 2164 + 1920 ,
. vso_bline = 51 ,
. vso_eline = 53 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 2249 ,
} ,
} ;
union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
. encp = {
. dvi_settings = 0x1 ,
. video_mode = 0x4040 ,
. video_mode_adv = 0x8 ,
/* video_sync_mode */
/* video_yc_dly */
/* video_rgb_ctrl */
. video_filt_ctrl = 0x1000 ,
. video_filt_ctrl_present = true ,
/* video_ofld_voav_ofst */
. yfp1_htime = 140 ,
. yfp2_htime = 140 + 3840 ,
. max_pxcnt = 3840 + 560 - 1 ,
. hspuls_begin = 2156 + 1920 ,
. hspuls_end = 44 ,
. hspuls_switch = 44 ,
. vspuls_begin = 140 ,
. vspuls_end = 2059 + 1920 ,
. vspuls_bline = 0 ,
. vspuls_eline = 4 ,
. havon_begin = 148 ,
. havon_end = 3987 ,
. vavon_bline = 89 ,
. vavon_eline = 2248 ,
/* eqpuls_begin */
/* eqpuls_end */
/* eqpuls_bline */
/* eqpuls_eline */
. hso_begin = 44 ,
. hso_end = 2156 + 1920 ,
. vso_begin = 2100 + 1920 ,
. vso_end = 2164 + 1920 ,
. vso_bline = 51 ,
. vso_eline = 53 ,
. vso_eline_present = true ,
/* sy_val */
/* sy2_val */
. max_lncnt = 2249 ,
} ,
} ;
2017-04-04 14:15:26 +02:00
struct meson_hdmi_venc_vic_mode {
unsigned int vic ;
union meson_hdmi_venc_mode * mode ;
} meson_hdmi_venc_vic_modes [ ] = {
{ 6 , & meson_hdmi_enci_mode_480i } ,
{ 7 , & meson_hdmi_enci_mode_480i } ,
{ 21 , & meson_hdmi_enci_mode_576i } ,
{ 22 , & meson_hdmi_enci_mode_576i } ,
{ 2 , & meson_hdmi_encp_mode_480p } ,
{ 3 , & meson_hdmi_encp_mode_480p } ,
{ 17 , & meson_hdmi_encp_mode_576p } ,
{ 18 , & meson_hdmi_encp_mode_576p } ,
{ 4 , & meson_hdmi_encp_mode_720p60 } ,
{ 19 , & meson_hdmi_encp_mode_720p50 } ,
{ 5 , & meson_hdmi_encp_mode_1080i60 } ,
{ 20 , & meson_hdmi_encp_mode_1080i50 } ,
{ 32 , & meson_hdmi_encp_mode_1080p24 } ,
2018-11-21 13:39:29 +04:00
{ 33 , & meson_hdmi_encp_mode_1080p50 } ,
2017-04-04 14:15:26 +02:00
{ 34 , & meson_hdmi_encp_mode_1080p30 } ,
{ 31 , & meson_hdmi_encp_mode_1080p50 } ,
{ 16 , & meson_hdmi_encp_mode_1080p60 } ,
2018-11-06 10:35:09 +01:00
{ 93 , & meson_hdmi_encp_mode_2160p24 } ,
{ 94 , & meson_hdmi_encp_mode_2160p25 } ,
{ 95 , & meson_hdmi_encp_mode_2160p30 } ,
2019-02-01 12:07:48 +00:00
{ 96 , & meson_hdmi_encp_mode_2160p25 } ,
{ 97 , & meson_hdmi_encp_mode_2160p30 } ,
2017-04-04 14:15:26 +02:00
{ 0 , NULL } , /* sentinel */
} ;
static signed int to_signed ( unsigned int a )
{
if ( a < = 7 )
return a ;
else
return a - 16 ;
}
static unsigned long modulo ( unsigned long a , unsigned long b )
{
if ( a > = b )
return a - b ;
else
return a ;
}
2018-07-16 09:40:14 +02:00
enum drm_mode_status
meson_venc_hdmi_supported_mode ( const struct drm_display_mode * mode )
2018-03-13 11:07:50 +01:00
{
2018-07-16 09:40:14 +02:00
if ( mode - > flags & ~ ( DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC ) )
return MODE_BAD ;
2018-03-13 11:07:50 +01:00
2018-07-16 09:40:14 +02:00
if ( mode - > hdisplay < 640 | | mode - > hdisplay > 1920 )
return MODE_BAD_HVALUE ;
2018-03-13 11:07:50 +01:00
2018-07-16 09:40:14 +02:00
if ( mode - > vdisplay < 480 | | mode - > vdisplay > 1200 )
return MODE_BAD_VVALUE ;
return MODE_OK ;
2018-03-13 11:07:50 +01:00
}
EXPORT_SYMBOL_GPL ( meson_venc_hdmi_supported_mode ) ;
2017-04-04 14:15:26 +02:00
bool meson_venc_hdmi_supported_vic ( int vic )
{
struct meson_hdmi_venc_vic_mode * vmode = meson_hdmi_venc_vic_modes ;
while ( vmode - > vic & & vmode - > mode ) {
if ( vmode - > vic = = vic )
return true ;
vmode + + ;
}
return false ;
}
EXPORT_SYMBOL_GPL ( meson_venc_hdmi_supported_vic ) ;
2018-07-16 09:40:14 +02:00
void meson_venc_hdmi_get_dmt_vmode ( const struct drm_display_mode * mode ,
union meson_hdmi_venc_mode * dmt_mode )
2018-03-13 11:07:50 +01:00
{
2018-07-16 09:40:14 +02:00
memset ( dmt_mode , 0 , sizeof ( * dmt_mode ) ) ;
dmt_mode - > encp . dvi_settings = 0x21 ;
dmt_mode - > encp . video_mode = 0x4040 ;
dmt_mode - > encp . video_mode_adv = 0x18 ;
dmt_mode - > encp . max_pxcnt = mode - > htotal - 1 ;
dmt_mode - > encp . havon_begin = mode - > htotal - mode - > hsync_start ;
dmt_mode - > encp . havon_end = dmt_mode - > encp . havon_begin +
mode - > hdisplay - 1 ;
dmt_mode - > encp . vavon_bline = mode - > vtotal - mode - > vsync_start ;
dmt_mode - > encp . vavon_eline = dmt_mode - > encp . vavon_bline +
mode - > vdisplay - 1 ;
dmt_mode - > encp . hso_begin = 0 ;
dmt_mode - > encp . hso_end = mode - > hsync_end - mode - > hsync_start ;
dmt_mode - > encp . vso_begin = 30 ;
dmt_mode - > encp . vso_end = 50 ;
dmt_mode - > encp . vso_bline = 0 ;
dmt_mode - > encp . vso_eline = mode - > vsync_end - mode - > vsync_start ;
dmt_mode - > encp . vso_eline_present = true ;
dmt_mode - > encp . max_lncnt = mode - > vtotal - 1 ;
2018-03-13 11:07:50 +01:00
}
2017-04-04 14:15:26 +02:00
static union meson_hdmi_venc_mode * meson_venc_hdmi_get_vic_vmode ( int vic )
{
struct meson_hdmi_venc_vic_mode * vmode = meson_hdmi_venc_vic_modes ;
while ( vmode - > vic & & vmode - > mode ) {
if ( vmode - > vic = = vic )
return vmode - > mode ;
vmode + + ;
}
return NULL ;
}
bool meson_venc_hdmi_venc_repeat ( int vic )
{
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
if ( vic = = 6 | | vic = = 7 | | /* 480i */
vic = = 21 | | vic = = 22 | | /* 576i */
vic = = 17 | | vic = = 18 | | /* 576p */
vic = = 2 | | vic = = 3 | | /* 480p */
vic = = 4 | | /* 720p60 */
vic = = 19 | | /* 720p50 */
vic = = 5 | | /* 1080i60 */
vic = = 20 ) /* 1080i50 */
return true ;
return false ;
}
EXPORT_SYMBOL_GPL ( meson_venc_hdmi_venc_repeat ) ;
void meson_venc_hdmi_mode_set ( struct meson_drm * priv , int vic ,
2020-03-04 11:40:50 +01:00
unsigned int ycrcb_map ,
bool yuv420_mode ,
2020-03-04 11:40:47 +01:00
const struct drm_display_mode * mode )
2017-04-04 14:15:26 +02:00
{
union meson_hdmi_venc_mode * vmode = NULL ;
2018-07-16 09:40:14 +02:00
union meson_hdmi_venc_mode vmode_dmt ;
2017-04-04 14:15:26 +02:00
bool use_enci = false ;
bool venc_repeat = false ;
bool hdmi_repeat = false ;
unsigned int venc_hdmi_latency = 2 ;
unsigned long total_pixels_venc = 0 ;
unsigned long active_pixels_venc = 0 ;
unsigned long front_porch_venc = 0 ;
unsigned long hsync_pixels_venc = 0 ;
unsigned long de_h_begin = 0 ;
unsigned long de_h_end = 0 ;
unsigned long de_v_begin_even = 0 ;
unsigned long de_v_end_even = 0 ;
unsigned long de_v_begin_odd = 0 ;
unsigned long de_v_end_odd = 0 ;
unsigned long hs_begin = 0 ;
unsigned long hs_end = 0 ;
unsigned long vs_adjust = 0 ;
unsigned long vs_bline_evn = 0 ;
unsigned long vs_eline_evn = 0 ;
unsigned long vs_bline_odd = 0 ;
unsigned long vs_eline_odd = 0 ;
unsigned long vso_begin_evn = 0 ;
unsigned long vso_begin_odd = 0 ;
unsigned int eof_lines ;
unsigned int sof_lines ;
unsigned int vsync_lines ;
2019-06-24 16:48:50 +02:00
u32 reg ;
2017-04-04 14:15:26 +02:00
2018-11-12 19:41:09 +01:00
/* Use VENCI for 480i and 576i and double HDMI pixels */
if ( mode - > flags & DRM_MODE_FLAG_DBLCLK ) {
hdmi_repeat = true ;
use_enci = true ;
venc_hdmi_latency = 1 ;
}
2018-07-16 09:40:14 +02:00
if ( meson_venc_hdmi_supported_vic ( vic ) ) {
2018-03-13 11:07:50 +01:00
vmode = meson_venc_hdmi_get_vic_vmode ( vic ) ;
2018-07-16 09:40:14 +02:00
if ( ! vmode ) {
dev_err ( priv - > dev , " %s: Fatal Error, unsupported mode "
DRM_MODE_FMT " \n " , __func__ ,
DRM_MODE_ARG ( mode ) ) ;
return ;
}
} else {
meson_venc_hdmi_get_dmt_vmode ( mode , & vmode_dmt ) ;
vmode = & vmode_dmt ;
2018-11-12 19:41:09 +01:00
use_enci = false ;
2017-04-04 14:15:26 +02:00
}
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
if ( meson_venc_hdmi_venc_repeat ( vic ) )
venc_repeat = true ;
eof_lines = mode - > vsync_start - mode - > vdisplay ;
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE )
eof_lines / = 2 ;
sof_lines = mode - > vtotal - mode - > vsync_end ;
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE )
sof_lines / = 2 ;
vsync_lines = mode - > vsync_end - mode - > vsync_start ;
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE )
vsync_lines / = 2 ;
total_pixels_venc = mode - > htotal ;
if ( hdmi_repeat )
total_pixels_venc / = 2 ;
if ( venc_repeat )
total_pixels_venc * = 2 ;
active_pixels_venc = mode - > hdisplay ;
if ( hdmi_repeat )
active_pixels_venc / = 2 ;
if ( venc_repeat )
active_pixels_venc * = 2 ;
front_porch_venc = ( mode - > hsync_start - mode - > hdisplay ) ;
if ( hdmi_repeat )
front_porch_venc / = 2 ;
if ( venc_repeat )
front_porch_venc * = 2 ;
hsync_pixels_venc = ( mode - > hsync_end - mode - > hsync_start ) ;
if ( hdmi_repeat )
hsync_pixels_venc / = 2 ;
if ( venc_repeat )
hsync_pixels_venc * = 2 ;
/* Disable VDACs */
2018-03-13 11:07:50 +01:00
writel_bits_relaxed ( 0xff , 0xff ,
2017-04-04 14:15:26 +02:00
priv - > io_base + _REG ( VENC_VDAC_SETTING ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_EN ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCP_VIDEO_EN ) ) ;
if ( use_enci ) {
unsigned int lines_f0 ;
unsigned int lines_f1 ;
/* CVBS Filter settings */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_CFILT_CMPT_SEL_HIGH | 0x10 ,
priv - > io_base + _REG ( ENCI_CFILT_CTRL ) ) ;
writel_relaxed ( ENCI_CFILT_CMPT_CR_DLY ( 2 ) |
ENCI_CFILT_CMPT_CB_DLY ( 1 ) ,
priv - > io_base + _REG ( ENCI_CFILT_CTRL2 ) ) ;
2017-04-04 14:15:26 +02:00
/* Digital Video Select : Interlace, clk27 clk, external */
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_DVI_SETTING ) ) ;
/* Reset Video Mode */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_MODE ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_MODE_ADV ) ) ;
/* Horizontal sync signal output */
writel_relaxed ( vmode - > enci . hso_begin ,
priv - > io_base + _REG ( ENCI_SYNC_HSO_BEGIN ) ) ;
writel_relaxed ( vmode - > enci . hso_end ,
priv - > io_base + _REG ( ENCI_SYNC_HSO_END ) ) ;
/* Vertical Sync lines */
writel_relaxed ( vmode - > enci . vso_even ,
priv - > io_base + _REG ( ENCI_SYNC_VSO_EVNLN ) ) ;
writel_relaxed ( vmode - > enci . vso_odd ,
priv - > io_base + _REG ( ENCI_SYNC_VSO_ODDLN ) ) ;
/* Macrovision max amplitude change */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
ENCI_MACV_MAX_AMP_VAL ( vmode - > enci . macv_max_amp ) ,
priv - > io_base + _REG ( ENCI_MACV_MAX_AMP ) ) ;
2017-04-04 14:15:26 +02:00
/* Video mode */
writel_relaxed ( vmode - > enci . video_prog_mode ,
priv - > io_base + _REG ( VENC_VIDEO_PROG_MODE ) ) ;
writel_relaxed ( vmode - > enci . video_mode ,
priv - > io_base + _REG ( ENCI_VIDEO_MODE ) ) ;
2019-06-24 16:48:57 +02:00
/*
* Advanced Video Mode :
2017-04-04 14:15:26 +02:00
* Demux shifting 0x2
* Blank line end at line17 / 22
* High bandwidth Luma Filter
* Low bandwidth Chroma Filter
* Bypass luma low pass filter
* No macrovision on CSYNC
*/
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_VIDEO_MODE_ADV_DMXMD ( 2 ) |
ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
ENCI_VIDEO_MODE_ADV_YBW_HIGH ,
priv - > io_base + _REG ( ENCI_VIDEO_MODE_ADV ) ) ;
2017-04-04 14:15:26 +02:00
writel ( vmode - > enci . sch_adjust ,
priv - > io_base + _REG ( ENCI_VIDEO_SCH ) ) ;
/* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
writel_relaxed ( 0x07 , priv - > io_base + _REG ( ENCI_SYNC_MODE ) ) ;
if ( vmode - > enci . yc_delay )
writel_relaxed ( vmode - > enci . yc_delay ,
priv - > io_base + _REG ( ENCI_YC_DELAY ) ) ;
/* UNreset Interlaced TV Encoder */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_DBG_PX_RST ) ) ;
2019-06-24 16:48:50 +02:00
/*
* Enable Vfifo2vd and set Y_Cb_Y_Cr :
* Corresponding value :
* Y = > 00 or 10
* Cb = > 01
* Cr = > 11
* Ex : 0x4e = > 01001110 would mean Cb / Y / Cr / Y
*/
writel_relaxed ( ENCI_VFIFO2VD_CTL_ENABLE |
ENCI_VFIFO2VD_CTL_VD_SEL ( 0x4e ) ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_CTL ) ) ;
2017-04-04 14:15:26 +02:00
/* Timings */
writel_relaxed ( vmode - > enci . pixel_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_PIXEL_START ) ) ;
writel_relaxed ( vmode - > enci . pixel_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_PIXEL_END ) ) ;
writel_relaxed ( vmode - > enci . top_field_line_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_TOP_START ) ) ;
writel_relaxed ( vmode - > enci . top_field_line_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_TOP_END ) ) ;
writel_relaxed ( vmode - > enci . bottom_field_line_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_BOT_START ) ) ;
writel_relaxed ( vmode - > enci . bottom_field_line_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_BOT_END ) ) ;
/* Select ENCI for VIU */
meson_vpp_setup_mux ( priv , MESON_VIU_VPP_MUX_ENCI ) ;
/* Interlace video enable */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_VIDEO_EN_ENABLE ,
priv - > io_base + _REG ( ENCI_VIDEO_EN ) ) ;
2017-04-04 14:15:26 +02:00
lines_f0 = mode - > vtotal > > 1 ;
lines_f1 = lines_f0 + 1 ;
de_h_begin = modulo ( readl_relaxed ( priv - > io_base +
_REG ( ENCI_VFIFO2VD_PIXEL_START ) )
+ venc_hdmi_latency ,
total_pixels_venc ) ;
de_h_end = modulo ( de_h_begin + active_pixels_venc ,
total_pixels_venc ) ;
writel_relaxed ( de_h_begin ,
priv - > io_base + _REG ( ENCI_DE_H_BEGIN ) ) ;
writel_relaxed ( de_h_end ,
priv - > io_base + _REG ( ENCI_DE_H_END ) ) ;
de_v_begin_even = readl_relaxed ( priv - > io_base +
_REG ( ENCI_VFIFO2VD_LINE_TOP_START ) ) ;
de_v_end_even = de_v_begin_even + mode - > vdisplay ;
de_v_begin_odd = readl_relaxed ( priv - > io_base +
_REG ( ENCI_VFIFO2VD_LINE_BOT_START ) ) ;
de_v_end_odd = de_v_begin_odd + mode - > vdisplay ;
writel_relaxed ( de_v_begin_even ,
priv - > io_base + _REG ( ENCI_DE_V_BEGIN_EVEN ) ) ;
writel_relaxed ( de_v_end_even ,
priv - > io_base + _REG ( ENCI_DE_V_END_EVEN ) ) ;
writel_relaxed ( de_v_begin_odd ,
priv - > io_base + _REG ( ENCI_DE_V_BEGIN_ODD ) ) ;
writel_relaxed ( de_v_end_odd ,
priv - > io_base + _REG ( ENCI_DE_V_END_ODD ) ) ;
/* Program Hsync timing */
hs_begin = de_h_end + front_porch_venc ;
if ( de_h_end + front_porch_venc > = total_pixels_venc ) {
hs_begin - = total_pixels_venc ;
vs_adjust = 1 ;
} else {
hs_begin = de_h_end + front_porch_venc ;
vs_adjust = 0 ;
}
hs_end = modulo ( hs_begin + hsync_pixels_venc ,
total_pixels_venc ) ;
writel_relaxed ( hs_begin ,
priv - > io_base + _REG ( ENCI_DVI_HSO_BEGIN ) ) ;
writel_relaxed ( hs_end ,
priv - > io_base + _REG ( ENCI_DVI_HSO_END ) ) ;
/* Program Vsync timing for even field */
if ( ( ( de_v_end_odd - 1 ) + eof_lines + vs_adjust ) > = lines_f1 ) {
vs_bline_evn = ( de_v_end_odd - 1 )
+ eof_lines
+ vs_adjust
- lines_f1 ;
vs_eline_evn = vs_bline_evn + vsync_lines ;
writel_relaxed ( vs_bline_evn ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BLINE_EVN ) ) ;
writel_relaxed ( vs_eline_evn ,
priv - > io_base + _REG ( ENCI_DVI_VSO_ELINE_EVN ) ) ;
writel_relaxed ( hs_begin ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BEGIN_EVN ) ) ;
writel_relaxed ( hs_begin ,
priv - > io_base + _REG ( ENCI_DVI_VSO_END_EVN ) ) ;
} else {
vs_bline_odd = ( de_v_end_odd - 1 )
+ eof_lines
+ vs_adjust ;
writel_relaxed ( vs_bline_odd ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BLINE_ODD ) ) ;
writel_relaxed ( hs_begin ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BEGIN_ODD ) ) ;
if ( ( vs_bline_odd + vsync_lines ) > = lines_f1 ) {
vs_eline_evn = vs_bline_odd
+ vsync_lines
- lines_f1 ;
writel_relaxed ( vs_eline_evn , priv - > io_base
+ _REG ( ENCI_DVI_VSO_ELINE_EVN ) ) ;
writel_relaxed ( hs_begin , priv - > io_base
+ _REG ( ENCI_DVI_VSO_END_EVN ) ) ;
} else {
vs_eline_odd = vs_bline_odd
+ vsync_lines ;
writel_relaxed ( vs_eline_odd , priv - > io_base
+ _REG ( ENCI_DVI_VSO_ELINE_ODD ) ) ;
writel_relaxed ( hs_begin , priv - > io_base
+ _REG ( ENCI_DVI_VSO_END_ODD ) ) ;
}
}
/* Program Vsync timing for odd field */
if ( ( ( de_v_end_even - 1 ) + ( eof_lines + 1 ) ) > = lines_f0 ) {
vs_bline_odd = ( de_v_end_even - 1 )
+ ( eof_lines + 1 )
- lines_f0 ;
vs_eline_odd = vs_bline_odd + vsync_lines ;
writel_relaxed ( vs_bline_odd ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BLINE_ODD ) ) ;
writel_relaxed ( vs_eline_odd ,
priv - > io_base + _REG ( ENCI_DVI_VSO_ELINE_ODD ) ) ;
vso_begin_odd = modulo ( hs_begin
+ ( total_pixels_venc > > 1 ) ,
total_pixels_venc ) ;
writel_relaxed ( vso_begin_odd ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BEGIN_ODD ) ) ;
writel_relaxed ( vso_begin_odd ,
priv - > io_base + _REG ( ENCI_DVI_VSO_END_ODD ) ) ;
} else {
vs_bline_evn = ( de_v_end_even - 1 )
+ ( eof_lines + 1 ) ;
writel_relaxed ( vs_bline_evn ,
priv - > io_base + _REG ( ENCI_DVI_VSO_BLINE_EVN ) ) ;
vso_begin_evn = modulo ( hs_begin
+ ( total_pixels_venc > > 1 ) ,
total_pixels_venc ) ;
writel_relaxed ( vso_begin_evn , priv - > io_base
+ _REG ( ENCI_DVI_VSO_BEGIN_EVN ) ) ;
if ( vs_bline_evn + vsync_lines > = lines_f0 ) {
vs_eline_odd = vs_bline_evn
+ vsync_lines
- lines_f0 ;
writel_relaxed ( vs_eline_odd , priv - > io_base
+ _REG ( ENCI_DVI_VSO_ELINE_ODD ) ) ;
writel_relaxed ( vso_begin_evn , priv - > io_base
+ _REG ( ENCI_DVI_VSO_END_ODD ) ) ;
} else {
vs_eline_evn = vs_bline_evn + vsync_lines ;
writel_relaxed ( vs_eline_evn , priv - > io_base
+ _REG ( ENCI_DVI_VSO_ELINE_EVN ) ) ;
writel_relaxed ( vso_begin_evn , priv - > io_base
+ _REG ( ENCI_DVI_VSO_END_EVN ) ) ;
}
}
} else {
writel_relaxed ( vmode - > encp . dvi_settings ,
priv - > io_base + _REG ( VENC_DVI_SETTING ) ) ;
writel_relaxed ( vmode - > encp . video_mode ,
priv - > io_base + _REG ( ENCP_VIDEO_MODE ) ) ;
writel_relaxed ( vmode - > encp . video_mode_adv ,
priv - > io_base + _REG ( ENCP_VIDEO_MODE_ADV ) ) ;
if ( vmode - > encp . video_prog_mode_present )
writel_relaxed ( vmode - > encp . video_prog_mode ,
priv - > io_base + _REG ( VENC_VIDEO_PROG_MODE ) ) ;
if ( vmode - > encp . video_sync_mode_present )
writel_relaxed ( vmode - > encp . video_sync_mode ,
priv - > io_base + _REG ( ENCP_VIDEO_SYNC_MODE ) ) ;
if ( vmode - > encp . video_yc_dly_present )
writel_relaxed ( vmode - > encp . video_yc_dly ,
priv - > io_base + _REG ( ENCP_VIDEO_YC_DLY ) ) ;
if ( vmode - > encp . video_rgb_ctrl_present )
writel_relaxed ( vmode - > encp . video_rgb_ctrl ,
priv - > io_base + _REG ( ENCP_VIDEO_RGB_CTRL ) ) ;
if ( vmode - > encp . video_filt_ctrl_present )
writel_relaxed ( vmode - > encp . video_filt_ctrl ,
priv - > io_base + _REG ( ENCP_VIDEO_FILT_CTRL ) ) ;
if ( vmode - > encp . video_ofld_voav_ofst_present )
writel_relaxed ( vmode - > encp . video_ofld_voav_ofst ,
priv - > io_base
+ _REG ( ENCP_VIDEO_OFLD_VOAV_OFST ) ) ;
writel_relaxed ( vmode - > encp . yfp1_htime ,
priv - > io_base + _REG ( ENCP_VIDEO_YFP1_HTIME ) ) ;
writel_relaxed ( vmode - > encp . yfp2_htime ,
priv - > io_base + _REG ( ENCP_VIDEO_YFP2_HTIME ) ) ;
writel_relaxed ( vmode - > encp . max_pxcnt ,
priv - > io_base + _REG ( ENCP_VIDEO_MAX_PXCNT ) ) ;
writel_relaxed ( vmode - > encp . hspuls_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_HSPULS_BEGIN ) ) ;
writel_relaxed ( vmode - > encp . hspuls_end ,
priv - > io_base + _REG ( ENCP_VIDEO_HSPULS_END ) ) ;
writel_relaxed ( vmode - > encp . hspuls_switch ,
priv - > io_base + _REG ( ENCP_VIDEO_HSPULS_SWITCH ) ) ;
writel_relaxed ( vmode - > encp . vspuls_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_VSPULS_BEGIN ) ) ;
writel_relaxed ( vmode - > encp . vspuls_end ,
priv - > io_base + _REG ( ENCP_VIDEO_VSPULS_END ) ) ;
writel_relaxed ( vmode - > encp . vspuls_bline ,
priv - > io_base + _REG ( ENCP_VIDEO_VSPULS_BLINE ) ) ;
writel_relaxed ( vmode - > encp . vspuls_eline ,
priv - > io_base + _REG ( ENCP_VIDEO_VSPULS_ELINE ) ) ;
if ( vmode - > encp . eqpuls_begin_present )
writel_relaxed ( vmode - > encp . eqpuls_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_EQPULS_BEGIN ) ) ;
if ( vmode - > encp . eqpuls_end_present )
writel_relaxed ( vmode - > encp . eqpuls_end ,
priv - > io_base + _REG ( ENCP_VIDEO_EQPULS_END ) ) ;
if ( vmode - > encp . eqpuls_bline_present )
writel_relaxed ( vmode - > encp . eqpuls_bline ,
priv - > io_base + _REG ( ENCP_VIDEO_EQPULS_BLINE ) ) ;
if ( vmode - > encp . eqpuls_eline_present )
writel_relaxed ( vmode - > encp . eqpuls_eline ,
priv - > io_base + _REG ( ENCP_VIDEO_EQPULS_ELINE ) ) ;
writel_relaxed ( vmode - > encp . havon_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_HAVON_BEGIN ) ) ;
writel_relaxed ( vmode - > encp . havon_end ,
priv - > io_base + _REG ( ENCP_VIDEO_HAVON_END ) ) ;
writel_relaxed ( vmode - > encp . vavon_bline ,
priv - > io_base + _REG ( ENCP_VIDEO_VAVON_BLINE ) ) ;
writel_relaxed ( vmode - > encp . vavon_eline ,
priv - > io_base + _REG ( ENCP_VIDEO_VAVON_ELINE ) ) ;
writel_relaxed ( vmode - > encp . hso_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_HSO_BEGIN ) ) ;
writel_relaxed ( vmode - > encp . hso_end ,
priv - > io_base + _REG ( ENCP_VIDEO_HSO_END ) ) ;
writel_relaxed ( vmode - > encp . vso_begin ,
priv - > io_base + _REG ( ENCP_VIDEO_VSO_BEGIN ) ) ;
writel_relaxed ( vmode - > encp . vso_end ,
priv - > io_base + _REG ( ENCP_VIDEO_VSO_END ) ) ;
writel_relaxed ( vmode - > encp . vso_bline ,
priv - > io_base + _REG ( ENCP_VIDEO_VSO_BLINE ) ) ;
if ( vmode - > encp . vso_eline_present )
writel_relaxed ( vmode - > encp . vso_eline ,
priv - > io_base + _REG ( ENCP_VIDEO_VSO_ELINE ) ) ;
if ( vmode - > encp . sy_val_present )
writel_relaxed ( vmode - > encp . sy_val ,
priv - > io_base + _REG ( ENCP_VIDEO_SY_VAL ) ) ;
if ( vmode - > encp . sy2_val_present )
writel_relaxed ( vmode - > encp . sy2_val ,
priv - > io_base + _REG ( ENCP_VIDEO_SY2_VAL ) ) ;
writel_relaxed ( vmode - > encp . max_lncnt ,
priv - > io_base + _REG ( ENCP_VIDEO_MAX_LNCNT ) ) ;
writel_relaxed ( 1 , priv - > io_base + _REG ( ENCP_VIDEO_EN ) ) ;
/* Set DE signal’ s polarity is active high */
2019-06-24 16:48:50 +02:00
writel_bits_relaxed ( ENCP_VIDEO_MODE_DE_V_HIGH ,
ENCP_VIDEO_MODE_DE_V_HIGH ,
2017-04-04 14:15:26 +02:00
priv - > io_base + _REG ( ENCP_VIDEO_MODE ) ) ;
/* Program DE timing */
de_h_begin = modulo ( readl_relaxed ( priv - > io_base +
_REG ( ENCP_VIDEO_HAVON_BEGIN ) )
+ venc_hdmi_latency ,
total_pixels_venc ) ;
de_h_end = modulo ( de_h_begin + active_pixels_venc ,
total_pixels_venc ) ;
writel_relaxed ( de_h_begin ,
priv - > io_base + _REG ( ENCP_DE_H_BEGIN ) ) ;
writel_relaxed ( de_h_end ,
priv - > io_base + _REG ( ENCP_DE_H_END ) ) ;
/* Program DE timing for even field */
de_v_begin_even = readl_relaxed ( priv - > io_base
+ _REG ( ENCP_VIDEO_VAVON_BLINE ) ) ;
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE )
de_v_end_even = de_v_begin_even +
( mode - > vdisplay / 2 ) ;
else
de_v_end_even = de_v_begin_even + mode - > vdisplay ;
writel_relaxed ( de_v_begin_even ,
priv - > io_base + _REG ( ENCP_DE_V_BEGIN_EVEN ) ) ;
writel_relaxed ( de_v_end_even ,
priv - > io_base + _REG ( ENCP_DE_V_END_EVEN ) ) ;
/* Program DE timing for odd field if needed */
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE ) {
unsigned int ofld_voav_ofst =
readl_relaxed ( priv - > io_base +
_REG ( ENCP_VIDEO_OFLD_VOAV_OFST ) ) ;
de_v_begin_odd = to_signed ( ( ofld_voav_ofst & 0xf0 ) > > 4 )
+ de_v_begin_even
+ ( ( mode - > vtotal - 1 ) / 2 ) ;
de_v_end_odd = de_v_begin_odd + ( mode - > vdisplay / 2 ) ;
writel_relaxed ( de_v_begin_odd ,
priv - > io_base + _REG ( ENCP_DE_V_BEGIN_ODD ) ) ;
writel_relaxed ( de_v_end_odd ,
priv - > io_base + _REG ( ENCP_DE_V_END_ODD ) ) ;
}
/* Program Hsync timing */
if ( ( de_h_end + front_porch_venc ) > = total_pixels_venc ) {
hs_begin = de_h_end
+ front_porch_venc
- total_pixels_venc ;
vs_adjust = 1 ;
} else {
hs_begin = de_h_end
+ front_porch_venc ;
vs_adjust = 0 ;
}
hs_end = modulo ( hs_begin + hsync_pixels_venc ,
total_pixels_venc ) ;
writel_relaxed ( hs_begin ,
priv - > io_base + _REG ( ENCP_DVI_HSO_BEGIN ) ) ;
writel_relaxed ( hs_end ,
priv - > io_base + _REG ( ENCP_DVI_HSO_END ) ) ;
/* Program Vsync timing for even field */
if ( de_v_begin_even > =
( sof_lines + vsync_lines + ( 1 - vs_adjust ) ) )
vs_bline_evn = de_v_begin_even
- sof_lines
- vsync_lines
- ( 1 - vs_adjust ) ;
else
vs_bline_evn = mode - > vtotal
+ de_v_begin_even
- sof_lines
- vsync_lines
- ( 1 - vs_adjust ) ;
vs_eline_evn = modulo ( vs_bline_evn + vsync_lines ,
mode - > vtotal ) ;
writel_relaxed ( vs_bline_evn ,
priv - > io_base + _REG ( ENCP_DVI_VSO_BLINE_EVN ) ) ;
writel_relaxed ( vs_eline_evn ,
priv - > io_base + _REG ( ENCP_DVI_VSO_ELINE_EVN ) ) ;
vso_begin_evn = hs_begin ;
writel_relaxed ( vso_begin_evn ,
priv - > io_base + _REG ( ENCP_DVI_VSO_BEGIN_EVN ) ) ;
writel_relaxed ( vso_begin_evn ,
priv - > io_base + _REG ( ENCP_DVI_VSO_END_EVN ) ) ;
/* Program Vsync timing for odd field if needed */
if ( mode - > flags & DRM_MODE_FLAG_INTERLACE ) {
vs_bline_odd = ( de_v_begin_odd - 1 )
- sof_lines
- vsync_lines ;
vs_eline_odd = ( de_v_begin_odd - 1 )
- vsync_lines ;
vso_begin_odd = modulo ( hs_begin
+ ( total_pixels_venc > > 1 ) ,
total_pixels_venc ) ;
writel_relaxed ( vs_bline_odd ,
priv - > io_base + _REG ( ENCP_DVI_VSO_BLINE_ODD ) ) ;
writel_relaxed ( vs_eline_odd ,
priv - > io_base + _REG ( ENCP_DVI_VSO_ELINE_ODD ) ) ;
writel_relaxed ( vso_begin_odd ,
priv - > io_base + _REG ( ENCP_DVI_VSO_BEGIN_ODD ) ) ;
writel_relaxed ( vso_begin_odd ,
priv - > io_base + _REG ( ENCP_DVI_VSO_END_ODD ) ) ;
}
/* Select ENCP for VIU */
meson_vpp_setup_mux ( priv , MESON_VIU_VPP_MUX_ENCP ) ;
}
2019-06-24 16:48:50 +02:00
/* Set VPU HDMI setting */
/* Select ENCP or ENCI data to HDMI */
if ( use_enci )
reg = VPU_HDMI_ENCI_DATA_TO_HDMI ;
else
reg = VPU_HDMI_ENCP_DATA_TO_HDMI ;
/* Invert polarity of HSYNC from VENC */
if ( mode - > flags & DRM_MODE_FLAG_PHSYNC )
reg | = VPU_HDMI_INV_HSYNC ;
/* Invert polarity of VSYNC from VENC */
if ( mode - > flags & DRM_MODE_FLAG_PVSYNC )
reg | = VPU_HDMI_INV_VSYNC ;
2020-03-04 11:40:50 +01:00
/* Output data format */
reg | = ycrcb_map ;
2019-06-24 16:48:50 +02:00
/*
* Write rate to the async FIFO between VENC and HDMI .
* One write every 2 wr_clk .
*/
2020-03-04 11:40:50 +01:00
if ( venc_repeat | | yuv420_mode )
2019-06-24 16:48:50 +02:00
reg | = VPU_HDMI_WR_RATE ( 2 ) ;
/*
* Read rate to the async FIFO between VENC and HDMI .
* One read every 2 wr_clk .
*/
if ( hdmi_repeat )
reg | = VPU_HDMI_RD_RATE ( 2 ) ;
writel_relaxed ( reg , priv - > io_base + _REG ( VPU_HDMI_SETTING ) ) ;
2017-04-04 14:15:26 +02:00
priv - > venc . hdmi_repeat = hdmi_repeat ;
priv - > venc . venc_repeat = venc_repeat ;
priv - > venc . hdmi_use_enci = use_enci ;
priv - > venc . current_mode = MESON_VENC_MODE_HDMI ;
}
EXPORT_SYMBOL_GPL ( meson_venc_hdmi_mode_set ) ;
2016-11-10 15:29:37 +01:00
void meson_venci_cvbs_mode_set ( struct meson_drm * priv ,
struct meson_cvbs_enci_mode * mode )
{
2019-06-24 16:48:50 +02:00
u32 reg ;
2016-11-10 15:29:37 +01:00
if ( mode - > mode_tag = = priv - > venc . current_mode )
return ;
/* CVBS Filter settings */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_CFILT_CMPT_SEL_HIGH | 0x10 ,
priv - > io_base + _REG ( ENCI_CFILT_CTRL ) ) ;
writel_relaxed ( ENCI_CFILT_CMPT_CR_DLY ( 2 ) |
ENCI_CFILT_CMPT_CB_DLY ( 1 ) ,
priv - > io_base + _REG ( ENCI_CFILT_CTRL2 ) ) ;
2016-11-10 15:29:37 +01:00
/* Digital Video Select : Interlace, clk27 clk, external */
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_DVI_SETTING ) ) ;
/* Reset Video Mode */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_MODE ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_MODE_ADV ) ) ;
/* Horizontal sync signal output */
writel_relaxed ( mode - > hso_begin ,
priv - > io_base + _REG ( ENCI_SYNC_HSO_BEGIN ) ) ;
writel_relaxed ( mode - > hso_end ,
priv - > io_base + _REG ( ENCI_SYNC_HSO_END ) ) ;
/* Vertical Sync lines */
writel_relaxed ( mode - > vso_even ,
priv - > io_base + _REG ( ENCI_SYNC_VSO_EVNLN ) ) ;
writel_relaxed ( mode - > vso_odd ,
priv - > io_base + _REG ( ENCI_SYNC_VSO_ODDLN ) ) ;
/* Macrovision max amplitude change */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
ENCI_MACV_MAX_AMP_VAL ( mode - > macv_max_amp ) ,
priv - > io_base + _REG ( ENCI_MACV_MAX_AMP ) ) ;
2016-11-10 15:29:37 +01:00
/* Video mode */
writel_relaxed ( mode - > video_prog_mode ,
priv - > io_base + _REG ( VENC_VIDEO_PROG_MODE ) ) ;
writel_relaxed ( mode - > video_mode ,
priv - > io_base + _REG ( ENCI_VIDEO_MODE ) ) ;
2019-06-24 16:48:57 +02:00
/*
* Advanced Video Mode :
2016-11-10 15:29:37 +01:00
* Demux shifting 0x2
* Blank line end at line17 / 22
* High bandwidth Luma Filter
* Low bandwidth Chroma Filter
* Bypass luma low pass filter
* No macrovision on CSYNC
*/
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_VIDEO_MODE_ADV_DMXMD ( 2 ) |
ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
ENCI_VIDEO_MODE_ADV_YBW_HIGH ,
priv - > io_base + _REG ( ENCI_VIDEO_MODE_ADV ) ) ;
2016-11-10 15:29:37 +01:00
writel ( mode - > sch_adjust , priv - > io_base + _REG ( ENCI_VIDEO_SCH ) ) ;
/* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
writel_relaxed ( 0x07 , priv - > io_base + _REG ( ENCI_SYNC_MODE ) ) ;
/* 0x3 Y, C, and Component Y delay */
writel_relaxed ( mode - > yc_delay , priv - > io_base + _REG ( ENCI_YC_DELAY ) ) ;
/* Timings */
writel_relaxed ( mode - > pixel_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_PIXEL_START ) ) ;
writel_relaxed ( mode - > pixel_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_PIXEL_END ) ) ;
writel_relaxed ( mode - > top_field_line_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_TOP_START ) ) ;
writel_relaxed ( mode - > top_field_line_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_TOP_END ) ) ;
writel_relaxed ( mode - > bottom_field_line_start ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_BOT_START ) ) ;
writel_relaxed ( mode - > bottom_field_line_end ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_LINE_BOT_END ) ) ;
/* Internal Venc, Internal VIU Sync, Internal Vencoder */
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_SYNC_ROUTE ) ) ;
/* UNreset Interlaced TV Encoder */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_DBG_PX_RST ) ) ;
2019-06-24 16:48:50 +02:00
/*
* Enable Vfifo2vd and set Y_Cb_Y_Cr :
* Corresponding value :
* Y = > 00 or 10
* Cb = > 01
* Cr = > 11
* Ex : 0x4e = > 01001110 would mean Cb / Y / Cr / Y
*/
writel_relaxed ( ENCI_VFIFO2VD_CTL_ENABLE |
ENCI_VFIFO2VD_CTL_VD_SEL ( 0x4e ) ,
priv - > io_base + _REG ( ENCI_VFIFO2VD_CTL ) ) ;
2016-11-10 15:29:37 +01:00
/* Power UP Dacs */
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_SETTING ) ) ;
/* Video Upsampling */
2019-06-24 16:48:50 +02:00
/*
* CTRL0 , CTRL1 and CTRL2 :
* Filter0 : input data sample every 2 cloks
* Filter1 : filtering and upsample enable
*/
reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN |
VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN ;
/*
* Upsample CTRL0 :
* Interlace High Bandwidth Luma
*/
writel_relaxed ( VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg ,
priv - > io_base + _REG ( VENC_UPSAMPLE_CTRL0 ) ) ;
/*
* Upsample CTRL1 :
* Interlace Pb
*/
writel_relaxed ( VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg ,
priv - > io_base + _REG ( VENC_UPSAMPLE_CTRL1 ) ) ;
/*
* Upsample CTRL2 :
* Interlace R
*/
writel_relaxed ( VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg ,
priv - > io_base + _REG ( VENC_UPSAMPLE_CTRL2 ) ) ;
2016-11-10 15:29:37 +01:00
/* Select Interlace Y DACs */
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL0 ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL1 ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL2 ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL3 ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL4 ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_VDAC_DACSEL5 ) ) ;
/* Select ENCI for VIU */
meson_vpp_setup_mux ( priv , MESON_VIU_VPP_MUX_ENCI ) ;
/* Enable ENCI FIFO */
2019-06-24 16:48:50 +02:00
writel_relaxed ( VENC_VDAC_FIFO_EN_ENCI_ENABLE ,
priv - > io_base + _REG ( VENC_VDAC_FIFO_CTRL ) ) ;
2016-11-10 15:29:37 +01:00
/* Select ENCI DACs 0, 1, 4, and 5 */
writel_relaxed ( 0x11 , priv - > io_base + _REG ( ENCI_DACSEL_0 ) ) ;
writel_relaxed ( 0x11 , priv - > io_base + _REG ( ENCI_DACSEL_1 ) ) ;
/* Interlace video enable */
2019-06-24 16:48:50 +02:00
writel_relaxed ( ENCI_VIDEO_EN_ENABLE ,
priv - > io_base + _REG ( ENCI_VIDEO_EN ) ) ;
2016-11-10 15:29:37 +01:00
/* Configure Video Saturation / Contrast / Brightness / Hue */
writel_relaxed ( mode - > video_saturation ,
priv - > io_base + _REG ( ENCI_VIDEO_SAT ) ) ;
writel_relaxed ( mode - > video_contrast ,
priv - > io_base + _REG ( ENCI_VIDEO_CONT ) ) ;
writel_relaxed ( mode - > video_brightness ,
priv - > io_base + _REG ( ENCI_VIDEO_BRIGHT ) ) ;
writel_relaxed ( mode - > video_hue ,
priv - > io_base + _REG ( ENCI_VIDEO_HUE ) ) ;
/* Enable DAC0 Filter */
2019-06-24 16:48:50 +02:00
writel_relaxed ( VENC_VDAC_DAC0_FILT_CTRL0_EN ,
priv - > io_base + _REG ( VENC_VDAC_DAC0_FILT_CTRL0 ) ) ;
2016-11-10 15:29:37 +01:00
writel_relaxed ( 0xfc48 , priv - > io_base + _REG ( VENC_VDAC_DAC0_FILT_CTRL1 ) ) ;
/* 0 in Macrovision register 0 */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_MACV_N0 ) ) ;
/* Analog Synchronization and color burst value adjust */
writel_relaxed ( mode - > analog_sync_adj ,
priv - > io_base + _REG ( ENCI_SYNC_ADJ ) ) ;
priv - > venc . current_mode = mode - > mode_tag ;
}
/* Returns the current ENCI field polarity */
unsigned int meson_venci_get_field ( struct meson_drm * priv )
{
return readl_relaxed ( priv - > io_base + _REG ( ENCI_INFO_READ ) ) & BIT ( 29 ) ;
}
void meson_venc_enable_vsync ( struct meson_drm * priv )
{
2019-06-24 16:48:50 +02:00
writel_relaxed ( VENC_INTCTRL_ENCI_LNRST_INT_EN ,
priv - > io_base + _REG ( VENC_INTCTRL ) ) ;
2018-11-22 17:01:03 +01:00
regmap_update_bits ( priv - > hhi , HHI_GCLK_MPEG2 , BIT ( 25 ) , BIT ( 25 ) ) ;
2016-11-10 15:29:37 +01:00
}
void meson_venc_disable_vsync ( struct meson_drm * priv )
{
2018-11-22 17:01:03 +01:00
regmap_update_bits ( priv - > hhi , HHI_GCLK_MPEG2 , BIT ( 25 ) , 0 ) ;
2016-11-10 15:29:37 +01:00
writel_relaxed ( 0 , priv - > io_base + _REG ( VENC_INTCTRL ) ) ;
}
void meson_venc_init ( struct meson_drm * priv )
{
2017-01-02 16:14:15 +01:00
/* Disable CVBS VDAC */
2019-08-22 16:43:41 +02:00
if ( meson_vpu_is_compatible ( priv , VPU_COMPATIBLE_G12A ) ) {
2019-03-25 15:18:21 +01:00
regmap_write ( priv - > hhi , HHI_VDAC_CNTL0_G12A , 0 ) ;
regmap_write ( priv - > hhi , HHI_VDAC_CNTL1_G12A , 8 ) ;
} else {
regmap_write ( priv - > hhi , HHI_VDAC_CNTL0 , 0 ) ;
regmap_write ( priv - > hhi , HHI_VDAC_CNTL1 , 8 ) ;
}
2017-01-02 16:14:15 +01:00
/* Power Down Dacs */
writel_relaxed ( 0xff , priv - > io_base + _REG ( VENC_VDAC_SETTING ) ) ;
/* Disable HDMI PHY */
regmap_write ( priv - > hhi , HHI_HDMI_PHY_CNTL0 , 0 ) ;
/* Disable HDMI */
2019-06-24 16:48:50 +02:00
writel_bits_relaxed ( VPU_HDMI_ENCI_DATA_TO_HDMI |
VPU_HDMI_ENCP_DATA_TO_HDMI , 0 ,
2017-01-02 16:14:15 +01:00
priv - > io_base + _REG ( VPU_HDMI_SETTING ) ) ;
2016-11-10 15:29:37 +01:00
/* Disable all encoders */
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCI_VIDEO_EN ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCP_VIDEO_EN ) ) ;
writel_relaxed ( 0 , priv - > io_base + _REG ( ENCL_VIDEO_EN ) ) ;
/* Disable VSync IRQ */
meson_venc_disable_vsync ( priv ) ;
priv - > venc . current_mode = MESON_VENC_MODE_NONE ;
}