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