linux/drivers/gpu/drm/exynos/exynos_hdmi.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
   3 * Authors:
   4 * Seung-Woo Kim <sw0312.kim@samsung.com>
   5 *      Inki Dae <inki.dae@samsung.com>
   6 *      Joonyoung Shim <jy0922.shim@samsung.com>
   7 *
   8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 *
  15 */
  16
  17#include <drm/drmP.h>
  18#include <drm/drm_edid.h>
  19#include <drm/drm_crtc_helper.h>
  20
  21#include "regs-hdmi.h"
  22
  23#include <linux/kernel.h>
  24#include <linux/spinlock.h>
  25#include <linux/wait.h>
  26#include <linux/i2c.h>
  27#include <linux/platform_device.h>
  28#include <linux/interrupt.h>
  29#include <linux/irq.h>
  30#include <linux/delay.h>
  31#include <linux/pm_runtime.h>
  32#include <linux/clk.h>
  33#include <linux/regulator/consumer.h>
  34#include <linux/io.h>
  35#include <linux/of.h>
  36#include <linux/of_address.h>
  37#include <linux/of_gpio.h>
  38#include <linux/hdmi.h>
  39#include <linux/component.h>
  40#include <linux/mfd/syscon.h>
  41#include <linux/regmap.h>
  42
  43#include <drm/exynos_drm.h>
  44
  45#include "exynos_drm_drv.h"
  46#include "exynos_drm_crtc.h"
  47#include "exynos_mixer.h"
  48
  49#include <linux/gpio.h>
  50#include <media/s5p_hdmi.h>
  51
  52#define get_hdmi_display(dev)   platform_get_drvdata(to_platform_device(dev))
  53#define ctx_from_connector(c)   container_of(c, struct hdmi_context, connector)
  54
  55#define HOTPLUG_DEBOUNCE_MS             1100
  56
  57/* AVI header and aspect ratio */
  58#define HDMI_AVI_VERSION                0x02
  59#define HDMI_AVI_LENGTH         0x0D
  60
  61/* AUI header info */
  62#define HDMI_AUI_VERSION        0x01
  63#define HDMI_AUI_LENGTH 0x0A
  64#define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8
  65#define AVI_4_3_CENTER_RATIO    0x9
  66#define AVI_16_9_CENTER_RATIO   0xa
  67
  68enum hdmi_type {
  69        HDMI_TYPE13,
  70        HDMI_TYPE14,
  71};
  72
  73struct hdmi_driver_data {
  74        unsigned int type;
  75        const struct hdmiphy_config *phy_confs;
  76        unsigned int phy_conf_count;
  77        unsigned int is_apb_phy:1;
  78};
  79
  80struct hdmi_resources {
  81        struct clk                      *hdmi;
  82        struct clk                      *sclk_hdmi;
  83        struct clk                      *sclk_pixel;
  84        struct clk                      *sclk_hdmiphy;
  85        struct clk                      *mout_hdmi;
  86        struct regulator_bulk_data      *regul_bulk;
  87        int                             regul_count;
  88};
  89
  90struct hdmi_tg_regs {
  91        u8 cmd[1];
  92        u8 h_fsz[2];
  93        u8 hact_st[2];
  94        u8 hact_sz[2];
  95        u8 v_fsz[2];
  96        u8 vsync[2];
  97        u8 vsync2[2];
  98        u8 vact_st[2];
  99        u8 vact_sz[2];
 100        u8 field_chg[2];
 101        u8 vact_st2[2];
 102        u8 vact_st3[2];
 103        u8 vact_st4[2];
 104        u8 vsync_top_hdmi[2];
 105        u8 vsync_bot_hdmi[2];
 106        u8 field_top_hdmi[2];
 107        u8 field_bot_hdmi[2];
 108        u8 tg_3d[1];
 109};
 110
 111struct hdmi_v13_core_regs {
 112        u8 h_blank[2];
 113        u8 v_blank[3];
 114        u8 h_v_line[3];
 115        u8 vsync_pol[1];
 116        u8 int_pro_mode[1];
 117        u8 v_blank_f[3];
 118        u8 h_sync_gen[3];
 119        u8 v_sync_gen1[3];
 120        u8 v_sync_gen2[3];
 121        u8 v_sync_gen3[3];
 122};
 123
 124struct hdmi_v14_core_regs {
 125        u8 h_blank[2];
 126        u8 v2_blank[2];
 127        u8 v1_blank[2];
 128        u8 v_line[2];
 129        u8 h_line[2];
 130        u8 hsync_pol[1];
 131        u8 vsync_pol[1];
 132        u8 int_pro_mode[1];
 133        u8 v_blank_f0[2];
 134        u8 v_blank_f1[2];
 135        u8 h_sync_start[2];
 136        u8 h_sync_end[2];
 137        u8 v_sync_line_bef_2[2];
 138        u8 v_sync_line_bef_1[2];
 139        u8 v_sync_line_aft_2[2];
 140        u8 v_sync_line_aft_1[2];
 141        u8 v_sync_line_aft_pxl_2[2];
 142        u8 v_sync_line_aft_pxl_1[2];
 143        u8 v_blank_f2[2]; /* for 3D mode */
 144        u8 v_blank_f3[2]; /* for 3D mode */
 145        u8 v_blank_f4[2]; /* for 3D mode */
 146        u8 v_blank_f5[2]; /* for 3D mode */
 147        u8 v_sync_line_aft_3[2];
 148        u8 v_sync_line_aft_4[2];
 149        u8 v_sync_line_aft_5[2];
 150        u8 v_sync_line_aft_6[2];
 151        u8 v_sync_line_aft_pxl_3[2];
 152        u8 v_sync_line_aft_pxl_4[2];
 153        u8 v_sync_line_aft_pxl_5[2];
 154        u8 v_sync_line_aft_pxl_6[2];
 155        u8 vact_space_1[2];
 156        u8 vact_space_2[2];
 157        u8 vact_space_3[2];
 158        u8 vact_space_4[2];
 159        u8 vact_space_5[2];
 160        u8 vact_space_6[2];
 161};
 162
 163struct hdmi_v13_conf {
 164        struct hdmi_v13_core_regs core;
 165        struct hdmi_tg_regs tg;
 166};
 167
 168struct hdmi_v14_conf {
 169        struct hdmi_v14_core_regs core;
 170        struct hdmi_tg_regs tg;
 171};
 172
 173struct hdmi_conf_regs {
 174        int pixel_clock;
 175        int cea_video_id;
 176        enum hdmi_picture_aspect aspect_ratio;
 177        union {
 178                struct hdmi_v13_conf v13_conf;
 179                struct hdmi_v14_conf v14_conf;
 180        } conf;
 181};
 182
 183struct hdmi_context {
 184        struct device                   *dev;
 185        struct drm_device               *drm_dev;
 186        struct drm_connector            connector;
 187        struct drm_encoder              *encoder;
 188        bool                            hpd;
 189        bool                            powered;
 190        bool                            dvi_mode;
 191        struct mutex                    hdmi_mutex;
 192
 193        void __iomem                    *regs;
 194        int                             irq;
 195        struct delayed_work             hotplug_work;
 196
 197        struct i2c_adapter              *ddc_adpt;
 198        struct i2c_client               *hdmiphy_port;
 199
 200        /* current hdmiphy conf regs */
 201        struct drm_display_mode         current_mode;
 202        struct hdmi_conf_regs           mode_conf;
 203
 204        struct hdmi_resources           res;
 205
 206        int                             hpd_gpio;
 207        void __iomem                    *regs_hdmiphy;
 208        const struct hdmiphy_config             *phy_confs;
 209        unsigned int                    phy_conf_count;
 210
 211        struct regmap                   *pmureg;
 212        enum hdmi_type                  type;
 213};
 214
 215struct hdmiphy_config {
 216        int pixel_clock;
 217        u8 conf[32];
 218};
 219
 220/* list of phy config settings */
 221static const struct hdmiphy_config hdmiphy_v13_configs[] = {
 222        {
 223                .pixel_clock = 27000000,
 224                .conf = {
 225                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
 226                        0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 227                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 228                        0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
 229                },
 230        },
 231        {
 232                .pixel_clock = 27027000,
 233                .conf = {
 234                        0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
 235                        0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
 236                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 237                        0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
 238                },
 239        },
 240        {
 241                .pixel_clock = 74176000,
 242                .conf = {
 243                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
 244                        0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
 245                        0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
 246                        0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
 247                },
 248        },
 249        {
 250                .pixel_clock = 74250000,
 251                .conf = {
 252                        0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
 253                        0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
 254                        0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
 255                        0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
 256                },
 257        },
 258        {
 259                .pixel_clock = 148500000,
 260                .conf = {
 261                        0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
 262                        0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
 263                        0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
 264                        0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
 265                },
 266        },
 267};
 268
 269static const struct hdmiphy_config hdmiphy_v14_configs[] = {
 270        {
 271                .pixel_clock = 25200000,
 272                .conf = {
 273                        0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
 274                        0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 275                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 276                        0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 277                },
 278        },
 279        {
 280                .pixel_clock = 27000000,
 281                .conf = {
 282                        0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
 283                        0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 284                        0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 285                        0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 286                },
 287        },
 288        {
 289                .pixel_clock = 27027000,
 290                .conf = {
 291                        0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
 292                        0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 293                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 294                        0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
 295                },
 296        },
 297        {
 298                .pixel_clock = 36000000,
 299                .conf = {
 300                        0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
 301                        0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 302                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 303                        0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 304                },
 305        },
 306        {
 307                .pixel_clock = 40000000,
 308                .conf = {
 309                        0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
 310                        0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 311                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 312                        0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 313                },
 314        },
 315        {
 316                .pixel_clock = 65000000,
 317                .conf = {
 318                        0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
 319                        0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 320                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 321                        0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 322                },
 323        },
 324        {
 325                .pixel_clock = 71000000,
 326                .conf = {
 327                        0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
 328                        0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 329                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 330                        0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 331                },
 332        },
 333        {
 334                .pixel_clock = 73250000,
 335                .conf = {
 336                        0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
 337                        0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 338                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 339                        0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 340                },
 341        },
 342        {
 343                .pixel_clock = 74176000,
 344                .conf = {
 345                        0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
 346                        0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 347                        0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 348                        0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 349                },
 350        },
 351        {
 352                .pixel_clock = 74250000,
 353                .conf = {
 354                        0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
 355                        0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 356                        0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 357                        0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
 358                },
 359        },
 360        {
 361                .pixel_clock = 83500000,
 362                .conf = {
 363                        0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
 364                        0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 365                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 366                        0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 367                },
 368        },
 369        {
 370                .pixel_clock = 106500000,
 371                .conf = {
 372                        0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
 373                        0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 374                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 375                        0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 376                },
 377        },
 378        {
 379                .pixel_clock = 108000000,
 380                .conf = {
 381                        0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
 382                        0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 383                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 384                        0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 385                },
 386        },
 387        {
 388                .pixel_clock = 115500000,
 389                .conf = {
 390                        0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
 391                        0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 392                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 393                        0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 394                },
 395        },
 396        {
 397                .pixel_clock = 119000000,
 398                .conf = {
 399                        0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
 400                        0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 401                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 402                        0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 403                },
 404        },
 405        {
 406                .pixel_clock = 146250000,
 407                .conf = {
 408                        0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
 409                        0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
 410                        0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 411                        0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 412                },
 413        },
 414        {
 415                .pixel_clock = 148500000,
 416                .conf = {
 417                        0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
 418                        0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
 419                        0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
 420                        0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
 421                },
 422        },
 423};
 424
 425static const struct hdmiphy_config hdmiphy_5420_configs[] = {
 426        {
 427                .pixel_clock = 25200000,
 428                .conf = {
 429                        0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
 430                        0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 431                        0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
 432                        0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 433                },
 434        },
 435        {
 436                .pixel_clock = 27000000,
 437                .conf = {
 438                        0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
 439                        0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 440                        0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 441                        0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 442                },
 443        },
 444        {
 445                .pixel_clock = 27027000,
 446                .conf = {
 447                        0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
 448                        0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 449                        0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 450                        0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 451                },
 452        },
 453        {
 454                .pixel_clock = 36000000,
 455                .conf = {
 456                        0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
 457                        0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 458                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 459                        0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 460                },
 461        },
 462        {
 463                .pixel_clock = 40000000,
 464                .conf = {
 465                        0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
 466                        0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 467                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 468                        0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 469                },
 470        },
 471        {
 472                .pixel_clock = 65000000,
 473                .conf = {
 474                        0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
 475                        0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 476                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 477                        0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 478                },
 479        },
 480        {
 481                .pixel_clock = 71000000,
 482                .conf = {
 483                        0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
 484                        0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 485                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 486                        0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 487                },
 488        },
 489        {
 490                .pixel_clock = 73250000,
 491                .conf = {
 492                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
 493                        0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 494                        0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 495                        0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 496                },
 497        },
 498        {
 499                .pixel_clock = 74176000,
 500                .conf = {
 501                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
 502                        0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 503                        0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 504                        0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 505                },
 506        },
 507        {
 508                .pixel_clock = 74250000,
 509                .conf = {
 510                        0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
 511                        0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 512                        0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 513                        0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 514                },
 515        },
 516        {
 517                .pixel_clock = 83500000,
 518                .conf = {
 519                        0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
 520                        0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 521                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 522                        0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 523                },
 524        },
 525        {
 526                .pixel_clock = 88750000,
 527                .conf = {
 528                        0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
 529                        0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 530                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 531                        0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
 532                },
 533        },
 534        {
 535                .pixel_clock = 106500000,
 536                .conf = {
 537                        0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
 538                        0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 539                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 540                        0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 541                },
 542        },
 543        {
 544                .pixel_clock = 108000000,
 545                .conf = {
 546                        0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
 547                        0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 548                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 549                        0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
 550                },
 551        },
 552        {
 553                .pixel_clock = 115500000,
 554                .conf = {
 555                        0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
 556                        0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 557                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 558                        0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 559                },
 560        },
 561        {
 562                .pixel_clock = 146250000,
 563                .conf = {
 564                        0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
 565                        0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
 566                        0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
 567                        0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 568                },
 569        },
 570        {
 571                .pixel_clock = 148500000,
 572                .conf = {
 573                        0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
 574                        0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
 575                        0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
 576                        0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
 577                },
 578        },
 579};
 580
 581static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
 582        .type           = HDMI_TYPE14,
 583        .phy_confs      = hdmiphy_5420_configs,
 584        .phy_conf_count = ARRAY_SIZE(hdmiphy_5420_configs),
 585        .is_apb_phy     = 1,
 586};
 587
 588static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
 589        .type           = HDMI_TYPE14,
 590        .phy_confs      = hdmiphy_v14_configs,
 591        .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs),
 592        .is_apb_phy     = 0,
 593};
 594
 595static struct hdmi_driver_data exynos5_hdmi_driver_data = {
 596        .type           = HDMI_TYPE14,
 597        .phy_confs      = hdmiphy_v13_configs,
 598        .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs),
 599        .is_apb_phy     = 0,
 600};
 601
 602static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
 603{
 604        return readl(hdata->regs + reg_id);
 605}
 606
 607static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
 608                                 u32 reg_id, u8 value)
 609{
 610        writeb(value, hdata->regs + reg_id);
 611}
 612
 613static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
 614                                 u32 reg_id, u32 value, u32 mask)
 615{
 616        u32 old = readl(hdata->regs + reg_id);
 617        value = (value & mask) | (old & ~mask);
 618        writel(value, hdata->regs + reg_id);
 619}
 620
 621static int hdmiphy_reg_writeb(struct hdmi_context *hdata,
 622                        u32 reg_offset, u8 value)
 623{
 624        if (hdata->hdmiphy_port) {
 625                u8 buffer[2];
 626                int ret;
 627
 628                buffer[0] = reg_offset;
 629                buffer[1] = value;
 630
 631                ret = i2c_master_send(hdata->hdmiphy_port, buffer, 2);
 632                if (ret == 2)
 633                        return 0;
 634                return ret;
 635        } else {
 636                writeb(value, hdata->regs_hdmiphy + (reg_offset<<2));
 637                return 0;
 638        }
 639}
 640
 641static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
 642                        u32 reg_offset, const u8 *buf, u32 len)
 643{
 644        if ((reg_offset + len) > 32)
 645                return -EINVAL;
 646
 647        if (hdata->hdmiphy_port) {
 648                int ret;
 649
 650                ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
 651                if (ret == len)
 652                        return 0;
 653                return ret;
 654        } else {
 655                int i;
 656                for (i = 0; i < len; i++)
 657                        writeb(buf[i], hdata->regs_hdmiphy +
 658                                ((reg_offset + i)<<2));
 659                return 0;
 660        }
 661}
 662
 663static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
 664{
 665#define DUMPREG(reg_id) \
 666        DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
 667        readl(hdata->regs + reg_id))
 668        DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
 669        DUMPREG(HDMI_INTC_FLAG);
 670        DUMPREG(HDMI_INTC_CON);
 671        DUMPREG(HDMI_HPD_STATUS);
 672        DUMPREG(HDMI_V13_PHY_RSTOUT);
 673        DUMPREG(HDMI_V13_PHY_VPLL);
 674        DUMPREG(HDMI_V13_PHY_CMU);
 675        DUMPREG(HDMI_V13_CORE_RSTOUT);
 676
 677        DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
 678        DUMPREG(HDMI_CON_0);
 679        DUMPREG(HDMI_CON_1);
 680        DUMPREG(HDMI_CON_2);
 681        DUMPREG(HDMI_SYS_STATUS);
 682        DUMPREG(HDMI_V13_PHY_STATUS);
 683        DUMPREG(HDMI_STATUS_EN);
 684        DUMPREG(HDMI_HPD);
 685        DUMPREG(HDMI_MODE_SEL);
 686        DUMPREG(HDMI_V13_HPD_GEN);
 687        DUMPREG(HDMI_V13_DC_CONTROL);
 688        DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
 689
 690        DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
 691        DUMPREG(HDMI_H_BLANK_0);
 692        DUMPREG(HDMI_H_BLANK_1);
 693        DUMPREG(HDMI_V13_V_BLANK_0);
 694        DUMPREG(HDMI_V13_V_BLANK_1);
 695        DUMPREG(HDMI_V13_V_BLANK_2);
 696        DUMPREG(HDMI_V13_H_V_LINE_0);
 697        DUMPREG(HDMI_V13_H_V_LINE_1);
 698        DUMPREG(HDMI_V13_H_V_LINE_2);
 699        DUMPREG(HDMI_VSYNC_POL);
 700        DUMPREG(HDMI_INT_PRO_MODE);
 701        DUMPREG(HDMI_V13_V_BLANK_F_0);
 702        DUMPREG(HDMI_V13_V_BLANK_F_1);
 703        DUMPREG(HDMI_V13_V_BLANK_F_2);
 704        DUMPREG(HDMI_V13_H_SYNC_GEN_0);
 705        DUMPREG(HDMI_V13_H_SYNC_GEN_1);
 706        DUMPREG(HDMI_V13_H_SYNC_GEN_2);
 707        DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
 708        DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
 709        DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
 710        DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
 711        DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
 712        DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
 713        DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
 714        DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
 715        DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
 716
 717        DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
 718        DUMPREG(HDMI_TG_CMD);
 719        DUMPREG(HDMI_TG_H_FSZ_L);
 720        DUMPREG(HDMI_TG_H_FSZ_H);
 721        DUMPREG(HDMI_TG_HACT_ST_L);
 722        DUMPREG(HDMI_TG_HACT_ST_H);
 723        DUMPREG(HDMI_TG_HACT_SZ_L);
 724        DUMPREG(HDMI_TG_HACT_SZ_H);
 725        DUMPREG(HDMI_TG_V_FSZ_L);
 726        DUMPREG(HDMI_TG_V_FSZ_H);
 727        DUMPREG(HDMI_TG_VSYNC_L);
 728        DUMPREG(HDMI_TG_VSYNC_H);
 729        DUMPREG(HDMI_TG_VSYNC2_L);
 730        DUMPREG(HDMI_TG_VSYNC2_H);
 731        DUMPREG(HDMI_TG_VACT_ST_L);
 732        DUMPREG(HDMI_TG_VACT_ST_H);
 733        DUMPREG(HDMI_TG_VACT_SZ_L);
 734        DUMPREG(HDMI_TG_VACT_SZ_H);
 735        DUMPREG(HDMI_TG_FIELD_CHG_L);
 736        DUMPREG(HDMI_TG_FIELD_CHG_H);
 737        DUMPREG(HDMI_TG_VACT_ST2_L);
 738        DUMPREG(HDMI_TG_VACT_ST2_H);
 739        DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
 740        DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
 741        DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
 742        DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
 743        DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
 744        DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
 745        DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
 746        DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
 747#undef DUMPREG
 748}
 749
 750static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
 751{
 752        int i;
 753
 754#define DUMPREG(reg_id) \
 755        DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
 756        readl(hdata->regs + reg_id))
 757
 758        DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
 759        DUMPREG(HDMI_INTC_CON);
 760        DUMPREG(HDMI_INTC_FLAG);
 761        DUMPREG(HDMI_HPD_STATUS);
 762        DUMPREG(HDMI_INTC_CON_1);
 763        DUMPREG(HDMI_INTC_FLAG_1);
 764        DUMPREG(HDMI_PHY_STATUS_0);
 765        DUMPREG(HDMI_PHY_STATUS_PLL);
 766        DUMPREG(HDMI_PHY_CON_0);
 767        DUMPREG(HDMI_PHY_RSTOUT);
 768        DUMPREG(HDMI_PHY_VPLL);
 769        DUMPREG(HDMI_PHY_CMU);
 770        DUMPREG(HDMI_CORE_RSTOUT);
 771
 772        DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
 773        DUMPREG(HDMI_CON_0);
 774        DUMPREG(HDMI_CON_1);
 775        DUMPREG(HDMI_CON_2);
 776        DUMPREG(HDMI_SYS_STATUS);
 777        DUMPREG(HDMI_PHY_STATUS_0);
 778        DUMPREG(HDMI_STATUS_EN);
 779        DUMPREG(HDMI_HPD);
 780        DUMPREG(HDMI_MODE_SEL);
 781        DUMPREG(HDMI_ENC_EN);
 782        DUMPREG(HDMI_DC_CONTROL);
 783        DUMPREG(HDMI_VIDEO_PATTERN_GEN);
 784
 785        DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
 786        DUMPREG(HDMI_H_BLANK_0);
 787        DUMPREG(HDMI_H_BLANK_1);
 788        DUMPREG(HDMI_V2_BLANK_0);
 789        DUMPREG(HDMI_V2_BLANK_1);
 790        DUMPREG(HDMI_V1_BLANK_0);
 791        DUMPREG(HDMI_V1_BLANK_1);
 792        DUMPREG(HDMI_V_LINE_0);
 793        DUMPREG(HDMI_V_LINE_1);
 794        DUMPREG(HDMI_H_LINE_0);
 795        DUMPREG(HDMI_H_LINE_1);
 796        DUMPREG(HDMI_HSYNC_POL);
 797
 798        DUMPREG(HDMI_VSYNC_POL);
 799        DUMPREG(HDMI_INT_PRO_MODE);
 800        DUMPREG(HDMI_V_BLANK_F0_0);
 801        DUMPREG(HDMI_V_BLANK_F0_1);
 802        DUMPREG(HDMI_V_BLANK_F1_0);
 803        DUMPREG(HDMI_V_BLANK_F1_1);
 804
 805        DUMPREG(HDMI_H_SYNC_START_0);
 806        DUMPREG(HDMI_H_SYNC_START_1);
 807        DUMPREG(HDMI_H_SYNC_END_0);
 808        DUMPREG(HDMI_H_SYNC_END_1);
 809
 810        DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
 811        DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
 812        DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
 813        DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
 814
 815        DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
 816        DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
 817        DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
 818        DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
 819
 820        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
 821        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
 822        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
 823        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
 824
 825        DUMPREG(HDMI_V_BLANK_F2_0);
 826        DUMPREG(HDMI_V_BLANK_F2_1);
 827        DUMPREG(HDMI_V_BLANK_F3_0);
 828        DUMPREG(HDMI_V_BLANK_F3_1);
 829        DUMPREG(HDMI_V_BLANK_F4_0);
 830        DUMPREG(HDMI_V_BLANK_F4_1);
 831        DUMPREG(HDMI_V_BLANK_F5_0);
 832        DUMPREG(HDMI_V_BLANK_F5_1);
 833
 834        DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
 835        DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
 836        DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
 837        DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
 838        DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
 839        DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
 840        DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
 841        DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
 842
 843        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
 844        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
 845        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
 846        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
 847        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
 848        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
 849        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
 850        DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
 851
 852        DUMPREG(HDMI_VACT_SPACE_1_0);
 853        DUMPREG(HDMI_VACT_SPACE_1_1);
 854        DUMPREG(HDMI_VACT_SPACE_2_0);
 855        DUMPREG(HDMI_VACT_SPACE_2_1);
 856        DUMPREG(HDMI_VACT_SPACE_3_0);
 857        DUMPREG(HDMI_VACT_SPACE_3_1);
 858        DUMPREG(HDMI_VACT_SPACE_4_0);
 859        DUMPREG(HDMI_VACT_SPACE_4_1);
 860        DUMPREG(HDMI_VACT_SPACE_5_0);
 861        DUMPREG(HDMI_VACT_SPACE_5_1);
 862        DUMPREG(HDMI_VACT_SPACE_6_0);
 863        DUMPREG(HDMI_VACT_SPACE_6_1);
 864
 865        DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
 866        DUMPREG(HDMI_TG_CMD);
 867        DUMPREG(HDMI_TG_H_FSZ_L);
 868        DUMPREG(HDMI_TG_H_FSZ_H);
 869        DUMPREG(HDMI_TG_HACT_ST_L);
 870        DUMPREG(HDMI_TG_HACT_ST_H);
 871        DUMPREG(HDMI_TG_HACT_SZ_L);
 872        DUMPREG(HDMI_TG_HACT_SZ_H);
 873        DUMPREG(HDMI_TG_V_FSZ_L);
 874        DUMPREG(HDMI_TG_V_FSZ_H);
 875        DUMPREG(HDMI_TG_VSYNC_L);
 876        DUMPREG(HDMI_TG_VSYNC_H);
 877        DUMPREG(HDMI_TG_VSYNC2_L);
 878        DUMPREG(HDMI_TG_VSYNC2_H);
 879        DUMPREG(HDMI_TG_VACT_ST_L);
 880        DUMPREG(HDMI_TG_VACT_ST_H);
 881        DUMPREG(HDMI_TG_VACT_SZ_L);
 882        DUMPREG(HDMI_TG_VACT_SZ_H);
 883        DUMPREG(HDMI_TG_FIELD_CHG_L);
 884        DUMPREG(HDMI_TG_FIELD_CHG_H);
 885        DUMPREG(HDMI_TG_VACT_ST2_L);
 886        DUMPREG(HDMI_TG_VACT_ST2_H);
 887        DUMPREG(HDMI_TG_VACT_ST3_L);
 888        DUMPREG(HDMI_TG_VACT_ST3_H);
 889        DUMPREG(HDMI_TG_VACT_ST4_L);
 890        DUMPREG(HDMI_TG_VACT_ST4_H);
 891        DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
 892        DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
 893        DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
 894        DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
 895        DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
 896        DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
 897        DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
 898        DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
 899        DUMPREG(HDMI_TG_3D);
 900
 901        DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
 902        DUMPREG(HDMI_AVI_CON);
 903        DUMPREG(HDMI_AVI_HEADER0);
 904        DUMPREG(HDMI_AVI_HEADER1);
 905        DUMPREG(HDMI_AVI_HEADER2);
 906        DUMPREG(HDMI_AVI_CHECK_SUM);
 907        DUMPREG(HDMI_VSI_CON);
 908        DUMPREG(HDMI_VSI_HEADER0);
 909        DUMPREG(HDMI_VSI_HEADER1);
 910        DUMPREG(HDMI_VSI_HEADER2);
 911        for (i = 0; i < 7; ++i)
 912                DUMPREG(HDMI_VSI_DATA(i));
 913
 914#undef DUMPREG
 915}
 916
 917static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
 918{
 919        if (hdata->type == HDMI_TYPE13)
 920                hdmi_v13_regs_dump(hdata, prefix);
 921        else
 922                hdmi_v14_regs_dump(hdata, prefix);
 923}
 924
 925static u8 hdmi_chksum(struct hdmi_context *hdata,
 926                        u32 start, u8 len, u32 hdr_sum)
 927{
 928        int i;
 929
 930        /* hdr_sum : header0 + header1 + header2
 931        * start : start address of packet byte1
 932        * len : packet bytes - 1 */
 933        for (i = 0; i < len; ++i)
 934                hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
 935
 936        /* return 2's complement of 8 bit hdr_sum */
 937        return (u8)(~(hdr_sum & 0xff) + 1);
 938}
 939
 940static void hdmi_reg_infoframe(struct hdmi_context *hdata,
 941                        union hdmi_infoframe *infoframe)
 942{
 943        u32 hdr_sum;
 944        u8 chksum;
 945        u32 mod;
 946        u32 vic;
 947
 948        mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
 949        if (hdata->dvi_mode) {
 950                hdmi_reg_writeb(hdata, HDMI_VSI_CON,
 951                                HDMI_VSI_CON_DO_NOT_TRANSMIT);
 952                hdmi_reg_writeb(hdata, HDMI_AVI_CON,
 953                                HDMI_AVI_CON_DO_NOT_TRANSMIT);
 954                hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
 955                return;
 956        }
 957
 958        switch (infoframe->any.type) {
 959        case HDMI_INFOFRAME_TYPE_AVI:
 960                hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
 961                hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
 962                hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
 963                                infoframe->any.version);
 964                hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
 965                hdr_sum = infoframe->any.type + infoframe->any.version +
 966                          infoframe->any.length;
 967
 968                /* Output format zero hardcoded ,RGB YBCR selection */
 969                hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
 970                        AVI_ACTIVE_FORMAT_VALID |
 971                        AVI_UNDERSCANNED_DISPLAY_VALID);
 972
 973                /*
 974                 * Set the aspect ratio as per the mode, mentioned in
 975                 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
 976                 */
 977                switch (hdata->mode_conf.aspect_ratio) {
 978                case HDMI_PICTURE_ASPECT_4_3:
 979                        hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
 980                                        hdata->mode_conf.aspect_ratio |
 981                                        AVI_4_3_CENTER_RATIO);
 982                        break;
 983                case HDMI_PICTURE_ASPECT_16_9:
 984                        hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
 985                                        hdata->mode_conf.aspect_ratio |
 986                                        AVI_16_9_CENTER_RATIO);
 987                        break;
 988                case HDMI_PICTURE_ASPECT_NONE:
 989                default:
 990                        hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
 991                                        hdata->mode_conf.aspect_ratio |
 992                                        AVI_SAME_AS_PIC_ASPECT_RATIO);
 993                        break;
 994                }
 995
 996                vic = hdata->mode_conf.cea_video_id;
 997                hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
 998
 999                chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
