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/module.h> 28 #include <linux/platform_device.h> 29 #include <linux/interrupt.h> 30 #include <linux/irq.h> 31 #include <linux/delay.h> 32 #include <linux/pm_runtime.h> 33 #include <linux/clk.h> 34 #include <linux/regulator/consumer.h> 35 #include <linux/io.h> 36 #include <linux/of_gpio.h> 37 38 #include <drm/exynos_drm.h> 39 40 #include "exynos_drm_drv.h" 41 #include "exynos_drm_hdmi.h" 42 43 #include "exynos_hdmi.h" 44 45 #include <linux/gpio.h> 46 #include <media/s5p_hdmi.h> 47 48 #define MAX_WIDTH 1920 49 #define MAX_HEIGHT 1080 50 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) 51 52 /* AVI header and aspect ratio */ 53 #define HDMI_AVI_VERSION 0x02 54 #define HDMI_AVI_LENGTH 0x0D 55 #define AVI_PIC_ASPECT_RATIO_16_9 (2 << 4) 56 #define AVI_SAME_AS_PIC_ASPECT_RATIO 8 57 58 /* AUI header info */ 59 #define HDMI_AUI_VERSION 0x01 60 #define HDMI_AUI_LENGTH 0x0A 61 62 /* HDMI infoframe to configure HDMI out packet header, AUI and AVI */ 63 enum HDMI_PACKET_TYPE { 64 /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */ 65 /* InfoFrame packet type */ 66 HDMI_PACKET_TYPE_INFOFRAME = 0x80, 67 /* Vendor-Specific InfoFrame */ 68 HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1, 69 /* Auxiliary Video information InfoFrame */ 70 HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2, 71 /* Audio information InfoFrame */ 72 HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4 73 }; 74 75 enum hdmi_type { 76 HDMI_TYPE13, 77 HDMI_TYPE14, 78 }; 79 80 struct hdmi_resources { 81 struct clk *hdmi; 82 struct clk *sclk_hdmi; 83 struct clk *sclk_pixel; 84 struct clk *sclk_hdmiphy; 85 struct clk *hdmiphy; 86 struct regulator_bulk_data *regul_bulk; 87 int regul_count; 88 }; 89 90 struct hdmi_context { 91 struct device *dev; 92 struct drm_device *drm_dev; 93 bool hpd; 94 bool powered; 95 bool dvi_mode; 96 struct mutex hdmi_mutex; 97 98 void __iomem *regs; 99 void *parent_ctx; 100 int irq; 101 102 struct i2c_client *ddc_port; 103 struct i2c_client *hdmiphy_port; 104 105 /* current hdmiphy conf index */ 106 int cur_conf; 107 108 struct hdmi_resources res; 109 110 int hpd_gpio; 111 112 enum hdmi_type type; 113 }; 114 115 /* HDMI Version 1.3 */ 116 static const u8 hdmiphy_v13_conf27[32] = { 117 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 118 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, 119 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 120 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, 121 }; 122 123 static const u8 hdmiphy_v13_conf27_027[32] = { 124 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, 125 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, 126 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 127 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, 128 }; 129 130 static const u8 hdmiphy_v13_conf74_175[32] = { 131 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, 132 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, 133 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 134 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, 135 }; 136 137 static const u8 hdmiphy_v13_conf74_25[32] = { 138 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, 139 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, 140 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, 141 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, 142 }; 143 144 static const u8 hdmiphy_v13_conf148_5[32] = { 145 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, 146 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, 147 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, 148 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, 149 }; 150 151 struct hdmi_v13_tg_regs { 152 u8 cmd; 153 u8 h_fsz_l; 154 u8 h_fsz_h; 155 u8 hact_st_l; 156 u8 hact_st_h; 157 u8 hact_sz_l; 158 u8 hact_sz_h; 159 u8 v_fsz_l; 160 u8 v_fsz_h; 161 u8 vsync_l; 162 u8 vsync_h; 163 u8 vsync2_l; 164 u8 vsync2_h; 165 u8 vact_st_l; 166 u8 vact_st_h; 167 u8 vact_sz_l; 168 u8 vact_sz_h; 169 u8 field_chg_l; 170 u8 field_chg_h; 171 u8 vact_st2_l; 172 u8 vact_st2_h; 173 u8 vsync_top_hdmi_l; 174 u8 vsync_top_hdmi_h; 175 u8 vsync_bot_hdmi_l; 176 u8 vsync_bot_hdmi_h; 177 u8 field_top_hdmi_l; 178 u8 field_top_hdmi_h; 179 u8 field_bot_hdmi_l; 180 u8 field_bot_hdmi_h; 181 }; 182 183 struct hdmi_v13_core_regs { 184 u8 h_blank[2]; 185 u8 v_blank[3]; 186 u8 h_v_line[3]; 187 u8 vsync_pol[1]; 188 u8 int_pro_mode[1]; 189 u8 v_blank_f[3]; 190 u8 h_sync_gen[3]; 191 u8 v_sync_gen1[3]; 192 u8 v_sync_gen2[3]; 193 u8 v_sync_gen3[3]; 194 }; 195 196 struct hdmi_v13_preset_conf { 197 struct hdmi_v13_core_regs core; 198 struct hdmi_v13_tg_regs tg; 199 }; 200 201 struct hdmi_v13_conf { 202 int width; 203 int height; 204 int vrefresh; 205 bool interlace; 206 int cea_video_id; 207 const u8 *hdmiphy_data; 208 const struct hdmi_v13_preset_conf *conf; 209 }; 210 211 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = { 212 .core = { 213 .h_blank = {0x8a, 0x00}, 214 .v_blank = {0x0d, 0x6a, 0x01}, 215 .h_v_line = {0x0d, 0xa2, 0x35}, 216 .vsync_pol = {0x01}, 217 .int_pro_mode = {0x00}, 218 .v_blank_f = {0x00, 0x00, 0x00}, 219 .h_sync_gen = {0x0e, 0x30, 0x11}, 220 .v_sync_gen1 = {0x0f, 0x90, 0x00}, 221 /* other don't care */ 222 }, 223 .tg = { 224 0x00, /* cmd */ 225 0x5a, 0x03, /* h_fsz */ 226 0x8a, 0x00, 0xd0, 0x02, /* hact */ 227 0x0d, 0x02, /* v_fsz */ 228 0x01, 0x00, 0x33, 0x02, /* vsync */ 229 0x2d, 0x00, 0xe0, 0x01, /* vact */ 230 0x33, 0x02, /* field_chg */ 231 0x49, 0x02, /* vact_st2 */ 232 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 233 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 234 }, 235 }; 236 237 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = { 238 .core = { 239 .h_blank = {0x72, 0x01}, 240 .v_blank = {0xee, 0xf2, 0x00}, 241 .h_v_line = {0xee, 0x22, 0x67}, 242 .vsync_pol = {0x00}, 243 .int_pro_mode = {0x00}, 244 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 245 .h_sync_gen = {0x6c, 0x50, 0x02}, 246 .v_sync_gen1 = {0x0a, 0x50, 0x00}, 247 .v_sync_gen2 = {0x01, 0x10, 0x00}, 248 .v_sync_gen3 = {0x01, 0x10, 0x00}, 249 /* other don't care */ 250 }, 251 .tg = { 252 0x00, /* cmd */ 253 0x72, 0x06, /* h_fsz */ 254 0x71, 0x01, 0x01, 0x05, /* hact */ 255 0xee, 0x02, /* v_fsz */ 256 0x01, 0x00, 0x33, 0x02, /* vsync */ 257 0x1e, 0x00, 0xd0, 0x02, /* vact */ 258 0x33, 0x02, /* field_chg */ 259 0x49, 0x02, /* vact_st2 */ 260 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 261 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 262 }, 263 }; 264 265 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = { 266 .core = { 267 .h_blank = {0xd0, 0x02}, 268 .v_blank = {0x32, 0xB2, 0x00}, 269 .h_v_line = {0x65, 0x04, 0xa5}, 270 .vsync_pol = {0x00}, 271 .int_pro_mode = {0x01}, 272 .v_blank_f = {0x49, 0x2A, 0x23}, 273 .h_sync_gen = {0x0E, 0xEA, 0x08}, 274 .v_sync_gen1 = {0x07, 0x20, 0x00}, 275 .v_sync_gen2 = {0x39, 0x42, 0x23}, 276 .v_sync_gen3 = {0x38, 0x87, 0x73}, 277 /* other don't care */ 278 }, 279 .tg = { 280 0x00, /* cmd */ 281 0x50, 0x0A, /* h_fsz */ 282 0xCF, 0x02, 0x81, 0x07, /* hact */ 283 0x65, 0x04, /* v_fsz */ 284 0x01, 0x00, 0x33, 0x02, /* vsync */ 285 0x16, 0x00, 0x1c, 0x02, /* vact */ 286 0x33, 0x02, /* field_chg */ 287 0x49, 0x02, /* vact_st2 */ 288 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 289 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 290 }, 291 }; 292 293 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = { 294 .core = { 295 .h_blank = {0xd0, 0x02}, 296 .v_blank = {0x65, 0x6c, 0x01}, 297 .h_v_line = {0x65, 0x04, 0xa5}, 298 .vsync_pol = {0x00}, 299 .int_pro_mode = {0x00}, 300 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 301 .h_sync_gen = {0x0e, 0xea, 0x08}, 302 .v_sync_gen1 = {0x09, 0x40, 0x00}, 303 .v_sync_gen2 = {0x01, 0x10, 0x00}, 304 .v_sync_gen3 = {0x01, 0x10, 0x00}, 305 /* other don't care */ 306 }, 307 .tg = { 308 0x00, /* cmd */ 309 0x50, 0x0A, /* h_fsz */ 310 0xCF, 0x02, 0x81, 0x07, /* hact */ 311 0x65, 0x04, /* v_fsz */ 312 0x01, 0x00, 0x33, 0x02, /* vsync */ 313 0x2d, 0x00, 0x38, 0x04, /* vact */ 314 0x33, 0x02, /* field_chg */ 315 0x48, 0x02, /* vact_st2 */ 316 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 317 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 318 }, 319 }; 320 321 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = { 322 .core = { 323 .h_blank = {0x18, 0x01}, 324 .v_blank = {0x32, 0xB2, 0x00}, 325 .h_v_line = {0x65, 0x84, 0x89}, 326 .vsync_pol = {0x00}, 327 .int_pro_mode = {0x01}, 328 .v_blank_f = {0x49, 0x2A, 0x23}, 329 .h_sync_gen = {0x56, 0x08, 0x02}, 330 .v_sync_gen1 = {0x07, 0x20, 0x00}, 331 .v_sync_gen2 = {0x39, 0x42, 0x23}, 332 .v_sync_gen3 = {0xa4, 0x44, 0x4a}, 333 /* other don't care */ 334 }, 335 .tg = { 336 0x00, /* cmd */ 337 0x98, 0x08, /* h_fsz */ 338 0x17, 0x01, 0x81, 0x07, /* hact */ 339 0x65, 0x04, /* v_fsz */ 340 0x01, 0x00, 0x33, 0x02, /* vsync */ 341 0x16, 0x00, 0x1c, 0x02, /* vact */ 342 0x33, 0x02, /* field_chg */ 343 0x49, 0x02, /* vact_st2 */ 344 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 345 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 346 }, 347 }; 348 349 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = { 350 .core = { 351 .h_blank = {0x18, 0x01}, 352 .v_blank = {0x65, 0x6c, 0x01}, 353 .h_v_line = {0x65, 0x84, 0x89}, 354 .vsync_pol = {0x00}, 355 .int_pro_mode = {0x00}, 356 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 357 .h_sync_gen = {0x56, 0x08, 0x02}, 358 .v_sync_gen1 = {0x09, 0x40, 0x00}, 359 .v_sync_gen2 = {0x01, 0x10, 0x00}, 360 .v_sync_gen3 = {0x01, 0x10, 0x00}, 361 /* other don't care */ 362 }, 363 .tg = { 364 0x00, /* cmd */ 365 0x98, 0x08, /* h_fsz */ 366 0x17, 0x01, 0x81, 0x07, /* hact */ 367 0x65, 0x04, /* v_fsz */ 368 0x01, 0x00, 0x33, 0x02, /* vsync */ 369 0x2d, 0x00, 0x38, 0x04, /* vact */ 370 0x33, 0x02, /* field_chg */ 371 0x48, 0x02, /* vact_st2 */ 372 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 373 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 374 }, 375 }; 376 377 static const struct hdmi_v13_conf hdmi_v13_confs[] = { 378 { 1280, 720, 60, false, 4, hdmiphy_v13_conf74_25, 379 &hdmi_v13_conf_720p60 }, 380 { 1280, 720, 50, false, 19, hdmiphy_v13_conf74_25, 381 &hdmi_v13_conf_720p60 }, 382 { 720, 480, 60, false, 3, hdmiphy_v13_conf27_027, 383 &hdmi_v13_conf_480p }, 384 { 1920, 1080, 50, true, 20, hdmiphy_v13_conf74_25, 385 &hdmi_v13_conf_1080i50 }, 386 { 1920, 1080, 50, false, 31, hdmiphy_v13_conf148_5, 387 &hdmi_v13_conf_1080p50 }, 388 { 1920, 1080, 60, true, 5, hdmiphy_v13_conf74_25, 389 &hdmi_v13_conf_1080i60 }, 390 { 1920, 1080, 60, false, 16, hdmiphy_v13_conf148_5, 391 &hdmi_v13_conf_1080p60 }, 392 }; 393 394 /* HDMI Version 1.4 */ 395 static const u8 hdmiphy_conf27_027[32] = { 396 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08, 397 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 398 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 399 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 400 }; 401 402 static const u8 hdmiphy_conf74_176[32] = { 403 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08, 404 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80, 405 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 406 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, 407 }; 408 409 static const u8 hdmiphy_conf74_25[32] = { 410 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08, 411 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 412 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 413 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, 414 }; 415 416 static const u8 hdmiphy_conf148_5[32] = { 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 struct hdmi_tg_regs { 424 u8 cmd; 425 u8 h_fsz_l; 426 u8 h_fsz_h; 427 u8 hact_st_l; 428 u8 hact_st_h; 429 u8 hact_sz_l; 430 u8 hact_sz_h; 431 u8 v_fsz_l; 432 u8 v_fsz_h; 433 u8 vsync_l; 434 u8 vsync_h; 435 u8 vsync2_l; 436 u8 vsync2_h; 437 u8 vact_st_l; 438 u8 vact_st_h; 439 u8 vact_sz_l; 440 u8 vact_sz_h; 441 u8 field_chg_l; 442 u8 field_chg_h; 443 u8 vact_st2_l; 444 u8 vact_st2_h; 445 u8 vact_st3_l; 446 u8 vact_st3_h; 447 u8 vact_st4_l; 448 u8 vact_st4_h; 449 u8 vsync_top_hdmi_l; 450 u8 vsync_top_hdmi_h; 451 u8 vsync_bot_hdmi_l; 452 u8 vsync_bot_hdmi_h; 453 u8 field_top_hdmi_l; 454 u8 field_top_hdmi_h; 455 u8 field_bot_hdmi_l; 456 u8 field_bot_hdmi_h; 457 u8 tg_3d; 458 }; 459 460 struct hdmi_core_regs { 461 u8 h_blank[2]; 462 u8 v2_blank[2]; 463 u8 v1_blank[2]; 464 u8 v_line[2]; 465 u8 h_line[2]; 466 u8 hsync_pol[1]; 467 u8 vsync_pol[1]; 468 u8 int_pro_mode[1]; 469 u8 v_blank_f0[2]; 470 u8 v_blank_f1[2]; 471 u8 h_sync_start[2]; 472 u8 h_sync_end[2]; 473 u8 v_sync_line_bef_2[2]; 474 u8 v_sync_line_bef_1[2]; 475 u8 v_sync_line_aft_2[2]; 476 u8 v_sync_line_aft_1[2]; 477 u8 v_sync_line_aft_pxl_2[2]; 478 u8 v_sync_line_aft_pxl_1[2]; 479 u8 v_blank_f2[2]; /* for 3D mode */ 480 u8 v_blank_f3[2]; /* for 3D mode */ 481 u8 v_blank_f4[2]; /* for 3D mode */ 482 u8 v_blank_f5[2]; /* for 3D mode */ 483 u8 v_sync_line_aft_3[2]; 484 u8 v_sync_line_aft_4[2]; 485 u8 v_sync_line_aft_5[2]; 486 u8 v_sync_line_aft_6[2]; 487 u8 v_sync_line_aft_pxl_3[2]; 488 u8 v_sync_line_aft_pxl_4[2]; 489 u8 v_sync_line_aft_pxl_5[2]; 490 u8 v_sync_line_aft_pxl_6[2]; 491 u8 vact_space_1[2]; 492 u8 vact_space_2[2]; 493 u8 vact_space_3[2]; 494 u8 vact_space_4[2]; 495 u8 vact_space_5[2]; 496 u8 vact_space_6[2]; 497 }; 498 499 struct hdmi_preset_conf { 500 struct hdmi_core_regs core; 501 struct hdmi_tg_regs tg; 502 }; 503 504 struct hdmi_conf { 505 int width; 506 int height; 507 int vrefresh; 508 bool interlace; 509 int cea_video_id; 510 const u8 *hdmiphy_data; 511 const struct hdmi_preset_conf *conf; 512 }; 513 514 static const struct hdmi_preset_conf hdmi_conf_480p60 = { 515 .core = { 516 .h_blank = {0x8a, 0x00}, 517 .v2_blank = {0x0d, 0x02}, 518 .v1_blank = {0x2d, 0x00}, 519 .v_line = {0x0d, 0x02}, 520 .h_line = {0x5a, 0x03}, 521 .hsync_pol = {0x01}, 522 .vsync_pol = {0x01}, 523 .int_pro_mode = {0x00}, 524 .v_blank_f0 = {0xff, 0xff}, 525 .v_blank_f1 = {0xff, 0xff}, 526 .h_sync_start = {0x0e, 0x00}, 527 .h_sync_end = {0x4c, 0x00}, 528 .v_sync_line_bef_2 = {0x0f, 0x00}, 529 .v_sync_line_bef_1 = {0x09, 0x00}, 530 .v_sync_line_aft_2 = {0xff, 0xff}, 531 .v_sync_line_aft_1 = {0xff, 0xff}, 532 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 533 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 534 .v_blank_f2 = {0xff, 0xff}, 535 .v_blank_f3 = {0xff, 0xff}, 536 .v_blank_f4 = {0xff, 0xff}, 537 .v_blank_f5 = {0xff, 0xff}, 538 .v_sync_line_aft_3 = {0xff, 0xff}, 539 .v_sync_line_aft_4 = {0xff, 0xff}, 540 .v_sync_line_aft_5 = {0xff, 0xff}, 541 .v_sync_line_aft_6 = {0xff, 0xff}, 542 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 543 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 544 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 545 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 546 .vact_space_1 = {0xff, 0xff}, 547 .vact_space_2 = {0xff, 0xff}, 548 .vact_space_3 = {0xff, 0xff}, 549 .vact_space_4 = {0xff, 0xff}, 550 .vact_space_5 = {0xff, 0xff}, 551 .vact_space_6 = {0xff, 0xff}, 552 /* other don't care */ 553 }, 554 .tg = { 555 0x00, /* cmd */ 556 0x5a, 0x03, /* h_fsz */ 557 0x8a, 0x00, 0xd0, 0x02, /* hact */ 558 0x0d, 0x02, /* v_fsz */ 559 0x01, 0x00, 0x33, 0x02, /* vsync */ 560 0x2d, 0x00, 0xe0, 0x01, /* vact */ 561 0x33, 0x02, /* field_chg */ 562 0x48, 0x02, /* vact_st2 */ 563 0x00, 0x00, /* vact_st3 */ 564 0x00, 0x00, /* vact_st4 */ 565 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 566 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 567 0x00, /* 3d FP */ 568 }, 569 }; 570 571 static const struct hdmi_preset_conf hdmi_conf_720p50 = { 572 .core = { 573 .h_blank = {0xbc, 0x02}, 574 .v2_blank = {0xee, 0x02}, 575 .v1_blank = {0x1e, 0x00}, 576 .v_line = {0xee, 0x02}, 577 .h_line = {0xbc, 0x07}, 578 .hsync_pol = {0x00}, 579 .vsync_pol = {0x00}, 580 .int_pro_mode = {0x00}, 581 .v_blank_f0 = {0xff, 0xff}, 582 .v_blank_f1 = {0xff, 0xff}, 583 .h_sync_start = {0xb6, 0x01}, 584 .h_sync_end = {0xde, 0x01}, 585 .v_sync_line_bef_2 = {0x0a, 0x00}, 586 .v_sync_line_bef_1 = {0x05, 0x00}, 587 .v_sync_line_aft_2 = {0xff, 0xff}, 588 .v_sync_line_aft_1 = {0xff, 0xff}, 589 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 590 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 591 .v_blank_f2 = {0xff, 0xff}, 592 .v_blank_f3 = {0xff, 0xff}, 593 .v_blank_f4 = {0xff, 0xff}, 594 .v_blank_f5 = {0xff, 0xff}, 595 .v_sync_line_aft_3 = {0xff, 0xff}, 596 .v_sync_line_aft_4 = {0xff, 0xff}, 597 .v_sync_line_aft_5 = {0xff, 0xff}, 598 .v_sync_line_aft_6 = {0xff, 0xff}, 599 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 600 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 601 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 602 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 603 .vact_space_1 = {0xff, 0xff}, 604 .vact_space_2 = {0xff, 0xff}, 605 .vact_space_3 = {0xff, 0xff}, 606 .vact_space_4 = {0xff, 0xff}, 607 .vact_space_5 = {0xff, 0xff}, 608 .vact_space_6 = {0xff, 0xff}, 609 /* other don't care */ 610 }, 611 .tg = { 612 0x00, /* cmd */ 613 0xbc, 0x07, /* h_fsz */ 614 0xbc, 0x02, 0x00, 0x05, /* hact */ 615 0xee, 0x02, /* v_fsz */ 616 0x01, 0x00, 0x33, 0x02, /* vsync */ 617 0x1e, 0x00, 0xd0, 0x02, /* vact */ 618 0x33, 0x02, /* field_chg */ 619 0x48, 0x02, /* vact_st2 */ 620 0x00, 0x00, /* vact_st3 */ 621 0x00, 0x00, /* vact_st4 */ 622 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 623 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 624 0x00, /* 3d FP */ 625 }, 626 }; 627 628 static const struct hdmi_preset_conf hdmi_conf_720p60 = { 629 .core = { 630 .h_blank = {0x72, 0x01}, 631 .v2_blank = {0xee, 0x02}, 632 .v1_blank = {0x1e, 0x00}, 633 .v_line = {0xee, 0x02}, 634 .h_line = {0x72, 0x06}, 635 .hsync_pol = {0x00}, 636 .vsync_pol = {0x00}, 637 .int_pro_mode = {0x00}, 638 .v_blank_f0 = {0xff, 0xff}, 639 .v_blank_f1 = {0xff, 0xff}, 640 .h_sync_start = {0x6c, 0x00}, 641 .h_sync_end = {0x94, 0x00}, 642 .v_sync_line_bef_2 = {0x0a, 0x00}, 643 .v_sync_line_bef_1 = {0x05, 0x00}, 644 .v_sync_line_aft_2 = {0xff, 0xff}, 645 .v_sync_line_aft_1 = {0xff, 0xff}, 646 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 647 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 648 .v_blank_f2 = {0xff, 0xff}, 649 .v_blank_f3 = {0xff, 0xff}, 650 .v_blank_f4 = {0xff, 0xff}, 651 .v_blank_f5 = {0xff, 0xff}, 652 .v_sync_line_aft_3 = {0xff, 0xff}, 653 .v_sync_line_aft_4 = {0xff, 0xff}, 654 .v_sync_line_aft_5 = {0xff, 0xff}, 655 .v_sync_line_aft_6 = {0xff, 0xff}, 656 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 657 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 658 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 659 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 660 .vact_space_1 = {0xff, 0xff}, 661 .vact_space_2 = {0xff, 0xff}, 662 .vact_space_3 = {0xff, 0xff}, 663 .vact_space_4 = {0xff, 0xff}, 664 .vact_space_5 = {0xff, 0xff}, 665 .vact_space_6 = {0xff, 0xff}, 666 /* other don't care */ 667 }, 668 .tg = { 669 0x00, /* cmd */ 670 0x72, 0x06, /* h_fsz */ 671 0x72, 0x01, 0x00, 0x05, /* hact */ 672 0xee, 0x02, /* v_fsz */ 673 0x01, 0x00, 0x33, 0x02, /* vsync */ 674 0x1e, 0x00, 0xd0, 0x02, /* vact */ 675 0x33, 0x02, /* field_chg */ 676 0x48, 0x02, /* vact_st2 */ 677 0x00, 0x00, /* vact_st3 */ 678 0x00, 0x00, /* vact_st4 */ 679 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 680 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 681 0x00, /* 3d FP */ 682 }, 683 }; 684 685 static const struct hdmi_preset_conf hdmi_conf_1080i50 = { 686 .core = { 687 .h_blank = {0xd0, 0x02}, 688 .v2_blank = {0x32, 0x02}, 689 .v1_blank = {0x16, 0x00}, 690 .v_line = {0x65, 0x04}, 691 .h_line = {0x50, 0x0a}, 692 .hsync_pol = {0x00}, 693 .vsync_pol = {0x00}, 694 .int_pro_mode = {0x01}, 695 .v_blank_f0 = {0x49, 0x02}, 696 .v_blank_f1 = {0x65, 0x04}, 697 .h_sync_start = {0x0e, 0x02}, 698 .h_sync_end = {0x3a, 0x02}, 699 .v_sync_line_bef_2 = {0x07, 0x00}, 700 .v_sync_line_bef_1 = {0x02, 0x00}, 701 .v_sync_line_aft_2 = {0x39, 0x02}, 702 .v_sync_line_aft_1 = {0x34, 0x02}, 703 .v_sync_line_aft_pxl_2 = {0x38, 0x07}, 704 .v_sync_line_aft_pxl_1 = {0x38, 0x07}, 705 .v_blank_f2 = {0xff, 0xff}, 706 .v_blank_f3 = {0xff, 0xff}, 707 .v_blank_f4 = {0xff, 0xff}, 708 .v_blank_f5 = {0xff, 0xff}, 709 .v_sync_line_aft_3 = {0xff, 0xff}, 710 .v_sync_line_aft_4 = {0xff, 0xff}, 711 .v_sync_line_aft_5 = {0xff, 0xff}, 712 .v_sync_line_aft_6 = {0xff, 0xff}, 713 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 714 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 715 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 716 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 717 .vact_space_1 = {0xff, 0xff}, 718 .vact_space_2 = {0xff, 0xff}, 719 .vact_space_3 = {0xff, 0xff}, 720 .vact_space_4 = {0xff, 0xff}, 721 .vact_space_5 = {0xff, 0xff}, 722 .vact_space_6 = {0xff, 0xff}, 723 /* other don't care */ 724 }, 725 .tg = { 726 0x00, /* cmd */ 727 0x50, 0x0a, /* h_fsz */ 728 0xd0, 0x02, 0x80, 0x07, /* hact */ 729 0x65, 0x04, /* v_fsz */ 730 0x01, 0x00, 0x33, 0x02, /* vsync */ 731 0x16, 0x00, 0x1c, 0x02, /* vact */ 732 0x33, 0x02, /* field_chg */ 733 0x49, 0x02, /* vact_st2 */ 734 0x00, 0x00, /* vact_st3 */ 735 0x00, 0x00, /* vact_st4 */ 736 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 737 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 738 0x00, /* 3d FP */ 739 }, 740 }; 741 742 static const struct hdmi_preset_conf hdmi_conf_1080i60 = { 743 .core = { 744 .h_blank = {0x18, 0x01}, 745 .v2_blank = {0x32, 0x02}, 746 .v1_blank = {0x16, 0x00}, 747 .v_line = {0x65, 0x04}, 748 .h_line = {0x98, 0x08}, 749 .hsync_pol = {0x00}, 750 .vsync_pol = {0x00}, 751 .int_pro_mode = {0x01}, 752 .v_blank_f0 = {0x49, 0x02}, 753 .v_blank_f1 = {0x65, 0x04}, 754 .h_sync_start = {0x56, 0x00}, 755 .h_sync_end = {0x82, 0x00}, 756 .v_sync_line_bef_2 = {0x07, 0x00}, 757 .v_sync_line_bef_1 = {0x02, 0x00}, 758 .v_sync_line_aft_2 = {0x39, 0x02}, 759 .v_sync_line_aft_1 = {0x34, 0x02}, 760 .v_sync_line_aft_pxl_2 = {0xa4, 0x04}, 761 .v_sync_line_aft_pxl_1 = {0xa4, 0x04}, 762 .v_blank_f2 = {0xff, 0xff}, 763 .v_blank_f3 = {0xff, 0xff}, 764 .v_blank_f4 = {0xff, 0xff}, 765 .v_blank_f5 = {0xff, 0xff}, 766 .v_sync_line_aft_3 = {0xff, 0xff}, 767 .v_sync_line_aft_4 = {0xff, 0xff}, 768 .v_sync_line_aft_5 = {0xff, 0xff}, 769 .v_sync_line_aft_6 = {0xff, 0xff}, 770 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 771 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 772 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 773 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 774 .vact_space_1 = {0xff, 0xff}, 775 .vact_space_2 = {0xff, 0xff}, 776 .vact_space_3 = {0xff, 0xff}, 777 .vact_space_4 = {0xff, 0xff}, 778 .vact_space_5 = {0xff, 0xff}, 779 .vact_space_6 = {0xff, 0xff}, 780 /* other don't care */ 781 }, 782 .tg = { 783 0x00, /* cmd */ 784 0x98, 0x08, /* h_fsz */ 785 0x18, 0x01, 0x80, 0x07, /* hact */ 786 0x65, 0x04, /* v_fsz */ 787 0x01, 0x00, 0x33, 0x02, /* vsync */ 788 0x16, 0x00, 0x1c, 0x02, /* vact */ 789 0x33, 0x02, /* field_chg */ 790 0x49, 0x02, /* vact_st2 */ 791 0x00, 0x00, /* vact_st3 */ 792 0x00, 0x00, /* vact_st4 */ 793 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 794 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 795 0x00, /* 3d FP */ 796 }, 797 }; 798 799 static const struct hdmi_preset_conf hdmi_conf_1080p30 = { 800 .core = { 801 .h_blank = {0x18, 0x01}, 802 .v2_blank = {0x65, 0x04}, 803 .v1_blank = {0x2d, 0x00}, 804 .v_line = {0x65, 0x04}, 805 .h_line = {0x98, 0x08}, 806 .hsync_pol = {0x00}, 807 .vsync_pol = {0x00}, 808 .int_pro_mode = {0x00}, 809 .v_blank_f0 = {0xff, 0xff}, 810 .v_blank_f1 = {0xff, 0xff}, 811 .h_sync_start = {0x56, 0x00}, 812 .h_sync_end = {0x82, 0x00}, 813 .v_sync_line_bef_2 = {0x09, 0x00}, 814 .v_sync_line_bef_1 = {0x04, 0x00}, 815 .v_sync_line_aft_2 = {0xff, 0xff}, 816 .v_sync_line_aft_1 = {0xff, 0xff}, 817 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 818 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 819 .v_blank_f2 = {0xff, 0xff}, 820 .v_blank_f3 = {0xff, 0xff}, 821 .v_blank_f4 = {0xff, 0xff}, 822 .v_blank_f5 = {0xff, 0xff}, 823 .v_sync_line_aft_3 = {0xff, 0xff}, 824 .v_sync_line_aft_4 = {0xff, 0xff}, 825 .v_sync_line_aft_5 = {0xff, 0xff}, 826 .v_sync_line_aft_6 = {0xff, 0xff}, 827 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 828 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 829 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 830 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 831 .vact_space_1 = {0xff, 0xff}, 832 .vact_space_2 = {0xff, 0xff}, 833 .vact_space_3 = {0xff, 0xff}, 834 .vact_space_4 = {0xff, 0xff}, 835 .vact_space_5 = {0xff, 0xff}, 836 .vact_space_6 = {0xff, 0xff}, 837 /* other don't care */ 838 }, 839 .tg = { 840 0x00, /* cmd */ 841 0x98, 0x08, /* h_fsz */ 842 0x18, 0x01, 0x80, 0x07, /* hact */ 843 0x65, 0x04, /* v_fsz */ 844 0x01, 0x00, 0x33, 0x02, /* vsync */ 845 0x2d, 0x00, 0x38, 0x04, /* vact */ 846 0x33, 0x02, /* field_chg */ 847 0x48, 0x02, /* vact_st2 */ 848 0x00, 0x00, /* vact_st3 */ 849 0x00, 0x00, /* vact_st4 */ 850 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 851 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 852 0x00, /* 3d FP */ 853 }, 854 }; 855 856 static const struct hdmi_preset_conf hdmi_conf_1080p50 = { 857 .core = { 858 .h_blank = {0xd0, 0x02}, 859 .v2_blank = {0x65, 0x04}, 860 .v1_blank = {0x2d, 0x00}, 861 .v_line = {0x65, 0x04}, 862 .h_line = {0x50, 0x0a}, 863 .hsync_pol = {0x00}, 864 .vsync_pol = {0x00}, 865 .int_pro_mode = {0x00}, 866 .v_blank_f0 = {0xff, 0xff}, 867 .v_blank_f1 = {0xff, 0xff}, 868 .h_sync_start = {0x0e, 0x02}, 869 .h_sync_end = {0x3a, 0x02}, 870 .v_sync_line_bef_2 = {0x09, 0x00}, 871 .v_sync_line_bef_1 = {0x04, 0x00}, 872 .v_sync_line_aft_2 = {0xff, 0xff}, 873 .v_sync_line_aft_1 = {0xff, 0xff}, 874 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 875 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 876 .v_blank_f2 = {0xff, 0xff}, 877 .v_blank_f3 = {0xff, 0xff}, 878 .v_blank_f4 = {0xff, 0xff}, 879 .v_blank_f5 = {0xff, 0xff}, 880 .v_sync_line_aft_3 = {0xff, 0xff}, 881 .v_sync_line_aft_4 = {0xff, 0xff}, 882 .v_sync_line_aft_5 = {0xff, 0xff}, 883 .v_sync_line_aft_6 = {0xff, 0xff}, 884 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 885 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 886 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 887 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 888 .vact_space_1 = {0xff, 0xff}, 889 .vact_space_2 = {0xff, 0xff}, 890 .vact_space_3 = {0xff, 0xff}, 891 .vact_space_4 = {0xff, 0xff}, 892 .vact_space_5 = {0xff, 0xff}, 893 .vact_space_6 = {0xff, 0xff}, 894 /* other don't care */ 895 }, 896 .tg = { 897 0x00, /* cmd */ 898 0x50, 0x0a, /* h_fsz */ 899 0xd0, 0x02, 0x80, 0x07, /* hact */ 900 0x65, 0x04, /* v_fsz */ 901 0x01, 0x00, 0x33, 0x02, /* vsync */ 902 0x2d, 0x00, 0x38, 0x04, /* vact */ 903 0x33, 0x02, /* field_chg */ 904 0x48, 0x02, /* vact_st2 */ 905 0x00, 0x00, /* vact_st3 */ 906 0x00, 0x00, /* vact_st4 */ 907 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 908 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 909 0x00, /* 3d FP */ 910 }, 911 }; 912 913 static const struct hdmi_preset_conf hdmi_conf_1080p60 = { 914 .core = { 915 .h_blank = {0x18, 0x01}, 916 .v2_blank = {0x65, 0x04}, 917 .v1_blank = {0x2d, 0x00}, 918 .v_line = {0x65, 0x04}, 919 .h_line = {0x98, 0x08}, 920 .hsync_pol = {0x00}, 921 .vsync_pol = {0x00}, 922 .int_pro_mode = {0x00}, 923 .v_blank_f0 = {0xff, 0xff}, 924 .v_blank_f1 = {0xff, 0xff}, 925 .h_sync_start = {0x56, 0x00}, 926 .h_sync_end = {0x82, 0x00}, 927 .v_sync_line_bef_2 = {0x09, 0x00}, 928 .v_sync_line_bef_1 = {0x04, 0x00}, 929 .v_sync_line_aft_2 = {0xff, 0xff}, 930 .v_sync_line_aft_1 = {0xff, 0xff}, 931 .v_sync_line_aft_pxl_2 = {0xff, 0xff}, 932 .v_sync_line_aft_pxl_1 = {0xff, 0xff}, 933 .v_blank_f2 = {0xff, 0xff}, 934 .v_blank_f3 = {0xff, 0xff}, 935 .v_blank_f4 = {0xff, 0xff}, 936 .v_blank_f5 = {0xff, 0xff}, 937 .v_sync_line_aft_3 = {0xff, 0xff}, 938 .v_sync_line_aft_4 = {0xff, 0xff}, 939 .v_sync_line_aft_5 = {0xff, 0xff}, 940 .v_sync_line_aft_6 = {0xff, 0xff}, 941 .v_sync_line_aft_pxl_3 = {0xff, 0xff}, 942 .v_sync_line_aft_pxl_4 = {0xff, 0xff}, 943 .v_sync_line_aft_pxl_5 = {0xff, 0xff}, 944 .v_sync_line_aft_pxl_6 = {0xff, 0xff}, 945 /* other don't care */ 946 }, 947 .tg = { 948 0x00, /* cmd */ 949 0x98, 0x08, /* h_fsz */ 950 0x18, 0x01, 0x80, 0x07, /* hact */ 951 0x65, 0x04, /* v_fsz */ 952 0x01, 0x00, 0x33, 0x02, /* vsync */ 953 0x2d, 0x00, 0x38, 0x04, /* vact */ 954 0x33, 0x02, /* field_chg */ 955 0x48, 0x02, /* vact_st2 */ 956 0x00, 0x00, /* vact_st3 */ 957 0x00, 0x00, /* vact_st4 */ 958 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 959 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 960 0x00, /* 3d FP */ 961 }, 962 }; 963 964 static const struct hdmi_conf hdmi_confs[] = { 965 { 720, 480, 60, false, 3, hdmiphy_conf27_027, &hdmi_conf_480p60 }, 966 { 1280, 720, 50, false, 19, hdmiphy_conf74_25, &hdmi_conf_720p50 }, 967 { 1280, 720, 60, false, 4, hdmiphy_conf74_25, &hdmi_conf_720p60 }, 968 { 1920, 1080, 50, true, 20, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, 969 { 1920, 1080, 60, true, 5, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, 970 { 1920, 1080, 30, false, 34, hdmiphy_conf74_176, &hdmi_conf_1080p30 }, 971 { 1920, 1080, 50, false, 31, hdmiphy_conf148_5, &hdmi_conf_1080p50 }, 972 { 1920, 1080, 60, false, 16, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, 973 }; 974 975 struct hdmi_infoframe { 976 enum HDMI_PACKET_TYPE type; 977 u8 ver; 978 u8 len; 979 }; 980 981 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) 982 { 983 return readl(hdata->regs + reg_id); 984 } 985 986 static inline void hdmi_reg_writeb(struct hdmi_context *hdata, 987 u32 reg_id, u8 value) 988 { 989 writeb(value, hdata->regs + reg_id); 990 } 991 992 static inline void hdmi_reg_writemask(struct hdmi_context *hdata, 993 u32 reg_id, u32 value, u32 mask) 994 { 995 u32 old = readl(hdata->regs + reg_id); 996 value = (value & mask) | (old & ~mask); 997 writel(value, hdata->regs + reg_id); 998 } 999 1000 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) 1001 { 1002 #define DUMPREG(reg_id) \ 1003 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 1004 readl(hdata->regs + reg_id)) 1005 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); 1006 DUMPREG(HDMI_INTC_FLAG); 1007 DUMPREG(HDMI_INTC_CON); 1008 DUMPREG(HDMI_HPD_STATUS); 1009 DUMPREG(HDMI_V13_PHY_RSTOUT); 1010 DUMPREG(HDMI_V13_PHY_VPLL); 1011 DUMPREG(HDMI_V13_PHY_CMU); 1012 DUMPREG(HDMI_V13_CORE_RSTOUT); 1013 1014 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); 1015 DUMPREG(HDMI_CON_0); 1016 DUMPREG(HDMI_CON_1); 1017 DUMPREG(HDMI_CON_2); 1018 DUMPREG(HDMI_SYS_STATUS); 1019 DUMPREG(HDMI_V13_PHY_STATUS); 1020 DUMPREG(HDMI_STATUS_EN); 1021 DUMPREG(HDMI_HPD); 1022 DUMPREG(HDMI_MODE_SEL); 1023 DUMPREG(HDMI_V13_HPD_GEN); 1024 DUMPREG(HDMI_V13_DC_CONTROL); 1025 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); 1026 1027 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); 1028 DUMPREG(HDMI_H_BLANK_0); 1029 DUMPREG(HDMI_H_BLANK_1); 1030 DUMPREG(HDMI_V13_V_BLANK_0); 1031 DUMPREG(HDMI_V13_V_BLANK_1); 1032 DUMPREG(HDMI_V13_V_BLANK_2); 1033 DUMPREG(HDMI_V13_H_V_LINE_0); 1034 DUMPREG(HDMI_V13_H_V_LINE_1); 1035 DUMPREG(HDMI_V13_H_V_LINE_2); 1036 DUMPREG(HDMI_VSYNC_POL); 1037 DUMPREG(HDMI_INT_PRO_MODE); 1038 DUMPREG(HDMI_V13_V_BLANK_F_0); 1039 DUMPREG(HDMI_V13_V_BLANK_F_1); 1040 DUMPREG(HDMI_V13_V_BLANK_F_2); 1041 DUMPREG(HDMI_V13_H_SYNC_GEN_0); 1042 DUMPREG(HDMI_V13_H_SYNC_GEN_1); 1043 DUMPREG(HDMI_V13_H_SYNC_GEN_2); 1044 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); 1045 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); 1046 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); 1047 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); 1048 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); 1049 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); 1050 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); 1051 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); 1052 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); 1053 1054 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); 1055 DUMPREG(HDMI_TG_CMD); 1056 DUMPREG(HDMI_TG_H_FSZ_L); 1057 DUMPREG(HDMI_TG_H_FSZ_H); 1058 DUMPREG(HDMI_TG_HACT_ST_L); 1059 DUMPREG(HDMI_TG_HACT_ST_H); 1060 DUMPREG(HDMI_TG_HACT_SZ_L); 1061 DUMPREG(HDMI_TG_HACT_SZ_H); 1062 DUMPREG(HDMI_TG_V_FSZ_L); 1063 DUMPREG(HDMI_TG_V_FSZ_H); 1064 DUMPREG(HDMI_TG_VSYNC_L); 1065 DUMPREG(HDMI_TG_VSYNC_H); 1066 DUMPREG(HDMI_TG_VSYNC2_L); 1067 DUMPREG(HDMI_TG_VSYNC2_H); 1068 DUMPREG(HDMI_TG_VACT_ST_L); 1069 DUMPREG(HDMI_TG_VACT_ST_H); 1070 DUMPREG(HDMI_TG_VACT_SZ_L); 1071 DUMPREG(HDMI_TG_VACT_SZ_H); 1072 DUMPREG(HDMI_TG_FIELD_CHG_L); 1073 DUMPREG(HDMI_TG_FIELD_CHG_H); 1074 DUMPREG(HDMI_TG_VACT_ST2_L); 1075 DUMPREG(HDMI_TG_VACT_ST2_H); 1076 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); 1077 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); 1078 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); 1079 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); 1080 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); 1081 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); 1082 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); 1083 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); 1084 #undef DUMPREG 1085 } 1086 1087 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) 1088 { 1089 int i; 1090 1091 #define DUMPREG(reg_id) \ 1092 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 1093 readl(hdata->regs + reg_id)) 1094 1095 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); 1096 DUMPREG(HDMI_INTC_CON); 1097 DUMPREG(HDMI_INTC_FLAG); 1098 DUMPREG(HDMI_HPD_STATUS); 1099 DUMPREG(HDMI_INTC_CON_1); 1100 DUMPREG(HDMI_INTC_FLAG_1); 1101 DUMPREG(HDMI_PHY_STATUS_0); 1102 DUMPREG(HDMI_PHY_STATUS_PLL); 1103 DUMPREG(HDMI_PHY_CON_0); 1104 DUMPREG(HDMI_PHY_RSTOUT); 1105 DUMPREG(HDMI_PHY_VPLL); 1106 DUMPREG(HDMI_PHY_CMU); 1107 DUMPREG(HDMI_CORE_RSTOUT); 1108 1109 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); 1110 DUMPREG(HDMI_CON_0); 1111 DUMPREG(HDMI_CON_1); 1112 DUMPREG(HDMI_CON_2); 1113 DUMPREG(HDMI_SYS_STATUS); 1114 DUMPREG(HDMI_PHY_STATUS_0); 1115 DUMPREG(HDMI_STATUS_EN); 1116 DUMPREG(HDMI_HPD); 1117 DUMPREG(HDMI_MODE_SEL); 1118 DUMPREG(HDMI_ENC_EN); 1119 DUMPREG(HDMI_DC_CONTROL); 1120 DUMPREG(HDMI_VIDEO_PATTERN_GEN); 1121 1122 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); 1123 DUMPREG(HDMI_H_BLANK_0); 1124 DUMPREG(HDMI_H_BLANK_1); 1125 DUMPREG(HDMI_V2_BLANK_0); 1126 DUMPREG(HDMI_V2_BLANK_1); 1127 DUMPREG(HDMI_V1_BLANK_0); 1128 DUMPREG(HDMI_V1_BLANK_1); 1129 DUMPREG(HDMI_V_LINE_0); 1130 DUMPREG(HDMI_V_LINE_1); 1131 DUMPREG(HDMI_H_LINE_0); 1132 DUMPREG(HDMI_H_LINE_1); 1133 DUMPREG(HDMI_HSYNC_POL); 1134 1135 DUMPREG(HDMI_VSYNC_POL); 1136 DUMPREG(HDMI_INT_PRO_MODE); 1137 DUMPREG(HDMI_V_BLANK_F0_0); 1138 DUMPREG(HDMI_V_BLANK_F0_1); 1139 DUMPREG(HDMI_V_BLANK_F1_0); 1140 DUMPREG(HDMI_V_BLANK_F1_1); 1141 1142 DUMPREG(HDMI_H_SYNC_START_0); 1143 DUMPREG(HDMI_H_SYNC_START_1); 1144 DUMPREG(HDMI_H_SYNC_END_0); 1145 DUMPREG(HDMI_H_SYNC_END_1); 1146 1147 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); 1148 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); 1149 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); 1150 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); 1151 1152 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); 1153 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); 1154 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); 1155 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); 1156 1157 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); 1158 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); 1159 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); 1160 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); 1161 1162 DUMPREG(HDMI_V_BLANK_F2_0); 1163 DUMPREG(HDMI_V_BLANK_F2_1); 1164 DUMPREG(HDMI_V_BLANK_F3_0); 1165 DUMPREG(HDMI_V_BLANK_F3_1); 1166 DUMPREG(HDMI_V_BLANK_F4_0); 1167 DUMPREG(HDMI_V_BLANK_F4_1); 1168 DUMPREG(HDMI_V_BLANK_F5_0); 1169 DUMPREG(HDMI_V_BLANK_F5_1); 1170 1171 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); 1172 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); 1173 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); 1174 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); 1175 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); 1176 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); 1177 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); 1178 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); 1179 1180 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); 1181 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); 1182 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); 1183 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); 1184 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); 1185 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); 1186 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); 1187 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); 1188 1189 DUMPREG(HDMI_VACT_SPACE_1_0); 1190 DUMPREG(HDMI_VACT_SPACE_1_1); 1191 DUMPREG(HDMI_VACT_SPACE_2_0); 1192 DUMPREG(HDMI_VACT_SPACE_2_1); 1193 DUMPREG(HDMI_VACT_SPACE_3_0); 1194 DUMPREG(HDMI_VACT_SPACE_3_1); 1195 DUMPREG(HDMI_VACT_SPACE_4_0); 1196 DUMPREG(HDMI_VACT_SPACE_4_1); 1197 DUMPREG(HDMI_VACT_SPACE_5_0); 1198 DUMPREG(HDMI_VACT_SPACE_5_1); 1199 DUMPREG(HDMI_VACT_SPACE_6_0); 1200 DUMPREG(HDMI_VACT_SPACE_6_1); 1201 1202 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); 1203 DUMPREG(HDMI_TG_CMD); 1204 DUMPREG(HDMI_TG_H_FSZ_L); 1205 DUMPREG(HDMI_TG_H_FSZ_H); 1206 DUMPREG(HDMI_TG_HACT_ST_L); 1207 DUMPREG(HDMI_TG_HACT_ST_H); 1208 DUMPREG(HDMI_TG_HACT_SZ_L); 1209 DUMPREG(HDMI_TG_HACT_SZ_H); 1210 DUMPREG(HDMI_TG_V_FSZ_L); 1211 DUMPREG(HDMI_TG_V_FSZ_H); 1212 DUMPREG(HDMI_TG_VSYNC_L); 1213 DUMPREG(HDMI_TG_VSYNC_H); 1214 DUMPREG(HDMI_TG_VSYNC2_L); 1215 DUMPREG(HDMI_TG_VSYNC2_H); 1216 DUMPREG(HDMI_TG_VACT_ST_L); 1217 DUMPREG(HDMI_TG_VACT_ST_H); 1218 DUMPREG(HDMI_TG_VACT_SZ_L); 1219 DUMPREG(HDMI_TG_VACT_SZ_H); 1220 DUMPREG(HDMI_TG_FIELD_CHG_L); 1221 DUMPREG(HDMI_TG_FIELD_CHG_H); 1222 DUMPREG(HDMI_TG_VACT_ST2_L); 1223 DUMPREG(HDMI_TG_VACT_ST2_H); 1224 DUMPREG(HDMI_TG_VACT_ST3_L); 1225 DUMPREG(HDMI_TG_VACT_ST3_H); 1226 DUMPREG(HDMI_TG_VACT_ST4_L); 1227 DUMPREG(HDMI_TG_VACT_ST4_H); 1228 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); 1229 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); 1230 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); 1231 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); 1232 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); 1233 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); 1234 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); 1235 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); 1236 DUMPREG(HDMI_TG_3D); 1237 1238 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); 1239 DUMPREG(HDMI_AVI_CON); 1240 DUMPREG(HDMI_AVI_HEADER0); 1241 DUMPREG(HDMI_AVI_HEADER1); 1242 DUMPREG(HDMI_AVI_HEADER2); 1243 DUMPREG(HDMI_AVI_CHECK_SUM); 1244 DUMPREG(HDMI_VSI_CON); 1245 DUMPREG(HDMI_VSI_HEADER0); 1246 DUMPREG(HDMI_VSI_HEADER1); 1247 DUMPREG(HDMI_VSI_HEADER2); 1248 for (i = 0; i < 7; ++i) 1249 DUMPREG(HDMI_VSI_DATA(i)); 1250 1251 #undef DUMPREG 1252 } 1253 1254 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) 1255 { 1256 if (hdata->type == HDMI_TYPE13) 1257 hdmi_v13_regs_dump(hdata, prefix); 1258 else 1259 hdmi_v14_regs_dump(hdata, prefix); 1260 } 1261 1262 static int hdmi_v13_conf_index(struct drm_display_mode *mode) 1263 { 1264 int i; 1265 1266 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) 1267 if (hdmi_v13_confs[i].width == mode->hdisplay && 1268 hdmi_v13_confs[i].height == mode->vdisplay && 1269 hdmi_v13_confs[i].vrefresh == mode->vrefresh && 1270 hdmi_v13_confs[i].interlace == 1271 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1272 true : false)) 1273 return i; 1274 1275 return -EINVAL; 1276 } 1277 1278 static int hdmi_v14_conf_index(struct drm_display_mode *mode) 1279 { 1280 int i; 1281 1282 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i) 1283 if (hdmi_confs[i].width == mode->hdisplay && 1284 hdmi_confs[i].height == mode->vdisplay && 1285 hdmi_confs[i].vrefresh == mode->vrefresh && 1286 hdmi_confs[i].interlace == 1287 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1288 true : false)) 1289 return i; 1290 1291 return -EINVAL; 1292 } 1293 1294 static int hdmi_conf_index(struct hdmi_context *hdata, 1295 struct drm_display_mode *mode) 1296 { 1297 if (hdata->type == HDMI_TYPE13) 1298 return hdmi_v13_conf_index(mode); 1299 1300 return hdmi_v14_conf_index(mode); 1301 } 1302 1303 static u8 hdmi_chksum(struct hdmi_context *hdata, 1304 u32 start, u8 len, u32 hdr_sum) 1305 { 1306 int i; 1307 1308 /* hdr_sum : header0 + header1 + header2 1309 * start : start address of packet byte1 1310 * len : packet bytes - 1 */ 1311 for (i = 0; i < len; ++i) 1312 hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4); 1313 1314 /* return 2's complement of 8 bit hdr_sum */ 1315 return (u8)(~(hdr_sum & 0xff) + 1); 1316 } 1317 1318 static void hdmi_reg_infoframe(struct hdmi_context *hdata, 1319 struct hdmi_infoframe *infoframe) 1320 { 1321 u32 hdr_sum; 1322 u8 chksum; 1323 u32 aspect_ratio; 1324 u32 mod; 1325 u32 vic; 1326 1327 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1328 1329 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL); 1330 if (hdata->dvi_mode) { 1331 hdmi_reg_writeb(hdata, HDMI_VSI_CON, 1332 HDMI_VSI_CON_DO_NOT_TRANSMIT); 1333 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 1334 HDMI_AVI_CON_DO_NOT_TRANSMIT); 1335 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN); 1336 return; 1337 } 1338 1339 switch (infoframe->type) { 1340 case HDMI_PACKET_TYPE_AVI: 1341 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); 1342 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type); 1343 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver); 1344 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len); 1345 hdr_sum = infoframe->type + infoframe->ver + infoframe->len; 1346 1347 /* Output format zero hardcoded ,RGB YBCR selection */ 1348 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | 1349 AVI_ACTIVE_FORMAT_VALID | 1350 AVI_UNDERSCANNED_DISPLAY_VALID); 1351 1352 aspect_ratio = AVI_PIC_ASPECT_RATIO_16_9; 1353 1354 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), aspect_ratio | 1355 AVI_SAME_AS_PIC_ASPECT_RATIO); 1356 1357 if (hdata->type == HDMI_TYPE13) 1358 vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id; 1359 else 1360 vic = hdmi_confs[hdata->cur_conf].cea_video_id; 1361 1362 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); 1363 1364 chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), 1365 infoframe->len, hdr_sum); 1366 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); 1367 hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); 1368 break; 1369 case HDMI_PACKET_TYPE_AUI: 1370 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); 1371 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type); 1372 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver); 1373 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len); 1374 hdr_sum = infoframe->type + infoframe->ver + infoframe->len; 1375 chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), 1376 infoframe->len, hdr_sum); 1377 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); 1378 hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); 1379 break; 1380 default: 1381 break; 1382 } 1383 } 1384 1385 static bool hdmi_is_connected(void *ctx) 1386 { 1387 struct hdmi_context *hdata = ctx; 1388 1389 return hdata->hpd; 1390 } 1391 1392 static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector) 1393 { 1394 struct edid *raw_edid; 1395 struct hdmi_context *hdata = ctx; 1396 1397 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1398 1399 if (!hdata->ddc_port) 1400 return ERR_PTR(-ENODEV); 1401 1402 raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); 1403 if (!raw_edid) 1404 return ERR_PTR(-ENODEV); 1405 1406 hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); 1407 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", 1408 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), 1409 raw_edid->width_cm, raw_edid->height_cm); 1410 1411 return raw_edid; 1412 } 1413 1414 static int hdmi_v13_check_timing(struct fb_videomode *check_timing) 1415 { 1416 int i; 1417 1418 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", 1419 check_timing->xres, check_timing->yres, 1420 check_timing->refresh, (check_timing->vmode & 1421 FB_VMODE_INTERLACED) ? true : false); 1422 1423 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) 1424 if (hdmi_v13_confs[i].width == check_timing->xres && 1425 hdmi_v13_confs[i].height == check_timing->yres && 1426 hdmi_v13_confs[i].vrefresh == check_timing->refresh && 1427 hdmi_v13_confs[i].interlace == 1428 ((check_timing->vmode & FB_VMODE_INTERLACED) ? 1429 true : false)) 1430 return 0; 1431 1432 /* TODO */ 1433 1434 return -EINVAL; 1435 } 1436 1437 static int hdmi_v14_check_timing(struct fb_videomode *check_timing) 1438 { 1439 int i; 1440 1441 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", 1442 check_timing->xres, check_timing->yres, 1443 check_timing->refresh, (check_timing->vmode & 1444 FB_VMODE_INTERLACED) ? true : false); 1445 1446 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++) 1447 if (hdmi_confs[i].width == check_timing->xres && 1448 hdmi_confs[i].height == check_timing->yres && 1449 hdmi_confs[i].vrefresh == check_timing->refresh && 1450 hdmi_confs[i].interlace == 1451 ((check_timing->vmode & FB_VMODE_INTERLACED) ? 1452 true : false)) 1453 return 0; 1454 1455 /* TODO */ 1456 1457 return -EINVAL; 1458 } 1459 1460 static int hdmi_check_timing(void *ctx, void *timing) 1461 { 1462 struct hdmi_context *hdata = ctx; 1463 struct fb_videomode *check_timing = timing; 1464 1465 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1466 1467 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, 1468 check_timing->yres, check_timing->refresh, 1469 check_timing->vmode); 1470 1471 if (hdata->type == HDMI_TYPE13) 1472 return hdmi_v13_check_timing(check_timing); 1473 else 1474 return hdmi_v14_check_timing(check_timing); 1475 } 1476 1477 static void hdmi_set_acr(u32 freq, u8 *acr) 1478 { 1479 u32 n, cts; 1480 1481 switch (freq) { 1482 case 32000: 1483 n = 4096; 1484 cts = 27000; 1485 break; 1486 case 44100: 1487 n = 6272; 1488 cts = 30000; 1489 break; 1490 case 88200: 1491 n = 12544; 1492 cts = 30000; 1493 break; 1494 case 176400: 1495 n = 25088; 1496 cts = 30000; 1497 break; 1498 case 48000: 1499 n = 6144; 1500 cts = 27000; 1501 break; 1502 case 96000: 1503 n = 12288; 1504 cts = 27000; 1505 break; 1506 case 192000: 1507 n = 24576; 1508 cts = 27000; 1509 break; 1510 default: 1511 n = 0; 1512 cts = 0; 1513 break; 1514 } 1515 1516 acr[1] = cts >> 16; 1517 acr[2] = cts >> 8 & 0xff; 1518 acr[3] = cts & 0xff; 1519 1520 acr[4] = n >> 16; 1521 acr[5] = n >> 8 & 0xff; 1522 acr[6] = n & 0xff; 1523 } 1524 1525 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr) 1526 { 1527 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]); 1528 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]); 1529 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]); 1530 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]); 1531 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]); 1532 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]); 1533 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]); 1534 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]); 1535 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]); 1536 1537 if (hdata->type == HDMI_TYPE13) 1538 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4); 1539 else 1540 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); 1541 } 1542 1543 static void hdmi_audio_init(struct hdmi_context *hdata) 1544 { 1545 u32 sample_rate, bits_per_sample, frame_size_code; 1546 u32 data_num, bit_ch, sample_frq; 1547 u32 val; 1548 u8 acr[7]; 1549 1550 sample_rate = 44100; 1551 bits_per_sample = 16; 1552 frame_size_code = 0; 1553 1554 switch (bits_per_sample) { 1555 case 20: 1556 data_num = 2; 1557 bit_ch = 1; 1558 break; 1559 case 24: 1560 data_num = 3; 1561 bit_ch = 1; 1562 break; 1563 default: 1564 data_num = 1; 1565 bit_ch = 0; 1566 break; 1567 } 1568 1569 hdmi_set_acr(sample_rate, acr); 1570 hdmi_reg_acr(hdata, acr); 1571 1572 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE 1573 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE 1574 | HDMI_I2S_MUX_ENABLE); 1575 1576 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN 1577 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); 1578 1579 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); 1580 1581 sample_frq = (sample_rate == 44100) ? 0 : 1582 (sample_rate == 48000) ? 2 : 1583 (sample_rate == 32000) ? 3 : 1584 (sample_rate == 96000) ? 0xa : 0x0; 1585 1586 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); 1587 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); 1588 1589 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01; 1590 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val); 1591 1592 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */ 1593 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5) 1594 | HDMI_I2S_SEL_LRCK(6)); 1595 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1) 1596 | HDMI_I2S_SEL_SDATA2(4)); 1597 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1) 1598 | HDMI_I2S_SEL_SDATA2(2)); 1599 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0)); 1600 1601 /* I2S_CON_1 & 2 */ 1602 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE 1603 | HDMI_I2S_L_CH_LOW_POL); 1604 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE 1605 | HDMI_I2S_SET_BIT_CH(bit_ch) 1606 | HDMI_I2S_SET_SDATA_BIT(data_num) 1607 | HDMI_I2S_BASIC_FORMAT); 1608 1609 /* Configure register related to CUV information */ 1610 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 1611 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH 1612 | HDMI_I2S_COPYRIGHT 1613 | HDMI_I2S_LINEAR_PCM 1614 | HDMI_I2S_CONSUMER_FORMAT); 1615 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER); 1616 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0)); 1617 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2 1618 | HDMI_I2S_SET_SMP_FREQ(sample_frq)); 1619 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4, 1620 HDMI_I2S_ORG_SMP_FREQ_44_1 1621 | HDMI_I2S_WORD_LEN_MAX24_24BITS 1622 | HDMI_I2S_WORD_LEN_MAX_24BITS); 1623 1624 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); 1625 } 1626 1627 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) 1628 { 1629 if (hdata->dvi_mode) 1630 return; 1631 1632 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); 1633 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? 1634 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); 1635 } 1636 1637 static void hdmi_conf_reset(struct hdmi_context *hdata) 1638 { 1639 u32 reg; 1640 1641 if (hdata->type == HDMI_TYPE13) 1642 reg = HDMI_V13_CORE_RSTOUT; 1643 else 1644 reg = HDMI_CORE_RSTOUT; 1645 1646 /* resetting HDMI core */ 1647 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); 1648 usleep_range(10000, 12000); 1649 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); 1650 usleep_range(10000, 12000); 1651 } 1652 1653 static void hdmi_conf_init(struct hdmi_context *hdata) 1654 { 1655 struct hdmi_infoframe infoframe; 1656 1657 /* disable HPD interrupts from HDMI IP block, use GPIO instead */ 1658 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | 1659 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); 1660 1661 /* choose HDMI mode */ 1662 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1663 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); 1664 /* disable bluescreen */ 1665 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); 1666 1667 if (hdata->dvi_mode) { 1668 /* choose DVI mode */ 1669 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1670 HDMI_MODE_DVI_EN, HDMI_MODE_MASK); 1671 hdmi_reg_writeb(hdata, HDMI_CON_2, 1672 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS); 1673 } 1674 1675 if (hdata->type == HDMI_TYPE13) { 1676 /* choose bluescreen (fecal) color */ 1677 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12); 1678 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34); 1679 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56); 1680 1681 /* enable AVI packet every vsync, fixes purple line problem */ 1682 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02); 1683 /* force RGB, look to CEA-861-D, table 7 for more detail */ 1684 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5); 1685 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); 1686 1687 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02); 1688 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); 1689 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); 1690 } else { 1691 infoframe.type = HDMI_PACKET_TYPE_AVI; 1692 infoframe.ver = HDMI_AVI_VERSION; 1693 infoframe.len = HDMI_AVI_LENGTH; 1694 hdmi_reg_infoframe(hdata, &infoframe); 1695 1696 infoframe.type = HDMI_PACKET_TYPE_AUI; 1697 infoframe.ver = HDMI_AUI_VERSION; 1698 infoframe.len = HDMI_AUI_LENGTH; 1699 hdmi_reg_infoframe(hdata, &infoframe); 1700 1701 /* enable AVI packet every vsync, fixes purple line problem */ 1702 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); 1703 } 1704 } 1705 1706 static void hdmi_v13_timing_apply(struct hdmi_context *hdata) 1707 { 1708 const struct hdmi_v13_preset_conf *conf = 1709 hdmi_v13_confs[hdata->cur_conf].conf; 1710 const struct hdmi_v13_core_regs *core = &conf->core; 1711 const struct hdmi_v13_tg_regs *tg = &conf->tg; 1712 int tries; 1713 1714 /* setting core registers */ 1715 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); 1716 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); 1717 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]); 1718 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]); 1719 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]); 1720 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]); 1721 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]); 1722 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]); 1723 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); 1724 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); 1725 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]); 1726 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]); 1727 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]); 1728 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]); 1729 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]); 1730 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]); 1731 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); 1732 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); 1733 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); 1734 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); 1735 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); 1736 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); 1737 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); 1738 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); 1739 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); 1740 /* Timing generator registers */ 1741 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 1742 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 1743 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); 1744 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); 1745 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); 1746 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); 1747 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); 1748 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); 1749 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); 1750 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); 1751 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); 1752 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); 1753 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); 1754 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); 1755 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); 1756 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); 1757 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); 1758 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 1759 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 1760 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 1761 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 1762 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); 1763 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); 1764 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); 1765 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); 1766 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); 1767 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); 1768 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); 1769 1770 /* waiting for HDMIPHY's PLL to get to steady state */ 1771 for (tries = 100; tries; --tries) { 1772 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS); 1773 if (val & HDMI_PHY_STATUS_READY) 1774 break; 1775 usleep_range(1000, 2000); 1776 } 1777 /* steady state not achieved */ 1778 if (tries == 0) { 1779 DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); 1780 hdmi_regs_dump(hdata, "timing apply"); 1781 } 1782 1783 clk_disable(hdata->res.sclk_hdmi); 1784 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); 1785 clk_enable(hdata->res.sclk_hdmi); 1786 1787 /* enable HDMI and timing generator */ 1788 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); 1789 if (core->int_pro_mode[0]) 1790 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | 1791 HDMI_FIELD_EN); 1792 else 1793 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); 1794 } 1795 1796 static void hdmi_v14_timing_apply(struct hdmi_context *hdata) 1797 { 1798 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf; 1799 const struct hdmi_core_regs *core = &conf->core; 1800 const struct hdmi_tg_regs *tg = &conf->tg; 1801 int tries; 1802 1803 /* setting core registers */ 1804 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); 1805 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); 1806 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]); 1807 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]); 1808 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]); 1809 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]); 1810 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]); 1811 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]); 1812 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]); 1813 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]); 1814 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]); 1815 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); 1816 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); 1817 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]); 1818 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]); 1819 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]); 1820 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]); 1821 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]); 1822 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]); 1823 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]); 1824 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]); 1825 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 1826 core->v_sync_line_bef_2[0]); 1827 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1, 1828 core->v_sync_line_bef_2[1]); 1829 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 1830 core->v_sync_line_bef_1[0]); 1831 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1, 1832 core->v_sync_line_bef_1[1]); 1833 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 1834 core->v_sync_line_aft_2[0]); 1835 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1, 1836 core->v_sync_line_aft_2[1]); 1837 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 1838 core->v_sync_line_aft_1[0]); 1839 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1, 1840 core->v_sync_line_aft_1[1]); 1841 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 1842 core->v_sync_line_aft_pxl_2[0]); 1843 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1, 1844 core->v_sync_line_aft_pxl_2[1]); 1845 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 1846 core->v_sync_line_aft_pxl_1[0]); 1847 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1, 1848 core->v_sync_line_aft_pxl_1[1]); 1849 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]); 1850 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]); 1851 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]); 1852 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]); 1853 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]); 1854 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]); 1855 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]); 1856 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]); 1857 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 1858 core->v_sync_line_aft_3[0]); 1859 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1, 1860 core->v_sync_line_aft_3[1]); 1861 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 1862 core->v_sync_line_aft_4[0]); 1863 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1, 1864 core->v_sync_line_aft_4[1]); 1865 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 1866 core->v_sync_line_aft_5[0]); 1867 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1, 1868 core->v_sync_line_aft_5[1]); 1869 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 1870 core->v_sync_line_aft_6[0]); 1871 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1, 1872 core->v_sync_line_aft_6[1]); 1873 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 1874 core->v_sync_line_aft_pxl_3[0]); 1875 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1, 1876 core->v_sync_line_aft_pxl_3[1]); 1877 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 1878 core->v_sync_line_aft_pxl_4[0]); 1879 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1, 1880 core->v_sync_line_aft_pxl_4[1]); 1881 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 1882 core->v_sync_line_aft_pxl_5[0]); 1883 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1, 1884 core->v_sync_line_aft_pxl_5[1]); 1885 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 1886 core->v_sync_line_aft_pxl_6[0]); 1887 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1, 1888 core->v_sync_line_aft_pxl_6[1]); 1889 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]); 1890 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]); 1891 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]); 1892 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]); 1893 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]); 1894 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]); 1895 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]); 1896 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]); 1897 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]); 1898 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]); 1899 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]); 1900 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]); 1901 1902 /* Timing generator registers */ 1903 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 1904 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 1905 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); 1906 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); 1907 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); 1908 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); 1909 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); 1910 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); 1911 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); 1912 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); 1913 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); 1914 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); 1915 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); 1916 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); 1917 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); 1918 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); 1919 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); 1920 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 1921 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 1922 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 1923 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l); 1924 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h); 1925 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l); 1926 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h); 1927 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 1928 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); 1929 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); 1930 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); 1931 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); 1932 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); 1933 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); 1934 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); 1935 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d); 1936 1937 /* waiting for HDMIPHY's PLL to get to steady state */ 1938 for (tries = 100; tries; --tries) { 1939 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0); 1940 if (val & HDMI_PHY_STATUS_READY) 1941 break; 1942 usleep_range(1000, 2000); 1943 } 1944 /* steady state not achieved */ 1945 if (tries == 0) { 1946 DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); 1947 hdmi_regs_dump(hdata, "timing apply"); 1948 } 1949 1950 clk_disable(hdata->res.sclk_hdmi); 1951 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); 1952 clk_enable(hdata->res.sclk_hdmi); 1953 1954 /* enable HDMI and timing generator */ 1955 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); 1956 if (core->int_pro_mode[0]) 1957 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | 1958 HDMI_FIELD_EN); 1959 else 1960 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); 1961 } 1962 1963 static void hdmi_timing_apply(struct hdmi_context *hdata) 1964 { 1965 if (hdata->type == HDMI_TYPE13) 1966 hdmi_v13_timing_apply(hdata); 1967 else 1968 hdmi_v14_timing_apply(hdata); 1969 } 1970 1971 static void hdmiphy_conf_reset(struct hdmi_context *hdata) 1972 { 1973 u8 buffer[2]; 1974 u32 reg; 1975 1976 clk_disable(hdata->res.sclk_hdmi); 1977 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); 1978 clk_enable(hdata->res.sclk_hdmi); 1979 1980 /* operation mode */ 1981 buffer[0] = 0x1f; 1982 buffer[1] = 0x00; 1983 1984 if (hdata->hdmiphy_port) 1985 i2c_master_send(hdata->hdmiphy_port, buffer, 2); 1986 1987 if (hdata->type == HDMI_TYPE13) 1988 reg = HDMI_V13_PHY_RSTOUT; 1989 else 1990 reg = HDMI_PHY_RSTOUT; 1991 1992 /* reset hdmiphy */ 1993 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); 1994 usleep_range(10000, 12000); 1995 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT); 1996 usleep_range(10000, 12000); 1997 } 1998 1999 static void hdmiphy_poweron(struct hdmi_context *hdata) 2000 { 2001 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2002 2003 if (hdata->type == HDMI_TYPE14) 2004 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, 2005 HDMI_PHY_POWER_OFF_EN); 2006 } 2007 2008 static void hdmiphy_poweroff(struct hdmi_context *hdata) 2009 { 2010 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2011 2012 if (hdata->type == HDMI_TYPE14) 2013 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, 2014 HDMI_PHY_POWER_OFF_EN); 2015 } 2016 2017 static void hdmiphy_conf_apply(struct hdmi_context *hdata) 2018 { 2019 const u8 *hdmiphy_data; 2020 u8 buffer[32]; 2021 u8 operation[2]; 2022 u8 read_buffer[32] = {0, }; 2023 int ret; 2024 int i; 2025 2026 if (!hdata->hdmiphy_port) { 2027 DRM_ERROR("hdmiphy is not attached\n"); 2028 return; 2029 } 2030 2031 /* pixel clock */ 2032 if (hdata->type == HDMI_TYPE13) 2033 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; 2034 else 2035 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; 2036 2037 memcpy(buffer, hdmiphy_data, 32); 2038 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); 2039 if (ret != 32) { 2040 DRM_ERROR("failed to configure HDMIPHY via I2C\n"); 2041 return; 2042 } 2043 2044 usleep_range(10000, 12000); 2045 2046 /* operation mode */ 2047 operation[0] = 0x1f; 2048 operation[1] = 0x80; 2049 2050 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2); 2051 if (ret != 2) { 2052 DRM_ERROR("failed to enable hdmiphy\n"); 2053 return; 2054 } 2055 2056 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32); 2057 if (ret < 0) { 2058 DRM_ERROR("failed to read hdmiphy config\n"); 2059 return; 2060 } 2061 2062 for (i = 0; i < ret; i++) 2063 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - " 2064 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]); 2065 } 2066 2067 static void hdmi_conf_apply(struct hdmi_context *hdata) 2068 { 2069 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2070 2071 hdmiphy_conf_reset(hdata); 2072 hdmiphy_conf_apply(hdata); 2073 2074 mutex_lock(&hdata->hdmi_mutex); 2075 hdmi_conf_reset(hdata); 2076 hdmi_conf_init(hdata); 2077 mutex_unlock(&hdata->hdmi_mutex); 2078 2079 hdmi_audio_init(hdata); 2080 2081 /* setting core registers */ 2082 hdmi_timing_apply(hdata); 2083 hdmi_audio_control(hdata, true); 2084 2085 hdmi_regs_dump(hdata, "start"); 2086 } 2087 2088 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, 2089 const struct drm_display_mode *mode, 2090 struct drm_display_mode *adjusted_mode) 2091 { 2092 struct drm_display_mode *m; 2093 struct hdmi_context *hdata = ctx; 2094 int index; 2095 2096 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2097 2098 drm_mode_set_crtcinfo(adjusted_mode, 0); 2099 2100 if (hdata->type == HDMI_TYPE13) 2101 index = hdmi_v13_conf_index(adjusted_mode); 2102 else 2103 index = hdmi_v14_conf_index(adjusted_mode); 2104 2105 /* just return if user desired mode exists. */ 2106 if (index >= 0) 2107 return; 2108 2109 /* 2110 * otherwise, find the most suitable mode among modes and change it 2111 * to adjusted_mode. 2112 */ 2113 list_for_each_entry(m, &connector->modes, head) { 2114 if (hdata->type == HDMI_TYPE13) 2115 index = hdmi_v13_conf_index(m); 2116 else 2117 index = hdmi_v14_conf_index(m); 2118 2119 if (index >= 0) { 2120 struct drm_mode_object base; 2121 struct list_head head; 2122 2123 DRM_INFO("desired mode doesn't exist so\n"); 2124 DRM_INFO("use the most suitable mode among modes.\n"); 2125 2126 /* preserve display mode header while copying. */ 2127 head = adjusted_mode->head; 2128 base = adjusted_mode->base; 2129 memcpy(adjusted_mode, m, sizeof(*m)); 2130 adjusted_mode->head = head; 2131 adjusted_mode->base = base; 2132 break; 2133 } 2134 } 2135 } 2136 2137 static void hdmi_mode_set(void *ctx, void *mode) 2138 { 2139 struct hdmi_context *hdata = ctx; 2140 int conf_idx; 2141 2142 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2143 2144 conf_idx = hdmi_conf_index(hdata, mode); 2145 if (conf_idx >= 0) 2146 hdata->cur_conf = conf_idx; 2147 else 2148 DRM_DEBUG_KMS("not supported mode\n"); 2149 } 2150 2151 static void hdmi_get_max_resol(void *ctx, unsigned int *width, 2152 unsigned int *height) 2153 { 2154 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2155 2156 *width = MAX_WIDTH; 2157 *height = MAX_HEIGHT; 2158 } 2159 2160 static void hdmi_commit(void *ctx) 2161 { 2162 struct hdmi_context *hdata = ctx; 2163 2164 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2165 2166 mutex_lock(&hdata->hdmi_mutex); 2167 if (!hdata->powered) { 2168 mutex_unlock(&hdata->hdmi_mutex); 2169 return; 2170 } 2171 mutex_unlock(&hdata->hdmi_mutex); 2172 2173 hdmi_conf_apply(hdata); 2174 } 2175 2176 static void hdmi_poweron(struct hdmi_context *hdata) 2177 { 2178 struct hdmi_resources *res = &hdata->res; 2179 2180 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2181 2182 mutex_lock(&hdata->hdmi_mutex); 2183 if (hdata->powered) { 2184 mutex_unlock(&hdata->hdmi_mutex); 2185 return; 2186 } 2187 2188 hdata->powered = true; 2189 2190 mutex_unlock(&hdata->hdmi_mutex); 2191 2192 regulator_bulk_enable(res->regul_count, res->regul_bulk); 2193 clk_enable(res->hdmiphy); 2194 clk_enable(res->hdmi); 2195 clk_enable(res->sclk_hdmi); 2196 2197 hdmiphy_poweron(hdata); 2198 } 2199 2200 static void hdmi_poweroff(struct hdmi_context *hdata) 2201 { 2202 struct hdmi_resources *res = &hdata->res; 2203 2204 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2205 2206 mutex_lock(&hdata->hdmi_mutex); 2207 if (!hdata->powered) 2208 goto out; 2209 mutex_unlock(&hdata->hdmi_mutex); 2210 2211 /* 2212 * The TV power domain needs any condition of hdmiphy to turn off and 2213 * its reset state seems to meet the condition. 2214 */ 2215 hdmiphy_conf_reset(hdata); 2216 hdmiphy_poweroff(hdata); 2217 2218 clk_disable(res->sclk_hdmi); 2219 clk_disable(res->hdmi); 2220 clk_disable(res->hdmiphy); 2221 regulator_bulk_disable(res->regul_count, res->regul_bulk); 2222 2223 mutex_lock(&hdata->hdmi_mutex); 2224 2225 hdata->powered = false; 2226 2227 out: 2228 mutex_unlock(&hdata->hdmi_mutex); 2229 } 2230 2231 static void hdmi_dpms(void *ctx, int mode) 2232 { 2233 struct hdmi_context *hdata = ctx; 2234 2235 DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode); 2236 2237 switch (mode) { 2238 case DRM_MODE_DPMS_ON: 2239 if (pm_runtime_suspended(hdata->dev)) 2240 pm_runtime_get_sync(hdata->dev); 2241 break; 2242 case DRM_MODE_DPMS_STANDBY: 2243 case DRM_MODE_DPMS_SUSPEND: 2244 case DRM_MODE_DPMS_OFF: 2245 if (!pm_runtime_suspended(hdata->dev)) 2246 pm_runtime_put_sync(hdata->dev); 2247 break; 2248 default: 2249 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 2250 break; 2251 } 2252 } 2253 2254 static struct exynos_hdmi_ops hdmi_ops = { 2255 /* display */ 2256 .is_connected = hdmi_is_connected, 2257 .get_edid = hdmi_get_edid, 2258 .check_timing = hdmi_check_timing, 2259 2260 /* manager */ 2261 .mode_fixup = hdmi_mode_fixup, 2262 .mode_set = hdmi_mode_set, 2263 .get_max_resol = hdmi_get_max_resol, 2264 .commit = hdmi_commit, 2265 .dpms = hdmi_dpms, 2266 }; 2267 2268 static irqreturn_t hdmi_irq_thread(int irq, void *arg) 2269 { 2270 struct exynos_drm_hdmi_context *ctx = arg; 2271 struct hdmi_context *hdata = ctx->ctx; 2272 2273 mutex_lock(&hdata->hdmi_mutex); 2274 hdata->hpd = gpio_get_value(hdata->hpd_gpio); 2275 mutex_unlock(&hdata->hdmi_mutex); 2276 2277 if (ctx->drm_dev) 2278 drm_helper_hpd_irq_event(ctx->drm_dev); 2279 2280 return IRQ_HANDLED; 2281 } 2282 2283 static int hdmi_resources_init(struct hdmi_context *hdata) 2284 { 2285 struct device *dev = hdata->dev; 2286 struct hdmi_resources *res = &hdata->res; 2287 static char *supply[] = { 2288 "hdmi-en", 2289 "vdd", 2290 "vdd_osc", 2291 "vdd_pll", 2292 }; 2293 int i, ret; 2294 2295 DRM_DEBUG_KMS("HDMI resource init\n"); 2296 2297 memset(res, 0, sizeof(*res)); 2298 2299 /* get clocks, power */ 2300 res->hdmi = devm_clk_get(dev, "hdmi"); 2301 if (IS_ERR_OR_NULL(res->hdmi)) { 2302 DRM_ERROR("failed to get clock 'hdmi'\n"); 2303 goto fail; 2304 } 2305 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 2306 if (IS_ERR_OR_NULL(res->sclk_hdmi)) { 2307 DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); 2308 goto fail; 2309 } 2310 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel"); 2311 if (IS_ERR_OR_NULL(res->sclk_pixel)) { 2312 DRM_ERROR("failed to get clock 'sclk_pixel'\n"); 2313 goto fail; 2314 } 2315 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy"); 2316 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) { 2317 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); 2318 goto fail; 2319 } 2320 res->hdmiphy = devm_clk_get(dev, "hdmiphy"); 2321 if (IS_ERR_OR_NULL(res->hdmiphy)) { 2322 DRM_ERROR("failed to get clock 'hdmiphy'\n"); 2323 goto fail; 2324 } 2325 2326 clk_set_parent(res->sclk_hdmi, res->sclk_pixel); 2327 2328 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) * 2329 sizeof(res->regul_bulk[0]), GFP_KERNEL); 2330 if (!res->regul_bulk) { 2331 DRM_ERROR("failed to get memory for regulators\n"); 2332 goto fail; 2333 } 2334 for (i = 0; i < ARRAY_SIZE(supply); ++i) { 2335 res->regul_bulk[i].supply = supply[i]; 2336 res->regul_bulk[i].consumer = NULL; 2337 } 2338 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk); 2339 if (ret) { 2340 DRM_ERROR("failed to get regulators\n"); 2341 goto fail; 2342 } 2343 res->regul_count = ARRAY_SIZE(supply); 2344 2345 return 0; 2346 fail: 2347 DRM_ERROR("HDMI resource init - failed\n"); 2348 return -ENODEV; 2349 } 2350 2351 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy; 2352 2353 void hdmi_attach_ddc_client(struct i2c_client *ddc) 2354 { 2355 if (ddc) 2356 hdmi_ddc = ddc; 2357 } 2358 2359 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) 2360 { 2361 if (hdmiphy) 2362 hdmi_hdmiphy = hdmiphy; 2363 } 2364 2365 #ifdef CONFIG_OF 2366 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata 2367 (struct device *dev) 2368 { 2369 struct device_node *np = dev->of_node; 2370 struct s5p_hdmi_platform_data *pd; 2371 enum of_gpio_flags flags; 2372 u32 value; 2373 2374 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); 2375 if (!pd) { 2376 DRM_ERROR("memory allocation for pdata failed\n"); 2377 goto err_data; 2378 } 2379 2380 if (!of_find_property(np, "hpd-gpio", &value)) { 2381 DRM_ERROR("no hpd gpio property found\n"); 2382 goto err_data; 2383 } 2384 2385 pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags); 2386 2387 return pd; 2388 2389 err_data: 2390 return NULL; 2391 } 2392 #else 2393 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata 2394 (struct device *dev) 2395 { 2396 return NULL; 2397 } 2398 #endif 2399 2400 static struct platform_device_id hdmi_driver_types[] = { 2401 { 2402 .name = "s5pv210-hdmi", 2403 .driver_data = HDMI_TYPE13, 2404 }, { 2405 .name = "exynos4-hdmi", 2406 .driver_data = HDMI_TYPE13, 2407 }, { 2408 .name = "exynos4-hdmi14", 2409 .driver_data = HDMI_TYPE14, 2410 }, { 2411 .name = "exynos5-hdmi", 2412 .driver_data = HDMI_TYPE14, 2413 }, { 2414 /* end node */ 2415 } 2416 }; 2417 2418 #ifdef CONFIG_OF 2419 static struct of_device_id hdmi_match_types[] = { 2420 { 2421 .compatible = "samsung,exynos5-hdmi", 2422 .data = (void *)HDMI_TYPE14, 2423 }, { 2424 /* end node */ 2425 } 2426 }; 2427 #endif 2428 2429 static int hdmi_probe(struct platform_device *pdev) 2430 { 2431 struct device *dev = &pdev->dev; 2432 struct exynos_drm_hdmi_context *drm_hdmi_ctx; 2433 struct hdmi_context *hdata; 2434 struct s5p_hdmi_platform_data *pdata; 2435 struct resource *res; 2436 int ret; 2437 2438 DRM_DEBUG_KMS("[%d]\n", __LINE__); 2439 2440 if (pdev->dev.of_node) { 2441 pdata = drm_hdmi_dt_parse_pdata(dev); 2442 if (IS_ERR(pdata)) { 2443 DRM_ERROR("failed to parse dt\n"); 2444 return PTR_ERR(pdata); 2445 } 2446 } else { 2447 pdata = pdev->dev.platform_data; 2448 } 2449 2450 if (!pdata) { 2451 DRM_ERROR("no platform data specified\n"); 2452 return -EINVAL; 2453 } 2454 2455 drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx), 2456 GFP_KERNEL); 2457 if (!drm_hdmi_ctx) { 2458 DRM_ERROR("failed to allocate common hdmi context.\n"); 2459 return -ENOMEM; 2460 } 2461 2462 hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context), 2463 GFP_KERNEL); 2464 if (!hdata) { 2465 DRM_ERROR("out of memory\n"); 2466 return -ENOMEM; 2467 } 2468 2469 mutex_init(&hdata->hdmi_mutex); 2470 2471 drm_hdmi_ctx->ctx = (void *)hdata; 2472 hdata->parent_ctx = (void *)drm_hdmi_ctx; 2473 2474 platform_set_drvdata(pdev, drm_hdmi_ctx); 2475 2476 if (dev->of_node) { 2477 const struct of_device_id *match; 2478 match = of_match_node(of_match_ptr(hdmi_match_types), 2479 pdev->dev.of_node); 2480 if (match == NULL) 2481 return -ENODEV; 2482 hdata->type = (enum hdmi_type)match->data; 2483 } else { 2484 hdata->type = (enum hdmi_type)platform_get_device_id 2485 (pdev)->driver_data; 2486 } 2487 2488 hdata->hpd_gpio = pdata->hpd_gpio; 2489 hdata->dev = dev; 2490 2491 ret = hdmi_resources_init(hdata); 2492 2493 if (ret) { 2494 DRM_ERROR("hdmi_resources_init failed\n"); 2495 return -EINVAL; 2496 } 2497 2498 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2499 if (!res) { 2500 DRM_ERROR("failed to find registers\n"); 2501 return -ENOENT; 2502 } 2503 2504 hdata->regs = devm_request_and_ioremap(&pdev->dev, res); 2505 if (!hdata->regs) { 2506 DRM_ERROR("failed to map registers\n"); 2507 return -ENXIO; 2508 } 2509 2510 ret = devm_gpio_request(&pdev->dev, hdata->hpd_gpio, "HPD"); 2511 if (ret) { 2512 DRM_ERROR("failed to request HPD gpio\n"); 2513 return ret; 2514 } 2515 2516 /* DDC i2c driver */ 2517 if (i2c_add_driver(&ddc_driver)) { 2518 DRM_ERROR("failed to register ddc i2c driver\n"); 2519 return -ENOENT; 2520 } 2521 2522 hdata->ddc_port = hdmi_ddc; 2523 2524 /* hdmiphy i2c driver */ 2525 if (i2c_add_driver(&hdmiphy_driver)) { 2526 DRM_ERROR("failed to register hdmiphy i2c driver\n"); 2527 ret = -ENOENT; 2528 goto err_ddc; 2529 } 2530 2531 hdata->hdmiphy_port = hdmi_hdmiphy; 2532 2533 hdata->irq = gpio_to_irq(hdata->hpd_gpio); 2534 if (hdata->irq < 0) { 2535 DRM_ERROR("failed to get GPIO irq\n"); 2536 ret = hdata->irq; 2537 goto err_hdmiphy; 2538 } 2539 2540 hdata->hpd = gpio_get_value(hdata->hpd_gpio); 2541 2542 ret = request_threaded_irq(hdata->irq, NULL, 2543 hdmi_irq_thread, IRQF_TRIGGER_RISING | 2544 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2545 "hdmi", drm_hdmi_ctx); 2546 if (ret) { 2547 DRM_ERROR("failed to register hdmi interrupt\n"); 2548 goto err_hdmiphy; 2549 } 2550 2551 /* Attach HDMI Driver to common hdmi. */ 2552 exynos_hdmi_drv_attach(drm_hdmi_ctx); 2553 2554 /* register specific callbacks to common hdmi. */ 2555 exynos_hdmi_ops_register(&hdmi_ops); 2556 2557 pm_runtime_enable(dev); 2558 2559 return 0; 2560 2561 err_hdmiphy: 2562 i2c_del_driver(&hdmiphy_driver); 2563 err_ddc: 2564 i2c_del_driver(&ddc_driver); 2565 return ret; 2566 } 2567 2568 static int hdmi_remove(struct platform_device *pdev) 2569 { 2570 struct device *dev = &pdev->dev; 2571 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); 2572 struct hdmi_context *hdata = ctx->ctx; 2573 2574 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2575 2576 pm_runtime_disable(dev); 2577 2578 free_irq(hdata->irq, hdata); 2579 2580 2581 /* hdmiphy i2c driver */ 2582 i2c_del_driver(&hdmiphy_driver); 2583 /* DDC i2c driver */ 2584 i2c_del_driver(&ddc_driver); 2585 2586 return 0; 2587 } 2588 2589 #ifdef CONFIG_PM_SLEEP 2590 static int hdmi_suspend(struct device *dev) 2591 { 2592 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2593 struct hdmi_context *hdata = ctx->ctx; 2594 2595 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2596 2597 disable_irq(hdata->irq); 2598 2599 hdata->hpd = false; 2600 if (ctx->drm_dev) 2601 drm_helper_hpd_irq_event(ctx->drm_dev); 2602 2603 if (pm_runtime_suspended(dev)) { 2604 DRM_DEBUG_KMS("%s : Already suspended\n", __func__); 2605 return 0; 2606 } 2607 2608 hdmi_poweroff(hdata); 2609 2610 return 0; 2611 } 2612 2613 static int hdmi_resume(struct device *dev) 2614 { 2615 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2616 struct hdmi_context *hdata = ctx->ctx; 2617 2618 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2619 2620 hdata->hpd = gpio_get_value(hdata->hpd_gpio); 2621 2622 enable_irq(hdata->irq); 2623 2624 if (!pm_runtime_suspended(dev)) { 2625 DRM_DEBUG_KMS("%s : Already resumed\n", __func__); 2626 return 0; 2627 } 2628 2629 hdmi_poweron(hdata); 2630 2631 return 0; 2632 } 2633 #endif 2634 2635 #ifdef CONFIG_PM_RUNTIME 2636 static int hdmi_runtime_suspend(struct device *dev) 2637 { 2638 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2639 struct hdmi_context *hdata = ctx->ctx; 2640 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2641 2642 hdmi_poweroff(hdata); 2643 2644 return 0; 2645 } 2646 2647 static int hdmi_runtime_resume(struct device *dev) 2648 { 2649 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2650 struct hdmi_context *hdata = ctx->ctx; 2651 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2652 2653 hdmi_poweron(hdata); 2654 2655 return 0; 2656 } 2657 #endif 2658 2659 static const struct dev_pm_ops hdmi_pm_ops = { 2660 SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume) 2661 SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL) 2662 }; 2663 2664 struct platform_driver hdmi_driver = { 2665 .probe = hdmi_probe, 2666 .remove = hdmi_remove, 2667 .id_table = hdmi_driver_types, 2668 .driver = { 2669 .name = "exynos-hdmi", 2670 .owner = THIS_MODULE, 2671 .pm = &hdmi_pm_ops, 2672 .of_match_table = of_match_ptr(hdmi_match_types), 2673 }, 2674 }; 2675