aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_hdmi.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/video/sh_mobile_hdmi.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/video/sh_mobile_hdmi.c')
-rw-r--r--drivers/video/sh_mobile_hdmi.c849
1 files changed, 613 insertions, 236 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 2fde08cc66bf..7d54e2c612f7 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -22,10 +22,15 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
25 28
26#include <video/sh_mobile_hdmi.h> 29#include <video/sh_mobile_hdmi.h>
27#include <video/sh_mobile_lcdc.h> 30#include <video/sh_mobile_lcdc.h>
28 31
32#include "sh_mobile_lcdcfb.h"
33
29#define HDMI_SYSTEM_CTRL 0x00 /* System control */ 34#define HDMI_SYSTEM_CTRL 0x00 /* System control */
30#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control, 35#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control,
31 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */ 36 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
@@ -204,12 +209,20 @@ enum hotplug_state {
204 209
205struct sh_hdmi { 210struct sh_hdmi {
206 void __iomem *base; 211 void __iomem *base;
207 enum hotplug_state hp_state; 212 enum hotplug_state hp_state; /* hot-plug status */
213 u8 preprogrammed_vic; /* use a pre-programmed VIC or
214 the external mode */
215 u8 edid_block_addr;
216 u8 edid_segment_nr;
217 u8 edid_blocks;
208 struct clk *hdmi_clk; 218 struct clk *hdmi_clk;
209 struct device *dev; 219 struct device *dev;
210 struct fb_info *info; 220 struct fb_info *info;
221 struct mutex mutex; /* Protect the info pointer */
211 struct delayed_work edid_work; 222 struct delayed_work edid_work;
212 struct fb_var_screeninfo var; 223 struct fb_var_screeninfo var;
224 struct fb_monspecs monspec;
225 struct notifier_block notifier;
213}; 226};
214 227
215static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) 228static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -222,8 +235,60 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
222 return ioread8(hdmi->base + reg); 235 return ioread8(hdmi->base + reg);
223} 236}
224 237
238/*
239 * HDMI sound
240 */
241static unsigned int sh_hdmi_snd_read(struct snd_soc_codec *codec,
242 unsigned int reg)
243{
244 struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
245
246 return hdmi_read(hdmi, reg);
247}
248
249static int sh_hdmi_snd_write(struct snd_soc_codec *codec,
250 unsigned int reg,
251 unsigned int value)
252{
253 struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
254
255 hdmi_write(hdmi, value, reg);
256 return 0;
257}
258
259static struct snd_soc_dai_driver sh_hdmi_dai = {
260 .name = "sh_mobile_hdmi-hifi",
261 .playback = {
262 .stream_name = "Playback",
263 .channels_min = 2,
264 .channels_max = 8,
265 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
266 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
267 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
268 SNDRV_PCM_RATE_192000,
269 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
270 },
271};
272
273static int sh_hdmi_snd_probe(struct snd_soc_codec *codec)
274{
275 dev_info(codec->dev, "SH Mobile HDMI Audio Codec");
276
277 return 0;
278}
279
280static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
281 .probe = sh_hdmi_snd_probe,
282 .read = sh_hdmi_snd_read,
283 .write = sh_hdmi_snd_write,
284};
285
286/*
287 * HDMI video
288 */
289
225/* External video parameter settings */ 290/* External video parameter settings */
226static void hdmi_external_video_param(struct sh_hdmi *hdmi) 291static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi)
227{ 292{
228 struct fb_var_screeninfo *var = &hdmi->var; 293 struct fb_var_screeninfo *var = &hdmi->var;
229 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; 294 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
@@ -255,9 +320,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
255 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 320 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
256 sync |= 8; 321 sync |= 8;
257 322
258 pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", 323 dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
259 htotal, hblank, hdelay, var->hsync_len, 324 htotal, hblank, hdelay, var->hsync_len,
260 vtotal, vblank, vdelay, var->vsync_len, sync); 325 vtotal, vblank, vdelay, var->vsync_len, sync);
261 326
262 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); 327 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
263 328
@@ -282,7 +347,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
282 347
283 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); 348 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
284 349
285 /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */ 350 /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
351 if (!hdmi->preprogrammed_vic)
352 hdmi_write(hdmi, sync | 1 | (voffset << 4),
353 HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
286} 354}
287 355
288/** 356/**
@@ -318,6 +386,9 @@ static void sh_hdmi_video_config(struct sh_hdmi *hdmi)
318 */ 386 */
319static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) 387static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
320{ 388{
389 u8 data;
390 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
391
321 /* 392 /*
322 * [7:4] L/R data swap control 393 * [7:4] L/R data swap control
323 * [3:0] appropriate N[19:16] 394 * [3:0] appropriate N[19:16]
@@ -335,7 +406,23 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
335 * [6:5] set required down sampling rate if required 406 * [6:5] set required down sampling rate if required
336 * [4:3] set required audio source 407 * [4:3] set required audio source
337 */ 408 */
338 hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1); 409 switch (pdata->flags & HDMI_SND_SRC_MASK) {
410 default:
411 /* fall through */
412 case HDMI_SND_SRC_I2S:
413 data = 0x0 << 3;
414 break;
415 case HDMI_SND_SRC_SPDIF:
416 data = 0x1 << 3;
417 break;
418 case HDMI_SND_SRC_DSD:
419 data = 0x2 << 3;
420 break;
421 case HDMI_SND_SRC_HBR:
422 data = 0x3 << 3;
423 break;
424 }
425 hdmi_write(hdmi, data, HDMI_AUDIO_SETTING_1);
339 426
340 /* [3:0] set sending channel number for channel status */ 427 /* [3:0] set sending channel number for channel status */
341 hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2); 428 hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2);
@@ -381,21 +468,72 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
381} 468}
382 469
383/** 470/**
384 * sh_hdmi_phy_config() 471 * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode
385 */ 472 */
386static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) 473static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
387{ 474{
388 /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ 475 if (hdmi->var.pixclock < 10000) {
389 hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); 476 /* for 1080p8bit 148MHz */
390 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); 477 hdmi_write(hdmi, 0x1d, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
391 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); 478 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
392 /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ 479 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
393 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); 480 hdmi_write(hdmi, 0x4c, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
394 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); 481 hdmi_write(hdmi, 0x1e, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
395 hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); 482 hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
396 hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); 483 hdmi_write(hdmi, 0x0e, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
397 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); 484 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
398 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); 485 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
486 } else if (hdmi->var.pixclock < 30000) {
487 /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
488 /*
489 * [1:0] Speed_A
490 * [3:2] Speed_B
491 * [4] PLLA_Bypass
492 * [6] DRV_TEST_EN
493 * [7] DRV_TEST_IN
494 */
495 hdmi_write(hdmi, 0x0f, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
496 /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */
497 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
498 /*
499 * [2:0] BGR_I_OFFSET
500 * [6:4] BGR_V_OFFSET
501 */
502 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
503 /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
504 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
505 /*
506 * PLLA_CONFIG[15:8]: regulator voltage[0], CP current,
507 * LPF capacitance, LPF resistance[1]
508 */
509 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
510 /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */
511 hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
512 /*
513 * PLLB_CONFIG[15:8]: regulator voltage[0], CP current,
514 * LPF capacitance, LPF resistance[1]
515 */
516 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
517 /* DRV_CONFIG, PE_CONFIG */
518 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
519 /*
520 * [2:0] AMON_SEL (4 == LPF voltage)
521 * [4] PLLA_CONFIG[16]
522 * [5] PLLB_CONFIG[16]
523 */
524 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
525 } else {
526 /* for 480p8bit 27MHz */
527 hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
528 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
529 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
530 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
531 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
532 hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
533 hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
534 hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
535 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
536 }
399} 537}
400 538
401/** 539/**
@@ -403,6 +541,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
403 */ 541 */
404static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) 542static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
405{ 543{
544 u8 vic;
545
406 /* AVI InfoFrame */ 546 /* AVI InfoFrame */
407 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX); 547 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX);
408 548
@@ -427,9 +567,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
427 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1); 567 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
428 568
429 /* 569 /*
430 * C = No Data 570 * [7:6] C = Colorimetry: no data
431 * M = 16:9 Picture Aspect Ratio 571 * [5:4] M = 2: 16:9, 1: 4:3 Picture Aspect Ratio
432 * R = Same as picture aspect ratio 572 * [3:0] R = 8: Active Frame Aspect Ratio: same as picture aspect ratio
433 */ 573 */
434 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2); 574 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
435 575
@@ -442,10 +582,14 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
442 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3); 582 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3);
443 583
444 /* 584 /*
445 * VIC = 1280 x 720p: ignored if external config is used 585 * VIC should be ignored if external config is used, so, we could just use 0,
446 * Send 2 for 720 x 480p, 16 for 1080p 586 * but play safe and use a valid value in any case just in case
447 */ 587 */
448 hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4); 588 if (hdmi->preprogrammed_vic)
589 vic = hdmi->preprogrammed_vic;
590 else
591 vic = 4;
592 hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
449 593
450 /* PR = No Repetition */ 594 /* PR = No Repetition */
451 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); 595 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
@@ -519,100 +663,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
519} 663}
520 664
521/** 665/**
522 * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
523 */
524static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi)
525{
526 int i;
527
528 /* Gamut Metadata Packet */
529 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX);
530
531 /* Packet Type = 0x0A */
532 hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
533 /* Gamut Packet is not used, so default value */
534 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
535 /* Gamut Packet is not used, so default value */
536 hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
537
538 /* GBD bytes 0 through 27 */
539 for (i = 0; i <= 27; i++)
540 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
541 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
542}
543
544/**
545 * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
546 */
547static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi)
548{
549 int i;
550
551 /* Audio Content Protection Packet (ACP) */
552 hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX);
553
554 /* Packet Type = 0x04 */
555 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
556 /* ACP_Type */
557 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
558 /* Reserved (0) */
559 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
560
561 /* GBD bytes 0 through 27 */
562 for (i = 0; i <= 27; i++)
563 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
564 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
565}
566
567/**
568 * sh_hdmi_isrc1_setup() - ISRC1 Packet
569 */
570static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi)
571{
572 int i;
573
574 /* ISRC1 Packet */
575 hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX);
576
577 /* Packet Type = 0x05 */
578 hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
579 /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
580 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
581 /* Reserved (0) */
582 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
583
584 /* PB0 UPC_EAN_ISRC_0-15 */
585 /* Bytes PB16-PB27 shall be set to a value of 0. */
586 for (i = 0; i <= 27; i++)
587 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
588 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
589}
590
591/**
592 * sh_hdmi_isrc2_setup() - ISRC2 Packet
593 */
594static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi)
595{
596 int i;
597
598 /* ISRC2 Packet */
599 hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX);
600
601 /* HB0 Packet Type = 0x06 */
602 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
603 /* Reserved (0) */
604 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
605 /* Reserved (0) */
606 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
607
608 /* PB0 UPC_EAN_ISRC_16-31 */
609 /* Bytes PB16-PB27 shall be set to a value of 0. */
610 for (i = 0; i <= 27; i++)
611 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
612 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
613}
614
615/**
616 * sh_hdmi_configure() - Initialise HDMI for output 666 * sh_hdmi_configure() - Initialise HDMI for output
617 */ 667 */
618static void sh_hdmi_configure(struct sh_hdmi *hdmi) 668static void sh_hdmi_configure(struct sh_hdmi *hdmi)
@@ -632,18 +682,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
632 /* Audio InfoFrame */ 682 /* Audio InfoFrame */
633 sh_hdmi_audio_infoframe_setup(hdmi); 683 sh_hdmi_audio_infoframe_setup(hdmi);
634 684
635 /* Gamut Metadata packet */
636 sh_hdmi_gamut_metadata_setup(hdmi);
637
638 /* Audio Content Protection (ACP) Packet */
639 sh_hdmi_acp_setup(hdmi);
640
641 /* ISRC1 Packet */
642 sh_hdmi_isrc1_setup(hdmi);
643
644 /* ISRC2 Packet */
645 sh_hdmi_isrc2_setup(hdmi);
646
647 /* 685 /*
648 * Control packet auto send with VSYNC control: auto send 686 * Control packet auto send with VSYNC control: auto send
649 * General control, Gamut metadata, ISRC, and ACP packets 687 * General control, Gamut metadata, ISRC, and ACP packets
@@ -661,17 +699,53 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
661 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL); 699 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
662} 700}
663 701
664static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) 702static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
703 const struct fb_videomode *mode,
704 unsigned long *hdmi_rate, unsigned long *parent_rate)
665{ 705{
666 struct fb_var_screeninfo *var = &hdmi->var; 706 unsigned long target = PICOS2KHZ(mode->pixclock) * 1000, rate_error;
667 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 707 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
668 struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg; 708
669 unsigned long height = var->height, width = var->width; 709 *hdmi_rate = clk_round_rate(hdmi->hdmi_clk, target);
670 int i; 710 if ((long)*hdmi_rate < 0)
711 *hdmi_rate = clk_get_rate(hdmi->hdmi_clk);
712
713 rate_error = (long)*hdmi_rate > 0 ? abs(*hdmi_rate - target) : ULONG_MAX;
714 if (rate_error && pdata->clk_optimize_parent)
715 rate_error = pdata->clk_optimize_parent(target, hdmi_rate, parent_rate);
716 else if (clk_get_parent(hdmi->hdmi_clk))
717 *parent_rate = clk_get_rate(clk_get_parent(hdmi->hdmi_clk));
718
719 dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n",
720 mode->left_margin, mode->xres,
721 mode->right_margin, mode->hsync_len,
722 mode->upper_margin, mode->yres,
723 mode->lower_margin, mode->vsync_len);
724
725 dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz, p=%luHz\n", target,
726 rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0,
727 mode->refresh, *parent_rate);
728
729 return rate_error;
730}
731
732static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
733 unsigned long *parent_rate)
734{
735 struct fb_var_screeninfo tmpvar;
736 struct fb_var_screeninfo *var = &tmpvar;
737 const struct fb_videomode *mode, *found = NULL;
738 struct fb_info *info = hdmi->info;
739 struct fb_modelist *modelist = NULL;
740 unsigned int f_width = 0, f_height = 0, f_refresh = 0;
741 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
742 bool scanning = false, preferred_bad = false;
671 u8 edid[128]; 743 u8 edid[128];
744 char *forced;
745 int i;
672 746
673 /* Read EDID */ 747 /* Read EDID */
674 pr_debug("Read back EDID code:"); 748 dev_dbg(hdmi->dev, "Read back EDID code:");
675 for (i = 0; i < 128; i++) { 749 for (i = 0; i < 128; i++) {
676 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); 750 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
677#ifdef DEBUG 751#ifdef DEBUG
@@ -686,29 +760,167 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
686#ifdef DEBUG 760#ifdef DEBUG
687 printk(KERN_CONT "\n"); 761 printk(KERN_CONT "\n");
688#endif 762#endif
689 fb_parse_edid(edid, var); 763
690 pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n", 764 if (!hdmi->edid_blocks) {
691 var->left_margin, var->xres, var->right_margin, var->hsync_len, 765 fb_edid_to_monspecs(edid, &hdmi->monspec);
692 var->upper_margin, var->yres, var->lower_margin, var->vsync_len, 766 hdmi->edid_blocks = edid[126] + 1;
693 PICOS2KHZ(var->pixclock)); 767
694 768 dev_dbg(hdmi->dev, "%d main modes, %d extension blocks\n",
695 /* FIXME: Use user-provided configuration instead of EDID */ 769 hdmi->monspec.modedb_len, hdmi->edid_blocks - 1);
696 var->width = width; 770 } else {
697 var->xres = lcd_cfg->xres; 771 dev_dbg(hdmi->dev, "Extension %u detected, DTD start %u\n",
698 var->xres_virtual = lcd_cfg->xres; 772 edid[0], edid[2]);
699 var->left_margin = lcd_cfg->left_margin; 773 fb_edid_add_monspecs(edid, &hdmi->monspec);
700 var->right_margin = lcd_cfg->right_margin; 774 }
701 var->hsync_len = lcd_cfg->hsync_len; 775
702 var->height = height; 776 if (hdmi->edid_blocks > hdmi->edid_segment_nr * 2 +
703 var->yres = lcd_cfg->yres; 777 (hdmi->edid_block_addr >> 7) + 1) {
704 var->yres_virtual = lcd_cfg->yres * 2; 778 /* More blocks to read */
705 var->upper_margin = lcd_cfg->upper_margin; 779 if (hdmi->edid_block_addr) {
706 var->lower_margin = lcd_cfg->lower_margin; 780 hdmi->edid_block_addr = 0;
707 var->vsync_len = lcd_cfg->vsync_len; 781 hdmi->edid_segment_nr++;
708 var->sync = lcd_cfg->sync; 782 } else {
709 var->pixclock = lcd_cfg->pixclock; 783 hdmi->edid_block_addr = 0x80;
710 784 }
711 hdmi_external_video_param(hdmi); 785 /* Set EDID word address */
786 hdmi_write(hdmi, hdmi->edid_block_addr, HDMI_EDID_WORD_ADDRESS);
787 /* Enable EDID interrupt */
788 hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1);
789 /* Set EDID segment pointer - starts reading EDID */
790 hdmi_write(hdmi, hdmi->edid_segment_nr, HDMI_EDID_SEGMENT_POINTER);
791 return -EAGAIN;
792 }
793
794 /* All E-EDID blocks ready */
795 dev_dbg(hdmi->dev, "%d main and extended modes\n", hdmi->monspec.modedb_len);
796
797 fb_get_options("sh_mobile_lcdc", &forced);
798 if (forced && *forced) {
799 /* Only primitive parsing so far */
800 i = sscanf(forced, "%ux%u@%u",
801 &f_width, &f_height, &f_refresh);
802 if (i < 2) {
803 f_width = 0;
804 f_height = 0;
805 } else {
806 /* The user wants us to use the EDID data */
807 scanning = true;
808 }
809 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
810 f_width, f_height, f_refresh);
811 }
812
813 /* Walk monitor modes to find the best or the exact match */
814 for (i = 0, mode = hdmi->monspec.modedb;
815 i < hdmi->monspec.modedb_len && scanning;
816 i++, mode++) {
817 unsigned long rate_error;
818
819 if (!f_width && !f_height) {
820 /*
821 * A parameter string "video=sh_mobile_lcdc:0x0" means
822 * use the preferred EDID mode. If it is rejected by
823 * .fb_check_var(), keep looking, until an acceptable
824 * one is found.
825 */
826 if ((mode->flag & FB_MODE_IS_FIRST) || preferred_bad)
827 scanning = false;
828 else
829 continue;
830 } else if (f_width != mode->xres || f_height != mode->yres) {
831 /* No interest in unmatching modes */
832 continue;
833 }
834
835 rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate);
836
837 if (scanning) {
838 if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
839 /*
840 * Exact match if either the refresh rate
841 * matches or it hasn't been specified and we've
842 * found a mode, for which we can configure the
843 * clock precisely
844 */
845 scanning = false;
846 else if (found && found_rate_error <= rate_error)
847 /*
848 * We otherwise search for the closest matching
849 * clock rate - either if no refresh rate has
850 * been specified or we cannot find an exactly
851 * matching one
852 */
853 continue;
854 }
855
856 /* Check if supported: sufficient fb memory, supported clock-rate */
857 fb_videomode_to_var(var, mode);
858
859 var->bits_per_pixel = info->var.bits_per_pixel;
860
861 if (info && info->fbops->fb_check_var &&
862 info->fbops->fb_check_var(var, info)) {
863 scanning = true;
864 preferred_bad = true;
865 continue;
866 }
867
868 found = mode;
869 found_rate_error = rate_error;
870 }
871
872 hdmi->var.width = hdmi->monspec.max_x * 10;
873 hdmi->var.height = hdmi->monspec.max_y * 10;
874
875 /*
876 * TODO 1: if no ->info is present, postpone running the config until
877 * after ->info first gets registered.
878 * TODO 2: consider registering the HDMI platform device from the LCDC
879 * driver, and passing ->info with HDMI platform data.
880 */
881 if (info && !found) {
882 modelist = info->modelist.next &&
883 !list_empty(&info->modelist) ?
884 list_entry(info->modelist.next,
885 struct fb_modelist, list) :
886 NULL;
887
888 if (modelist) {
889 found = &modelist->mode;
890 found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate, parent_rate);
891 }
892 }
893
894 /* No cookie today */
895 if (!found)
896 return -ENXIO;
897
898 if (found->xres == 640 && found->yres == 480 && found->refresh == 60)
899 hdmi->preprogrammed_vic = 1;
900 else if (found->xres == 720 && found->yres == 480 && found->refresh == 60)
901 hdmi->preprogrammed_vic = 2;
902 else if (found->xres == 720 && found->yres == 576 && found->refresh == 50)
903 hdmi->preprogrammed_vic = 17;
904 else if (found->xres == 1280 && found->yres == 720 && found->refresh == 60)
905 hdmi->preprogrammed_vic = 4;
906 else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 24)
907 hdmi->preprogrammed_vic = 32;
908 else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 50)
909 hdmi->preprogrammed_vic = 31;
910 else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 60)
911 hdmi->preprogrammed_vic = 16;
912 else
913 hdmi->preprogrammed_vic = 0;
914
915 dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
916 modelist ? "default" : "EDID", hdmi->preprogrammed_vic ? "VIC" : "external",
917 found->xres, found->yres, found->refresh,
918 PICOS2KHZ(found->pixclock) * 1000, found_rate_error);
919
920 fb_videomode_to_var(&hdmi->var, found);
921 sh_hdmi_external_video_param(hdmi);
922
923 return 0;
712} 924}
713 925
714static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) 926static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
@@ -736,8 +948,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
736 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2); 948 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);
737 949
738 if (printk_ratelimit()) 950 if (printk_ratelimit())
739 pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n", 951 dev_dbg(hdmi->dev, "IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
740 irq, status1, mask1, status2, mask2); 952 irq, status1, mask1, status2, mask2);
741 953
742 if (!((status1 & mask1) | (status2 & mask2))) { 954 if (!((status1 & mask1) | (status2 & mask2))) {
743 return IRQ_NONE; 955 return IRQ_NONE;
@@ -748,136 +960,283 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
748 udelay(500); 960 udelay(500);
749 961
750 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS); 962 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
751 pr_debug("MSENS 0x%x\n", msens); 963 dev_dbg(hdmi->dev, "MSENS 0x%x\n", msens);
752 /* Check, if hot plug & MSENS pin status are both high */ 964 /* Check, if hot plug & MSENS pin status are both high */
753 if ((msens & 0xC0) == 0xC0) { 965 if ((msens & 0xC0) == 0xC0) {
754 /* Display plug in */ 966 /* Display plug in */
967 hdmi->edid_segment_nr = 0;
968 hdmi->edid_block_addr = 0;
969 hdmi->edid_blocks = 0;
755 hdmi->hp_state = HDMI_HOTPLUG_CONNECTED; 970 hdmi->hp_state = HDMI_HOTPLUG_CONNECTED;
756 971
757 /* Set EDID word address */ 972 /* Set EDID word address */
758 hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); 973 hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS);
759 /* Set EDID segment pointer */
760 hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
761 /* Enable EDID interrupt */ 974 /* Enable EDID interrupt */
762 hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1); 975 hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1);
976 /* Set EDID segment pointer - starts reading EDID */
977 hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
763 } else if (!(status1 & 0x80)) { 978 } else if (!(status1 & 0x80)) {
764 /* Display unplug, beware multiple interrupts */ 979 /* Display unplug, beware multiple interrupts */
765 if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED) 980 if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED) {
981 hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
766 schedule_delayed_work(&hdmi->edid_work, 0); 982 schedule_delayed_work(&hdmi->edid_work, 0);
767 983 }
768 hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
769 /* display_off will switch back to mode_a */ 984 /* display_off will switch back to mode_a */
770 } 985 }
771 } else if (status1 & 2) { 986 } else if (status1 & 2) {
772 /* EDID error interrupt: retry */ 987 /* EDID error interrupt: retry */
773 /* Set EDID word address */ 988 /* Set EDID word address */
774 hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); 989 hdmi_write(hdmi, hdmi->edid_block_addr, HDMI_EDID_WORD_ADDRESS);
775 /* Set EDID segment pointer */ 990 /* Set EDID segment pointer */
776 hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); 991 hdmi_write(hdmi, hdmi->edid_segment_nr, HDMI_EDID_SEGMENT_POINTER);
777 } else if (status1 & 4) { 992 } else if (status1 & 4) {
778 /* Disable EDID interrupt */ 993 /* Disable EDID interrupt */
779 hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1); 994 hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1);
780 hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
781 schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10)); 995 schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10));
782 } 996 }
783 997
784 return IRQ_HANDLED; 998 return IRQ_HANDLED;
785} 999}
786 1000
787static void hdmi_display_on(void *arg, struct fb_info *info) 1001/* locking: called with info->lock held, or before register_framebuffer() */
1002static void sh_hdmi_display_on(void *arg, struct fb_info *info)
788{ 1003{
1004 /*
1005 * info is guaranteed to be valid, when we are called, because our
1006 * FB_EVENT_FB_UNBIND notify is also called with info->lock held
1007 */
789 struct sh_hdmi *hdmi = arg; 1008 struct sh_hdmi *hdmi = arg;
790 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 1009 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
1010 struct sh_mobile_lcdc_chan *ch = info->par;
791 1011
792 if (info->var.xres != 1280 || info->var.yres != 720) { 1012 dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
793 dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n", 1013 pdata->lcd_dev, info->state);
794 info->var.xres, info->var.yres); 1014
795 return; 1015 /* No need to lock */
796 } 1016 hdmi->info = info;
797 1017
798 pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
799 /* 1018 /*
800 * FIXME: not a good place to store fb_info. And we cannot nullify it 1019 * hp_state can be set to
801 * even on monitor disconnect. What should the lifecycle be? 1020 * HDMI_HOTPLUG_DISCONNECTED: on monitor unplug
1021 * HDMI_HOTPLUG_CONNECTED: on monitor plug-in
1022 * HDMI_HOTPLUG_EDID_DONE: on EDID read completion
802 */ 1023 */
803 hdmi->info = info;
804 switch (hdmi->hp_state) { 1024 switch (hdmi->hp_state) {
805 case HDMI_HOTPLUG_EDID_DONE: 1025 case HDMI_HOTPLUG_EDID_DONE:
806 /* PS mode d->e. All functions are active */ 1026 /* PS mode d->e. All functions are active */
807 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); 1027 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
808 pr_debug("HDMI running\n"); 1028 dev_dbg(hdmi->dev, "HDMI running\n");
809 break; 1029 break;
810 case HDMI_HOTPLUG_DISCONNECTED: 1030 case HDMI_HOTPLUG_DISCONNECTED:
811 info->state = FBINFO_STATE_SUSPENDED; 1031 info->state = FBINFO_STATE_SUSPENDED;
812 default: 1032 default:
813 hdmi->var = info->var; 1033 hdmi->var = ch->display_var;
814 } 1034 }
815} 1035}
816 1036
817static void hdmi_display_off(void *arg) 1037/* locking: called with info->lock held */
1038static void sh_hdmi_display_off(void *arg)
818{ 1039{
819 struct sh_hdmi *hdmi = arg; 1040 struct sh_hdmi *hdmi = arg;
820 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 1041 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
821 1042
822 pr_debug("%s(%p)\n", __func__, pdata->lcd_dev); 1043 dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
823 /* PS mode e->a */ 1044 /* PS mode e->a */
824 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); 1045 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
825} 1046}
826 1047
1048static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
1049{
1050 struct fb_info *info = hdmi->info;
1051 struct sh_mobile_lcdc_chan *ch = info->par;
1052 struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
1053 struct fb_videomode mode1, mode2;
1054
1055 fb_var_to_videomode(&mode1, old_var);
1056 fb_var_to_videomode(&mode2, new_var);
1057
1058 dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
1059 mode1.xres, mode1.yres, mode2.xres, mode2.yres);
1060
1061 if (fb_mode_is_equal(&mode1, &mode2)) {
1062 /* It can be a different monitor with an equal video-mode */
1063 old_var->width = new_var->width;
1064 old_var->height = new_var->height;
1065 return false;
1066 }
1067
1068 dev_dbg(info->dev, "Switching %u -> %u lines\n",
1069 mode1.yres, mode2.yres);
1070 *old_var = *new_var;
1071
1072 return true;
1073}
1074
1075/**
1076 * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
1077 * @hdmi: driver context
1078 * @hdmi_rate: HDMI clock frequency in Hz
1079 * @parent_rate: if != 0 - set parent clock rate for optimal precision
1080 * return: configured positive rate if successful
1081 * 0 if couldn't set the rate, but managed to enable the
1082 * clock, negative error, if couldn't enable the clock
1083 */
1084static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
1085 unsigned long parent_rate)
1086{
1087 int ret;
1088
1089 if (parent_rate && clk_get_parent(hdmi->hdmi_clk)) {
1090 ret = clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate);
1091 if (ret < 0) {
1092 dev_warn(hdmi->dev, "Cannot set parent rate %ld: %d\n", parent_rate, ret);
1093 hdmi_rate = clk_round_rate(hdmi->hdmi_clk, hdmi_rate);
1094 } else {
1095 dev_dbg(hdmi->dev, "HDMI set parent frequency %lu\n", parent_rate);
1096 }
1097 }
1098
1099 ret = clk_set_rate(hdmi->hdmi_clk, hdmi_rate);
1100 if (ret < 0) {
1101 dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", hdmi_rate, ret);
1102 hdmi_rate = 0;
1103 } else {
1104 dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", hdmi_rate);
1105 }
1106
1107 return hdmi_rate;
1108}
1109
827/* Hotplug interrupt occurred, read EDID */ 1110/* Hotplug interrupt occurred, read EDID */
828static void edid_work_fn(struct work_struct *work) 1111static void sh_hdmi_edid_work_fn(struct work_struct *work)
829{ 1112{
830 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work); 1113 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
831 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 1114 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
1115 struct sh_mobile_lcdc_chan *ch;
1116 int ret;
832 1117
833 pr_debug("%s(%p): begin, hotplug status %d\n", __func__, 1118 dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
834 pdata->lcd_dev, hdmi->hp_state); 1119 pdata->lcd_dev, hdmi->hp_state);
835 1120
836 if (!pdata->lcd_dev) 1121 if (!pdata->lcd_dev)
837 return; 1122 return;
838 1123
839 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { 1124 mutex_lock(&hdmi->mutex);
840 pm_runtime_get_sync(hdmi->dev); 1125
841 /* A device has been plugged in */ 1126 if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) {
842 sh_hdmi_read_edid(hdmi); 1127 struct fb_info *info = hdmi->info;
1128 unsigned long parent_rate = 0, hdmi_rate;
1129
1130 ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
1131 if (ret < 0)
1132 goto out;
1133
1134 hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
1135
1136 /* Reconfigure the clock */
1137 ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
1138 if (ret < 0)
1139 goto out;
1140
843 msleep(10); 1141 msleep(10);
844 sh_hdmi_configure(hdmi); 1142 sh_hdmi_configure(hdmi);
845 /* Switched to another (d) power-save mode */ 1143 /* Switched to another (d) power-save mode */
846 msleep(10); 1144 msleep(10);
847 1145
848 if (!hdmi->info) 1146 if (!info)
849 return; 1147 goto out;
1148
1149 ch = info->par;
850 1150
851 acquire_console_sem(); 1151 console_lock();
852 1152
853 /* HDMI plug in */ 1153 /* HDMI plug in */
854 hdmi->info->var = hdmi->var; 1154 if (!sh_hdmi_must_reconfigure(hdmi) &&
855 if (hdmi->info->state != FBINFO_STATE_RUNNING) 1155 info->state == FBINFO_STATE_RUNNING) {
856 fb_set_suspend(hdmi->info, 0); 1156 /*
857 else 1157 * First activation with the default monitor - just turn
858 hdmi_display_on(hdmi, hdmi->info); 1158 * on, if we run a resume here, the logo disappears
1159 */
1160 if (lock_fb_info(info)) {
1161 info->var.width = hdmi->var.width;
1162 info->var.height = hdmi->var.height;
1163 sh_hdmi_display_on(hdmi, info);
1164 unlock_fb_info(info);
1165 }
1166 } else {
1167 /* New monitor or have to wake up */
1168 fb_set_suspend(info, 0);
1169 }
859 1170
860 release_console_sem(); 1171 console_unlock();
861 } else { 1172 } else {
1173 ret = 0;
862 if (!hdmi->info) 1174 if (!hdmi->info)
863 return; 1175 goto out;
1176
1177 hdmi->monspec.modedb_len = 0;
1178 fb_destroy_modedb(hdmi->monspec.modedb);
1179 hdmi->monspec.modedb = NULL;
864 1180
865 acquire_console_sem(); 1181 console_lock();
866 1182
867 /* HDMI disconnect */ 1183 /* HDMI disconnect */
868 fb_set_suspend(hdmi->info, 1); 1184 fb_set_suspend(hdmi->info, 1);
869 1185
870 release_console_sem(); 1186 console_unlock();
871 pm_runtime_put(hdmi->dev);
872 } 1187 }
873 1188
874 pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev); 1189out:
1190 if (ret < 0 && ret != -EAGAIN)
1191 hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
1192 mutex_unlock(&hdmi->mutex);
1193
1194 dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
1195}
1196
1197static int sh_hdmi_notify(struct notifier_block *nb,
1198 unsigned long action, void *data)
1199{
1200 struct fb_event *event = data;
1201 struct fb_info *info = event->info;
1202 struct sh_mobile_lcdc_chan *ch = info->par;
1203 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1204 struct sh_hdmi *hdmi = board_cfg->board_data;
1205
1206 if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
1207 return NOTIFY_DONE;
1208
1209 switch(action) {
1210 case FB_EVENT_FB_REGISTERED:
1211 /* Unneeded, activation taken care by sh_hdmi_display_on() */
1212 break;
1213 case FB_EVENT_FB_UNREGISTERED:
1214 /*
1215 * We are called from unregister_framebuffer() with the
1216 * info->lock held. This is bad for us, because we can race with
1217 * the scheduled work, which has to call fb_set_suspend(), which
1218 * takes info->lock internally, so, sh_hdmi_edid_work_fn()
1219 * cannot take and hold info->lock for the whole function
1220 * duration. Using an additional lock creates a classical AB-BA
1221 * lock up. Therefore, we have to release the info->lock
1222 * temporarily, synchronise with the work queue and re-acquire
1223 * the info->lock.
1224 */
1225 unlock_fb_info(info);
1226 mutex_lock(&hdmi->mutex);
1227 hdmi->info = NULL;
1228 mutex_unlock(&hdmi->mutex);
1229 lock_fb_info(info);
1230 return NOTIFY_OK;
1231 }
1232 return NOTIFY_DONE;
875} 1233}
876 1234
877static int __init sh_hdmi_probe(struct platform_device *pdev) 1235static int __init sh_hdmi_probe(struct platform_device *pdev)
878{ 1236{
879 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1237 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
880 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1238 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1239 struct sh_mobile_lcdc_board_cfg *board_cfg;
881 int irq = platform_get_irq(pdev, 0), ret; 1240 int irq = platform_get_irq(pdev, 0), ret;
882 struct sh_hdmi *hdmi; 1241 struct sh_hdmi *hdmi;
883 long rate; 1242 long rate;
@@ -891,6 +1250,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
891 return -ENOMEM; 1250 return -ENOMEM;
892 } 1251 }
893 1252
1253 mutex_init(&hdmi->mutex);
1254
894 hdmi->dev = &pdev->dev; 1255 hdmi->dev = &pdev->dev;
895 1256
896 hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); 1257 hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
@@ -900,30 +1261,23 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
900 goto egetclk; 1261 goto egetclk;
901 } 1262 }
902 1263
903 rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000; 1264 /* An arbitrary relaxed pixclock just to get things started: from standard 480p */
1265 rate = clk_round_rate(hdmi->hdmi_clk, PICOS2KHZ(37037));
1266 if (rate > 0)
1267 rate = sh_hdmi_clk_configure(hdmi, rate, 0);
904 1268
905 rate = clk_round_rate(hdmi->hdmi_clk, rate);
906 if (rate < 0) { 1269 if (rate < 0) {
907 ret = rate; 1270 ret = rate;
908 dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
909 goto erate; 1271 goto erate;
910 } 1272 }
911 1273
912 ret = clk_set_rate(hdmi->hdmi_clk, rate);
913 if (ret < 0) {
914 dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
915 goto erate;
916 }
917
918 pr_debug("HDMI set frequency %lu\n", rate);
919
920 ret = clk_enable(hdmi->hdmi_clk); 1274 ret = clk_enable(hdmi->hdmi_clk);
921 if (ret < 0) { 1275 if (ret < 0) {
922 dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret); 1276 dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
923 goto eclkenable; 1277 goto erate;
924 } 1278 }
925 1279
926 dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); 1280 dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
927 1281
928 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { 1282 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
929 dev_err(&pdev->dev, "HDMI register region already claimed\n"); 1283 dev_err(&pdev->dev, "HDMI register region already claimed\n");
@@ -940,21 +1294,21 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
940 1294
941 platform_set_drvdata(pdev, hdmi); 1295 platform_set_drvdata(pdev, hdmi);
942 1296
943#if 1
944 /* Product and revision IDs are 0 in sh-mobile version */
945 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
946 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
947#endif
948
949 /* Set up LCDC callbacks */ 1297 /* Set up LCDC callbacks */
950 pdata->lcd_chan->board_cfg.board_data = hdmi; 1298 board_cfg = &pdata->lcd_chan->board_cfg;
951 pdata->lcd_chan->board_cfg.display_on = hdmi_display_on; 1299 board_cfg->owner = THIS_MODULE;
952 pdata->lcd_chan->board_cfg.display_off = hdmi_display_off; 1300 board_cfg->board_data = hdmi;
1301 board_cfg->display_on = sh_hdmi_display_on;
1302 board_cfg->display_off = sh_hdmi_display_off;
953 1303
954 INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn); 1304 INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
955 1305
956 pm_runtime_enable(&pdev->dev); 1306 pm_runtime_enable(&pdev->dev);
957 pm_runtime_resume(&pdev->dev); 1307 pm_runtime_get_sync(&pdev->dev);
1308
1309 /* Product and revision IDs are 0 in sh-mobile version */
1310 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
1311 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
958 1312
959 ret = request_irq(irq, sh_hdmi_hotplug, 0, 1313 ret = request_irq(irq, sh_hdmi_hotplug, 0,
960 dev_name(&pdev->dev), hdmi); 1314 dev_name(&pdev->dev), hdmi);
@@ -963,19 +1317,32 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
963 goto ereqirq; 1317 goto ereqirq;
964 } 1318 }
965 1319
1320 ret = snd_soc_register_codec(&pdev->dev,
1321 &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
1322 if (ret < 0) {
1323 dev_err(&pdev->dev, "codec registration failed\n");
1324 goto ecodec;
1325 }
1326
1327 hdmi->notifier.notifier_call = sh_hdmi_notify;
1328 fb_register_client(&hdmi->notifier);
1329
966 return 0; 1330 return 0;
967 1331
1332ecodec:
1333 free_irq(irq, hdmi);
968ereqirq: 1334ereqirq:
1335 pm_runtime_put(&pdev->dev);
969 pm_runtime_disable(&pdev->dev); 1336 pm_runtime_disable(&pdev->dev);
970 iounmap(hdmi->base); 1337 iounmap(hdmi->base);
971emap: 1338emap:
972 release_mem_region(res->start, resource_size(res)); 1339 release_mem_region(res->start, resource_size(res));
973ereqreg: 1340ereqreg:
974 clk_disable(hdmi->hdmi_clk); 1341 clk_disable(hdmi->hdmi_clk);
975eclkenable:
976erate: 1342erate:
977 clk_put(hdmi->hdmi_clk); 1343 clk_put(hdmi->hdmi_clk);
978egetclk: 1344egetclk:
1345 mutex_destroy(&hdmi->mutex);
979 kfree(hdmi); 1346 kfree(hdmi);
980 1347
981 return ret; 1348 return ret;
@@ -986,19 +1353,29 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
986 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1353 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
987 struct sh_hdmi *hdmi = platform_get_drvdata(pdev); 1354 struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
988 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1355 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1356 struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
989 int irq = platform_get_irq(pdev, 0); 1357 int irq = platform_get_irq(pdev, 0);
990 1358
991 pdata->lcd_chan->board_cfg.display_on = NULL; 1359 snd_soc_unregister_codec(&pdev->dev);
992 pdata->lcd_chan->board_cfg.display_off = NULL; 1360
993 pdata->lcd_chan->board_cfg.board_data = NULL; 1361 fb_unregister_client(&hdmi->notifier);
994 1362
1363 board_cfg->display_on = NULL;
1364 board_cfg->display_off = NULL;
1365 board_cfg->board_data = NULL;
1366 board_cfg->owner = NULL;
1367
1368 /* No new work will be scheduled, wait for running ISR */
995 free_irq(irq, hdmi); 1369 free_irq(irq, hdmi);
996 pm_runtime_disable(&pdev->dev); 1370 /* Wait for already scheduled work */
997 cancel_delayed_work_sync(&hdmi->edid_work); 1371 cancel_delayed_work_sync(&hdmi->edid_work);
1372 pm_runtime_put(&pdev->dev);
1373 pm_runtime_disable(&pdev->dev);
998 clk_disable(hdmi->hdmi_clk); 1374 clk_disable(hdmi->hdmi_clk);
999 clk_put(hdmi->hdmi_clk); 1375 clk_put(hdmi->hdmi_clk);
1000 iounmap(hdmi->base); 1376 iounmap(hdmi->base);
1001 release_mem_region(res->start, resource_size(res)); 1377 release_mem_region(res->start, resource_size(res));
1378 mutex_destroy(&hdmi->mutex);
1002 kfree(hdmi); 1379 kfree(hdmi);
1003 1380
1004 return 0; 1381 return 0;