uboot/drivers/video/nexell/s5pxx18_dp_hdmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016  Nexell Co., Ltd.
   4 *
   5 * Author: junghyun, kim <jhkim@nexell.co.kr>
   6 */
   7
   8#include <config.h>
   9#include <common.h>
  10#include <errno.h>
  11#include <log.h>
  12
  13#include <asm/arch/nexell.h>
  14#include <asm/arch/tieoff.h>
  15#include <asm/arch/reset.h>
  16#include <asm/arch/display.h>
  17
  18#include <linux/delay.h>
  19
  20#include "soc/s5pxx18_soc_dpc.h"
  21#include "soc/s5pxx18_soc_hdmi.h"
  22#include "soc/s5pxx18_soc_disptop.h"
  23#include "soc/s5pxx18_soc_disptop_clk.h"
  24
  25#define __io_address(a) (void *)(uintptr_t)(a)
  26
  27static const u8 hdmiphy_preset74_25[32] = {
  28        0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0xc8, 0x81,
  29        0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
  30        0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
  31        0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x10, 0x80,
  32};
  33
  34static const u8 hdmiphy_preset148_5[32] = {
  35        0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0xc8, 0x81,
  36        0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
  37        0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
  38        0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
  39};
  40
  41#define HDMIPHY_PRESET_TABLE_SIZE   (32)
  42
  43enum NXP_HDMI_PRESET {
  44        NXP_HDMI_PRESET_720P = 0,       /* 1280 x 720 */
  45        NXP_HDMI_PRESET_1080P,  /* 1920 x 1080 */
  46        NXP_HDMI_PRESET_MAX
  47};
  48
  49static void hdmi_reset(void)
  50{
  51        nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_ASSERT);
  52        nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_ASSERT);
  53        nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_ASSERT);
  54        nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_NEGATE);
  55        nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_NEGATE);
  56        nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_NEGATE);
  57}
  58
  59static int hdmi_phy_enable(int preset, int enable)
  60{
  61        const u8 *table = NULL;
  62        int size = 0;
  63        u32 addr, i = 0;
  64
  65        if (!enable)
  66                return 0;
  67
  68        switch (preset) {
  69        case NXP_HDMI_PRESET_720P:
  70                table = hdmiphy_preset74_25;
  71                size = 32;
  72                break;
  73        case NXP_HDMI_PRESET_1080P:
  74                table = hdmiphy_preset148_5;
  75                size = 31;
  76                break;
  77        default:
  78                printf("hdmi: phy not support preset %d\n", preset);
  79                return -EINVAL;
  80        }
  81
  82        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
  83        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
  84        nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
  85        nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
  86        nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
  87        nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
  88
  89        for (i = 0, addr = HDMI_PHY_REG04; size > i; i++, addr += 4) {
  90                nx_hdmi_set_reg(0, addr, table[i]);
  91                nx_hdmi_set_reg(0, addr, table[i]);
  92        }
  93
  94        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
  95        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
  96        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
  97        nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
  98        debug("%s: preset = %d\n", __func__, preset);
  99
 100        return 0;
 101}
 102
 103static inline int hdmi_wait_phy_ready(void)
 104{
 105        int count = 500;
 106
 107        do {
 108                u32 val = nx_hdmi_get_reg(0, HDMI_LINK_PHY_STATUS_0);
 109
 110                if (val & 0x01) {
 111                        printf("HDMI:  phy ready...\n");
 112                        return 1;
 113                }
 114                mdelay(10);
 115        } while (count--);
 116
 117        return 0;
 118}
 119
 120static inline int hdmi_get_vsync(int preset,
 121                                 struct dp_sync_info *sync,
 122                                 struct dp_ctrl_info *ctrl)
 123{
 124        switch (preset) {
 125        case NXP_HDMI_PRESET_720P:      /* 720p: 1280x720 */
 126                sync->h_active_len = 1280;
 127                sync->h_sync_width = 40;
 128                sync->h_back_porch = 220;
 129                sync->h_front_porch = 110;
 130                sync->h_sync_invert = 0;
 131                sync->v_active_len = 720;
 132                sync->v_sync_width = 5;
 133                sync->v_back_porch = 20;
 134                sync->v_front_porch = 5;
 135                sync->v_sync_invert = 0;
 136                break;
 137
 138        case NXP_HDMI_PRESET_1080P:     /* 1080p: 1920x1080 */
 139                sync->h_active_len = 1920;
 140                sync->h_sync_width = 44;
 141                sync->h_back_porch = 148;
 142                sync->h_front_porch = 88;
 143                sync->h_sync_invert = 0;
 144                sync->v_active_len = 1080;
 145                sync->v_sync_width = 5;
 146                sync->v_back_porch = 36;
 147                sync->v_front_porch = 4;
 148                sync->v_sync_invert = 0;
 149                break;
 150        default:
 151                printf("HDMI: not support preset sync %d\n", preset);
 152                return -EINVAL;
 153        }
 154
 155        ctrl->clk_src_lv0 = 4;
 156        ctrl->clk_div_lv0 = 1;
 157        ctrl->clk_src_lv1 = 7;
 158        ctrl->clk_div_lv1 = 1;
 159
 160        ctrl->out_format = outputformat_rgb888;
 161        ctrl->delay_mask = (DP_SYNC_DELAY_RGB_PVD | DP_SYNC_DELAY_HSYNC_CP1 |
 162                            DP_SYNC_DELAY_VSYNC_FRAM | DP_SYNC_DELAY_DE_CP);
 163        ctrl->d_rgb_pvd = 0;
 164        ctrl->d_hsync_cp1 = 0;
 165        ctrl->d_vsync_fram = 0;
 166        ctrl->d_de_cp2 = 7;
 167
 168        /* HFP + HSW + HBP + AVWidth-VSCLRPIXEL- 1; */
 169        ctrl->vs_start_offset = (sync->h_front_porch + sync->h_sync_width +
 170                                 sync->h_back_porch + sync->h_active_len - 1);
 171        ctrl->vs_end_offset = 0;
 172
 173        /* HFP + HSW + HBP + AVWidth-EVENVSCLRPIXEL- 1 */
 174        ctrl->ev_start_offset = (sync->h_front_porch + sync->h_sync_width +
 175                                 sync->h_back_porch + sync->h_active_len - 1);
 176        ctrl->ev_end_offset = 0;
 177        debug("%s: preset: %d\n", __func__, preset);
 178
 179        return 0;
 180}
 181
 182static void hdmi_clock(void)
 183{
 184        void *base =
 185            __io_address(nx_disp_top_clkgen_get_physical_address
 186                         (to_mipi_clkgen));
 187
 188        nx_disp_top_clkgen_set_base_address(to_mipi_clkgen, base);
 189        nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 0);
 190        nx_disp_top_clkgen_set_clock_pclk_mode(to_mipi_clkgen,
 191                                               nx_pclkmode_always);
 192        nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
 193                                            2);
 194        nx_disp_top_clkgen_set_clock_divisor(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
 195                                             2);
 196        nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, 1, 7);
 197        nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 1);
 198
 199        /* must initialize this !!! */
 200        nx_disp_top_hdmi_set_vsync_hsstart_end(0, 0);
 201        nx_disp_top_hdmi_set_vsync_start(0);
 202        nx_disp_top_hdmi_set_hactive_start(0);
 203        nx_disp_top_hdmi_set_hactive_end(0);
 204}
 205
 206static void hdmi_vsync(struct dp_sync_info *sync)
 207{
 208        int width = sync->h_active_len;
 209        int hsw = sync->h_sync_width;
 210        int hbp = sync->h_back_porch;
 211        int height = sync->v_active_len;
 212        int vsw = sync->v_sync_width;
 213        int vbp = sync->v_back_porch;
 214
 215        int v_sync_s = vsw + vbp + height - 1;
 216        int h_active_s = hsw + hbp;
 217        int h_active_e = width + hsw + hbp;
 218        int v_sync_hs_se0 = hsw + hbp + 1;
 219        int v_sync_hs_se1 = hsw + hbp + 2;
 220
 221        nx_disp_top_hdmi_set_vsync_start(v_sync_s);
 222        nx_disp_top_hdmi_set_hactive_start(h_active_s);
 223        nx_disp_top_hdmi_set_hactive_end(h_active_e);
 224        nx_disp_top_hdmi_set_vsync_hsstart_end(v_sync_hs_se0, v_sync_hs_se1);
 225}
 226
 227static int hdmi_prepare(struct dp_sync_info *sync)
 228{
 229        int width = sync->h_active_len;
 230        int hsw = sync->h_sync_width;
 231        int hfp = sync->h_front_porch;
 232        int hbp = sync->h_back_porch;
 233        int height = sync->v_active_len;
 234        int vsw = sync->v_sync_width;
 235        int vfp = sync->v_front_porch;
 236        int vbp = sync->v_back_porch;
 237
 238        u32 h_blank, h_line, h_sync_start, h_sync_end;
 239        u32 v_blank, v2_blank, v_line;
 240        u32 v_sync_line_bef_1, v_sync_line_bef_2;
 241
 242        u32 fixed_ffff = 0xffff;
 243
 244        /* calculate sync variables */
 245        h_blank = hfp + hsw + hbp;
 246        v_blank = vfp + vsw + vbp;
 247        v2_blank = height + vfp + vsw + vbp;
 248        v_line = height + vfp + vsw + vbp;      /* total v */
 249        h_line = width + hfp + hsw + hbp;       /* total h */
 250        h_sync_start = hfp;
 251        h_sync_end = hfp + hsw;
 252        v_sync_line_bef_1 = vfp;
 253        v_sync_line_bef_2 = vfp + vsw;
 254
 255        /* no blue screen mode, encoding order as it is */
 256        nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0, (0 << 5) | (1 << 4));
 257
 258        /* set HDMI_LINK_BLUE_SCREEN_* to 0x0 */
 259        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_0, 0x5555);
 260        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_1, 0x5555);
 261        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_0, 0x5555);
 262        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_1, 0x5555);
 263        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_0, 0x5555);
 264        nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_1, 0x5555);
 265
 266        /* set HDMI_CON_1 to 0x0 */
 267        nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_1, 0x0);
 268        nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_2, 0x0);
 269
 270        /* set interrupt : enable hpd_plug, hpd_unplug */
 271        nx_hdmi_set_reg(0, HDMI_LINK_INTC_CON_0,
 272                        (1 << 6) | (1 << 3) | (1 << 2));
 273
 274        /* set STATUS_EN to 0x17 */
 275        nx_hdmi_set_reg(0, HDMI_LINK_STATUS_EN, 0x17);
 276
 277        /* TODO set HDP to 0x0 : later check hpd */
 278        nx_hdmi_set_reg(0, HDMI_LINK_HPD, 0x0);
 279
 280        /* set MODE_SEL to 0x02 */
 281        nx_hdmi_set_reg(0, HDMI_LINK_MODE_SEL, 0x2);
 282
 283        /* set H_BLANK_*, V1_BLANK_*, V2_BLANK_*, V_LINE_*,
 284         * H_LINE_*, H_SYNC_START_*, H_SYNC_END_ *
 285         * V_SYNC_LINE_BEF_1_*, V_SYNC_LINE_BEF_2_*
 286         */
 287        nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_0, h_blank % 256);
 288        nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_1, h_blank >> 8);
 289        nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_0, v_blank % 256);
 290        nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_1, v_blank >> 8);
 291        nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_0, v2_blank % 256);
 292        nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_1, v2_blank >> 8);
 293        nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_0, v_line % 256);
 294        nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_1, v_line >> 8);
 295        nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_0, h_line % 256);
 296        nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_1, h_line >> 8);
 297
 298        if (width == 1280) {
 299                nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x1);
 300                nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x1);
 301        } else {
 302                nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x0);
 303                nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x0);
 304        }
 305
 306        nx_hdmi_set_reg(0, HDMI_LINK_INT_PRO_MODE, 0x0);
 307
 308        nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_0, (h_sync_start % 256) - 2);
 309        nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_1, h_sync_start >> 8);
 310        nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_0, (h_sync_end % 256) - 2);
 311        nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_1, h_sync_end >> 8);
 312        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_0,
 313                        v_sync_line_bef_1 % 256);
 314        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_1,
 315                        v_sync_line_bef_1 >> 8);
 316        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_0,
 317                        v_sync_line_bef_2 % 256);
 318        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_1,
 319                        v_sync_line_bef_2 >> 8);
 320
 321        /* Set V_SYNC_LINE_AFT*, V_SYNC_LINE_AFT_PXL*, VACT_SPACE* */
 322        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_0, fixed_ffff % 256);
 323        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_1, fixed_ffff >> 8);
 324        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_0, fixed_ffff % 256);
 325        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_1, fixed_ffff >> 8);
 326        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_0, fixed_ffff % 256);
 327        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_1, fixed_ffff >> 8);
 328        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_0, fixed_ffff % 256);
 329        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_1, fixed_ffff >> 8);
 330        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_0, fixed_ffff % 256);
 331        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_1, fixed_ffff >> 8);
 332        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_0, fixed_ffff % 256);
 333        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_1, fixed_ffff >> 8);
 334
 335        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_0, fixed_ffff % 256);
 336        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_1, fixed_ffff >> 8);
 337        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_0, fixed_ffff % 256);
 338        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_1, fixed_ffff >> 8);
 339        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_0, fixed_ffff % 256);
 340        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_1, fixed_ffff >> 8);
 341        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_0, fixed_ffff % 256);
 342        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_1, fixed_ffff >> 8);
 343        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_0, fixed_ffff % 256);
 344        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_1, fixed_ffff >> 8);
 345        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_0, fixed_ffff % 256);
 346        nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_1, fixed_ffff >> 8);
 347
 348        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_0, fixed_ffff % 256);
 349        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_1, fixed_ffff >> 8);
 350        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_0, fixed_ffff % 256);
 351        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_1, fixed_ffff >> 8);
 352        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_0, fixed_ffff % 256);
 353        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_1, fixed_ffff >> 8);
 354        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_0, fixed_ffff % 256);
 355        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_1, fixed_ffff >> 8);
 356        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_0, fixed_ffff % 256);
 357        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_1, fixed_ffff >> 8);
 358        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_0, fixed_ffff % 256);
 359        nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_1, fixed_ffff >> 8);
 360
 361        nx_hdmi_set_reg(0, HDMI_LINK_CSC_MUX, 0x0);
 362        nx_hdmi_set_reg(0, HDMI_LINK_SYNC_GEN_MUX, 0x0);
 363
 364        nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_0, 0xfd);
 365        nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_1, 0x01);
 366        nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_0, 0x0d);
 367        nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_1, 0x3a);
 368        nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_2, 0x08);
 369
 370        /* Set DC_CONTROL to 0x00 */
 371        nx_hdmi_set_reg(0, HDMI_LINK_DC_CONTROL, 0x0);
 372
 373        if (IS_ENABLED(CONFIG_HDMI_PATTERN))
 374                nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x1);
 375        else
 376                nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x0);
 377
 378        nx_hdmi_set_reg(0, HDMI_LINK_GCP_CON, 0x0a);
 379        return 0;
 380}
 381
 382static void hdmi_init(void)
 383{
 384        void *base;
 385   /**
 386    * [SEQ 2] set the HDMI CLKGEN's PCLKMODE to always enabled
 387    */
 388        base =
 389            __io_address(nx_disp_top_clkgen_get_physical_address(hdmi_clkgen));
 390        nx_disp_top_clkgen_set_base_address(hdmi_clkgen, base);
 391        nx_disp_top_clkgen_set_clock_pclk_mode(hdmi_clkgen, nx_pclkmode_always);
 392
 393        base = __io_address(nx_hdmi_get_physical_address(0));
 394        nx_hdmi_set_base_address(0, base);
 395
 396    /**
 397     * [SEQ 3] set the 0xC001100C[0] to 1
 398     */
 399        nx_tieoff_set(NX_TIEOFF_DISPLAYTOP0_i_HDMI_PHY_REFCLK_SEL, 1);
 400
 401    /**
 402     * [SEQ 4] release the resets of HDMI.i_PHY_nRST and HDMI.i_nRST
 403     */
 404        nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_ASSERT);
 405        nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_ASSERT);
 406        nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_NEGATE);
 407        nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_NEGATE);
 408}
 409
 410void hdmi_enable(int input, int preset, struct dp_sync_info *sync, int enable)
 411{
 412        if (enable) {
 413                nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0,
 414                                (nx_hdmi_get_reg(0, HDMI_LINK_HDMI_CON_0) |
 415                                 0x1));
 416                hdmi_vsync(sync);
 417        } else {
 418                hdmi_phy_enable(preset, 0);
 419        }
 420}
 421
 422static int hdmi_setup(int input, int preset,
 423                      struct dp_sync_info *sync, struct dp_ctrl_info *ctrl)
 424{
 425        u32 HDMI_SEL = 0;
 426        int ret;
 427
 428        switch (input) {
 429        case DP_DEVICE_DP0:
 430                HDMI_SEL = primary_mlc;
 431                break;
 432        case DP_DEVICE_DP1:
 433                HDMI_SEL = secondary_mlc;
 434                break;
 435        case DP_DEVICE_RESCONV:
 436                HDMI_SEL = resolution_conv;
 437                break;
 438        default:
 439                printf("HDMI: not support source device %d\n", input);
 440                return -EINVAL;
 441        }
 442
 443        /**
 444         * [SEQ 5] set up the HDMI PHY to specific video clock.
 445         */
 446        ret = hdmi_phy_enable(preset, 1);
 447        if (ret < 0)
 448                return ret;
 449
 450        /**
 451         * [SEQ 6] I2S (or SPDIFTX) configuration for the source audio data
 452         * this is done in another user app  - ex> Android Audio HAL
 453         */
 454
 455        /**
 456         * [SEQ 7] Wait for ECID ready
 457         */
 458
 459        /**
 460         * [SEQ 8] release the resets of HDMI.i_VIDEO_nRST and HDMI.i_SPDIF_nRST
 461         * and HDMI.i_TMDS_nRST
 462         */
 463        hdmi_reset();
 464
 465        /**
 466         * [SEQ 9] Wait for HDMI PHY ready (wait until 0xC0200020.[0], 1)
 467         */
 468        if (hdmi_wait_phy_ready() == 0) {
 469                printf("%s: failed to wait for hdmiphy ready\n", __func__);
 470                hdmi_phy_enable(preset, 0);
 471                return -EIO;
 472        }
 473        /* set mux */
 474        nx_disp_top_set_hdmimux(1, HDMI_SEL);
 475
 476        /**
 477         * [SEC 10] Set the DPC CLKGEN's Source Clock to HDMI_CLK &
 478         * Set Sync Parameter
 479         */
 480        hdmi_clock();
 481        /* set hdmi link clk to clkgen  vs default is hdmi phy clk */
 482
 483        /**
 484         * [SEQ 11] Set up the HDMI Converter parameters
 485         */
 486        hdmi_get_vsync(preset, sync, ctrl);
 487        hdmi_prepare(sync);
 488
 489        return 0;
 490}
 491
 492void nx_hdmi_display(int module,
 493                     struct dp_sync_info *sync, struct dp_ctrl_info *ctrl,
 494                     struct dp_plane_top *top, struct dp_plane_info *planes,
 495                     struct dp_hdmi_dev *dev)
 496{
 497        struct dp_plane_info *plane = planes;
 498        int input = module == 0 ? DP_DEVICE_DP0 : DP_DEVICE_DP1;
 499        int count = top->plane_num;
 500        int preset = dev->preset;
 501        int i = 0;
 502
 503        debug("HDMI:  display.%d\n", module);
 504
 505        switch (preset) {
 506        case 0:
 507                top->screen_width = 1280;
 508                top->screen_height = 720;
 509                sync->h_active_len = 1280;
 510                sync->v_active_len = 720;
 511                break;
 512        case 1:
 513                top->screen_width = 1920;
 514                top->screen_height = 1080;
 515                sync->h_active_len = 1920;
 516                sync->v_active_len = 1080;
 517                break;
 518        default:
 519                printf("hdmi not support preset %d\n", preset);
 520                return;
 521        }
 522
 523        printf("HDMI:  display.%d, preset %d (%4d * %4d)\n",
 524               module, preset, top->screen_width, top->screen_height);
 525
 526        dp_control_init(module);
 527        dp_plane_init(module);
 528
 529        hdmi_init();
 530        hdmi_setup(input, preset, sync, ctrl);
 531
 532        dp_plane_screen_setup(module, top);
 533        for (i = 0; count > i; i++, plane++) {
 534                if (!plane->enable)
 535                        continue;
 536                dp_plane_layer_setup(module, plane);
 537                dp_plane_layer_enable(module, plane, 1);
 538        }
 539        dp_plane_screen_enable(module, 1);
 540
 541        dp_control_setup(module, sync, ctrl);
 542        dp_control_enable(module, 1);
 543
 544        hdmi_enable(input, preset, sync, 1);
 545}
 546