blob: 89acafe340cb33b3dc4780ff742a17f791c2f8a7 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2016-2017 Cadence Design Systems, Inc.
* All rights reserved worldwide.
*
* Copyright 2017-2018 NXP
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE SOFTWARE IS PROVIDED "AS IS",
* WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
******************************************************************************
*
* avgen_drv.c
*
******************************************************************************
*/
#include "mhl_hdtx_top.h"
#include "address.h"
#include "avgen.h"
#include "avgen_drv.h"
#include "util.h"
#include "externs.h"
#define ADDR_AVGEN 0x80000
CDN_API_STATUS CDN_API_AVGEN_Set(VIC_MODES vicMode, CDN_PROTOCOL_TYPE protocol,
VIC_PXL_ENCODING_FORMAT format)
{
/*CDN_API_STATUS ret; */
/*GENERAL_Read_Register_response resp; */
unsigned int pixelClockFreq = CDN_API_Get_PIXEL_FREQ_KHZ_ClosetVal
(vic_table[vicMode][PIXEL_FREQ_KHZ], protocol);
unsigned int v_h_polarity =
((vic_table[vicMode][HSYNC_POL] == ACTIVE_LOW) ? 0 : 1) +
((vic_table[vicMode][VSYNC_POL] == ACTIVE_LOW) ? 0 : 2);
unsigned int front_porche_l = vic_table[vicMode][FRONT_PORCH] - 256 *
((unsigned int)vic_table[vicMode][FRONT_PORCH] / 256);
unsigned int front_porche_h = vic_table[vicMode][FRONT_PORCH] / 256;
unsigned int back_porche_l = vic_table[vicMode][BACK_PORCH] - 256 *
((unsigned int)vic_table[vicMode][BACK_PORCH] / 256);
unsigned int back_porche_h = vic_table[vicMode][BACK_PORCH] / 256;
unsigned int active_slot_l = vic_table[vicMode][H_BLANK] - 256 *
((unsigned int)vic_table[vicMode][H_BLANK] / 256);
unsigned int active_slot_h = vic_table[vicMode][H_BLANK] / 256;
unsigned int frame_lines_l = vic_table[vicMode][V_TOTAL] - 256 *
((unsigned int)vic_table[vicMode][V_TOTAL] / 256);
unsigned int frame_lines_h = vic_table[vicMode][V_TOTAL] / 256;
unsigned int line_width_l = vic_table[vicMode][H_TOTAL] - 256 *
((unsigned int)vic_table[vicMode][H_TOTAL] / 256);
unsigned int line_width_h = vic_table[vicMode][H_TOTAL] / 256;
unsigned int vsync_lines = vic_table[vicMode][VSYNC];
unsigned int eof_lines = vic_table[vicMode][TYPE_EOF];
unsigned int sof_lines = vic_table[vicMode][SOF];
unsigned int interlace_progressive =
(vic_table[vicMode][I_P] == INTERLACED) ? 2 : 0;
unsigned int set_vif_clock = 0;
/*needed for HDMI /////////////////////////////// */
/*unsigned int hblank = vic_table[vicMode][H_BLANK]; */
/*unsigned int hactive = vic_table[vicMode][H_TOTAL]-hblank; */
/*unsigned int vblank = vsync_lines+eof_lines+sof_lines; */
/*unsigned int vactive = vic_table[vicMode][V_TOTAL]-vblank; */
/*unsigned int hfront = vic_table[vicMode][FRONT_PORCH]; */
/*unsigned int hback = vic_table[vicMode][BACK_PORCH]; */
/*unsigned int vfront = eof_lines; */
/*unsigned int hsync = hblank-hfront-hback; */
/*unsigned int vsync = vsync_lines; */
/*unsigned int vback = sof_lines; */
unsigned int set_CLK_SEL = 0;
unsigned int set_REF_CLK_SEL = 0;
unsigned int set_pll_CLK_IN = 0;
unsigned int set_pll_clkfbout_l = 0;
unsigned int set_pll_clkfbout_h = 0;
unsigned int set_pll_CLKOUT5_L = 0;
unsigned int set_pll_CLKOUT5_H = 0;
unsigned int set_pll2_CLKIN = 0;
unsigned int set_pll2_CLKFBOUT_L = 0;
unsigned int set_pll2_CLKFBOUT_H = 0;
unsigned int set_pll2_CLKOUT5_L = 0;
unsigned int set_pll2_CLKOUT5_H = 0;
/*///////////////////////////////////////////////// */
cdn_apb_write(0x1c00C6 << 2,
(int)(vic_table[vicMode][PIXEL_FREQ_KHZ] * 1000));
cdn_apb_write(0x1c00C6 << 2, (int)(pixelClockFreq));
if ((int)(pixelClockFreq) == 25) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 4;
set_REF_CLK_SEL = 0;
set_pll_CLK_IN = 65;
set_pll_clkfbout_l = 4292;
set_pll_clkfbout_h = 128;
set_pll_CLKOUT5_L = 4422;
set_pll_CLKOUT5_H = 128;
set_pll2_CLKIN = 12289;
set_pll2_CLKFBOUT_L = 4356;
set_pll2_CLKFBOUT_H = 0;
set_pll2_CLKOUT5_L = 4552;
set_pll2_CLKOUT5_H = 128;
} else {
set_vif_clock = 0x300;
}
} else if ((int)pixelClockFreq == 27000) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 5;
set_REF_CLK_SEL = 0;
set_pll_CLK_IN = 49217;
set_pll_clkfbout_l = 4226;
set_pll_clkfbout_h = 0;
set_pll_CLKOUT5_L = 4422;
set_pll_CLKOUT5_H = 128;
} else {
set_vif_clock = 0x301;
}
} else if ((int)pixelClockFreq == 54000) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 5;
set_REF_CLK_SEL = 0;
set_pll_CLK_IN = 4096;
set_pll_clkfbout_l = 4226;
set_pll_clkfbout_h = 0;
set_pll_CLKOUT5_L = 4422;
set_pll_CLKOUT5_H = 128;
} else {
set_vif_clock = 0x302;
}
} else if (pixelClockFreq == 74250) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 1;
set_pll_CLK_IN = 74;
} else {
set_vif_clock = 0x303;
}
} else if (pixelClockFreq == 148500) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 0;
set_pll_CLK_IN = 148;
} else {
set_vif_clock = 0x304;
}
} else if ((int)pixelClockFreq == 108000) {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 5;
set_REF_CLK_SEL = 2;
set_pll_CLK_IN = 8258;
set_pll_clkfbout_l = 4616;
set_pll_clkfbout_h = 0;
set_pll_CLKOUT5_L = 4422;
set_pll_CLKOUT5_H = 128;
} else {
set_vif_clock = 0x305;
}
} else {
if (protocol == CDN_HDMITX_TYPHOON) {
set_CLK_SEL = 1;
set_pll_CLK_IN = pixelClockFreq;
} else {
set_vif_clock = 0;
}
}
unsigned int start_pgen = 128;
/*unsigned int temp; */
if (protocol == CDN_HDMITX_TYPHOON) {
if (cdn_apb_write(0x0c0001 << 2,
((0) + (2 * set_CLK_SEL) + (16 * 0) +
(32 * 0) + (64 * 3) + (65536 * 3) +
(1048576 * set_REF_CLK_SEL))))
return CDN_ERR;
if (cdn_apb_write(0x1c00C6 << 2, set_pll_CLK_IN))
return CDN_ERR;
if (cdn_apb_write(0x1c00CC << 2, set_pll_clkfbout_l))
return CDN_ERR;
if (cdn_apb_write(0x1c00CD << 2, set_pll_clkfbout_h))
return CDN_ERR;
if (cdn_apb_write(0x1c00CE << 2, set_pll_CLKOUT5_L))
return CDN_ERR;
if (cdn_apb_write(0x1c00CF << 2, set_pll_CLKOUT5_H))
return CDN_ERR;
if (cdn_apb_write(0x1c0086 << 2, set_pll2_CLKIN))
return CDN_ERR;
if (cdn_apb_write(0x1c008C << 2, set_pll2_CLKFBOUT_L))
return CDN_ERR;
if (cdn_apb_write(0x1c008D << 2, set_pll2_CLKFBOUT_H))
return CDN_ERR;
if (cdn_apb_write(0x1c008E << 2, set_pll2_CLKOUT5_L))
return CDN_ERR;
if (cdn_apb_write(0x1c008F << 2, set_pll2_CLKOUT5_H))
return CDN_ERR;
if (cdn_apb_write(0x0c0001 << 2,
((1) + (2 * set_CLK_SEL) + (16 * 0) +
(32 * 0) + (64 * 3) + (65536 * 3) +
(1048576 * set_REF_CLK_SEL))))
return CDN_ERR;
}
if (cdn_apb_write((ADDR_AVGEN + HDMIPOL) << 2, v_h_polarity))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDMI_FRONT_PORCHE_L) << 2,
front_porche_l))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDFP) << 2, front_porche_h))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDBP) << 2, back_porche_l))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDMI_BACK_PORCHE_H) << 2,
back_porche_h))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDAS) << 2, active_slot_l))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDMI_ACTIVE_SLOT_H) << 2,
active_slot_h))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDFL) << 2, frame_lines_l))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDMI_FRAME_LINES_H) << 2,
frame_lines_h))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDLW) << 2, line_width_l))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDMI_LINE_WIDTH_H) << 2, line_width_h))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDVL) << 2, vsync_lines))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDEL) << 2, eof_lines))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + HDSL) << 2, sof_lines))
return CDN_ERR;
if (cdn_apb_write((ADDR_AVGEN + PTRNGENFF) << 2, interlace_progressive))
return CDN_ERR;
if (protocol == CDN_HDMITX_TYPHOON) {
switch (format) {
case PXL_RGB:
if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2,
F_PIC_SEL(1) | F_PIC_YCBCR_SEL(0)))
return CDN_ERR;
break;
case YCBCR_4_4_4:
if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2,
F_PIC_SEL(2) | F_PIC_YCBCR_SEL(0)))
return CDN_ERR;
break;
case YCBCR_4_2_2:
if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2,
F_PIC_SEL(2) | F_PIC_YCBCR_SEL(1)))
return CDN_ERR;
break;
case YCBCR_4_2_0:
if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2,
F_PIC_SEL(2) | F_PIC_YCBCR_SEL(2)))
return CDN_ERR;
break;
case Y_ONLY:
/*not exist in hdmi */
break;
}
} else {
if (set_vif_clock != 0)
if (cdn_apb_write(0xC0006 << 2, set_vif_clock))
return CDN_ERR;
}
if (cdn_apb_write((ADDR_AVGEN + PGENCTRL) << 2, start_pgen))
return CDN_ERR;
return CDN_OK;
}