1000                                        infoframe->any.length, hdr_sum);
1001                DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
1002                hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
1003                break;
1004        case HDMI_INFOFRAME_TYPE_AUDIO:
1005                hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
1006                hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
1007                hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
1008                                infoframe->any.version);
1009                hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
1010                hdr_sum = infoframe->any.type + infoframe->any.version +
1011                          infoframe->any.length;
1012                chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
1013                                        infoframe->any.length, hdr_sum);
1014                DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
1015                hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
1016                break;
1017        default:
1018                break;
1019        }
1020}
1021
1022static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
1023                                bool force)
1024{
1025        struct hdmi_context *hdata = ctx_from_connector(connector);
1026
1027        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
1028
1029        return hdata->hpd ? connector_status_connected :
1030                        connector_status_disconnected;
1031}
1032
1033static void hdmi_connector_destroy(struct drm_connector *connector)
1034{
1035}
1036
1037static struct drm_connector_funcs hdmi_connector_funcs = {
1038        .dpms = drm_helper_connector_dpms,
1039        .fill_modes = drm_helper_probe_single_connector_modes,
1040        .detect = hdmi_detect,
1041        .destroy = hdmi_connector_destroy,
1042};
1043
1044static int hdmi_get_modes(struct drm_connector *connector)
1045{
1046        struct hdmi_context *hdata = ctx_from_connector(connector);
1047        struct edid *edid;
1048
1049        if (!hdata->ddc_adpt)
1050                return -ENODEV;
1051
1052        edid = drm_get_edid(connector, hdata->ddc_adpt);
1053        if (!edid)
1054                return -ENODEV;
1055
1056        hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
1057        DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1058                (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1059                edid->width_cm, edid->height_cm);
1060
1061        drm_mode_connector_update_edid_property(connector, edid);
1062
1063        return drm_add_edid_modes(connector, edid);
1064}
1065
1066static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
1067{
1068        int i;
1069
1070        for (i = 0; i < hdata->phy_conf_count; i++)
1071                if (hdata->phy_confs[i].pixel_clock == pixel_clock)
1072                        return i;
1073
1074        DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1075        return -EINVAL;
1076}
1077
1078static int hdmi_mode_valid(struct drm_connector *connector,
1079                        struct drm_display_mode *mode)
1080{
1081        struct hdmi_context *hdata = ctx_from_connector(connector);
1082        int ret;
1083
1084        DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1085                mode->hdisplay, mode->vdisplay, mode->vrefresh,
1086                (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
1087                false, mode->clock * 1000);
1088
1089        ret = mixer_check_mode(mode);
1090        if (ret)
1091                return MODE_BAD;
1092
1093        ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
1094        if (ret < 0)
1095                return MODE_BAD;
1096
1097        return MODE_OK;
1098}
1099
1100static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
1101{
1102        struct hdmi_context *hdata = ctx_from_connector(connector);
1103
1104        return hdata->encoder;
1105}
1106
1107static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
1108        .get_modes = hdmi_get_modes,
1109        .mode_valid = hdmi_mode_valid,
1110        .best_encoder = hdmi_best_encoder,
1111};
1112
1113static int hdmi_create_connector(struct exynos_drm_display *display,
1114                        struct drm_encoder *encoder)
1115{
1116        struct hdmi_context *hdata = display->ctx;
1117        struct drm_connector *connector = &hdata->connector;
1118        int ret;
1119
1120        hdata->encoder = encoder;
1121        connector->interlace_allowed = true;
1122        connector->polled = DRM_CONNECTOR_POLL_HPD;
1123
1124        ret = drm_connector_init(hdata->drm_dev, connector,
1125                        &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1126        if (ret) {
1127                DRM_ERROR("Failed to initialize connector with drm\n");
1128                return ret;
1129        }
1130
1131        drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
1132        drm_sysfs_connector_add(connector);
1133        drm_mode_connector_attach_encoder(connector, encoder);
1134
1135        return 0;
1136}
1137
1138static void hdmi_mode_fixup(struct exynos_drm_display *display,
1139                                struct drm_connector *connector,
1140                                const struct drm_display_mode *mode,
1141                                struct drm_display_mode *adjusted_mode)
1142{
1143        struct drm_display_mode *m;
1144        int mode_ok;
1145
1146        DRM_DEBUG_KMS("%s\n", __FILE__);
1147
1148        drm_mode_set_crtcinfo(adjusted_mode, 0);
1149
1150        mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1151
1152        /* just return if user desired mode exists. */
1153        if (mode_ok == MODE_OK)
1154                return;
1155
1156        /*
1157         * otherwise, find the most suitable mode among modes and change it
1158         * to adjusted_mode.
1159         */
1160        list_for_each_entry(m, &connector->modes, head) {
1161                mode_ok = hdmi_mode_valid(connector, m);
1162
1163                if (mode_ok == MODE_OK) {
1164                        DRM_INFO("desired mode doesn't exist so\n");
1165                        DRM_INFO("use the most suitable mode among modes.\n");
1166
1167                        DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1168                                m->hdisplay, m->vdisplay, m->vrefresh);
1169
1170                        drm_mode_copy(adjusted_mode, m);
1171                        break;
1172                }
1173        }
1174}
1175
1176static void hdmi_set_acr(u32 freq, u8 *acr)
1177{
1178        u32 n, cts;
1179
1180        switch (freq) {
1181        case 32000:
1182                n = 4096;
1183                cts = 27000;
1184                break;
1185        case 44100:
1186                n = 6272;
1187                cts = 30000;
1188                break;
1189        case 88200:
1190                n = 12544;
1191                cts = 30000;
1192                break;
1193        case 176400:
1194                n = 25088;
1195                cts = 30000;
1196                break;
1197        case 48000:
1198                n = 6144;
1199                cts = 27000;
1200                break;
1201        case 96000:
1202                n = 12288;
1203                cts = 27000;
1204                break;
1205        case 192000:
1206                n = 24576;
1207                cts = 27000;
1208                break;
1209        default:
1210                n = 0;
1211                cts = 0;
1212                break;
1213        }
1214
1215        acr[1] = cts >> 16;
1216        acr[2] = cts >> 8 & 0xff;
1217        acr[3] = cts & 0xff;
1218
1219        acr[4] = n >> 16;
1220        acr[5] = n >> 8 & 0xff;
1221        acr[6] = n & 0xff;
1222}
1223
1224static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1225{
1226        hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1227        hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1228        hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1229        hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1230        hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1231        hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1232        hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1233        hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1234        hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1235
1236        if (hdata->type == HDMI_TYPE13)
1237                hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1238        else
1239                hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1240}
1241
1242static void hdmi_audio_init(struct hdmi_context *hdata)
1243{
1244        u32 sample_rate, bits_per_sample, frame_size_code;
1245        u32 data_num, bit_ch, sample_frq;
1246        u32 val;
1247        u8 acr[7];
1248
1249        sample_rate = 44100;
1250        bits_per_sample = 16;
1251        frame_size_code = 0;
1252
1253        switch (bits_per_sample) {
1254        case 20:
1255                data_num = 2;
1256                bit_ch  = 1;
1257                break;
1258        case 24:
1259                data_num = 3;
1260                bit_ch  = 1;
1261                break;
1262        default:
1263                data_num = 1;
1264                bit_ch  = 0;
1265                break;
1266        }
1267
1268        hdmi_set_acr(sample_rate, acr);
1269        hdmi_reg_acr(hdata, acr);
1270
1271        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1272                                | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1273                                | HDMI_I2S_MUX_ENABLE);
1274
1275        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1276                        | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1277
1278        hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1279
1280        sample_frq = (sample_rate == 44100) ? 0 :
1281                        (sample_rate == 48000) ? 2 :
1282                        (sample_rate == 32000) ? 3 :
1283                        (sample_rate == 96000) ? 0xa : 0x0;
1284
1285        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1286        hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1287
1288        val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1289        hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1290
1291        /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1292        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1293                        | HDMI_I2S_SEL_LRCK(6));
1294        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1295                        | HDMI_I2S_SEL_SDATA2(4));
1296        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1297                        | HDMI_I2S_SEL_SDATA2(2));
1298        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1299
1300        /* I2S_CON_1 & 2 */
1301        hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1302                        | HDMI_I2S_L_CH_LOW_POL);
1303        hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1304                        | HDMI_I2S_SET_BIT_CH(bit_ch)
1305                        | HDMI_I2S_SET_SDATA_BIT(data_num)
1306                        | HDMI_I2S_BASIC_FORMAT);
1307
1308        /* Configure register related to CUV information */
1309        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1310                        | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1311                        | HDMI_I2S_COPYRIGHT
1312                        | HDMI_I2S_LINEAR_PCM
1313                        | HDMI_I2S_CONSUMER_FORMAT);
1314        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1315        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1316        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1317                        | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1318        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1319                        HDMI_I2S_ORG_SMP_FREQ_44_1
1320                        | HDMI_I2S_WORD_LEN_MAX24_24BITS
1321                        | HDMI_I2S_WORD_LEN_MAX_24BITS);
1322
1323        hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1324}
1325
1326static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1327{
1328        if (hdata->dvi_mode)
1329                return;
1330
1331        hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1332        hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1333                        HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1334}
1335
1336static void hdmi_start(struct hdmi_context *hdata, bool start)
1337{
1338        u32 val = start ? HDMI_TG_EN : 0;
1339
1340        if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1341                val |= HDMI_FIELD_EN;
1342
1343        hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1344        hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1345}
1346
1347static void hdmi_conf_init(struct hdmi_context *hdata)
1348{
1349        union hdmi_infoframe infoframe;
1350
1351        /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1352        hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1353                HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1354
1355        /* choose HDMI mode */
1356        hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1357                HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1358        /* Apply Video preable and Guard band in HDMI mode only */
1359        hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1360        /* disable bluescreen */
1361        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1362
1363        if (hdata->dvi_mode) {
1364                /* choose DVI mode */
1365                hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1366                                HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1367                hdmi_reg_writeb(hdata, HDMI_CON_2,
1368                                HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1369        }
1370
1371        if (hdata->type == HDMI_TYPE13) {
1372                /* choose bluescreen (fecal) color */
1373                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1374                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1375                hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1376
1377                /* enable AVI packet every vsync, fixes purple line problem */
1378                hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1379                /* force RGB, look to CEA-861-D, table 7 for more detail */
1380                hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1381                hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1382
1383                hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1384                hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1385                hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1386        } else {
1387                infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1388                infoframe.any.version = HDMI_AVI_VERSION;
1389                infoframe.any.length = HDMI_AVI_LENGTH;
1390                hdmi_reg_infoframe(hdata, &infoframe);
1391
1392                infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1393                infoframe.any.version = HDMI_AUI_VERSION;
1394                infoframe.any.length = HDMI_AUI_LENGTH;
1395                hdmi_reg_infoframe(hdata, &infoframe);
1396
1397                /* enable AVI packet every vsync, fixes purple line problem */
1398                hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1399        }
1400}
1401
1402static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1403{
1404        const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1405        const struct hdmi_v13_core_regs *core =
1406                &hdata->mode_conf.conf.v13_conf.core;
1407        int tries;
1408
1409        /* setting core registers */
1410        hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1411        hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1412        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1413        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1414        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1415        hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1416        hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1417        hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1418        hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1419        hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1420        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1421        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1422        hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1423        hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1424        hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1425        hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1426        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1427        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1428        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1429        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1430        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1431        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1432        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1433        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1434        hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1435        /* Timing generator registers */
1436        hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1437        hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1438        hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1439        hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1440        hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1441        hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1442        hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1443        hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1444        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1445        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1446        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1447        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1448        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1449        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1450        hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1451        hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1452        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1453        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1454        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1455        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1456        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1457        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1458        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1459        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1460        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1461        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1462        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1463        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1464
1465        /* waiting for HDMIPHY's PLL to get to steady state */
1466        for (tries = 100; tries; --tries) {
1467                u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1468                if (val & HDMI_PHY_STATUS_READY)
1469                        break;
1470                usleep_range(1000, 2000);
1471        }
1472        /* steady state not achieved */
1473        if (tries == 0) {
1474                DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1475                hdmi_regs_dump(hdata, "timing apply");
1476        }
1477
1478        clk_disable_unprepare(hdata->res.sclk_hdmi);
1479        clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1480        clk_prepare_enable(hdata->res.sclk_hdmi);
1481
1482        /* enable HDMI and timing generator */
1483        hdmi_start(hdata, true);
1484}
1485
1486static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1487{
1488        const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1489        const struct hdmi_v14_core_regs *core =
1490                &hdata->mode_conf.conf.v14_conf.core;
1491        int tries;
1492
1493        /* setting core registers */
1494        hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1495        hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1496        hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1497        hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1498        hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1499        hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1500        hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1501        hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1502        hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1503        hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1504        hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1505        hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1506        hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1507        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1508        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1509        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1510        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1511        hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1512        hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1513        hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1514        hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1515        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1516                        core->v_sync_line_bef_2[0]);
1517        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1518                        core->v_sync_line_bef_2[1]);
1519        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1520                        core->v_sync_line_bef_1[0]);
1521        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1522                        core->v_sync_line_bef_1[1]);
1523        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1524                        core->v_sync_line_aft_2[0]);
1525        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1526                        core->v_sync_line_aft_2[1]);
1527        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1528                        core->v_sync_line_aft_1[0]);
1529        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1530                        core->v_sync_line_aft_1[1]);
1531        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1532                        core->v_sync_line_aft_pxl_2[0]);
1533        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1534                        core->v_sync_line_aft_pxl_2[1]);
1535        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1536                        core->v_sync_line_aft_pxl_1[0]);
1537        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1538                        core->v_sync_line_aft_pxl_1[1]);
1539        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1540        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1541        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1542        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1543        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1544        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1545        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1546        hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1547        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1548                        core->v_sync_line_aft_3[0]);
1549        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1550                        core->v_sync_line_aft_3[1]);
1551        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1552                        core->v_sync_line_aft_4[0]);
1553        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1554                        core->v_sync_line_aft_4[1]);
1555        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1556                        core->v_sync_line_aft_5[0]);
1557        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1558                        core->v_sync_line_aft_5[1]);
1559        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1560                        core->v_sync_line_aft_6[0]);
1561        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1562                        core->v_sync_line_aft_6[1]);
1563        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1564                        core->v_sync_line_aft_pxl_3[0]);
1565        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1566                        core->v_sync_line_aft_pxl_3[1]);
1567        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1568                        core->v_sync_line_aft_pxl_4[0]);
1569        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1570                        core->v_sync_line_aft_pxl_4[1]);
1571        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1572                        core->v_sync_line_aft_pxl_5[0]);
1573        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1574                        core->v_sync_line_aft_pxl_5[1]);
1575        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1576                        core->v_sync_line_aft_pxl_6[0]);
1577        hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1578                        core->v_sync_line_aft_pxl_6[1]);
1579        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1580        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1581        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1582        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1583        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1584        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1585        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1586        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1587        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1588        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1589        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1590        hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1591
1592        /* Timing generator registers */
1593        hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1594        hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1595        hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1596        hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1597        hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1598        hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1599        hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1600        hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1601        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1602        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1603        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1604        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1605        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1606        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1607        hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1608        hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1609        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1610        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1611        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1612        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1613        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3[0]);
1614        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3[1]);
1615        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4[0]);
1616        hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4[1]);
1617        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1618        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1619        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1620        hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1621        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1622        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1623        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1624        hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1625        hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d[0]);
1626
1627        /* waiting for HDMIPHY's PLL to get to steady state */
1628        for (tries = 100; tries; --tries) {
1629                u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1630                if (val & HDMI_PHY_STATUS_READY)
1631                        break;
1632                usleep_range(1000, 2000);
1633        }
1634        /* steady state not achieved */
1635        if (tries == 0) {
1636                DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1637                hdmi_regs_dump(hdata, "timing apply");
1638        }
1639
1640        clk_disable_unprepare(hdata->res.sclk_hdmi);
1641        clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1642        clk_prepare_enable(hdata->res.sclk_hdmi);
1643
1644        /* enable HDMI and timing generator */
1645        hdmi_start(hdata, true);
1646}
1647
1648static void hdmi_mode_apply(struct hdmi_context *hdata)
1649{
1650        if (hdata->type == HDMI_TYPE13)
1651                hdmi_v13_mode_apply(hdata);
1652        else
1653                hdmi_v14_mode_apply(hdata);
1654}
1655
1656static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1657{
1658        u8 buffer[2];
1659        u32 reg;
1660
1661        clk_disable_unprepare(hdata->res.sclk_hdmi);
1662        clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
1663        clk_prepare_enable(hdata->res.sclk_hdmi);
1664
1665        /* operation mode */
1666        buffer[0] = 0x1f;
1667        buffer[1] = 0x00;
1668
1669        if (hdata->hdmiphy_port)
1670                i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1671
1672        if (hdata->type == HDMI_TYPE13)
1673                reg = HDMI_V13_PHY_RSTOUT;
1674        else
1675                reg = HDMI_PHY_RSTOUT;
1676
1677        /* reset hdmiphy */
1678        hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1679        usleep_range(10000, 12000);
1680        hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1681        usleep_range(10000, 12000);
1682}
1683
1684static void hdmiphy_poweron(struct hdmi_context *hdata)
1685{
1686        if (hdata->type != HDMI_TYPE14)
1687                return;
1688
1689        DRM_DEBUG_KMS("\n");
1690
1691        /* For PHY Mode Setting */
1692        hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1693                                HDMI_PHY_ENABLE_MODE_SET);
1694        /* Phy Power On */
1695        hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1696                                HDMI_PHY_POWER_ON);
1697        /* For PHY Mode Setting */
1698        hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1699                                HDMI_PHY_DISABLE_MODE_SET);
1700        /* PHY SW Reset */
1701        hdmiphy_conf_reset(hdata);
1702}
1703
1704static void hdmiphy_poweroff(struct hdmi_context *hdata)
1705{
1706        if (hdata->type != HDMI_TYPE14)
1707                return;
1708
1709        DRM_DEBUG_KMS("\n");
1710
1711        /* PHY SW Reset */
1712        hdmiphy_conf_reset(hdata);
1713        /* For PHY Mode Setting */
1714        hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1715                                HDMI_PHY_ENABLE_MODE_SET);
1716
1717        /* PHY Power Off */
1718        hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1719                                HDMI_PHY_POWER_OFF);
1720
1721        /* For PHY Mode Setting */
1722        hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1723                                HDMI_PHY_DISABLE_MODE_SET);
1724}
1725
1726static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1727{
1728        int ret;
1729        int i;
1730
1731        /* pixel clock */
1732        i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
1733        if (i < 0) {
1734                DRM_ERROR("failed to find hdmiphy conf\n");
1735                return;
1736        }
1737
1738        ret = hdmiphy_reg_write_buf(hdata, 0, hdata->phy_confs[i].conf, 32);
1739        if (ret) {
1740                DRM_ERROR("failed to configure hdmiphy\n");
1741                return;
1742        }
1743
1744        usleep_range(10000, 12000);
1745
1746        ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1747                                HDMI_PHY_DISABLE_MODE_SET);
1748        if (ret) {
1749                DRM_ERROR("failed to enable hdmiphy\n");
1750                return;
1751        }
1752
1753}
1754
1755static void hdmi_conf_apply(struct hdmi_context *hdata)
1756{
1757        hdmiphy_conf_reset(hdata);
1758        hdmiphy_conf_apply(hdata);
1759
1760        mutex_lock(&hdata->hdmi_mutex);
1761        hdmi_start(hdata, false);
1762        hdmi_conf_init(hdata);
1763        mutex_unlock(&hdata->hdmi_mutex);
1764
1765        hdmi_audio_init(hdata);
1766
1767        /* setting core registers */
1768        hdmi_mode_apply(hdata);
1769        hdmi_audio_control(hdata, true);
1770
1771        hdmi_regs_dump(hdata, "start");
1772}
1773
1774static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
1775{
1776        int i;
1777        BUG_ON(num_bytes > 4);
1778        for (i = 0; i < num_bytes; i++)
1779                reg_pair[i] = (value >> (8 * i)) & 0xff;
1780}
1781
1782static void hdmi_v13_mode_set(struct hdmi_context *hdata,
1783                        struct drm_display_mode *m)
1784{
1785        struct hdmi_v13_core_regs *core = &hdata->mode_conf.conf.v13_conf.core;
1786        struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1787        unsigned int val;
1788
1789        hdata->mode_conf.cea_video_id =
1790                drm_match_cea_mode((struct drm_display_mode *)m);
1791        hdata->mode_conf.pixel_clock = m->clock * 1000;
1792        hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1793
1794        hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1795        hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
1796
1797        val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1798        hdmi_set_reg(core->vsync_pol, 1, val);
1799
1800        val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1801        hdmi_set_reg(core->int_pro_mode, 1, val);
1802
1803        val = (m->hsync_start - m->hdisplay - 2);
1804        val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1805        val |= ((m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0)<<20;
1806        hdmi_set_reg(core->h_sync_gen, 3, val);
1807
1808        /*
1809         * Quirk requirement for exynos HDMI IP design,
1810         * 2 pixels less than the actual calculation for hsync_start
1811         * and end.
1812         */
1813
1814        /* Following values & calculations differ for different type of modes */
1815        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1816                /* Interlaced Mode */
1817                val = ((m->vsync_end - m->vdisplay) / 2);
1818                val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1819                hdmi_set_reg(core->v_sync_gen1, 3, val);
1820
1821                val = m->vtotal / 2;
1822                val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1823                hdmi_set_reg(core->v_blank, 3, val);
1824
1825                val = (m->vtotal +
1826                        ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1827                val |= m->vtotal << 11;
1828                hdmi_set_reg(core->v_blank_f, 3, val);
1829
1830                val = ((m->vtotal / 2) + 7);
1831                val |= ((m->vtotal / 2) + 2) << 12;
1832                hdmi_set_reg(core->v_sync_gen2, 3, val);
1833
1834                val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1835                val |= ((m->htotal / 2) +
1836                        (m->hsync_start - m->hdisplay)) << 12;
1837                hdmi_set_reg(core->v_sync_gen3, 3, val);
1838
1839                hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1840                hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1841
1842                hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
1843        } else {
1844                /* Progressive Mode */
1845
1846                val = m->vtotal;
1847                val |= (m->vtotal - m->vdisplay) << 11;
1848                hdmi_set_reg(core->v_blank, 3, val);
1849
1850                hdmi_set_reg(core->v_blank_f, 3, 0);
1851
1852                val = (m->vsync_end - m->vdisplay);
1853                val |= ((m->vsync_start - m->vdisplay) << 12);
1854                hdmi_set_reg(core->v_sync_gen1, 3, val);
1855
1856                hdmi_set_reg(core->v_sync_gen2, 3, 0x1001);/* Reset value  */
1857                hdmi_set_reg(core->v_sync_gen3, 3, 0x1001);/* Reset value  */
1858                hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1859                hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1860                hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1861        }
1862
1863        /* Timing generator registers */
1864        hdmi_set_reg(tg->cmd, 1, 0x0);
1865        hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1866        hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1867        hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1868        hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1869        hdmi_set_reg(tg->vsync, 2, 0x1);
1870        hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1871        hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1872        hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1873        hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1874        hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1875        hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1876        hdmi_set_reg(tg->tg_3d, 1, 0x0); /* Not used */
1877}
1878
1879static void hdmi_v14_mode_set(struct hdmi_context *hdata,
1880                        struct drm_display_mode *m)
1881{
1882        struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1883        struct hdmi_v14_core_regs *core =
1884                &hdata->mode_conf.conf.v14_conf.core;
1885
1886        hdata->mode_conf.cea_video_id =
1887                drm_match_cea_mode((struct drm_display_mode *)m);
1888        hdata->mode_conf.pixel_clock = m->clock * 1000;
1889        hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1890
1891        hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1892        hdmi_set_reg(core->v_line, 2, m->vtotal);
1893        hdmi_set_reg(core->h_line, 2, m->htotal);
1894        hdmi_set_reg(core->hsync_pol, 1,
1895                        (m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0);
1896        hdmi_set_reg(core->vsync_pol, 1,
1897                        (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1898        hdmi_set_reg(core->int_pro_mode, 1,
1899                        (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1900
1901        /*
1902         * Quirk requirement for exynos 5 HDMI IP design,
1903         * 2 pixels less than the actual calculation for hsync_start
1904         * and end.
1905         */
1906
1907        /* Following values & calculations differ for different type of modes */
1908        if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1909                /* Interlaced Mode */
1910                hdmi_set_reg(core->v_sync_line_bef_2, 2,
1911                        (m->vsync_end - m->vdisplay) / 2);
1912                hdmi_set_reg(core->v_sync_line_bef_1, 2,
1913                        (m->vsync_start - m->vdisplay) / 2);
1914                hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
1915                hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
1916                hdmi_set_reg(core->v_blank_f0, 2, m->vtotal - m->vdisplay / 2);
1917                hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
1918                hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
1919                hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
1920                hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2,
1921                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1922                hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2,
1923                        (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1924                hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1925                hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1926                hdmi_set_reg(tg->vact_st2, 2, m->vtotal - m->vdisplay / 2);
1927                hdmi_set_reg(tg->vsync2, 2, (m->vtotal / 2) + 1);
1928                hdmi_set_reg(tg->vsync_bot_hdmi, 2, (m->vtotal / 2) + 1);
1929                hdmi_set_reg(tg->field_bot_hdmi, 2, (m->vtotal / 2) + 1);
1930                hdmi_set_reg(tg->vact_st3, 2, 0x0);
1931                hdmi_set_reg(tg->vact_st4, 2, 0x0);
1932        } else {
1933                /* Progressive Mode */
1934                hdmi_set_reg(core->v_sync_line_bef_2, 2,
1935                        m->vsync_end - m->vdisplay);
1936                hdmi_set_reg(core->v_sync_line_bef_1, 2,
1937                        m->vsync_start - m->vdisplay);
1938                hdmi_set_reg(core->v2_blank, 2, m->vtotal);
1939                hdmi_set_reg(core->v1_blank, 2, m->vtotal - m->vdisplay);
1940                hdmi_set_reg(core->v_blank_f0, 2, 0xffff);
1941                hdmi_set_reg(core->v_blank_f1, 2, 0xffff);
1942                hdmi_set_reg(core->v_sync_line_aft_2, 2, 0xffff);
1943                hdmi_set_reg(core->v_sync_line_aft_1, 2, 0xffff);
1944                hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2, 0xffff);
1945                hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2, 0xffff);
1946                hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1947                hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1948                hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1949                hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
1950                hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
1951                hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1952                hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1953                hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1954        }
1955
1956        /* Following values & calculations are same irrespective of mode type */
1957        hdmi_set_reg(core->h_sync_start, 2, m->hsync_start - m->hdisplay - 2);
1958        hdmi_set_reg(core->h_sync_end, 2, m->hsync_end - m->hdisplay - 2);
1959        hdmi_set_reg(core->vact_space_1, 2, 0xffff);
1960        hdmi_set_reg(core->vact_space_2, 2, 0xffff);
1961        hdmi_set_reg(core->vact_space_3, 2, 0xffff);
1962        hdmi_set_reg(core->vact_space_4, 2, 0xffff);
1963        hdmi_set_reg(core->vact_space_5, 2, 0xffff);
1964        hdmi_set_reg(core->vact_space_6, 2, 0xffff);
1965        hdmi_set_reg(core->v_blank_f2, 2, 0xffff);
1966        hdmi_set_reg(core->v_blank_f3, 2, 0xffff);
1967        hdmi_set_reg(core->v_blank_f4, 2, 0xffff);
1968        hdmi_set_reg(core->v_blank_f5, 2, 0xffff);
1969        hdmi_set_reg(core->v_sync_line_aft_3, 2, 0xffff);
1970        hdmi_set_reg(core->v_sync_line_aft_4, 2, 0xffff);
1971        hdmi_set_reg(core->v_sync_line_aft_5, 2, 0xffff);
1972        hdmi_set_reg(core->v_sync_line_aft_6, 2, 0xffff);
1973        hdmi_set_reg(core->v_sync_line_aft_pxl_3, 2, 0xffff);
1974        hdmi_set_reg(core->v_sync_line_aft_pxl_4, 2, 0xffff);
1975        hdmi_set_reg(core->v_sync_line_aft_pxl_5, 2, 0xffff);
1976        hdmi_set_reg(core->v_sync_line_aft_pxl_6, 2, 0xffff);
1977
1978        /* Timing generator registers */
1979        hdmi_set_reg(tg->cmd, 1, 0x0);
1980        hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1981        hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1982        hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1983        hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1984        hdmi_set_reg(tg->vsync, 2, 0x1);
1985        hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1986        hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1987        hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1988        hdmi_set_reg(tg->tg_3d, 1, 0x0);
1989}
1990
1991static void hdmi_mode_set(struct exynos_drm_display *display,
1992                        struct drm_display_mode *mode)
1993{
1994        struct hdmi_context *hdata = display->ctx;
1995        struct drm_display_mode *m = mode;
1996
1997        DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1998                m->hdisplay, m->vdisplay,
1999                m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
2000                "INTERLACED" : "PROGERESSIVE");
2001
2002        /* preserve mode information for later use. */
2003        drm_mode_copy(&hdata->current_mode, mode);
2004
2005        if (hdata->type == HDMI_TYPE13)
2006                hdmi_v13_mode_set(hdata, mode);
2007        else
2008                hdmi_v14_mode_set(hdata, mode);
2009}
2010
2011static void hdmi_commit(struct exynos_drm_display *display)
2012{
2013        struct hdmi_context *hdata = display->ctx;
2014
2015        mutex_lock(&hdata->hdmi_mutex);
2016        if (!hdata->powered) {
2017                mutex_unlock(&hdata->hdmi_mutex);
2018                return;
2019        }
2020        mutex_unlock(&hdata->hdmi_mutex);
2021
2022        hdmi_conf_apply(hdata);
2023}
2024
2025static void hdmi_poweron(struct exynos_drm_display *display)
2026{
2027        struct hdmi_context *hdata = display->ctx;
2028        struct hdmi_resources *res = &hdata->res;
2029
2030        mutex_lock(&hdata->hdmi_mutex);
2031        if (hdata->powered) {
2032                mutex_unlock(&hdata->hdmi_mutex);
2033                return;
2034        }
2035
2036        hdata->powered = true;
2037
2038        mutex_unlock(&hdata->hdmi_mutex);
2039
2040        pm_runtime_get_sync(hdata->dev);
2041
2042        if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
2043                DRM_DEBUG_KMS("failed to enable regulator bulk\n");
2044
2045        /* set pmu hdmiphy control bit to enable hdmiphy */
2046        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2047                        PMU_HDMI_PHY_ENABLE_BIT, 1);
2048
2049        clk_prepare_enable(res->hdmi);
2050        clk_prepare_enable(res->sclk_hdmi);
2051
2052        hdmiphy_poweron(hdata);
2053        hdmi_commit(display);
2054}
2055
2056static void hdmi_poweroff(struct exynos_drm_display *display)
2057{
2058        struct hdmi_context *hdata = display->ctx;
2059        struct hdmi_resources *res = &hdata->res;
2060
2061        mutex_lock(&hdata->hdmi_mutex);
2062        if (!hdata->powered)
2063                goto out;
2064        mutex_unlock(&hdata->hdmi_mutex);
2065
2066        /* HDMI System Disable */
2067        hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
2068
2069        hdmiphy_poweroff(hdata);
2070
2071        cancel_delayed_work(&hdata->hotplug_work);
2072
2073        clk_disable_unprepare(res->sclk_hdmi);
2074        clk_disable_unprepare(res->hdmi);
2075
2076        /* reset pmu hdmiphy control bit to disable hdmiphy */
2077        regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2078                        PMU_HDMI_PHY_ENABLE_BIT, 0);
2079
2080        regulator_bulk_disable(res->regul_count, res->regul_bulk);
2081
2082        pm_runtime_put_sync(hdata->dev);
2083
2084        mutex_lock(&hdata->hdmi_mutex);
2085        hdata->powered = false;
2086
2087out:
2088        mutex_unlock(&hdata->hdmi_mutex);
2089}
2090
2091static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2092{
2093        struct hdmi_context *hdata = display->ctx;
2094        struct drm_encoder *encoder = hdata->encoder;
2095        struct drm_crtc *crtc = encoder->crtc;
2096        struct drm_crtc_helper_funcs *funcs = NULL;
2097
2098        DRM_DEBUG_KMS("mode %d\n", mode);
2099
2100        switch (mode) {
2101        case DRM_MODE_DPMS_ON:
2102                hdmi_poweron(display);
2103                break;
2104        case DRM_MODE_DPMS_STANDBY:
2105        case DRM_MODE_DPMS_SUSPEND:
2106        case DRM_MODE_DPMS_OFF:
2107                /*
2108                 * The SFRs of VP and Mixer are updated by Vertical Sync of
2109                 * Timing generator which is a part of HDMI so the sequence
2110                 * to disable TV Subsystem should be as following,
2111                 *      VP -> Mixer -> HDMI
2112                 *
2113                 * Below codes will try to disable Mixer and VP(if used)
2114                 * prior to disabling HDMI.
2115                 */
2116                if (crtc)
2117                        funcs = crtc->helper_private;
2118                if (funcs && funcs->dpms)
2119                        (*funcs->dpms)(crtc, mode);
2120
2121                hdmi_poweroff(display);
2122                break;
2123        default:
2124                DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2125                break;
2126        }
2127}
2128
2129static struct exynos_drm_display_ops hdmi_display_ops = {
2130        .create_connector = hdmi_create_connector,
2131        .mode_fixup     = hdmi_mode_fixup,
2132        .mode_set       = hdmi_mode_set,
2133        .dpms           = hdmi_dpms,
2134        .commit         = hdmi_commit,
2135};
2136
2137static struct exynos_drm_display hdmi_display = {
2138        .type = EXYNOS_DISPLAY_TYPE_HDMI,
2139        .ops = &hdmi_display_ops,
2140};
2141
2142static void hdmi_hotplug_work_func(struct work_struct *work)
2143{
2144        struct hdmi_context *hdata;
2145
2146        hdata = container_of(work, struct hdmi_context, hotplug_work.work);
2147
2148        mutex_lock(&hdata->hdmi_mutex);
2149        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2150        mutex_unlock(&hdata->hdmi_mutex);
2151
2152        if (hdata->drm_dev)
2153                drm_helper_hpd_irq_event(hdata->drm_dev);
2154}
2155
2156static irqreturn_t hdmi_irq_thread(int irq, void *arg)
2157{
2158        struct hdmi_context *hdata = arg;
2159
2160        mod_delayed_work(system_wq, &hdata->hotplug_work,
2161                        msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
2162
2163        return IRQ_HANDLED;
2164}
2165
2166static int hdmi_resources_init(struct hdmi_context *hdata)
2167{
2168        struct device *dev = hdata->dev;
2169        struct hdmi_resources *res = &hdata->res;
2170        static char *supply[] = {
2171                "hdmi-en",
2172                "vdd",
2173                "vdd_osc",
2174                "vdd_pll",
2175        };
2176        int i, ret;
2177
2178        DRM_DEBUG_KMS("HDMI resource init\n");
2179
2180        /* get clocks, power */
2181        res->hdmi = devm_clk_get(dev, "hdmi");
2182        if (IS_ERR(res->hdmi)) {
2183                DRM_ERROR("failed to get clock 'hdmi'\n");
2184                ret = PTR_ERR(res->hdmi);
2185                goto fail;
2186        }
2187        res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
2188        if (IS_ERR(res->sclk_hdmi)) {
2189                DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2190                ret = PTR_ERR(res->sclk_hdmi);
2191                goto fail;
2192        }
2193        res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
2194        if (IS_ERR(res->sclk_pixel)) {
2195                DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2196                ret = PTR_ERR(res->sclk_pixel);
2197                goto fail;
2198        }
2199        res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
2200        if (IS_ERR(res->sclk_hdmiphy)) {
2201                DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2202                ret = PTR_ERR(res->sclk_hdmiphy);
2203                goto fail;
2204        }
2205        res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
2206        if (IS_ERR(res->mout_hdmi)) {
2207                DRM_ERROR("failed to get clock 'mout_hdmi'\n");
2208                ret = PTR_ERR(res->mout_hdmi);
2209                goto fail;
2210        }
2211
2212        clk_set_parent(res->mout_hdmi, res->sclk_pixel);
2213
2214        res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
2215                sizeof(res->regul_bulk[0]), GFP_KERNEL);
2216        if (!res->regul_bulk) {
2217                ret = -ENOMEM;
2218                goto fail;
2219        }
2220        for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2221                res->regul_bulk[i].supply = supply[i];
2222                res->regul_bulk[i].consumer = NULL;
2223        }
2224        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2225        if (ret) {
2226                DRM_ERROR("failed to get regulators\n");
2227                return ret;
2228        }
2229        res->regul_count = ARRAY_SIZE(supply);
2230
2231        return ret;
2232fail:
2233        DRM_ERROR("HDMI resource init - failed\n");
2234        return ret;
2235}
2236
2237static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2238                                        (struct device *dev)
2239{
2240        struct device_node *np = dev->of_node;
2241        struct s5p_hdmi_platform_data *pd;
2242        u32 value;
2243
2244        pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2245        if (!pd)
2246                goto err_data;
2247
2248        if (!of_find_property(np, "hpd-gpio", &value)) {
2249                DRM_ERROR("no hpd gpio property found\n");
2250                goto err_data;
2251        }
2252
2253        pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
2254
2255        return pd;
2256
2257err_data:
2258        return NULL;
2259}
2260
2261static struct of_device_id hdmi_match_types[] = {
2262        {
2263                .compatible = "samsung,exynos5-hdmi",
2264                .data = &exynos5_hdmi_driver_data,
2265        }, {
2266                .compatible = "samsung,exynos4212-hdmi",
2267                .data = &exynos4212_hdmi_driver_data,
2268        }, {
2269                .compatible = "samsung,exynos5420-hdmi",
2270                .data = &exynos5420_hdmi_driver_data,
2271        }, {
2272                /* end node */
2273        }
2274};
2275
2276static int hdmi_bind(struct device *dev, struct device *master, void *data)
2277{
2278        struct drm_device *drm_dev = data;
2279        struct hdmi_context *hdata;
2280
2281        hdata = hdmi_display.ctx;
2282        hdata->drm_dev = drm_dev;
2283
2284        return exynos_drm_create_enc_conn(drm_dev, &hdmi_display);
2285}
2286
2287static void hdmi_unbind(struct device *dev, struct device *master, void *data)
2288{
2289        struct exynos_drm_display *display = get_hdmi_display(dev);
2290        struct drm_encoder *encoder = display->encoder;
2291        struct hdmi_context *hdata = display->ctx;
2292
2293        encoder->funcs->destroy(encoder);
2294        drm_connector_cleanup(&hdata->connector);
2295}
2296
2297static const struct component_ops hdmi_component_ops = {
2298        .bind   = hdmi_bind,
2299        .unbind = hdmi_unbind,
2300};
2301
2302static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
2303{
2304        const char *compatible_str = "samsung,exynos4210-hdmiddc";
2305        struct device_node *np;
2306
2307        np = of_find_compatible_node(NULL, NULL, compatible_str);
2308        if (np)
2309                return of_get_next_parent(np);
2310
2311        return NULL;
2312}
2313
2314static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
2315{
2316        const char *compatible_str = "samsung,exynos4212-hdmiphy";
2317
2318        return of_find_compatible_node(NULL, NULL, compatible_str);
2319}
2320
2321static int hdmi_probe(struct platform_device *pdev)
2322{
2323        struct device_node *ddc_node, *phy_node;
2324        struct s5p_hdmi_platform_data *pdata;
2325        struct hdmi_driver_data *drv_data;
2326        const struct of_device_id *match;
2327        struct device *dev = &pdev->dev;
2328        struct hdmi_context *hdata;
2329        struct resource *res;
2330        int ret;
2331
2332        ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2333                                        hdmi_display.type);
2334        if (ret)
2335                return ret;
2336
2337        if (!dev->of_node) {
2338                ret = -ENODEV;
2339                goto err_del_component;
2340        }
2341
2342        pdata = drm_hdmi_dt_parse_pdata(dev);
2343        if (!pdata) {
2344                ret = -EINVAL;
2345                goto err_del_component;
2346        }
2347
2348        hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2349        if (!hdata) {
2350                ret = -ENOMEM;
2351                goto err_del_component;
2352        }
2353
2354        mutex_init(&hdata->hdmi_mutex);
2355
2356        platform_set_drvdata(pdev, &hdmi_display);
2357
2358        match = of_match_node(hdmi_match_types, dev->of_node);
2359        if (!match) {
2360                ret = -ENODEV;
2361                goto err_del_component;
2362        }
2363
2364        drv_data = (struct hdmi_driver_data *)match->data;
2365        hdata->type = drv_data->type;
2366        hdata->phy_confs = drv_data->phy_confs;
2367        hdata->phy_conf_count = drv_data->phy_conf_count;
2368
2369        hdata->hpd_gpio = pdata->hpd_gpio;
2370        hdata->dev = dev;
2371
2372        ret = hdmi_resources_init(hdata);
2373        if (ret) {
2374                DRM_ERROR("hdmi_resources_init failed\n");
2375                return ret;
2376        }
2377
2378        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2379        hdata->regs = devm_ioremap_resource(dev, res);
2380        if (IS_ERR(hdata->regs)) {
2381                ret = PTR_ERR(hdata->regs);
2382                goto err_del_component;
2383        }
2384
2385        ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
2386        if (ret) {
2387                DRM_ERROR("failed to request HPD gpio\n");
2388                goto err_del_component;
2389        }
2390
2391        ddc_node = hdmi_legacy_ddc_dt_binding(dev);
2392        if (ddc_node)
2393                goto out_get_ddc_adpt;
2394
2395        /* DDC i2c driver */
2396        ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
2397        if (!ddc_node) {
2398                DRM_ERROR("Failed to find ddc node in device tree\n");
2399                ret = -ENODEV;
2400                goto err_del_component;
2401        }
2402
2403out_get_ddc_adpt:
2404        hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
2405        if (!hdata->ddc_adpt) {
2406                DRM_ERROR("Failed to get ddc i2c adapter by node\n");
2407                return -EPROBE_DEFER;
2408        }
2409
2410        phy_node = hdmi_legacy_phy_dt_binding(dev);
2411        if (phy_node)
2412                goto out_get_phy_port;
2413
2414        /* hdmiphy i2c driver */
2415        phy_node = of_parse_phandle(dev->of_node, "phy", 0);
2416        if (!phy_node) {
2417                DRM_ERROR("Failed to find hdmiphy node in device tree\n");
2418                ret = -ENODEV;
2419                goto err_ddc;
2420        }
2421
2422out_get_phy_port:
2423        if (drv_data->is_apb_phy) {
2424                hdata->regs_hdmiphy = of_iomap(phy_node, 0);
2425                if (!hdata->regs_hdmiphy) {
2426                        DRM_ERROR("failed to ioremap hdmi phy\n");
2427                        ret = -ENOMEM;
2428                        goto err_ddc;
2429                }
2430        } else {
2431                hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
2432                if (!hdata->hdmiphy_port) {
2433                        DRM_ERROR("Failed to get hdmi phy i2c client\n");
2434                        ret = -EPROBE_DEFER;
2435                        goto err_ddc;
2436                }
2437        }
2438
2439        hdata->irq = gpio_to_irq(hdata->hpd_gpio);
2440        if (hdata->irq < 0) {
2441                DRM_ERROR("failed to get GPIO irq\n");
2442                ret = hdata->irq;
2443                goto err_hdmiphy;
2444        }
2445
2446        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2447
2448        INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
2449
2450        ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
2451                        hdmi_irq_thread, IRQF_TRIGGER_RISING |
2452                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2453                        "hdmi", hdata);
2454        if (ret) {
2455                DRM_ERROR("failed to register hdmi interrupt\n");
2456                goto err_hdmiphy;
2457        }
2458
2459        hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2460                        "samsung,syscon-phandle");
2461        if (IS_ERR(hdata->pmureg)) {
2462                DRM_ERROR("syscon regmap lookup failed.\n");
2463                ret = -EPROBE_DEFER;
2464                goto err_hdmiphy;
2465        }
2466
2467        pm_runtime_enable(dev);
2468        hdmi_display.ctx = hdata;
2469
2470        ret = component_add(&pdev->dev, &hdmi_component_ops);
2471        if (ret)
2472                goto err_disable_pm_runtime;
2473
2474        return ret;
2475
2476err_disable_pm_runtime:
2477        pm_runtime_disable(dev);
2478
2479err_hdmiphy:
2480        if (hdata->hdmiphy_port)
2481                put_device(&hdata->hdmiphy_port->dev);
2482err_ddc:
2483        put_device(&hdata->ddc_adpt->dev);
2484
2485err_del_component:
2486        exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2487
2488        return ret;
2489}
2490
2491static int hdmi_remove(struct platform_device *pdev)
2492{
2493        struct hdmi_context *hdata = hdmi_display.ctx;
2494
2495        cancel_delayed_work_sync(&hdata->hotplug_work);
2496
2497        put_device(&hdata->hdmiphy_port->dev);
2498        put_device(&hdata->ddc_adpt->dev);
2499
2500        pm_runtime_disable(&pdev->dev);
2501        component_del(&pdev->dev, &hdmi_component_ops);
2502
2503        exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2504        return 0;
2505}
2506
2507struct platform_driver hdmi_driver = {
2508        .probe          = hdmi_probe,
2509        .remove         = hdmi_remove,
2510        .driver         = {
2511                .name   = "exynos-hdmi",
2512                .owner  = THIS_MODULE,
2513                .of_match_table = hdmi_match_types,
2514        },
2515};
2516