blob: a449fc72b4fa5c9006251f044b8ff090a49a4408 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14/* #define DEBUG */
15#define DEV_DBG_PREFIX "HDMI: "
16/* #define REG_DUMP */
17
Manoj Raoa2c27672011-08-30 17:19:39 -070018#define CEC_MSG_PRINT
Manoj Rao0f0ab642011-11-01 12:28:24 -070019#define TOGGLE_CEC_HARDWARE_FSM
Manoj Raoa2c27672011-08-30 17:19:39 -070020
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <linux/types.h>
22#include <linux/bitops.h>
23#include <linux/clk.h>
24#include <linux/mutex.h>
25#include <mach/msm_hdmi_audio.h>
26#include <mach/clk.h>
27#include <mach/msm_iomap.h>
Stepan Moskovchenko164fe8a2011-08-05 18:10:54 -070028#include <mach/socinfo.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029
30#include "msm_fb.h"
31#include "hdmi_msm.h"
32
33/* Supported HDMI Audio channels */
34#define MSM_HDMI_AUDIO_CHANNEL_2 0
35#define MSM_HDMI_AUDIO_CHANNEL_4 1
36#define MSM_HDMI_AUDIO_CHANNEL_6 2
37#define MSM_HDMI_AUDIO_CHANNEL_8 3
38#define MSM_HDMI_AUDIO_CHANNEL_MAX 4
39#define MSM_HDMI_AUDIO_CHANNEL_FORCE_32BIT 0x7FFFFFFF
40
41/* Supported HDMI Audio sample rates */
42#define MSM_HDMI_SAMPLE_RATE_32KHZ 0
43#define MSM_HDMI_SAMPLE_RATE_44_1KHZ 1
44#define MSM_HDMI_SAMPLE_RATE_48KHZ 2
45#define MSM_HDMI_SAMPLE_RATE_88_2KHZ 3
46#define MSM_HDMI_SAMPLE_RATE_96KHZ 4
47#define MSM_HDMI_SAMPLE_RATE_176_4KHZ 5
48#define MSM_HDMI_SAMPLE_RATE_192KHZ 6
49#define MSM_HDMI_SAMPLE_RATE_MAX 7
50#define MSM_HDMI_SAMPLE_RATE_FORCE_32BIT 0x7FFFFFFF
51
Ajay Singh Parmar0fc5d362011-11-16 05:48:33 +053052static int msm_hdmi_sample_rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
53
Aravind Venkateswarand2fb0bd2011-11-30 18:38:14 -080054/* HDMI/HDCP Registers */
55#define HDCP_DDC_STATUS 0x0128
56#define HDCP_DDC_CTRL_0 0x0120
57#define HDCP_DDC_CTRL_1 0x0124
58#define HDMI_DDC_CTRL 0x020C
59
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070060struct workqueue_struct *hdmi_work_queue;
61struct hdmi_msm_state_type *hdmi_msm_state;
62
Manoj Raoa2c27672011-08-30 17:19:39 -070063DEFINE_MUTEX(hdmi_msm_state_mutex);
64EXPORT_SYMBOL(hdmi_msm_state_mutex);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065static DEFINE_MUTEX(hdcp_auth_state_mutex);
66
67#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
68static void hdmi_msm_hdcp_enable(void);
69#else
70static inline void hdmi_msm_hdcp_enable(void) {}
71#endif
72
Manoj Raoa2c27672011-08-30 17:19:39 -070073static void hdmi_msm_turn_on(void);
74static int hdmi_msm_audio_off(void);
75static int hdmi_msm_read_edid(void);
76static void hdmi_msm_hpd_off(void);
77
78#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
79
Manoj Rao0f0ab642011-11-01 12:28:24 -070080#ifdef TOGGLE_CEC_HARDWARE_FSM
81static boolean msg_send_complete = TRUE;
82static boolean msg_recv_complete = TRUE;
83#endif
84
Manoj Raoa2c27672011-08-30 17:19:39 -070085#define HDMI_MSM_CEC_REFTIMER_REFTIMER_ENABLE BIT(16)
86#define HDMI_MSM_CEC_REFTIMER_REFTIMER(___t) (((___t)&0xFFFF) << 0)
87
88#define HDMI_MSM_CEC_TIME_SIGNAL_FREE_TIME(___t) (((___t)&0x1FF) << 7)
89#define HDMI_MSM_CEC_TIME_ENABLE BIT(0)
90
91#define HDMI_MSM_CEC_ADDR_LOGICAL_ADDR(___la) (((___la)&0xFF) << 0)
92
93#define HDMI_MSM_CEC_CTRL_LINE_OE BIT(9)
94#define HDMI_MSM_CEC_CTRL_FRAME_SIZE(___sz) (((___sz)&0x1F) << 4)
95#define HDMI_MSM_CEC_CTRL_SOFT_RESET BIT(2)
96#define HDMI_MSM_CEC_CTRL_SEND_TRIG BIT(1)
97#define HDMI_MSM_CEC_CTRL_ENABLE BIT(0)
98
99#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_MASK BIT(7)
100#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_ACK BIT(6)
101#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_INT BIT(6)
102#define HDMI_MSM_CEC_INT_MONITOR_MASK BIT(5)
103#define HDMI_MSM_CEC_INT_MONITOR_ACK BIT(4)
104#define HDMI_MSM_CEC_INT_MONITOR_INT BIT(4)
105#define HDMI_MSM_CEC_INT_FRAME_ERROR_MASK BIT(3)
106#define HDMI_MSM_CEC_INT_FRAME_ERROR_ACK BIT(2)
107#define HDMI_MSM_CEC_INT_FRAME_ERROR_INT BIT(2)
108#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK BIT(1)
109#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK BIT(0)
110#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT BIT(0)
111
112#define HDMI_MSM_CEC_FRAME_WR_SUCCESS(___st) (((___st)&0xF) ==\
Manoj Rao0f0ab642011-11-01 12:28:24 -0700113 (HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT |\
114 HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK |\
115 HDMI_MSM_CEC_INT_FRAME_ERROR_MASK))
Manoj Raoa2c27672011-08-30 17:19:39 -0700116
117#define HDMI_MSM_CEC_RETRANSMIT_NUM(___num) (((___num)&0xF) << 4)
118#define HDMI_MSM_CEC_RETRANSMIT_ENABLE BIT(0)
119
120#define HDMI_MSM_CEC_WR_DATA_DATA(___d) (((___d)&0xFF) << 8)
121
122
123void hdmi_msm_cec_init(void)
124{
125 /* 0x02A8 CEC_REFTIMER */
126 HDMI_OUTP(0x02A8,
127 HDMI_MSM_CEC_REFTIMER_REFTIMER_ENABLE
128 | HDMI_MSM_CEC_REFTIMER_REFTIMER(27 * 50)
129 );
130
131 /* 0x02A4 CEC_TIME */
132 HDMI_OUTP(0x02A4,
133 HDMI_MSM_CEC_TIME_SIGNAL_FREE_TIME(350)
134 | HDMI_MSM_CEC_TIME_ENABLE
135 );
136
137 /*
138 * 0x02A0 CEC_ADDR
139 * Starting with a default address of 4
140 */
141 HDMI_OUTP(0x02A0, HDMI_MSM_CEC_ADDR_LOGICAL_ADDR(4));
142
143 /* 0x028C CEC_CTRL */
144 HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
145
146 /* 0x029C CEC_INT */
147 /* Enable CEC interrupts */
148 HDMI_OUTP(0x029C, \
149 HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK \
150 | HDMI_MSM_CEC_INT_FRAME_ERROR_MASK \
151 | HDMI_MSM_CEC_INT_MONITOR_MASK \
152 | HDMI_MSM_CEC_INT_FRAME_RD_DONE_MASK);
153
154 HDMI_OUTP(0x02B0, 0x7FF << 4 | 1);
155
156 /*
157 * Slight adjustment to logic 1 low periods on read,
158 * CEC Test 8.2-3 was failing, 8 for the
159 * BIT_1_ERR_RANGE_HI = 8 => 750us, the test used 775us,
160 * so increased this to 9 which => 800us.
161 */
162 HDMI_OUTP(0x02E0, 0x889788);
163
164 /*
165 * Slight adjustment to logic 0 low period on write
166 */
167 HDMI_OUTP(0x02DC, 0x8888A888);
168
169 /*
170 * Enable Signal Free Time counter and set to 7 bit periods
171 */
172 HDMI_OUTP(0x02A4, 0x1 | (7 * 0x30) << 7);
173
174}
175
176void hdmi_msm_cec_write_logical_addr(int addr)
177{
178 /* 0x02A0 CEC_ADDR
179 * LOGICAL_ADDR 7:0 NUM
180 */
181 HDMI_OUTP(0x02A0, addr & 0xFF);
182}
183
184void hdmi_msm_dump_cec_msg(struct hdmi_msm_cec_msg *msg)
185{
186#ifdef CEC_MSG_PRINT
187 int i;
188 DEV_DBG("sender_id : %d", msg->sender_id);
189 DEV_DBG("recvr_id : %d", msg->recvr_id);
190 if (msg->frame_size < 2) {
191 DEV_DBG("polling message");
192 return;
193 }
194 DEV_DBG("opcode : %02x", msg->opcode);
195 for (i = 0; i < msg->frame_size - 2; i++)
196 DEV_DBG("operand(%2d) : %02x", i + 1, msg->operand[i]);
197#endif /* CEC_MSG_PRINT */
198}
199
200void hdmi_msm_cec_msg_send(struct hdmi_msm_cec_msg *msg)
201{
202 int i;
203 uint32 timeout_count = 1;
204 int retry = 10;
205
206 boolean frameType = (msg->recvr_id == 15 ? BIT(0) : 0);
207
Manoj Rao0f0ab642011-11-01 12:28:24 -0700208#ifdef TOGGLE_CEC_HARDWARE_FSM
209 msg_send_complete = FALSE;
210#endif
211
Manoj Raoa2c27672011-08-30 17:19:39 -0700212 INIT_COMPLETION(hdmi_msm_state->cec_frame_wr_done);
213 hdmi_msm_state->cec_frame_wr_status = 0;
214
215 /* 0x0294 HDMI_MSM_CEC_RETRANSMIT */
216 HDMI_OUTP(0x0294,
217 HDMI_MSM_CEC_RETRANSMIT_NUM(msg->retransmit)
218 | (msg->retransmit > 0) ? HDMI_MSM_CEC_RETRANSMIT_ENABLE : 0);
219
220 /* 0x028C CEC_CTRL */
221 HDMI_OUTP(0x028C, 0x1 | msg->frame_size << 4);
222
223 /* 0x0290 CEC_WR_DATA */
224
225 /* header block */
226 HDMI_OUTP(0x0290,
227 HDMI_MSM_CEC_WR_DATA_DATA(msg->sender_id << 4 | msg->recvr_id)
228 | frameType);
229
230 /* data block 0 : opcode */
231 HDMI_OUTP(0x0290,
232 HDMI_MSM_CEC_WR_DATA_DATA(msg->frame_size < 2 ? 0 : msg->opcode)
233 | frameType);
234
235 /* data block 1-14 : operand 0-13 */
236 for (i = 0; i < msg->frame_size - 1; i++)
237 HDMI_OUTP(0x0290,
238 HDMI_MSM_CEC_WR_DATA_DATA(msg->operand[i])
239 | (msg->recvr_id == 15 ? BIT(0) : 0));
240
241 for (; i < 14; i++)
242 HDMI_OUTP(0x0290,
243 HDMI_MSM_CEC_WR_DATA_DATA(0)
244 | (msg->recvr_id == 15 ? BIT(0) : 0));
245
246 while ((HDMI_INP(0x0298) & 1) && retry--) {
247 DEV_DBG("CEC line is busy(%d)\n", retry);
248 schedule();
249 }
250
251 /* 0x028C CEC_CTRL */
252 HDMI_OUTP(0x028C,
253 HDMI_MSM_CEC_CTRL_LINE_OE
254 | HDMI_MSM_CEC_CTRL_FRAME_SIZE(msg->frame_size)
255 | HDMI_MSM_CEC_CTRL_SEND_TRIG
256 | HDMI_MSM_CEC_CTRL_ENABLE);
257
258 timeout_count = wait_for_completion_interruptible_timeout(
259 &hdmi_msm_state->cec_frame_wr_done, HZ);
260
261 if (!timeout_count) {
262 hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_TMOUT;
263 DEV_ERR("%s: timedout", __func__);
264 hdmi_msm_dump_cec_msg(msg);
265 } else {
266 DEV_DBG("CEC write frame done (frame len=%d)",
267 msg->frame_size);
268 hdmi_msm_dump_cec_msg(msg);
269 }
Manoj Rao0f0ab642011-11-01 12:28:24 -0700270
271#ifdef TOGGLE_CEC_HARDWARE_FSM
272 if (!msg_recv_complete) {
273 /* Toggle CEC hardware FSM */
274 HDMI_OUTP(0x028C, 0x0);
275 HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
276 msg_recv_complete = TRUE;
277 }
278 msg_send_complete = TRUE;
279#endif
Manoj Raoa2c27672011-08-30 17:19:39 -0700280}
281
282void hdmi_msm_cec_msg_recv(void)
283{
284 uint32 data;
285 int i;
Manoj Rao0f0ab642011-11-01 12:28:24 -0700286#ifdef DRVR_ONLY_CECT_NO_DAEMON
Manoj Raoa2c27672011-08-30 17:19:39 -0700287 struct hdmi_msm_cec_msg temp_msg;
288#endif
289 mutex_lock(&hdmi_msm_state_mutex);
290 if (hdmi_msm_state->cec_queue_wr == hdmi_msm_state->cec_queue_rd
291 && hdmi_msm_state->cec_queue_full) {
292 mutex_unlock(&hdmi_msm_state_mutex);
293 DEV_ERR("CEC message queue is overflowing\n");
Manoj Rao0f0ab642011-11-01 12:28:24 -0700294#ifdef DRVR_ONLY_CECT_NO_DAEMON
Manoj Raoa2c27672011-08-30 17:19:39 -0700295 /*
296 * Without CEC daemon:
297 * Compliance tests fail once the queue gets filled up.
298 * so reset the pointers to the start of the queue.
299 */
300 hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
301 hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
302 hdmi_msm_state->cec_queue_full = false;
303#else
304 return;
305#endif
306 }
307 if (hdmi_msm_state->cec_queue_wr == NULL) {
308 DEV_ERR("%s: wp is NULL\n", __func__);
309 return;
310 }
311 mutex_unlock(&hdmi_msm_state_mutex);
312
313 /* 0x02AC CEC_RD_DATA */
314 data = HDMI_INP(0x02AC);
315
316 hdmi_msm_state->cec_queue_wr->sender_id = (data & 0xF0) >> 4;
317 hdmi_msm_state->cec_queue_wr->recvr_id = (data & 0x0F);
318 hdmi_msm_state->cec_queue_wr->frame_size = (data & 0x1F00) >> 8;
319 DEV_DBG("Recvd init=[%u] dest=[%u] size=[%u]\n",
320 hdmi_msm_state->cec_queue_wr->sender_id,
321 hdmi_msm_state->cec_queue_wr->recvr_id,
322 hdmi_msm_state->cec_queue_wr->frame_size);
323
324 if (hdmi_msm_state->cec_queue_wr->frame_size < 1) {
325 DEV_ERR("%s: invalid message (frame length = %d)",
326 __func__, hdmi_msm_state->cec_queue_wr->frame_size);
327 return;
328 } else if (hdmi_msm_state->cec_queue_wr->frame_size == 1) {
329 DEV_DBG("%s: polling message (dest[%x] <- init[%x])",
330 __func__,
331 hdmi_msm_state->cec_queue_wr->recvr_id,
332 hdmi_msm_state->cec_queue_wr->sender_id);
333 return;
334 }
335
336 /* data block 0 : opcode */
337 data = HDMI_INP(0x02AC);
338 hdmi_msm_state->cec_queue_wr->opcode = data & 0xFF;
339
340 /* data block 1-14 : operand 0-13 */
341 for (i = 0; i < hdmi_msm_state->cec_queue_wr->frame_size - 2; i++) {
342 data = HDMI_INP(0x02AC);
343 hdmi_msm_state->cec_queue_wr->operand[i] = data & 0xFF;
344 }
345
346 for (; i < 14; i++)
347 hdmi_msm_state->cec_queue_wr->operand[i] = 0;
348
349 DEV_DBG("CEC read frame done\n");
350 DEV_DBG("=======================================\n");
351 hdmi_msm_dump_cec_msg(hdmi_msm_state->cec_queue_wr);
352 DEV_DBG("=======================================\n");
353
Manoj Rao0f0ab642011-11-01 12:28:24 -0700354#ifdef DRVR_ONLY_CECT_NO_DAEMON
Manoj Raoa2c27672011-08-30 17:19:39 -0700355 switch (hdmi_msm_state->cec_queue_wr->opcode) {
356 case 0x64:
357 /* Set OSD String */
358 DEV_INFO("Recvd OSD Str=[%x]\n",\
359 hdmi_msm_state->cec_queue_wr->operand[3]);
360 break;
361 case 0x83:
362 /* Give Phy Addr */
363 DEV_INFO("Recvd a Give Phy Addr cmd\n");
364 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
365 /* Setup a frame for sending out phy addr */
366 temp_msg.sender_id = 0x4;
367
368 /* Broadcast */
369 temp_msg.recvr_id = 0xf;
370 temp_msg.opcode = 0x84;
371 i = 0;
372 temp_msg.operand[i++] = 0x10;
373 temp_msg.operand[i++] = 0x00;
374 temp_msg.operand[i++] = 0x04;
375 temp_msg.frame_size = i + 2;
376 hdmi_msm_cec_msg_send(&temp_msg);
377 break;
378 case 0xFF:
379 /* Abort */
380 DEV_INFO("Recvd an abort cmd 0xFF\n");
381 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
382 temp_msg.sender_id = 0x4;
383 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
384 i = 0;
385
386 /*feature abort */
387 temp_msg.opcode = 0x00;
388 temp_msg.operand[i++] =
389 hdmi_msm_state->cec_queue_wr->opcode;
390
391 /*reason for abort = "Refused" */
392 temp_msg.operand[i++] = 0x04;
393 temp_msg.frame_size = i + 2;
394 hdmi_msm_dump_cec_msg(&temp_msg);
395 hdmi_msm_cec_msg_send(&temp_msg);
396 break;
397 case 0x046:
398 /* Give OSD name */
399 DEV_INFO("Recvd cmd 0x046\n");
400 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
401 temp_msg.sender_id = 0x4;
402 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
403 i = 0;
404
405 /* OSD Name */
406 temp_msg.opcode = 0x47;
407
408 /* Display control byte */
409 temp_msg.operand[i++] = 0x00;
410 temp_msg.operand[i++] = 'H';
411 temp_msg.operand[i++] = 'e';
412 temp_msg.operand[i++] = 'l';
413 temp_msg.operand[i++] = 'l';
414 temp_msg.operand[i++] = 'o';
415 temp_msg.operand[i++] = ' ';
416 temp_msg.operand[i++] = 'W';
417 temp_msg.operand[i++] = 'o';
418 temp_msg.operand[i++] = 'r';
419 temp_msg.operand[i++] = 'l';
420 temp_msg.operand[i++] = 'd';
421 temp_msg.frame_size = i + 2;
422 hdmi_msm_cec_msg_send(&temp_msg);
423 break;
424 case 0x08F:
425 /* Give Device Power status */
426 DEV_INFO("Recvd a Power status message\n");
427 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
428 temp_msg.sender_id = 0x4;
429 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
430 i = 0;
431
432 /* OSD String */
433 temp_msg.opcode = 0x90;
434 temp_msg.operand[i++] = 'H';
435 temp_msg.operand[i++] = 'e';
436 temp_msg.operand[i++] = 'l';
437 temp_msg.operand[i++] = 'l';
438 temp_msg.operand[i++] = 'o';
439 temp_msg.operand[i++] = ' ';
440 temp_msg.operand[i++] = 'W';
441 temp_msg.operand[i++] = 'o';
442 temp_msg.operand[i++] = 'r';
443 temp_msg.operand[i++] = 'l';
444 temp_msg.operand[i++] = 'd';
445 temp_msg.frame_size = i + 2;
446 hdmi_msm_cec_msg_send(&temp_msg);
447 break;
448 case 0x080:
449 /* Routing Change cmd */
450 case 0x086:
451 /* Set Stream Path */
452 DEV_INFO("Recvd Set Stream\n");
453 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
454 temp_msg.sender_id = 0x4;
455
456 /*Broadcast this message*/
457 temp_msg.recvr_id = 0xf;
458 i = 0;
459 temp_msg.opcode = 0x82; /* Active Source */
460 temp_msg.operand[i++] = 0x10;
461 temp_msg.operand[i++] = 0x00;
462 temp_msg.frame_size = i + 2;
463 hdmi_msm_cec_msg_send(&temp_msg);
464
465 /*
466 * sending <Image View On> message
467 */
468 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
469 temp_msg.sender_id = 0x4;
470 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
471 i = 0;
472 /* opcode for Image View On */
473 temp_msg.opcode = 0x04;
474 temp_msg.frame_size = i + 2;
475 hdmi_msm_cec_msg_send(&temp_msg);
476 break;
477 default:
478 DEV_INFO("Recvd an unknown cmd = [%u]\n",
479 hdmi_msm_state->cec_queue_wr->opcode);
480#ifdef __SEND_ABORT__
481 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
482 temp_msg.sender_id = 0x4;
483 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
484 i = 0;
485 /* opcode for feature abort */
486 temp_msg.opcode = 0x00;
487 temp_msg.operand[i++] =
488 hdmi_msm_state->cec_queue_wr->opcode;
489 /*reason for abort = "Unrecognized opcode" */
490 temp_msg.operand[i++] = 0x00;
491 temp_msg.frame_size = i + 2;
492 hdmi_msm_cec_msg_send(&temp_msg);
493 break;
494#else
495 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
496 temp_msg.sender_id = 0x4;
497 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
498 i = 0;
499 /* OSD String */
500 temp_msg.opcode = 0x64;
501 temp_msg.operand[i++] = 0x0;
502 temp_msg.operand[i++] = 'H';
503 temp_msg.operand[i++] = 'e';
504 temp_msg.operand[i++] = 'l';
505 temp_msg.operand[i++] = 'l';
506 temp_msg.operand[i++] = 'o';
507 temp_msg.operand[i++] = ' ';
508 temp_msg.operand[i++] = 'W';
509 temp_msg.operand[i++] = 'o';
510 temp_msg.operand[i++] = 'r';
511 temp_msg.operand[i++] = 'l';
512 temp_msg.operand[i++] = 'd';
513 temp_msg.frame_size = i + 2;
514 hdmi_msm_cec_msg_send(&temp_msg);
515 break;
516#endif /* __SEND_ABORT__ */
517 }
518
Manoj Rao0f0ab642011-11-01 12:28:24 -0700519#endif /* DRVR_ONLY_CECT_NO_DAEMON */
Manoj Raoa2c27672011-08-30 17:19:39 -0700520 mutex_lock(&hdmi_msm_state_mutex);
521 hdmi_msm_state->cec_queue_wr++;
522 if (hdmi_msm_state->cec_queue_wr == CEC_QUEUE_END)
523 hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
524 if (hdmi_msm_state->cec_queue_wr == hdmi_msm_state->cec_queue_rd)
525 hdmi_msm_state->cec_queue_full = true;
526 mutex_unlock(&hdmi_msm_state_mutex);
527 DEV_DBG("Exiting %s()\n", __func__);
528}
529
530void hdmi_msm_cec_one_touch_play(void)
531{
532 struct hdmi_msm_cec_msg temp_msg;
533 uint32 i = 0;
534 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
535 temp_msg.sender_id = 0x4;
536 /*
537 * Broadcast this message
538 */
539 temp_msg.recvr_id = 0xf;
540 i = 0;
541 /* Active Source */
542 temp_msg.opcode = 0x82;
543 temp_msg.operand[i++] = 0x10;
544 temp_msg.operand[i++] = 0x00;
545 /*temp_msg.operand[i++] = 0x04;*/
546 temp_msg.frame_size = i + 2;
547 hdmi_msm_cec_msg_send(&temp_msg);
548 /*
549 * sending <Image View On> message
550 */
551 memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
552 temp_msg.sender_id = 0x4;
553 temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
554 i = 0;
555 /* Image View On */
556 temp_msg.opcode = 0x04;
557 temp_msg.frame_size = i + 2;
558 hdmi_msm_cec_msg_send(&temp_msg);
559
560}
561#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
562
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700563uint32 hdmi_msm_get_io_base(void)
564{
565 return (uint32)MSM_HDMI_BASE;
566}
567EXPORT_SYMBOL(hdmi_msm_get_io_base);
568
569/* Table indicating the video format supported by the HDMI TX Core v1.0 */
570/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
571static void hdmi_msm_setup_video_mode_lut(void)
572{
573 HDMI_SETUP_LUT(640x480p60_4_3);
574 HDMI_SETUP_LUT(720x480p60_4_3);
575 HDMI_SETUP_LUT(720x480p60_16_9);
576 HDMI_SETUP_LUT(1280x720p60_16_9);
577 HDMI_SETUP_LUT(1920x1080i60_16_9);
578 HDMI_SETUP_LUT(1440x480i60_4_3);
579 HDMI_SETUP_LUT(1440x480i60_16_9);
580 HDMI_SETUP_LUT(1920x1080p60_16_9);
581 HDMI_SETUP_LUT(720x576p50_4_3);
582 HDMI_SETUP_LUT(720x576p50_16_9);
583 HDMI_SETUP_LUT(1280x720p50_16_9);
584 HDMI_SETUP_LUT(1440x576i50_4_3);
585 HDMI_SETUP_LUT(1440x576i50_16_9);
586 HDMI_SETUP_LUT(1920x1080p50_16_9);
587 HDMI_SETUP_LUT(1920x1080p24_16_9);
588 HDMI_SETUP_LUT(1920x1080p25_16_9);
589 HDMI_SETUP_LUT(1920x1080p30_16_9);
590}
591
592#ifdef PORT_DEBUG
593const char *hdmi_msm_name(uint32 offset)
594{
595 switch (offset) {
596 case 0x0000: return "CTRL";
597 case 0x0020: return "AUDIO_PKT_CTRL1";
598 case 0x0024: return "ACR_PKT_CTRL";
599 case 0x0028: return "VBI_PKT_CTRL";
600 case 0x002C: return "INFOFRAME_CTRL0";
601#ifdef CONFIG_FB_MSM_HDMI_3D
602 case 0x0034: return "GEN_PKT_CTRL";
603#endif
604 case 0x003C: return "ACP";
605 case 0x0040: return "GC";
606 case 0x0044: return "AUDIO_PKT_CTRL2";
607 case 0x0048: return "ISRC1_0";
608 case 0x004C: return "ISRC1_1";
609 case 0x0050: return "ISRC1_2";
610 case 0x0054: return "ISRC1_3";
611 case 0x0058: return "ISRC1_4";
612 case 0x005C: return "ISRC2_0";
613 case 0x0060: return "ISRC2_1";
614 case 0x0064: return "ISRC2_2";
615 case 0x0068: return "ISRC2_3";
616 case 0x006C: return "AVI_INFO0";
617 case 0x0070: return "AVI_INFO1";
618 case 0x0074: return "AVI_INFO2";
619 case 0x0078: return "AVI_INFO3";
620#ifdef CONFIG_FB_MSM_HDMI_3D
621 case 0x0084: return "GENERIC0_HDR";
622 case 0x0088: return "GENERIC0_0";
623 case 0x008C: return "GENERIC0_1";
624#endif
625 case 0x00C4: return "ACR_32_0";
626 case 0x00C8: return "ACR_32_1";
627 case 0x00CC: return "ACR_44_0";
628 case 0x00D0: return "ACR_44_1";
629 case 0x00D4: return "ACR_48_0";
630 case 0x00D8: return "ACR_48_1";
631 case 0x00E4: return "AUDIO_INFO0";
632 case 0x00E8: return "AUDIO_INFO1";
633#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
634 case 0x0110: return "HDCP_CTRL";
635 case 0x0114: return "HDCP_DEBUG_CTRL";
636 case 0x0118: return "HDCP_INT_CTRL";
637 case 0x011C: return "HDCP_LINK0_STATUS";
638 case 0x012C: return "HDCP_ENTROPY_CTRL0";
639 case 0x0130: return "HDCP_RESET";
640 case 0x0134: return "HDCP_RCVPORT_DATA0";
641 case 0x0138: return "HDCP_RCVPORT_DATA1";
642 case 0x013C: return "HDCP_RCVPORT_DATA2";
643 case 0x0144: return "HDCP_RCVPORT_DATA3";
644 case 0x0148: return "HDCP_RCVPORT_DATA4";
645 case 0x014C: return "HDCP_RCVPORT_DATA5";
646 case 0x0150: return "HDCP_RCVPORT_DATA6";
647 case 0x0168: return "HDCP_RCVPORT_DATA12";
648#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
649 case 0x01D0: return "AUDIO_CFG";
650 case 0x0208: return "USEC_REFTIMER";
651 case 0x020C: return "DDC_CTRL";
652 case 0x0214: return "DDC_INT_CTRL";
653 case 0x0218: return "DDC_SW_STATUS";
654 case 0x021C: return "DDC_HW_STATUS";
655 case 0x0220: return "DDC_SPEED";
656 case 0x0224: return "DDC_SETUP";
657 case 0x0228: return "DDC_TRANS0";
658 case 0x022C: return "DDC_TRANS1";
659 case 0x0238: return "DDC_DATA";
660 case 0x0250: return "HPD_INT_STATUS";
661 case 0x0254: return "HPD_INT_CTRL";
662 case 0x0258: return "HPD_CTRL";
663#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
664 case 0x025C: return "HDCP_ENTROPY_CTRL1";
665#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
666 case 0x027C: return "DDC_REF";
667#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
668 case 0x0284: return "HDCP_SW_UPPER_AKSV";
669 case 0x0288: return "HDCP_SW_LOWER_AKSV";
670#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
671 case 0x02B4: return "ACTIVE_H";
672 case 0x02B8: return "ACTIVE_V";
673 case 0x02BC: return "ACTIVE_V_F2";
674 case 0x02C0: return "TOTAL";
675 case 0x02C4: return "V_TOTAL_F2";
676 case 0x02C8: return "FRAME_CTRL";
677 case 0x02CC: return "AUD_INT";
678 case 0x0300: return "PHY_REG0";
679 case 0x0304: return "PHY_REG1";
680 case 0x0308: return "PHY_REG2";
681 case 0x030C: return "PHY_REG3";
682 case 0x0310: return "PHY_REG4";
683 case 0x0314: return "PHY_REG5";
684 case 0x0318: return "PHY_REG6";
685 case 0x031C: return "PHY_REG7";
686 case 0x0320: return "PHY_REG8";
687 case 0x0324: return "PHY_REG9";
688 case 0x0328: return "PHY_REG10";
689 case 0x032C: return "PHY_REG11";
690 case 0x0330: return "PHY_REG12";
691 default: return "???";
692 }
693}
694
695void hdmi_outp(uint32 offset, uint32 value)
696{
697 uint32 in_val;
698
699 outpdw(MSM_HDMI_BASE+offset, value);
700 in_val = inpdw(MSM_HDMI_BASE+offset);
701 DEV_DBG("HDMI[%04x] => %08x [%08x] %s\n",
702 offset, value, in_val, hdmi_msm_name(offset));
703}
704
705uint32 hdmi_inp(uint32 offset)
706{
707 uint32 value = inpdw(MSM_HDMI_BASE+offset);
708 DEV_DBG("HDMI[%04x] <= %08x %s\n",
709 offset, value, hdmi_msm_name(offset));
710 return value;
711}
712#endif /* DEBUG */
713
714static void hdmi_msm_turn_on(void);
715static int hdmi_msm_audio_off(void);
716static int hdmi_msm_read_edid(void);
717static void hdmi_msm_hpd_off(void);
718
719static void hdmi_msm_hpd_state_work(struct work_struct *work)
720{
721 boolean hpd_state;
722 char *envp[2];
723
724 if (!hdmi_msm_state || !hdmi_msm_state->hpd_initialized ||
725 !MSM_HDMI_BASE) {
726 DEV_DBG("%s: ignored, probe failed\n", __func__);
727 return;
728 }
729#ifdef CONFIG_SUSPEND
730 mutex_lock(&hdmi_msm_state_mutex);
731 if (hdmi_msm_state->pm_suspended) {
732 mutex_unlock(&hdmi_msm_state_mutex);
733 DEV_WARN("%s: ignored, pm_suspended\n", __func__);
734 return;
735 }
736 mutex_unlock(&hdmi_msm_state_mutex);
737#endif
738
Manoj Raob91fa712011-06-29 09:07:55 -0700739 DEV_DBG("%s:Got interrupt\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700740 /* HPD_INT_STATUS[0x0250] */
741 hpd_state = (HDMI_INP(0x0250) & 0x2) >> 1;
742 mutex_lock(&external_common_state_hpd_mutex);
743 mutex_lock(&hdmi_msm_state_mutex);
744 if ((external_common_state->hpd_state != hpd_state) || (hdmi_msm_state->
745 hpd_prev_state != external_common_state->hpd_state)) {
746 external_common_state->hpd_state = hpd_state;
747 hdmi_msm_state->hpd_prev_state =
748 external_common_state->hpd_state;
749 DEV_DBG("%s: state not stable yet, wait again (%d|%d|%d)\n",
750 __func__, hdmi_msm_state->hpd_prev_state,
751 external_common_state->hpd_state, hpd_state);
752 mutex_unlock(&external_common_state_hpd_mutex);
753 hdmi_msm_state->hpd_stable = 0;
754 mutex_unlock(&hdmi_msm_state_mutex);
755 mod_timer(&hdmi_msm_state->hpd_state_timer, jiffies + HZ/2);
756 return;
757 }
758 mutex_unlock(&external_common_state_hpd_mutex);
759
760 if (hdmi_msm_state->hpd_stable++) {
761 mutex_unlock(&hdmi_msm_state_mutex);
762 DEV_DBG("%s: no more timer, depending for IRQ now\n",
763 __func__);
764 return;
765 }
766
767 hdmi_msm_state->hpd_stable = 1;
768 DEV_INFO("HDMI HPD: event detected\n");
769
770 if (!hdmi_msm_state->hpd_cable_chg_detected) {
771 mutex_unlock(&hdmi_msm_state_mutex);
772 if (hpd_state) {
773 if (!external_common_state->
774 disp_mode_list.num_of_elements)
775 hdmi_msm_read_edid();
776 hdmi_msm_turn_on();
777 }
778 } else {
779 hdmi_msm_state->hpd_cable_chg_detected = FALSE;
780 mutex_unlock(&hdmi_msm_state_mutex);
Manoj Rao09ab5652011-10-10 17:36:15 -0700781 /* QDSP OFF preceding the HPD event notification */
782 envp[0] = "HDCP_STATE=FAIL";
783 envp[1] = NULL;
784 DEV_INFO("HDMI HPD: QDSP OFF\n");
785 kobject_uevent_env(external_common_state->uevent_kobj,
786 KOBJ_CHANGE, envp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700787 if (hpd_state) {
788 hdmi_msm_read_edid();
789#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
790 hdmi_msm_state->reauth = FALSE ;
791#endif
792 /* Build EDID table */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700793 hdmi_msm_turn_on();
794 DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
795 kobject_uevent(external_common_state->uevent_kobj,
796 KOBJ_ONLINE);
797 hdmi_msm_hdcp_enable();
Abhishek Kharbandad5315bd2011-08-10 19:45:53 -0700798#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
799 /* Send Audio for HDMI Compliance Cases*/
800 envp[0] = "HDCP_STATE=PASS";
801 envp[1] = NULL;
802 DEV_INFO("HDMI HPD: sense : send HDCP_PASS\n");
803 kobject_uevent_env(external_common_state->uevent_kobj,
804 KOBJ_CHANGE, envp);
805#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700806 } else {
807 DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n"
808 );
809 kobject_uevent(external_common_state->uevent_kobj,
810 KOBJ_OFFLINE);
811 }
812 }
813
814 /* HPD_INT_CTRL[0x0254]
815 * 31:10 Reserved
816 * 9 RCV_PLUGIN_DET_MASK receiver plug in interrupt mask.
817 * When programmed to 1,
818 * RCV_PLUGIN_DET_INT will toggle
819 * the interrupt line
820 * 8:6 Reserved
821 * 5 RX_INT_EN Panel RX interrupt enable
822 * 0: Disable
823 * 1: Enable
824 * 4 RX_INT_ACK WRITE ONLY. Panel RX interrupt
825 * ack
826 * 3 Reserved
827 * 2 INT_EN Panel interrupt control
828 * 0: Disable
829 * 1: Enable
830 * 1 INT_POLARITY Panel interrupt polarity
831 * 0: generate interrupt on disconnect
832 * 1: generate interrupt on connect
833 * 0 INT_ACK WRITE ONLY. Panel interrupt ack */
834 /* Set IRQ for HPD */
835 HDMI_OUTP(0x0254, 4 | (hpd_state ? 0 : 2));
836}
837
838#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
839static void hdcp_deauthenticate(void);
840static void hdmi_msm_hdcp_reauth_work(struct work_struct *work)
841{
842#ifdef CONFIG_SUSPEND
843 mutex_lock(&hdmi_msm_state_mutex);
844 if (hdmi_msm_state->pm_suspended) {
845 mutex_unlock(&hdmi_msm_state_mutex);
846 DEV_WARN("HDCP: deauthenticating skipped, pm_suspended\n");
847 return;
848 }
849 mutex_unlock(&hdmi_msm_state_mutex);
850#endif
851
852 /* Don't process recursive actions */
853 mutex_lock(&hdmi_msm_state_mutex);
854 if (hdmi_msm_state->hdcp_activating) {
855 mutex_unlock(&hdmi_msm_state_mutex);
856 return;
857 }
858 mutex_unlock(&hdmi_msm_state_mutex);
859
860 /*
861 * Reauth=>deauth, hdcp_auth
862 * hdcp_auth=>turn_on() which calls
863 * HDMI Core reset without informing the Audio QDSP
864 * this can do bad things to video playback on the HDTV
865 * Therefore, as surprising as it may sound do reauth
866 * only if the device is HDCP-capable
867 */
868 if (external_common_state->present_hdcp) {
869 hdcp_deauthenticate();
870 mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
871 }
872}
873
874static void hdmi_msm_hdcp_work(struct work_struct *work)
875{
876#ifdef CONFIG_SUSPEND
877 mutex_lock(&hdmi_msm_state_mutex);
878 if (hdmi_msm_state->pm_suspended) {
879 mutex_unlock(&hdmi_msm_state_mutex);
880 DEV_WARN("HDCP: Re-enable skipped, pm_suspended\n");
881 return;
882 }
883 mutex_unlock(&hdmi_msm_state_mutex);
884#endif
885
886 /* Only re-enable if cable still connected */
887 mutex_lock(&external_common_state_hpd_mutex);
888 if (external_common_state->hpd_state &&
889 !(hdmi_msm_state->full_auth_done)) {
890 mutex_unlock(&external_common_state_hpd_mutex);
891 hdmi_msm_state->reauth = TRUE;
892 hdmi_msm_turn_on();
893 } else
894 mutex_unlock(&external_common_state_hpd_mutex);
895}
896#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
897
898static irqreturn_t hdmi_msm_isr(int irq, void *dev_id)
899{
900 uint32 hpd_int_status;
901 uint32 hpd_int_ctrl;
Manoj Raoa2c27672011-08-30 17:19:39 -0700902#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
903 uint32 cec_intr_status;
904#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700905 uint32 ddc_int_ctrl;
906 uint32 audio_int_val;
907#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
908 uint32 hdcp_int_val;
909 char *envp[2];
910#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
911 static uint32 fifo_urun_int_occurred;
912 static uint32 sample_drop_int_occurred;
913 const uint32 occurrence_limit = 5;
914
915 if (!hdmi_msm_state || !hdmi_msm_state->hpd_initialized ||
916 !MSM_HDMI_BASE) {
917 DEV_DBG("ISR ignored, probe failed\n");
918 return IRQ_HANDLED;
919 }
920#ifdef CONFIG_SUSPEND
921 mutex_lock(&hdmi_msm_state_mutex);
922 if (hdmi_msm_state->pm_suspended) {
923 mutex_unlock(&hdmi_msm_state_mutex);
924 DEV_WARN("ISR ignored, pm_suspended\n");
925 return IRQ_HANDLED;
926 }
927 mutex_unlock(&hdmi_msm_state_mutex);
928#endif
929
930 /* Process HPD Interrupt */
931 /* HDMI_HPD_INT_STATUS[0x0250] */
932 hpd_int_status = HDMI_INP_ND(0x0250);
933 /* HDMI_HPD_INT_CTRL[0x0254] */
934 hpd_int_ctrl = HDMI_INP_ND(0x0254);
935 if ((hpd_int_ctrl & (1 << 2)) && (hpd_int_status & (1 << 0))) {
936 boolean cable_detected = (hpd_int_status & 2) >> 1;
937
938 /* HDMI_HPD_INT_CTRL[0x0254] */
Manoj Raof74d2edd2011-07-18 14:25:38 -0700939 /* Clear all interrupts, timer will turn IRQ back on
940 * Leaving the bit[2] on, else core goes off
941 * on getting HPD during power off
942 */
943 HDMI_OUTP(0x0254, (1 << 2) | (1 << 0));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700944
945 DEV_DBG("%s: HPD IRQ, Ctrl=%04x, State=%04x\n", __func__,
946 hpd_int_ctrl, hpd_int_status);
947 mutex_lock(&hdmi_msm_state_mutex);
948 hdmi_msm_state->hpd_cable_chg_detected = TRUE;
949
950 /* ensure 2 readouts */
951 hdmi_msm_state->hpd_prev_state = cable_detected ? 0 : 1;
952 external_common_state->hpd_state = cable_detected ? 1 : 0;
953 hdmi_msm_state->hpd_stable = 0;
954 mod_timer(&hdmi_msm_state->hpd_state_timer, jiffies + HZ/2);
955 mutex_unlock(&hdmi_msm_state_mutex);
956 /*
957 * HDCP Compliance 1A-01:
958 * The Quantum Data Box 882 triggers two consecutive
959 * HPD events very close to each other as a part of this
960 * test which can trigger two parallel HDCP auth threads
961 * if HDCP authentication is going on and we get ISR
962 * then stop the authentication , rather than
963 * reauthenticating it again
964 */
965 if (!(hdmi_msm_state->full_auth_done)) {
966 DEV_DBG("%s getting hpd while authenticating\n",\
967 __func__);
968 mutex_lock(&hdcp_auth_state_mutex);
969 hdmi_msm_state->hpd_during_auth = TRUE;
970 mutex_unlock(&hdcp_auth_state_mutex);
971 }
972 return IRQ_HANDLED;
973 }
974
975 /* Process DDC Interrupts */
976 /* HDMI_DDC_INT_CTRL[0x0214] */
977 ddc_int_ctrl = HDMI_INP_ND(0x0214);
978 if ((ddc_int_ctrl & (1 << 2)) && (ddc_int_ctrl & (1 << 0))) {
979 /* SW_DONE INT occured, clr it */
980 HDMI_OUTP_ND(0x0214, ddc_int_ctrl | (1 << 1));
981 complete(&hdmi_msm_state->ddc_sw_done);
982 return IRQ_HANDLED;
983 }
984
985 /* FIFO Underrun Int is enabled */
986 /* HDMI_AUD_INT[0x02CC]
987 * [3] AUD_SAM_DROP_MASK [R/W]
988 * [2] AUD_SAM_DROP_ACK [W], AUD_SAM_DROP_INT [R]
989 * [1] AUD_FIFO_URUN_MASK [R/W]
990 * [0] AUD_FIFO_URUN_ACK [W], AUD_FIFO_URUN_INT [R] */
991 audio_int_val = HDMI_INP_ND(0x02CC);
992 if ((audio_int_val & (1 << 1)) && (audio_int_val & (1 << 0))) {
993 /* FIFO Underrun occured, clr it */
994 HDMI_OUTP(0x02CC, audio_int_val | (1 << 0));
995
996 ++fifo_urun_int_occurred;
997 DEV_INFO("HDMI AUD_FIFO_URUN: %d\n", fifo_urun_int_occurred);
998
999 if (fifo_urun_int_occurred >= occurrence_limit) {
1000 HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) & ~(1 << 1));
1001 DEV_INFO("HDMI AUD_FIFO_URUN: INT has been disabled "
1002 "by the ISR after %d occurences...\n",
1003 fifo_urun_int_occurred);
1004 }
1005 return IRQ_HANDLED;
1006 }
1007
1008 /* Audio Sample Drop int is enabled */
1009 if ((audio_int_val & (1 << 3)) && (audio_int_val & (1 << 2))) {
1010 /* Audio Sample Drop occured, clr it */
1011 HDMI_OUTP(0x02CC, audio_int_val | (1 << 2));
1012 DEV_DBG("%s: AUD_SAM_DROP", __func__);
1013
1014 ++sample_drop_int_occurred;
1015 if (sample_drop_int_occurred >= occurrence_limit) {
1016 HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) & ~(1 << 3));
1017 DEV_INFO("HDMI AUD_SAM_DROP: INT has been disabled "
1018 "by the ISR after %d occurences...\n",
1019 sample_drop_int_occurred);
1020 }
1021 return IRQ_HANDLED;
1022 }
1023
1024#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
1025 /* HDCP_INT_CTRL[0x0118]
1026 * [0] AUTH_SUCCESS_INT [R] HDCP Authentication Success
1027 * interrupt status
1028 * [1] AUTH_SUCCESS_ACK [W] Acknowledge bit for HDCP
1029 * Authentication Success bit - write 1 to clear
1030 * [2] AUTH_SUCCESS_MASK [R/W] Mask bit for HDCP Authentication
1031 * Success interrupt - set to 1 to enable interrupt */
1032 hdcp_int_val = HDMI_INP_ND(0x0118);
1033 if ((hdcp_int_val & (1 << 2)) && (hdcp_int_val & (1 << 0))) {
1034 /* AUTH_SUCCESS_INT */
1035 HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 1)) & ~(1 << 0));
1036 DEV_INFO("HDCP: AUTH_SUCCESS_INT received\n");
1037 complete_all(&hdmi_msm_state->hdcp_success_done);
1038 return IRQ_HANDLED;
1039 }
1040 /* [4] AUTH_FAIL_INT [R] HDCP Authentication Lost
1041 * interrupt Status
1042 * [5] AUTH_FAIL_ACK [W] Acknowledge bit for HDCP
1043 * Authentication Lost bit - write 1 to clear
1044 * [6] AUTH_FAIL_MASK [R/W] Mask bit fo HDCP Authentication
1045 * Lost interrupt set to 1 to enable interrupt
1046 * [7] AUTH_FAIL_INFO_ACK [W] Acknowledge bit for HDCP
1047 * Authentication Failure Info field - write 1 to clear */
1048 if ((hdcp_int_val & (1 << 6)) && (hdcp_int_val & (1 << 4))) {
1049 /* AUTH_FAIL_INT */
1050 /* Clear and Disable */
1051 HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 5))
1052 & ~((1 << 6) | (1 << 4)));
1053 DEV_INFO("HDCP: AUTH_FAIL_INT received, LINK0_STATUS=0x%08x\n",
1054 HDMI_INP_ND(0x011C));
1055 if (hdmi_msm_state->full_auth_done) {
1056 envp[0] = "HDCP_STATE=FAIL";
1057 envp[1] = NULL;
1058 DEV_INFO("HDMI HPD:QDSP OFF\n");
1059 kobject_uevent_env(external_common_state->uevent_kobj,
1060 KOBJ_CHANGE, envp);
1061 mutex_lock(&hdcp_auth_state_mutex);
1062 hdmi_msm_state->full_auth_done = FALSE;
1063 mutex_unlock(&hdcp_auth_state_mutex);
1064 /* Calling reauth only when authentication
1065 * is sucessful or else we always go into
1066 * the reauth loop
1067 */
1068 queue_work(hdmi_work_queue,
1069 &hdmi_msm_state->hdcp_reauth_work);
1070 }
1071 mutex_lock(&hdcp_auth_state_mutex);
1072 /* This flag prevents other threads from re-authenticating
1073 * after we've just authenticated (i.e., finished part3)
1074 */
1075 hdmi_msm_state->full_auth_done = FALSE;
1076
1077 mutex_unlock(&hdcp_auth_state_mutex);
1078 DEV_DBG("calling reauthenticate from %s HDCP FAIL INT ",
1079 __func__);
1080
Aravind Venkateswarandaf5e172011-11-30 18:34:40 -08001081 /* Clear AUTH_FAIL_INFO as well */
1082 HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001083 return IRQ_HANDLED;
1084 }
1085 /* [8] DDC_XFER_REQ_INT [R] HDCP DDC Transfer Request
1086 * interrupt status
1087 * [9] DDC_XFER_REQ_ACK [W] Acknowledge bit for HDCP DDC
1088 * Transfer Request bit - write 1 to clear
1089 * [10] DDC_XFER_REQ_MASK [R/W] Mask bit for HDCP DDC Transfer
1090 * Request interrupt - set to 1 to enable interrupt */
1091 if ((hdcp_int_val & (1 << 10)) && (hdcp_int_val & (1 << 8))) {
1092 /* DDC_XFER_REQ_INT */
1093 HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 9)) & ~(1 << 8));
1094 if (!(hdcp_int_val & (1 << 12)))
1095 return IRQ_HANDLED;
1096 }
1097 /* [12] DDC_XFER_DONE_INT [R] HDCP DDC Transfer done interrupt
1098 * status
1099 * [13] DDC_XFER_DONE_ACK [W] Acknowledge bit for HDCP DDC
1100 * Transfer done bit - write 1 to clear
1101 * [14] DDC_XFER_DONE_MASK [R/W] Mask bit for HDCP DDC Transfer
1102 * done interrupt - set to 1 to enable interrupt */
1103 if ((hdcp_int_val & (1 << 14)) && (hdcp_int_val & (1 << 12))) {
1104 /* DDC_XFER_DONE_INT */
1105 HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 13)) & ~(1 << 12));
1106 DEV_INFO("HDCP: DDC_XFER_DONE received\n");
1107 return IRQ_HANDLED;
1108 }
1109#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
1110
Manoj Raoa2c27672011-08-30 17:19:39 -07001111#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
1112 /* Process CEC Interrupt */
1113 /* HDMI_MSM_CEC_INT[0x029C] */
1114 cec_intr_status = HDMI_INP_ND(0x029C);
1115
1116 DEV_DBG("cec interrupt status is [%u]\n", cec_intr_status);
1117
1118 if (HDMI_MSM_CEC_FRAME_WR_SUCCESS(cec_intr_status)) {
1119 DEV_DBG("CEC_IRQ_FRAME_WR_DONE\n");
1120 HDMI_OUTP(0x029C, cec_intr_status |
1121 HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK);
1122 mutex_lock(&hdmi_msm_state_mutex);
1123 hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_DONE;
1124 mutex_unlock(&hdmi_msm_state_mutex);
1125 complete(&hdmi_msm_state->cec_frame_wr_done);
1126 return IRQ_HANDLED;
1127 }
1128 if ((cec_intr_status & (1 << 2)) && (cec_intr_status & (1 << 3))) {
1129 DEV_DBG("CEC_IRQ_FRAME_ERROR\n");
Manoj Rao0f0ab642011-11-01 12:28:24 -07001130#ifdef TOGGLE_CEC_HARDWARE_FSM
Manoj Raoa2c27672011-08-30 17:19:39 -07001131 /* Toggle CEC hardware FSM */
1132 HDMI_OUTP(0x028C, 0x0);
1133 HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
Manoj Rao0f0ab642011-11-01 12:28:24 -07001134#endif
Manoj Raoa2c27672011-08-30 17:19:39 -07001135 HDMI_OUTP(0x029C, cec_intr_status);
1136 mutex_lock(&hdmi_msm_state_mutex);
1137 hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_ERROR;
1138 mutex_unlock(&hdmi_msm_state_mutex);
1139 complete(&hdmi_msm_state->cec_frame_wr_done);
1140 return IRQ_HANDLED;
1141 }
1142
1143 if ((cec_intr_status & (1 << 4)) && (cec_intr_status & (1 << 5)))
1144 DEV_DBG("CEC_IRQ_MONITOR\n");
1145
1146 if ((cec_intr_status & (1 << 6)) && (cec_intr_status & (1 << 7))) {
1147 DEV_DBG("CEC_IRQ_FRAME_RD_DONE\n");
1148 HDMI_OUTP(0x029C, cec_intr_status |
1149 HDMI_MSM_CEC_INT_FRAME_RD_DONE_ACK);
1150 hdmi_msm_cec_msg_recv();
1151
Manoj Rao0f0ab642011-11-01 12:28:24 -07001152#ifdef TOGGLE_CEC_HARDWARE_FSM
1153 if (!msg_send_complete)
1154 msg_recv_complete = FALSE;
1155 else {
1156 /* Toggle CEC hardware FSM */
1157 HDMI_OUTP(0x028C, 0x0);
1158 HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
1159 }
1160#endif
Manoj Raoa2c27672011-08-30 17:19:39 -07001161
1162 return IRQ_HANDLED;
1163 }
1164#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
1165
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001166 DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>, ddc_int_ctrl=%04x, "
Manoj Raoa2c27672011-08-30 17:19:39 -07001167 "aud_int=%04x, cec_intr_status=%04x\n", __func__, hpd_int_ctrl,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001168 hpd_int_status, ddc_int_ctrl, audio_int_val,
1169 HDMI_INP_ND(0x029C));
1170
1171 return IRQ_HANDLED;
1172}
1173
1174static int check_hdmi_features(void)
1175{
1176 /* RAW_FEAT_CONFIG_ROW0_LSB */
1177 uint32 val = inpdw(QFPROM_BASE + 0x0238);
1178 /* HDMI_DISABLE */
1179 boolean hdmi_disabled = (val & 0x00200000) >> 21;
1180 /* HDCP_DISABLE */
1181 boolean hdcp_disabled = (val & 0x00400000) >> 22;
1182
1183 DEV_DBG("Features <val:0x%08x, HDMI:%s, HDCP:%s>\n", val,
1184 hdmi_disabled ? "OFF" : "ON", hdcp_disabled ? "OFF" : "ON");
1185 if (hdmi_disabled) {
1186 DEV_ERR("ERROR: HDMI disabled\n");
1187 return -ENODEV;
1188 }
1189
1190 if (hdcp_disabled)
1191 DEV_WARN("WARNING: HDCP disabled\n");
1192
1193 return 0;
1194}
1195
1196static boolean hdmi_msm_has_hdcp(void)
1197{
1198 /* RAW_FEAT_CONFIG_ROW0_LSB, HDCP_DISABLE */
1199 return (inpdw(QFPROM_BASE + 0x0238) & 0x00400000) ? FALSE : TRUE;
1200}
1201
1202static boolean hdmi_msm_is_power_on(void)
1203{
1204 /* HDMI_CTRL, ENABLE */
1205 return (HDMI_INP_ND(0x0000) & 0x00000001) ? TRUE : FALSE;
1206}
1207
1208/* 1.2.1.2.1 DVI Operation
1209 * HDMI compliance requires the HDMI core to support DVI as well. The
1210 * HDMI core also supports DVI. In DVI operation there are no preambles
1211 * and guardbands transmitted. THe TMDS encoding of video data remains
1212 * the same as HDMI. There are no VBI or audio packets transmitted. In
1213 * order to enable DVI mode in HDMI core, HDMI_DVI_SEL field of
1214 * HDMI_CTRL register needs to be programmed to 0. */
1215static boolean hdmi_msm_is_dvi_mode(void)
1216{
1217 /* HDMI_CTRL, HDMI_DVI_SEL */
1218 return (HDMI_INP_ND(0x0000) & 0x00000002) ? FALSE : TRUE;
1219}
1220
Ravishangar Kalyanam49a83b22011-07-20 15:28:44 -07001221void hdmi_msm_set_mode(boolean power_on)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001222{
1223 uint32 reg_val = 0;
1224 if (power_on) {
1225 /* ENABLE */
1226 reg_val |= 0x00000001; /* Enable the block */
1227 if (external_common_state->hdmi_sink == 0) {
1228 /* HDMI_DVI_SEL */
1229 reg_val |= 0x00000002;
Manoj Raob91fa712011-06-29 09:07:55 -07001230 if (external_common_state->present_hdcp)
1231 /* HDMI Encryption */
1232 reg_val |= 0x00000004;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001233 /* HDMI_CTRL */
1234 HDMI_OUTP(0x0000, reg_val);
1235 /* HDMI_DVI_SEL */
1236 reg_val &= ~0x00000002;
Manoj Raob91fa712011-06-29 09:07:55 -07001237 } else {
1238 if (external_common_state->present_hdcp)
1239 /* HDMI_Encryption_ON */
1240 reg_val |= 0x00000006;
1241 else
1242 reg_val |= 0x00000002;
1243 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001244 } else
1245 reg_val = 0x00000002;
1246
1247 /* HDMI_CTRL */
1248 HDMI_OUTP(0x0000, reg_val);
1249 DEV_DBG("HDMI Core: %s\n", power_on ? "Enable" : "Disable");
1250}
1251
1252static void msm_hdmi_init_ddc(void)
1253{
1254 /* 0x0220 HDMI_DDC_SPEED
1255 [31:16] PRESCALE prescale = (m * xtal_frequency) /
1256 (desired_i2c_speed), where m is multiply
1257 factor, default: m = 1
1258 [1:0] THRESHOLD Select threshold to use to determine whether value
1259 sampled on SDA is a 1 or 0. Specified in terms of the ratio
1260 between the number of sampled ones and the total number of times
1261 SDA is sampled.
1262 * 0x0: >0
1263 * 0x1: 1/4 of total samples
1264 * 0x2: 1/2 of total samples
1265 * 0x3: 3/4 of total samples */
1266 /* Configure the Pre-Scale multiplier
1267 * Configure the Threshold */
1268 HDMI_OUTP_ND(0x0220, (10 << 16) | (2 << 0));
1269
Abhishek Kharbandadee95102011-09-19 14:08:33 -07001270 /*
1271 * 0x0224 HDMI_DDC_SETUP
1272 * Setting 31:24 bits : Time units to wait before timeout
1273 * when clock is being stalled by external sink device
1274 */
1275 HDMI_OUTP_ND(0x0224, 0xff000000);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001276
1277 /* 0x027C HDMI_DDC_REF
1278 [6] REFTIMER_ENABLE Enable the timer
1279 * 0: Disable
1280 * 1: Enable
1281 [15:0] REFTIMER Value to set the register in order to generate
1282 DDC strobe. This register counts on HDCP application clock */
1283 /* Enable reference timer
1284 * 27 micro-seconds */
1285 HDMI_OUTP_ND(0x027C, (1 << 16) | (27 << 0));
1286}
1287
1288static int hdmi_msm_ddc_clear_irq(const char *what)
1289{
1290 const uint32 time_out = 0xFFFF;
1291 uint32 time_out_count, reg_val;
1292
1293 /* clear pending and enable interrupt */
1294 time_out_count = time_out;
1295 do {
1296 --time_out_count;
1297 /* HDMI_DDC_INT_CTRL[0x0214]
1298 [2] SW_DONE_MK Mask bit for SW_DONE_INT. Set to 1 to enable
1299 interrupt.
1300 [1] SW_DONE_ACK WRITE ONLY. Acknowledge bit for SW_DONE_INT.
1301 Write 1 to clear interrupt.
1302 [0] SW_DONE_INT READ ONLY. SW_DONE interrupt status */
1303 /* Clear and Enable DDC interrupt */
1304 /* Write */
1305 HDMI_OUTP_ND(0x0214, (1 << 2) | (1 << 1));
1306 /* Read back */
1307 reg_val = HDMI_INP_ND(0x0214);
1308 } while ((reg_val & 0x1) && time_out_count);
1309 if (!time_out_count) {
1310 DEV_ERR("%s[%s]: timedout\n", __func__, what);
1311 return -ETIMEDOUT;
1312 }
1313
1314 return 0;
1315}
1316
1317#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
1318static int hdmi_msm_ddc_write(uint32 dev_addr, uint32 offset,
1319 const uint8 *data_buf, uint32 data_len, const char *what)
1320{
1321 uint32 reg_val, ndx;
1322 int status = 0, retry = 10;
1323 uint32 time_out_count;
1324
1325 if (NULL == data_buf) {
1326 status = -EINVAL;
1327 DEV_ERR("%s[%s]: invalid input paramter\n", __func__, what);
1328 goto error;
1329 }
1330
1331again:
1332 status = hdmi_msm_ddc_clear_irq(what);
1333 if (status)
1334 goto error;
1335
1336 /* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
1337 dev_addr &= 0xFE;
1338
1339 /* 0x0238 HDMI_DDC_DATA
1340 [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
1341 1 while writing HDMI_DDC_DATA.
1342 [23:16] INDEX Use to set index into DDC buffer for next read or
1343 current write, or to read index of current read or next write.
1344 Writable only when INDEX_WRITE=1.
1345 [15:8] DATA Use to fill or read the DDC buffer
1346 [0] DATA_RW Select whether buffer access will be a read or write.
1347 For writes, address auto-increments on write to HDMI_DDC_DATA.
1348 For reads, address autoincrements on reads to HDMI_DDC_DATA.
1349 * 0: Write
1350 * 1: Read */
1351
1352 /* 1. Write to HDMI_I2C_DATA with the following fields set in order to
1353 * handle portion #1
1354 * DATA_RW = 0x1 (write)
1355 * DATA = linkAddress (primary link address and writing)
1356 * INDEX = 0x0 (initial offset into buffer)
1357 * INDEX_WRITE = 0x1 (setting initial offset) */
1358 HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (dev_addr << 8));
1359
1360 /* 2. Write to HDMI_I2C_DATA with the following fields set in order to
1361 * handle portion #2
1362 * DATA_RW = 0x0 (write)
1363 * DATA = offsetAddress
1364 * INDEX = 0x0
1365 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1366 HDMI_OUTP_ND(0x0238, offset << 8);
1367
1368 /* 3. Write to HDMI_I2C_DATA with the following fields set in order to
1369 * handle portion #3
1370 * DATA_RW = 0x0 (write)
1371 * DATA = data_buf[ndx]
1372 * INDEX = 0x0
1373 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1374 for (ndx = 0; ndx < data_len; ++ndx)
1375 HDMI_OUTP_ND(0x0238, ((uint32)data_buf[ndx]) << 8);
1376
1377 /* Data setup is complete, now setup the transaction characteristics */
1378
1379 /* 0x0228 HDMI_DDC_TRANS0
1380 [23:16] CNT0 Byte count for first transaction (excluding the first
1381 byte, which is usually the address).
1382 [13] STOP0 Determines whether a stop bit will be sent after the first
1383 transaction
1384 * 0: NO STOP
1385 * 1: STOP
1386 [12] START0 Determines whether a start bit will be sent before the
1387 first transaction
1388 * 0: NO START
1389 * 1: START
1390 [8] STOP_ON_NACK0 Determines whether the current transfer will stop
1391 if a NACK is received during the first transaction (current
1392 transaction always stops).
1393 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1394 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1395 [0] RW0 Read/write indicator for first transaction - set to 0 for
1396 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1397 the R/W bit in the transaction is programmed into the DDC buffer
1398 as the LSB of the address byte.
1399 * 0: WRITE
1400 * 1: READ */
1401
1402 /* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
1403 order to handle characteristics of portion #1 and portion #2
1404 * RW0 = 0x0 (write)
1405 * START0 = 0x1 (insert START bit)
1406 * STOP0 = 0x0 (do NOT insert STOP bit)
1407 * CNT0 = 0x1 (single byte transaction excluding address) */
1408 HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
1409
1410 /* 0x022C HDMI_DDC_TRANS1
1411 [23:16] CNT1 Byte count for second transaction (excluding the first
1412 byte, which is usually the address).
1413 [13] STOP1 Determines whether a stop bit will be sent after the second
1414 transaction
1415 * 0: NO STOP
1416 * 1: STOP
1417 [12] START1 Determines whether a start bit will be sent before the
1418 second transaction
1419 * 0: NO START
1420 * 1: START
1421 [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
1422 a NACK is received during the second transaction (current
1423 transaction always stops).
1424 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1425 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1426 [0] RW1 Read/write indicator for second transaction - set to 0 for
1427 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1428 the R/W bit in the transaction is programmed into the DDC buffer
1429 as the LSB of the address byte.
1430 * 0: WRITE
1431 * 1: READ */
1432
1433 /* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
1434 order to handle characteristics of portion #3
1435 * RW1 = 0x1 (read)
1436 * START1 = 0x1 (insert START bit)
1437 * STOP1 = 0x1 (insert STOP bit)
1438 * CNT1 = data_len (0xN (write N bytes of data))
1439 * Byte count for second transition (excluding the first
1440 * Byte which is usually the address) */
1441 HDMI_OUTP_ND(0x022C, (1 << 13) | ((data_len-1) << 16));
1442
1443 /* Trigger the I2C transfer */
1444 /* 0x020C HDMI_DDC_CTRL
1445 [21:20] TRANSACTION_CNT
1446 Number of transactions to be done in current transfer.
1447 * 0x0: transaction0 only
1448 * 0x1: transaction0, transaction1
1449 * 0x2: transaction0, transaction1, transaction2
1450 * 0x3: transaction0, transaction1, transaction2, transaction3
1451 [3] SW_STATUS_RESET
1452 Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
1453 ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
1454 STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
1455 [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
1456 data) at start of transfer. This sequence is sent after GO is
1457 written to 1, before the first transaction only.
1458 [1] SOFT_RESET Write 1 to reset DDC controller
1459 [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
1460
1461 /* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
1462 * Note that NOTHING has been transmitted on the DDC lines up to this
1463 * point.
1464 * TRANSACTION_CNT = 0x1 (execute transaction0 followed by
1465 * transaction1)
1466 * GO = 0x1 (kicks off hardware) */
1467 INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
1468 HDMI_OUTP_ND(0x020C, (1 << 0) | (1 << 20));
1469
1470 time_out_count = wait_for_completion_interruptible_timeout(
1471 &hdmi_msm_state->ddc_sw_done, HZ/2);
1472 HDMI_OUTP_ND(0x0214, 0x2);
1473 if (!time_out_count) {
1474 if (retry-- > 0) {
1475 DEV_INFO("%s[%s]: failed timout, retry=%d\n", __func__,
1476 what, retry);
1477 goto again;
1478 }
1479 status = -ETIMEDOUT;
1480 DEV_ERR("%s[%s]: timedout, DDC SW Status=%08x, HW "
1481 "Status=%08x, Int Ctrl=%08x\n", __func__, what,
1482 HDMI_INP_ND(0x0218), HDMI_INP_ND(0x021C),
1483 HDMI_INP_ND(0x0214));
1484 goto error;
1485 }
1486
1487 /* Read DDC status */
1488 reg_val = HDMI_INP_ND(0x0218);
1489 reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
1490
1491 /* Check if any NACK occurred */
1492 if (reg_val) {
1493 if (retry > 1)
1494 HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
1495 else
1496 HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
1497 if (retry-- > 0) {
1498 DEV_DBG("%s[%s]: failed NACK=%08x, retry=%d\n",
1499 __func__, what, reg_val, retry);
1500 msleep(100);
1501 goto again;
1502 }
1503 status = -EIO;
1504 DEV_ERR("%s[%s]: failed NACK: %08x\n", __func__, what, reg_val);
1505 goto error;
1506 }
1507
1508 DEV_DBG("%s[%s] success\n", __func__, what);
1509
1510error:
1511 return status;
1512}
1513#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
1514
1515static int hdmi_msm_ddc_read_retry(uint32 dev_addr, uint32 offset,
1516 uint8 *data_buf, uint32 data_len, uint32 request_len, int retry,
1517 const char *what)
1518{
1519 uint32 reg_val, ndx;
1520 int status = 0;
1521 uint32 time_out_count;
1522 int log_retry_fail = retry != 1;
1523
1524 if (NULL == data_buf) {
1525 status = -EINVAL;
1526 DEV_ERR("%s: invalid input paramter\n", __func__);
1527 goto error;
1528 }
1529
1530again:
1531 status = hdmi_msm_ddc_clear_irq(what);
1532 if (status)
1533 goto error;
1534
1535 /* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
1536 dev_addr &= 0xFE;
1537
1538 /* 0x0238 HDMI_DDC_DATA
1539 [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
1540 1 while writing HDMI_DDC_DATA.
1541 [23:16] INDEX Use to set index into DDC buffer for next read or
1542 current write, or to read index of current read or next write.
1543 Writable only when INDEX_WRITE=1.
1544 [15:8] DATA Use to fill or read the DDC buffer
1545 [0] DATA_RW Select whether buffer access will be a read or write.
1546 For writes, address auto-increments on write to HDMI_DDC_DATA.
1547 For reads, address autoincrements on reads to HDMI_DDC_DATA.
1548 * 0: Write
1549 * 1: Read */
1550
1551 /* 1. Write to HDMI_I2C_DATA with the following fields set in order to
1552 * handle portion #1
1553 * DATA_RW = 0x0 (write)
1554 * DATA = linkAddress (primary link address and writing)
1555 * INDEX = 0x0 (initial offset into buffer)
1556 * INDEX_WRITE = 0x1 (setting initial offset) */
1557 HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (dev_addr << 8));
1558
1559 /* 2. Write to HDMI_I2C_DATA with the following fields set in order to
1560 * handle portion #2
1561 * DATA_RW = 0x0 (write)
1562 * DATA = offsetAddress
1563 * INDEX = 0x0
1564 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1565 HDMI_OUTP_ND(0x0238, offset << 8);
1566
1567 /* 3. Write to HDMI_I2C_DATA with the following fields set in order to
1568 * handle portion #3
1569 * DATA_RW = 0x0 (write)
1570 * DATA = linkAddress + 1 (primary link address 0x74 and reading)
1571 * INDEX = 0x0
1572 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1573 HDMI_OUTP_ND(0x0238, (dev_addr | 1) << 8);
1574
1575 /* Data setup is complete, now setup the transaction characteristics */
1576
1577 /* 0x0228 HDMI_DDC_TRANS0
1578 [23:16] CNT0 Byte count for first transaction (excluding the first
1579 byte, which is usually the address).
1580 [13] STOP0 Determines whether a stop bit will be sent after the first
1581 transaction
1582 * 0: NO STOP
1583 * 1: STOP
1584 [12] START0 Determines whether a start bit will be sent before the
1585 first transaction
1586 * 0: NO START
1587 * 1: START
1588 [8] STOP_ON_NACK0 Determines whether the current transfer will stop
1589 if a NACK is received during the first transaction (current
1590 transaction always stops).
1591 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1592 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1593 [0] RW0 Read/write indicator for first transaction - set to 0 for
1594 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1595 the R/W bit in the transaction is programmed into the DDC buffer
1596 as the LSB of the address byte.
1597 * 0: WRITE
1598 * 1: READ */
1599
1600 /* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
1601 order to handle characteristics of portion #1 and portion #2
1602 * RW0 = 0x0 (write)
1603 * START0 = 0x1 (insert START bit)
1604 * STOP0 = 0x0 (do NOT insert STOP bit)
1605 * CNT0 = 0x1 (single byte transaction excluding address) */
1606 HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
1607
1608 /* 0x022C HDMI_DDC_TRANS1
1609 [23:16] CNT1 Byte count for second transaction (excluding the first
1610 byte, which is usually the address).
1611 [13] STOP1 Determines whether a stop bit will be sent after the second
1612 transaction
1613 * 0: NO STOP
1614 * 1: STOP
1615 [12] START1 Determines whether a start bit will be sent before the
1616 second transaction
1617 * 0: NO START
1618 * 1: START
1619 [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
1620 a NACK is received during the second transaction (current
1621 transaction always stops).
1622 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1623 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1624 [0] RW1 Read/write indicator for second transaction - set to 0 for
1625 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1626 the R/W bit in the transaction is programmed into the DDC buffer
1627 as the LSB of the address byte.
1628 * 0: WRITE
1629 * 1: READ */
1630
1631 /* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
1632 order to handle characteristics of portion #3
1633 * RW1 = 0x1 (read)
1634 * START1 = 0x1 (insert START bit)
1635 * STOP1 = 0x1 (insert STOP bit)
1636 * CNT1 = data_len (it's 128 (0x80) for a blk read) */
1637 HDMI_OUTP_ND(0x022C, 1 | (1 << 12) | (1 << 13) | (request_len << 16));
1638
1639 /* Trigger the I2C transfer */
1640 /* 0x020C HDMI_DDC_CTRL
1641 [21:20] TRANSACTION_CNT
1642 Number of transactions to be done in current transfer.
1643 * 0x0: transaction0 only
1644 * 0x1: transaction0, transaction1
1645 * 0x2: transaction0, transaction1, transaction2
1646 * 0x3: transaction0, transaction1, transaction2, transaction3
1647 [3] SW_STATUS_RESET
1648 Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
1649 ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
1650 STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
1651 [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
1652 data) at start of transfer. This sequence is sent after GO is
1653 written to 1, before the first transaction only.
1654 [1] SOFT_RESET Write 1 to reset DDC controller
1655 [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
1656
1657 /* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
1658 * Note that NOTHING has been transmitted on the DDC lines up to this
1659 * point.
1660 * TRANSACTION_CNT = 0x1 (execute transaction0 followed by
1661 * transaction1)
1662 * SEND_RESET = Set to 1 to send reset sequence
1663 * GO = 0x1 (kicks off hardware) */
1664 INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
1665 HDMI_OUTP_ND(0x020C, (1 << 0) | (1 << 20));
1666
1667 time_out_count = wait_for_completion_interruptible_timeout(
1668 &hdmi_msm_state->ddc_sw_done, HZ/2);
1669 HDMI_OUTP_ND(0x0214, 0x2);
1670 if (!time_out_count) {
1671 if (retry-- > 0) {
1672 DEV_INFO("%s: failed timout, retry=%d\n", __func__,
1673 retry);
1674 goto again;
1675 }
1676 status = -ETIMEDOUT;
1677 DEV_ERR("%s: timedout(7), DDC SW Status=%08x, HW "
1678 "Status=%08x, Int Ctrl=%08x\n", __func__,
1679 HDMI_INP(0x0218), HDMI_INP(0x021C), HDMI_INP(0x0214));
1680 goto error;
1681 }
1682
1683 /* Read DDC status */
1684 reg_val = HDMI_INP_ND(0x0218);
1685 reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
1686
1687 /* Check if any NACK occurred */
1688 if (reg_val) {
1689 HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
1690 if (retry == 1)
1691 HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
1692 if (retry-- > 0) {
1693 DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d, "
1694 "dev-addr=0x%02x, offset=0x%02x, "
1695 "length=%d\n", __func__, what,
1696 reg_val, retry, dev_addr,
1697 offset, data_len);
1698 goto again;
1699 }
1700 status = -EIO;
1701 if (log_retry_fail)
1702 DEV_ERR("%s(%s): failed NACK=0x%08x, dev-addr=0x%02x, "
1703 "offset=0x%02x, length=%d\n", __func__, what,
1704 reg_val, dev_addr, offset, data_len);
1705 goto error;
1706 }
1707
1708 /* 0x0238 HDMI_DDC_DATA
1709 [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to 1
1710 while writing HDMI_DDC_DATA.
1711 [23:16] INDEX Use to set index into DDC buffer for next read or
1712 current write, or to read index of current read or next write.
1713 Writable only when INDEX_WRITE=1.
1714 [15:8] DATA Use to fill or read the DDC buffer
1715 [0] DATA_RW Select whether buffer access will be a read or write.
1716 For writes, address auto-increments on write to HDMI_DDC_DATA.
1717 For reads, address autoincrements on reads to HDMI_DDC_DATA.
1718 * 0: Write
1719 * 1: Read */
1720
1721 /* 8. ALL data is now available and waiting in the DDC buffer.
1722 * Read HDMI_I2C_DATA with the following fields set
1723 * RW = 0x1 (read)
1724 * DATA = BCAPS (this is field where data is pulled from)
1725 * INDEX = 0x3 (where the data has been placed in buffer by hardware)
1726 * INDEX_WRITE = 0x1 (explicitly define offset) */
1727 /* Write this data to DDC buffer */
1728 HDMI_OUTP_ND(0x0238, 0x1 | (3 << 16) | (1 << 31));
1729
1730 /* Discard first byte */
1731 HDMI_INP_ND(0x0238);
1732 for (ndx = 0; ndx < data_len; ++ndx) {
1733 reg_val = HDMI_INP_ND(0x0238);
1734 data_buf[ndx] = (uint8) ((reg_val & 0x0000FF00) >> 8);
1735 }
1736
1737 DEV_DBG("%s[%s] success\n", __func__, what);
1738
1739error:
1740 return status;
1741}
1742
1743static int hdmi_msm_ddc_read_edid_seg(uint32 dev_addr, uint32 offset,
1744 uint8 *data_buf, uint32 data_len, uint32 request_len, int retry,
1745 const char *what)
1746{
1747 uint32 reg_val, ndx;
1748 int status = 0;
1749 uint32 time_out_count;
1750 int log_retry_fail = retry != 1;
1751 int seg_addr = 0x60, seg_num = 0x01;
1752
1753 if (NULL == data_buf) {
1754 status = -EINVAL;
1755 DEV_ERR("%s: invalid input paramter\n", __func__);
1756 goto error;
1757 }
1758
1759again:
1760 status = hdmi_msm_ddc_clear_irq(what);
1761 if (status)
1762 goto error;
1763
1764 /* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
1765 dev_addr &= 0xFE;
1766
1767 /* 0x0238 HDMI_DDC_DATA
1768 [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
1769 1 while writing HDMI_DDC_DATA.
1770 [23:16] INDEX Use to set index into DDC buffer for next read or
1771 current write, or to read index of current read or next write.
1772 Writable only when INDEX_WRITE=1.
1773 [15:8] DATA Use to fill or read the DDC buffer
1774 [0] DATA_RW Select whether buffer access will be a read or write.
1775 For writes, address auto-increments on write to HDMI_DDC_DATA.
1776 For reads, address autoincrements on reads to HDMI_DDC_DATA.
1777 * 0: Write
1778 * 1: Read */
1779
1780 /* 1. Write to HDMI_I2C_DATA with the following fields set in order to
1781 * handle portion #1
1782 * DATA_RW = 0x0 (write)
1783 * DATA = linkAddress (primary link address and writing)
1784 * INDEX = 0x0 (initial offset into buffer)
1785 * INDEX_WRITE = 0x1 (setting initial offset) */
1786 HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (seg_addr << 8));
1787
1788 /* 2. Write to HDMI_I2C_DATA with the following fields set in order to
1789 * handle portion #2
1790 * DATA_RW = 0x0 (write)
1791 * DATA = offsetAddress
1792 * INDEX = 0x0
1793 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1794 HDMI_OUTP_ND(0x0238, seg_num << 8);
1795
1796 /* 3. Write to HDMI_I2C_DATA with the following fields set in order to
1797 * handle portion #3
1798 * DATA_RW = 0x0 (write)
1799 * DATA = linkAddress + 1 (primary link address 0x74 and reading)
1800 * INDEX = 0x0
1801 * INDEX_WRITE = 0x0 (auto-increment by hardware) */
1802 HDMI_OUTP_ND(0x0238, dev_addr << 8);
1803 HDMI_OUTP_ND(0x0238, offset << 8);
1804 HDMI_OUTP_ND(0x0238, (dev_addr | 1) << 8);
1805
1806 /* Data setup is complete, now setup the transaction characteristics */
1807
1808 /* 0x0228 HDMI_DDC_TRANS0
1809 [23:16] CNT0 Byte count for first transaction (excluding the first
1810 byte, which is usually the address).
1811 [13] STOP0 Determines whether a stop bit will be sent after the first
1812 transaction
1813 * 0: NO STOP
1814 * 1: STOP
1815 [12] START0 Determines whether a start bit will be sent before the
1816 first transaction
1817 * 0: NO START
1818 * 1: START
1819 [8] STOP_ON_NACK0 Determines whether the current transfer will stop
1820 if a NACK is received during the first transaction (current
1821 transaction always stops).
1822 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1823 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1824 [0] RW0 Read/write indicator for first transaction - set to 0 for
1825 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1826 the R/W bit in the transaction is programmed into the DDC buffer
1827 as the LSB of the address byte.
1828 * 0: WRITE
1829 * 1: READ */
1830
1831 /* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
1832 order to handle characteristics of portion #1 and portion #2
1833 * RW0 = 0x0 (write)
1834 * START0 = 0x1 (insert START bit)
1835 * STOP0 = 0x0 (do NOT insert STOP bit)
1836 * CNT0 = 0x1 (single byte transaction excluding address) */
1837 HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
1838
1839 /* 0x022C HDMI_DDC_TRANS1
1840 [23:16] CNT1 Byte count for second transaction (excluding the first
1841 byte, which is usually the address).
1842 [13] STOP1 Determines whether a stop bit will be sent after the second
1843 transaction
1844 * 0: NO STOP
1845 * 1: STOP
1846 [12] START1 Determines whether a start bit will be sent before the
1847 second transaction
1848 * 0: NO START
1849 * 1: START
1850 [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
1851 a NACK is received during the second transaction (current
1852 transaction always stops).
1853 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1854 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1855 [0] RW1 Read/write indicator for second transaction - set to 0 for
1856 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1857 the R/W bit in the transaction is programmed into the DDC buffer
1858 as the LSB of the address byte.
1859 * 0: WRITE
1860 * 1: READ */
1861
1862 /* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
1863 order to handle characteristics of portion #3
1864 * RW1 = 0x1 (read)
1865 * START1 = 0x1 (insert START bit)
1866 * STOP1 = 0x1 (insert STOP bit)
1867 * CNT1 = data_len (it's 128 (0x80) for a blk read) */
1868 HDMI_OUTP_ND(0x022C, (1 << 12) | (1 << 16));
1869
1870 /* 0x022C HDMI_DDC_TRANS2
1871 [23:16] CNT1 Byte count for second transaction (excluding the first
1872 byte, which is usually the address).
1873 [13] STOP1 Determines whether a stop bit will be sent after the second
1874 transaction
1875 * 0: NO STOP
1876 * 1: STOP
1877 [12] START1 Determines whether a start bit will be sent before the
1878 second transaction
1879 * 0: NO START
1880 * 1: START
1881 [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
1882 a NACK is received during the second transaction (current
1883 transaction always stops).
1884 * 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
1885 * 1: STOP ALL TRANSACTIONS, SEND STOP BIT
1886 [0] RW1 Read/write indicator for second transaction - set to 0 for
1887 write, 1 for read. This bit only controls HDMI_DDC behaviour -
1888 the R/W bit in the transaction is programmed into the DDC buffer
1889 as the LSB of the address byte.
1890 * 0: WRITE
1891 * 1: READ */
1892
1893 /* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
1894 order to handle characteristics of portion #3
1895 * RW1 = 0x1 (read)
1896 * START1 = 0x1 (insert START bit)
1897 * STOP1 = 0x1 (insert STOP bit)
1898 * CNT1 = data_len (it's 128 (0x80) for a blk read) */
1899 HDMI_OUTP_ND(0x0230, 1 | (1 << 12) | (1 << 13) | (request_len << 16));
1900
1901 /* Trigger the I2C transfer */
1902 /* 0x020C HDMI_DDC_CTRL
1903 [21:20] TRANSACTION_CNT
1904 Number of transactions to be done in current transfer.
1905 * 0x0: transaction0 only
1906 * 0x1: transaction0, transaction1
1907 * 0x2: transaction0, transaction1, transaction2
1908 * 0x3: transaction0, transaction1, transaction2, transaction3
1909 [3] SW_STATUS_RESET
1910 Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
1911 ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
1912 STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
1913 [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
1914 data) at start of transfer. This sequence is sent after GO is
1915 written to 1, before the first transaction only.
1916 [1] SOFT_RESET Write 1 to reset DDC controller
1917 [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
1918
1919 /* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
1920 * Note that NOTHING has been transmitted on the DDC lines up to this
1921 * point.
1922 * TRANSACTION_CNT = 0x2 (execute transaction0 followed by
1923 * transaction1)
1924 * GO = 0x1 (kicks off hardware) */
1925 INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
1926 HDMI_OUTP_ND(0x020C, (1 << 0) | (2 << 20));
1927
1928 time_out_count = wait_for_completion_interruptible_timeout(
1929 &hdmi_msm_state->ddc_sw_done, HZ/2);
1930 HDMI_OUTP_ND(0x0214, 0x2);
1931 if (!time_out_count) {
1932 if (retry-- > 0) {
1933 DEV_INFO("%s: failed timout, retry=%d\n", __func__,
1934 retry);
1935 goto again;
1936 }
1937 status = -ETIMEDOUT;
1938 DEV_ERR("%s: timedout(7), DDC SW Status=%08x, HW "
1939 "Status=%08x, Int Ctrl=%08x\n", __func__,
1940 HDMI_INP(0x0218), HDMI_INP(0x021C), HDMI_INP(0x0214));
1941 goto error;
1942 }
1943
1944 /* Read DDC status */
1945 reg_val = HDMI_INP_ND(0x0218);
1946 reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
1947
1948 /* Check if any NACK occurred */
1949 if (reg_val) {
1950 HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
1951 if (retry == 1)
1952 HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
1953 if (retry-- > 0) {
1954 DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d, "
1955 "dev-addr=0x%02x, offset=0x%02x, "
1956 "length=%d\n", __func__, what,
1957 reg_val, retry, dev_addr,
1958 offset, data_len);
1959 goto again;
1960 }
1961 status = -EIO;
1962 if (log_retry_fail)
1963 DEV_ERR("%s(%s): failed NACK=0x%08x, dev-addr=0x%02x, "
1964 "offset=0x%02x, length=%d\n", __func__, what,
1965 reg_val, dev_addr, offset, data_len);
1966 goto error;
1967 }
1968
1969 /* 0x0238 HDMI_DDC_DATA
1970 [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to 1
1971 while writing HDMI_DDC_DATA.
1972 [23:16] INDEX Use to set index into DDC buffer for next read or
1973 current write, or to read index of current read or next write.
1974 Writable only when INDEX_WRITE=1.
1975 [15:8] DATA Use to fill or read the DDC buffer
1976 [0] DATA_RW Select whether buffer access will be a read or write.
1977 For writes, address auto-increments on write to HDMI_DDC_DATA.
1978 For reads, address autoincrements on reads to HDMI_DDC_DATA.
1979 * 0: Write
1980 * 1: Read */
1981
1982 /* 8. ALL data is now available and waiting in the DDC buffer.
1983 * Read HDMI_I2C_DATA with the following fields set
1984 * RW = 0x1 (read)
1985 * DATA = BCAPS (this is field where data is pulled from)
Manoj Raoebefc802011-10-19 11:16:08 -07001986 * INDEX = 0x5 (where the data has been placed in buffer by hardware)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001987 * INDEX_WRITE = 0x1 (explicitly define offset) */
1988 /* Write this data to DDC buffer */
Manoj Raoebefc802011-10-19 11:16:08 -07001989 HDMI_OUTP_ND(0x0238, 0x1 | (5 << 16) | (1 << 31));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001990
1991 /* Discard first byte */
1992 HDMI_INP_ND(0x0238);
Manoj Raoebefc802011-10-19 11:16:08 -07001993
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001994 for (ndx = 0; ndx < data_len; ++ndx) {
1995 reg_val = HDMI_INP_ND(0x0238);
1996 data_buf[ndx] = (uint8) ((reg_val & 0x0000FF00) >> 8);
1997 }
1998
1999 DEV_DBG("%s[%s] success\n", __func__, what);
2000
2001error:
2002 return status;
2003}
2004
2005
2006static int hdmi_msm_ddc_read(uint32 dev_addr, uint32 offset, uint8 *data_buf,
2007 uint32 data_len, int retry, const char *what, boolean no_align)
2008{
2009 int ret = hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf, data_len,
2010 data_len, retry, what);
2011 if (!ret)
2012 return 0;
2013 if (no_align) {
2014 return hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf,
2015 data_len, data_len, retry, what);
2016 } else {
2017 return hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf,
2018 data_len, 32 * ((data_len + 31) / 32), retry, what);
2019 }
2020}
2021
2022
2023static int hdmi_msm_read_edid_block(int block, uint8 *edid_buf)
2024{
2025 int i, rc = 0;
2026 int block_size = 0x80;
2027
2028 do {
2029 DEV_DBG("EDID: reading block(%d) with block-size=%d\n",
2030 block, block_size);
2031 for (i = 0; i < 0x80; i += block_size) {
2032 /*Read EDID twice with 32bit alighnment too */
2033 if (block < 2) {
2034 rc = hdmi_msm_ddc_read(0xA0, block*0x80 + i,
2035 edid_buf+i, block_size, 1,
2036 "EDID", FALSE);
2037 } else {
2038 rc = hdmi_msm_ddc_read_edid_seg(0xA0,
2039 block*0x80 + i, edid_buf+i, block_size,
2040 block_size, 1, "EDID");
2041 }
2042 if (rc)
2043 break;
2044 }
2045
2046 block_size /= 2;
2047 } while (rc && (block_size >= 16));
2048
2049 return rc;
2050}
2051
2052static int hdmi_msm_read_edid(void)
2053{
2054 int status;
2055
2056 msm_hdmi_init_ddc();
2057 /* Looks like we need to turn on HDMI engine before any
2058 * DDC transaction */
2059 if (!hdmi_msm_is_power_on()) {
2060 DEV_ERR("%s: failed: HDMI power is off", __func__);
2061 status = -ENXIO;
2062 goto error;
2063 }
2064
2065 external_common_state->read_edid_block = hdmi_msm_read_edid_block;
2066 status = hdmi_common_read_edid();
2067 if (!status)
2068 DEV_DBG("EDID: successfully read\n");
2069
2070error:
2071 return status;
2072}
2073
2074#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
2075static void hdcp_auth_info(uint32 auth_info)
2076{
2077 switch (auth_info) {
2078 case 0:
2079 DEV_INFO("%s: None", __func__);
2080 break;
2081 case 1:
2082 DEV_INFO("%s: Software Disabled Authentication", __func__);
2083 break;
2084 case 2:
2085 DEV_INFO("%s: An Written", __func__);
2086 break;
2087 case 3:
2088 DEV_INFO("%s: Invalid Aksv", __func__);
2089 break;
2090 case 4:
2091 DEV_INFO("%s: Invalid Bksv", __func__);
2092 break;
2093 case 5:
2094 DEV_INFO("%s: RI Mismatch (including RO)", __func__);
2095 break;
2096 case 6:
2097 DEV_INFO("%s: consecutive Pj Mismatches", __func__);
2098 break;
2099 case 7:
2100 DEV_INFO("%s: HPD Disconnect", __func__);
2101 break;
2102 case 8:
2103 default:
2104 DEV_INFO("%s: Reserved", __func__);
2105 break;
2106 }
2107}
2108
2109static void hdcp_key_state(uint32 key_state)
2110{
2111 switch (key_state) {
2112 case 0:
2113 DEV_WARN("%s: No HDCP Keys", __func__);
2114 break;
2115 case 1:
2116 DEV_WARN("%s: Not Checked", __func__);
2117 break;
2118 case 2:
2119 DEV_DBG("%s: Checking", __func__);
2120 break;
2121 case 3:
2122 DEV_DBG("%s: HDCP Keys Valid", __func__);
2123 break;
2124 case 4:
2125 DEV_WARN("%s: AKSV not valid", __func__);
2126 break;
2127 case 5:
2128 DEV_WARN("%s: Checksum Mismatch", __func__);
2129 break;
2130 case 6:
2131 DEV_DBG("%s: Production AKSV"
2132 "with ENABLE_USER_DEFINED_AN=1", __func__);
2133 break;
2134 case 7:
2135 default:
2136 DEV_INFO("%s: Reserved", __func__);
2137 break;
2138 }
2139}
2140
2141static int hdmi_msm_count_one(uint8 *array, uint8 len)
2142{
2143 int i, j, count = 0;
2144 for (i = 0; i < len; i++)
2145 for (j = 0; j < 8; j++)
2146 count += (((array[i] >> j) & 0x1) ? 1 : 0);
2147 return count;
2148}
2149
2150static void hdcp_deauthenticate(void)
2151{
2152 int hdcp_link_status = HDMI_INP(0x011C);
2153
2154 external_common_state->hdcp_active = FALSE;
2155 /* 0x0130 HDCP_RESET
2156 [0] LINK0_DEAUTHENTICATE */
2157 HDMI_OUTP(0x0130, 0x1);
2158
2159 /* 0x0110 HDCP_CTRL
2160 [8] ENCRYPTION_ENABLE
2161 [0] ENABLE */
2162 /* encryption_enable = 0 | hdcp block enable = 1 */
2163 HDMI_OUTP(0x0110, 0x0);
2164
2165 if (hdcp_link_status & 0x00000004)
2166 hdcp_auth_info((hdcp_link_status & 0x000000F0) >> 4);
Aravind Venkateswarandaf5e172011-11-30 18:34:40 -08002167
2168 /* Disable HDCP interrupts */
2169 HDMI_OUTP(0x0118, 0x0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002170}
2171
Aravind Venkateswarand2fb0bd2011-11-30 18:38:14 -08002172static void check_and_clear_HDCP_DDC_Failure(void)
2173{
2174 int hdcp_ddc_ctrl1_reg;
2175 int hdcp_ddc_status;
2176 int failure;
2177 int nack0;
2178
2179 /*
2180 * Check for any DDC transfer failures
2181 * 0x0128 HDCP_DDC_STATUS
2182 * [16] FAILED Indicates that the last HDCP HW DDC transer
2183 * failed. This occurs when a transfer is
2184 * attempted with HDCP DDC disabled
2185 * (HDCP_DDC_DISABLE=1) or the number of retries
2186 * match HDCP_DDC_RETRY_CNT
2187 *
2188 * [14] NACK0 Indicates that the last HDCP HW DDC transfer
2189 * was aborted due to a NACK on the first
2190 * transaction - cleared by writing 0 to GO bit
2191 */
2192 hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
2193 failure = (hdcp_ddc_status >> 16) & 0x1;
2194 nack0 = (hdcp_ddc_status >> 14) & 0x1;
2195 DEV_DBG("%s: On Entry: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
2196 "NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
2197
2198 if (failure == 0x1) {
2199 /*
2200 * Indicates that the last HDCP HW DDC transfer failed.
2201 * This occurs when a transfer is attempted with HDCP DDC
2202 * disabled (HDCP_DDC_DISABLE=1) or the number of retries
2203 * matches HDCP_DDC_RETRY_CNT.
2204 * Failure occured, let's clear it.
2205 */
2206 DEV_INFO("%s: DDC failure detected. HDCP_DDC_STATUS=0x%08x\n",
2207 __func__, hdcp_ddc_status);
2208 /*
2209 * First, Disable DDC
2210 * 0x0120 HDCP_DDC_CTRL_0
2211 * [0] DDC_DISABLE Determines whether HDCP Ri and Pj reads
2212 * are done unassisted by hardware or by
2213 * software via HDMI_DDC (HDCP provides
2214 * interrupts to request software
2215 * transfers)
2216 * 0 : Use Hardware DDC
2217 * 1 : Use Software DDC
2218 */
2219 HDMI_OUTP(HDCP_DDC_CTRL_0, 0x1);
2220
2221 /*
2222 * ACK the Failure to Clear it
2223 * 0x0124 HDCP_DDC_CTRL_1
2224 * [0] DDC_FAILED_ACK Write 1 to clear
2225 * HDCP_STATUS.HDCP_DDC_FAILED
2226 */
2227 hdcp_ddc_ctrl1_reg = HDMI_INP(HDCP_DDC_CTRL_1);
2228 HDMI_OUTP(HDCP_DDC_CTRL_1, hdcp_ddc_ctrl1_reg | 0x1);
2229
2230 /* Check if the FAILURE got Cleared */
2231 hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
2232 hdcp_ddc_status = (hdcp_ddc_status >> 16) & 0x1;
2233 if (hdcp_ddc_status == 0x0) {
2234 DEV_INFO("%s: HDCP DDC Failure has been cleared\n",
2235 __func__);
2236 } else {
2237 DEV_WARN("%s: Error: HDCP DDC Failure DID NOT get"
2238 "cleared\n", __func__);
2239 }
2240
2241 /* Re-Enable HDCP DDC */
2242 HDMI_OUTP(HDCP_DDC_CTRL_0, 0x0);
2243 }
2244
2245 if (nack0 == 0x1) {
2246 /*
2247 * 0x020C HDMI_DDC_CTRL
2248 * [3] SW_STATUS_RESET Write 1 to reset HDMI_DDC_SW_STATUS
2249 * flags, will reset SW_DONE, ABORTED,
2250 * TIMEOUT, SW_INTERRUPTED,
2251 * BUFFER_OVERFLOW, STOPPED_ON_NACK, NACK0,
2252 * NACK1, NACK2, NACK3
2253 */
2254 HDMI_OUTP_ND(HDMI_DDC_CTRL,
2255 HDMI_INP(HDMI_DDC_CTRL) | (0x1 << 3));
2256 msleep(20);
2257 HDMI_OUTP_ND(HDMI_DDC_CTRL,
2258 HDMI_INP(HDMI_DDC_CTRL) & ~(0x1 << 3));
2259 }
2260
2261 hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
2262
2263 failure = (hdcp_ddc_status >> 16) & 0x1;
2264 nack0 = (hdcp_ddc_status >> 14) & 0x1;
2265 DEV_DBG("%s: On Exit: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
2266 "NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
2267}
2268
2269
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002270static int hdcp_authentication_part1(void)
2271{
2272 int ret = 0;
2273 boolean is_match;
2274 boolean is_part1_done = FALSE;
2275 uint32 timeout_count;
2276 uint8 bcaps;
2277 uint8 aksv[5];
2278 uint32 qfprom_aksv_0, qfprom_aksv_1, link0_aksv_0, link0_aksv_1;
2279 uint8 bksv[5];
2280 uint32 link0_bksv_0, link0_bksv_1;
2281 uint8 an[8];
2282 uint32 link0_an_0, link0_an_1;
2283 uint32 hpd_int_status, hpd_int_ctrl;
2284
2285
2286 static uint8 buf[0xFF];
2287 memset(buf, 0, sizeof(buf));
2288
2289 if (!is_part1_done) {
2290 is_part1_done = TRUE;
2291
2292 /* Fetch aksv from QFprom, this info should be public. */
2293 qfprom_aksv_0 = inpdw(QFPROM_BASE + 0x000060D8);
2294 qfprom_aksv_1 = inpdw(QFPROM_BASE + 0x000060DC);
2295
2296 /* copy an and aksv to byte arrays for transmission */
2297 aksv[0] = qfprom_aksv_0 & 0xFF;
2298 aksv[1] = (qfprom_aksv_0 >> 8) & 0xFF;
2299 aksv[2] = (qfprom_aksv_0 >> 16) & 0xFF;
2300 aksv[3] = (qfprom_aksv_0 >> 24) & 0xFF;
2301 aksv[4] = qfprom_aksv_1 & 0xFF;
2302 /* check there are 20 ones in AKSV */
2303 if (hdmi_msm_count_one(aksv, 5) != 20) {
Aravind Venkateswarane88f8f52011-12-13 19:07:20 -08002304 DEV_ERR("HDCP: AKSV read from QFPROM doesn't have "
2305 "20 1's and 20 0's, FAIL (AKSV=%02x%08x)\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002306 qfprom_aksv_1, qfprom_aksv_0);
2307 ret = -EINVAL;
2308 goto error;
2309 }
2310 DEV_DBG("HDCP: AKSV=%02x%08x\n", qfprom_aksv_1, qfprom_aksv_0);
2311
2312 /* 0x0288 HDCP_SW_LOWER_AKSV
2313 [31:0] LOWER_AKSV */
2314 /* 0x0284 HDCP_SW_UPPER_AKSV
2315 [7:0] UPPER_AKSV */
2316
2317 /* This is the lower 32 bits of the SW
2318 * injected AKSV value(AKSV[31:0]) read
2319 * from the EFUSE. It is needed for HDCP
2320 * authentication and must be written
2321 * before enabling HDCP. */
2322 HDMI_OUTP(0x0288, qfprom_aksv_0);
2323 HDMI_OUTP(0x0284, qfprom_aksv_1);
2324
2325 msm_hdmi_init_ddc();
2326
2327 /* Read Bksv 5 bytes at 0x00 in HDCP port */
2328 ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
2329 if (ret) {
2330 DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
2331 goto error;
2332 }
2333 /* check there are 20 ones in BKSV */
2334 if (hdmi_msm_count_one(bksv, 5) != 20) {
Aravind Venkateswarane88f8f52011-12-13 19:07:20 -08002335 DEV_ERR("HDCP: BKSV read from Sink doesn't have "
2336 "20 1's and 20 0's, FAIL (BKSV="
2337 "%02x%02x%02x%02x%02x)\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002338 bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
2339 ret = -EINVAL;
2340 goto error;
2341 }
2342
2343 link0_bksv_0 = bksv[3];
2344 link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
2345 link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
2346 link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
2347 link0_bksv_1 = bksv[4];
2348 DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
2349
2350 /* read Bcaps at 0x40 in HDCP Port */
2351 ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps",
2352 TRUE);
2353 if (ret) {
2354 DEV_ERR("%s(%d): Read Bcaps failed", __func__,
2355 __LINE__);
2356 goto error;
2357 }
2358 DEV_DBG("HDCP: Bcaps=%02x\n", bcaps);
2359
2360 /* HDCP setup prior to HDCP enabled */
2361
2362 /* 0x0148 HDCP_RCVPORT_DATA4
2363 [15:8] LINK0_AINFO
2364 [7:0] LINK0_AKSV_1 */
2365 /* LINK0_AINFO = 0x2 FEATURE 1.1 on.
2366 * = 0x0 FEATURE 1.1 off*/
2367 HDMI_OUTP(0x0148, 0x2 << 8);
2368
2369 /* 0x012C HDCP_ENTROPY_CTRL0
2370 [31:0] BITS_OF_INFLUENCE_0 */
2371 /* 0x025C HDCP_ENTROPY_CTRL1
2372 [31:0] BITS_OF_INFLUENCE_1 */
2373 HDMI_OUTP(0x012C, 0xB1FFB0FF);
2374 HDMI_OUTP(0x025C, 0xF00DFACE);
2375
2376 /* 0x0114 HDCP_DEBUG_CTRL
2377 [2] DEBUG_RNG_CIPHER
2378 else default 0 */
2379 HDMI_OUTP(0x0114, HDMI_INP(0x0114) & 0xFFFFFFFB);
2380
2381 /* 0x0110 HDCP_CTRL
2382 [8] ENCRYPTION_ENABLE
2383 [0] ENABLE */
2384 /* encryption_enable | enable */
2385 HDMI_OUTP(0x0110, (1 << 8) | (1 << 0));
2386
Aravind Venkateswarand2fb0bd2011-11-30 18:38:14 -08002387 /*
2388 * Check to see if a HDCP DDC Failure is indicated in
2389 * HDCP_DDC_STATUS. If yes, clear it.
2390 */
2391 check_and_clear_HDCP_DDC_Failure();
2392
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002393 /* 0x0118 HDCP_INT_CTRL
2394 * [2] AUTH_SUCCESS_MASK [R/W] Mask bit for\
2395 * HDCP Authentication
2396 * Success interrupt - set to 1 to enable interrupt
2397 *
2398 * [6] AUTH_FAIL_MASK [R/W] Mask bit for HDCP
2399 * Authentication
2400 * Lost interrupt set to 1 to enable interrupt
2401 *
2402 * [7] AUTH_FAIL_INFO_ACK [W] Acknwledge bit for HDCP
2403 * Auth Failure Info field - write 1 to clear
2404 *
2405 * [10] DDC_XFER_REQ_MASK [R/W] Mask bit for HDCP\
2406 * DDC Transfer
2407 * Request interrupt - set to 1 to enable interrupt
2408 *
2409 * [14] DDC_XFER_DONE_MASK [R/W] Mask bit for HDCP\
2410 * DDC Transfer
2411 * done interrupt - set to 1 to enable interrupt */
2412 /* enable all HDCP ints */
2413 HDMI_OUTP(0x0118, (1 << 2) | (1 << 6) | (1 << 7));
2414
2415 /* 0x011C HDCP_LINK0_STATUS
2416 [8] AN_0_READY
2417 [9] AN_1_READY */
2418 /* wait for an0 and an1 ready bits to be set in LINK0_STATUS */
2419 timeout_count = 100;
2420 while (((HDMI_INP_ND(0x011C) & (0x3 << 8)) != (0x3 << 8))
2421 && timeout_count--)
2422 msleep(20);
2423 if (!timeout_count) {
2424 ret = -ETIMEDOUT;
2425 DEV_ERR("%s(%d): timedout, An0=%d, An1=%d\n",
2426 __func__, __LINE__,
2427 (HDMI_INP_ND(0x011C) & BIT(8)) >> 8,
2428 (HDMI_INP_ND(0x011C) & BIT(9)) >> 9);
2429 goto error;
2430 }
2431
Aravind Venkateswaran954620c2011-11-30 14:50:48 -08002432 /*
2433 * A small delay is needed here to avoid device crash observed
2434 * during reauthentication in MSM8960
2435 */
2436 msleep(20);
2437
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002438 /* 0x0168 HDCP_RCVPORT_DATA12
2439 [23:8] BSTATUS
2440 [7:0] BCAPS */
2441 HDMI_OUTP(0x0168, bcaps);
2442
2443 /* 0x014C HDCP_RCVPORT_DATA5
2444 [31:0] LINK0_AN_0 */
2445 /* read an0 calculation */
2446 link0_an_0 = HDMI_INP(0x014C);
2447
2448 /* 0x0150 HDCP_RCVPORT_DATA6
2449 [31:0] LINK0_AN_1 */
2450 /* read an1 calculation */
2451 link0_an_1 = HDMI_INP(0x0150);
2452
2453 /* three bits 28..30 */
2454 hdcp_key_state((HDMI_INP(0x011C) >> 28) & 0x7);
2455
2456 /* 0x0144 HDCP_RCVPORT_DATA3
2457 [31:0] LINK0_AKSV_0 public key
2458 0x0148 HDCP_RCVPORT_DATA4
2459 [15:8] LINK0_AINFO
2460 [7:0] LINK0_AKSV_1 public key */
2461 link0_aksv_0 = HDMI_INP(0x0144);
2462 link0_aksv_1 = HDMI_INP(0x0148);
2463
2464 /* copy an and aksv to byte arrays for transmission */
2465 aksv[0] = link0_aksv_0 & 0xFF;
2466 aksv[1] = (link0_aksv_0 >> 8) & 0xFF;
2467 aksv[2] = (link0_aksv_0 >> 16) & 0xFF;
2468 aksv[3] = (link0_aksv_0 >> 24) & 0xFF;
2469 aksv[4] = link0_aksv_1 & 0xFF;
2470
2471 an[0] = link0_an_0 & 0xFF;
2472 an[1] = (link0_an_0 >> 8) & 0xFF;
2473 an[2] = (link0_an_0 >> 16) & 0xFF;
2474 an[3] = (link0_an_0 >> 24) & 0xFF;
2475 an[4] = link0_an_1 & 0xFF;
2476 an[5] = (link0_an_1 >> 8) & 0xFF;
2477 an[6] = (link0_an_1 >> 16) & 0xFF;
2478 an[7] = (link0_an_1 >> 24) & 0xFF;
2479
2480 /* Write An 8 bytes to offset 0x18 */
2481 ret = hdmi_msm_ddc_write(0x74, 0x18, an, 8, "An");
2482 if (ret) {
2483 DEV_ERR("%s(%d): Write An failed", __func__, __LINE__);
2484 goto error;
2485 }
2486
2487 /* Write Aksv 5 bytes to offset 0x10 */
2488 ret = hdmi_msm_ddc_write(0x74, 0x10, aksv, 5, "Aksv");
2489 if (ret) {
2490 DEV_ERR("%s(%d): Write Aksv failed", __func__,
2491 __LINE__);
2492 goto error;
2493 }
2494 DEV_DBG("HDCP: Link0-AKSV=%02x%08x\n",
2495 link0_aksv_1 & 0xFF, link0_aksv_0);
2496
2497 /* 0x0134 HDCP_RCVPORT_DATA0
2498 [31:0] LINK0_BKSV_0 */
2499 HDMI_OUTP(0x0134, link0_bksv_0);
2500 /* 0x0138 HDCP_RCVPORT_DATA1
2501 [31:0] LINK0_BKSV_1 */
2502 HDMI_OUTP(0x0138, link0_bksv_1);
2503 DEV_DBG("HDCP: Link0-BKSV=%02x%08x\n", link0_bksv_1,
2504 link0_bksv_0);
2505
2506 /* HDMI_HPD_INT_STATUS[0x0250] */
2507 hpd_int_status = HDMI_INP_ND(0x0250);
2508 /* HDMI_HPD_INT_CTRL[0x0254] */
2509 hpd_int_ctrl = HDMI_INP_ND(0x0254);
Aravind Venkateswarane88f8f52011-12-13 19:07:20 -08002510 DEV_DBG("[SR-DEUG]: HPD_INTR_CTRL=[%u] HPD_INTR_STATUS=[%u] "
2511 "before reading R0'\n", hpd_int_ctrl, hpd_int_status);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002512
2513 /*
2514 * HDCP Compliace Test case 1B-01:
2515 * Wait here until all the ksv bytes have been
2516 * read from the KSV FIFO register.
2517 */
2518 msleep(125);
2519
2520 /* Reading R0' 2 bytes at offset 0x08 */
2521 ret = hdmi_msm_ddc_read(0x74, 0x08, buf, 2, 5, "RO'", TRUE);
2522 if (ret) {
2523 DEV_ERR("%s(%d): Read RO's failed", __func__,
2524 __LINE__);
2525 goto error;
2526 }
2527
Abhishek Kharbanda39cf2092011-12-15 11:37:57 -08002528 DEV_DBG("HDCP: R0'=%02x%02x\n", buf[1], buf[0]);
2529 INIT_COMPLETION(hdmi_msm_state->hdcp_success_done);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002530 /* 0x013C HDCP_RCVPORT_DATA2_0
2531 [15:0] LINK0_RI */
2532 HDMI_OUTP(0x013C, (((uint32)buf[1]) << 8) | buf[0]);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002533
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002534 timeout_count = wait_for_completion_interruptible_timeout(
2535 &hdmi_msm_state->hdcp_success_done, HZ*2);
2536
2537 if (!timeout_count) {
2538 ret = -ETIMEDOUT;
2539 is_match = HDMI_INP(0x011C) & BIT(12);
2540 DEV_ERR("%s(%d): timedout, Link0=<%s>\n", __func__,
2541 __LINE__,
2542 is_match ? "RI_MATCH" : "No RI Match INTR in time");
2543 if (!is_match)
2544 goto error;
2545 }
2546
2547 /* 0x011C HDCP_LINK0_STATUS
2548 [12] RI_MATCHES [0] MISMATCH, [1] MATCH
2549 [0] AUTH_SUCCESS */
2550 /* Checking for RI, R0 Match */
2551 /* RI_MATCHES */
2552 if ((HDMI_INP(0x011C) & BIT(12)) != BIT(12)) {
2553 ret = -EINVAL;
2554 DEV_ERR("%s: HDCP_LINK0_STATUS[RI_MATCHES]: MISMATCH\n",
2555 __func__);
2556 goto error;
2557 }
2558
2559 DEV_INFO("HDCP: authentication part I, successful\n");
2560 is_part1_done = FALSE;
2561 return 0;
2562error:
2563 DEV_ERR("[%s]: HDCP Reauthentication\n", __func__);
2564 is_part1_done = FALSE;
2565 return ret;
2566 } else {
2567 return 1;
2568 }
2569}
2570
2571static int hdmi_msm_transfer_v_h(void)
2572{
2573 /* Read V'.HO 4 Byte at offset 0x20 */
2574 char what[20];
2575 int ret;
2576 uint8 buf[4];
2577
2578 snprintf(what, sizeof(what), "V' H0");
2579 ret = hdmi_msm_ddc_read(0x74, 0x20, buf, 4, 5, what, TRUE);
2580 if (ret) {
2581 DEV_ERR("%s: Read %s failed", __func__, what);
2582 return ret;
2583 }
2584 DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
2585 buf[0] , buf[1] , buf[2] , buf[3]);
2586
2587 /* 0x0154 HDCP_RCVPORT_DATA7
2588 [31:0] V_HO */
2589 HDMI_OUTP(0x0154 ,
2590 (buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
2591
2592 snprintf(what, sizeof(what), "V' H1");
2593 ret = hdmi_msm_ddc_read(0x74, 0x24, buf, 4, 5, what, TRUE);
2594 if (ret) {
2595 DEV_ERR("%s: Read %s failed", __func__, what);
2596 return ret;
2597 }
2598 DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
2599 buf[0] , buf[1] , buf[2] , buf[3]);
2600
2601 /* 0x0158 HDCP_RCVPORT_ DATA8
2602 [31:0] V_H1 */
2603 HDMI_OUTP(0x0158,
2604 (buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
2605
2606
2607 snprintf(what, sizeof(what), "V' H2");
2608 ret = hdmi_msm_ddc_read(0x74, 0x28, buf, 4, 5, what, TRUE);
2609 if (ret) {
2610 DEV_ERR("%s: Read %s failed", __func__, what);
2611 return ret;
2612 }
2613 DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
2614 buf[0] , buf[1] , buf[2] , buf[3]);
2615
2616 /* 0x015c HDCP_RCVPORT_DATA9
2617 [31:0] V_H2 */
2618 HDMI_OUTP(0x015c ,
2619 (buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
2620
2621 snprintf(what, sizeof(what), "V' H3");
2622 ret = hdmi_msm_ddc_read(0x74, 0x2c, buf, 4, 5, what, TRUE);
2623 if (ret) {
2624 DEV_ERR("%s: Read %s failed", __func__, what);
2625 return ret;
2626 }
2627 DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
2628 buf[0] , buf[1] , buf[2] , buf[3]);
2629
2630 /* 0x0160 HDCP_RCVPORT_DATA10
2631 [31:0] V_H3 */
2632 HDMI_OUTP(0x0160,
2633 (buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
2634
2635 snprintf(what, sizeof(what), "V' H4");
2636 ret = hdmi_msm_ddc_read(0x74, 0x30, buf, 4, 5, what, TRUE);
2637 if (ret) {
2638 DEV_ERR("%s: Read %s failed", __func__, what);
2639 return ret;
2640 }
2641 DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
2642 buf[0] , buf[1] , buf[2] , buf[3]);
2643 /* 0x0164 HDCP_RCVPORT_DATA11
2644 [31:0] V_H4 */
2645 HDMI_OUTP(0x0164,
2646 (buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
2647
2648 return 0;
2649}
2650
2651static int hdcp_authentication_part2(void)
2652{
2653 int ret = 0;
2654 uint32 timeout_count;
2655 int i = 0;
2656 int cnt = 0;
2657 uint bstatus;
2658 uint8 bcaps;
2659 uint32 down_stream_devices;
2660 uint32 ksv_bytes;
2661
2662 static uint8 buf[0xFF];
2663 static uint8 kvs_fifo[5 * 127];
2664
2665 boolean max_devs_exceeded = 0;
2666 boolean max_cascade_exceeded = 0;
2667
2668 boolean ksv_done = FALSE;
2669
2670 memset(buf, 0, sizeof(buf));
2671 memset(kvs_fifo, 0, sizeof(kvs_fifo));
2672
2673 /* wait until READY bit is set in bcaps */
2674 timeout_count = 50;
2675 do {
2676 timeout_count--;
2677 /* read bcaps 1 Byte at offset 0x40 */
2678 ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 1,
2679 "Bcaps", FALSE);
2680 if (ret) {
2681 DEV_ERR("%s(%d): Read Bcaps failed", __func__,
2682 __LINE__);
2683 goto error;
2684 }
2685 msleep(100);
2686 } while ((0 == (bcaps & 0x20)) && timeout_count); /* READY (Bit 5) */
2687 if (!timeout_count) {
2688 ret = -ETIMEDOUT;
2689 DEV_ERR("%s:timedout(1)", __func__);
2690 goto error;
2691 }
2692
2693 /* read bstatus 2 bytes at offset 0x41 */
2694
2695 ret = hdmi_msm_ddc_read(0x74, 0x41, buf, 2, 5, "Bstatus", FALSE);
2696 if (ret) {
2697 DEV_ERR("%s(%d): Read Bstatus failed", __func__, __LINE__);
2698 goto error;
2699 }
2700 bstatus = buf[1];
2701 bstatus = (bstatus << 8) | buf[0];
2702 /* 0x0168 DCP_RCVPORT_DATA12
2703 [7:0] BCAPS
2704 [23:8 BSTATUS */
2705 HDMI_OUTP(0x0168, bcaps | (bstatus << 8));
2706 /* BSTATUS [6:0] DEVICE_COUNT Number of HDMI device attached to repeater
2707 * - see HDCP spec */
2708 down_stream_devices = bstatus & 0x7F;
2709
2710 if (down_stream_devices == 0x0) {
2711 /* There isn't any devices attaced to the Repeater */
2712 DEV_ERR("%s: there isn't any devices attached to the "
2713 "Repeater\n", __func__);
2714 ret = -EINVAL;
2715 goto error;
2716 }
2717
2718 /*
2719 * HDCP Compliance 1B-05:
2720 * Check if no. of devices connected to repeater
2721 * exceed max_devices_connected from bit 7 of Bstatus.
2722 */
2723 max_devs_exceeded = (bstatus & 0x80) >> 7;
2724 if (max_devs_exceeded == 0x01) {
2725 DEV_ERR("%s: Number of devs connected to repeater "
2726 "exceeds max_devs\n", __func__);
2727 ret = -EINVAL;
2728 goto hdcp_error;
2729 }
2730
2731 /*
2732 * HDCP Compliance 1B-06:
2733 * Check if no. of cascade connected to repeater
2734 * exceed max_cascade_connected from bit 11 of Bstatus.
2735 */
2736 max_cascade_exceeded = (bstatus & 0x800) >> 11;
2737 if (max_cascade_exceeded == 0x01) {
2738 DEV_ERR("%s: Number of cascade connected to repeater "
2739 "exceeds max_cascade\n", __func__);
2740 ret = -EINVAL;
2741 goto hdcp_error;
2742 }
2743
2744 /* Read KSV FIFO over DDC
2745 * Key Slection vector FIFO
2746 * Used to pull downstream KSVs from HDCP Repeaters.
2747 * All bytes (DEVICE_COUNT * 5) must be read in a single,
2748 * auto incrementing access.
2749 * All bytes read as 0x00 for HDCP Receivers that are not
2750 * HDCP Repeaters (REPEATER == 0). */
2751 ksv_bytes = 5 * down_stream_devices;
2752 /* Reading KSV FIFO / KSV FIFO */
2753 ksv_done = FALSE;
2754
2755 ret = hdmi_msm_ddc_read(0x74, 0x43, kvs_fifo, ksv_bytes, 5,
2756 "KSV FIFO", TRUE);
2757 do {
2758 if (ret) {
2759 DEV_ERR("%s(%d): Read KSV FIFO failed",
2760 __func__, __LINE__);
2761 /*
2762 * HDCP Compliace Test case 1B-01:
2763 * Wait here until all the ksv bytes have been
2764 * read from the KSV FIFO register.
2765 */
2766 msleep(25);
2767 } else {
2768 ksv_done = TRUE;
2769 }
2770 cnt++;
2771 } while (!ksv_done && cnt != 20);
2772
2773 if (ksv_done == FALSE)
2774 goto error;
2775
2776 ret = hdmi_msm_transfer_v_h();
2777 if (ret)
2778 goto error;
2779
2780 /* Next: Write KSV FIFO to HDCP_SHA_DATA.
2781 * This is done 1 byte at time starting with the LSB.
2782 * On the very last byte write,
2783 * the HDCP_SHA_DATA_DONE bit[0]
2784 */
2785
2786 /* 0x023C HDCP_SHA_CTRL
2787 [0] RESET [0] Enable, [1] Reset
2788 [4] SELECT [0] DIGA_HDCP, [1] DIGB_HDCP */
2789 /* reset SHA engine */
2790 HDMI_OUTP(0x023C, 1);
2791 /* enable SHA engine, SEL=DIGA_HDCP */
2792 HDMI_OUTP(0x023C, 0);
2793
2794 for (i = 0; i < ksv_bytes - 1; i++) {
2795 /* Write KSV byte and do not set DONE bit[0] */
2796 HDMI_OUTP_ND(0x0244, kvs_fifo[i] << 16);
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002797
2798 /* Once 64 bytes have been written, we need to poll for
2799 * HDCP_SHA_BLOCK_DONE before writing any further
2800 */
2801 if (i && !((i+1)%64)) {
2802 timeout_count = 100;
2803 while (!(HDMI_INP_ND(0x0240) & 0x1)
2804 && (--timeout_count)) {
2805 DEV_DBG("HDCP Auth Part II: Waiting for the "
2806 "computation of the current 64 byte to "
2807 "complete. HDCP_SHA_STATUS=%08x. "
2808 "timeout_count=%d\n",
2809 HDMI_INP_ND(0x0240), timeout_count);
2810 msleep(20);
2811 }
2812 if (!timeout_count) {
2813 ret = -ETIMEDOUT;
2814 DEV_ERR("%s(%d): timedout", __func__, __LINE__);
2815 goto error;
2816 }
2817 }
2818
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002819 }
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002820
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002821 /* Write l to DONE bit[0] */
2822 HDMI_OUTP_ND(0x0244, (kvs_fifo[ksv_bytes - 1] << 16) | 0x1);
2823
2824 /* 0x0240 HDCP_SHA_STATUS
2825 [4] COMP_DONE */
2826 /* Now wait for HDCP_SHA_COMP_DONE */
2827 timeout_count = 100;
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002828 while ((0x10 != (HDMI_INP_ND(0x0240) & 0xFFFFFF10)) && --timeout_count)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002829 msleep(20);
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002830
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002831 if (!timeout_count) {
2832 ret = -ETIMEDOUT;
2833 DEV_ERR("%s(%d): timedout", __func__, __LINE__);
2834 goto error;
2835 }
2836
2837 /* 0x011C HDCP_LINK0_STATUS
2838 [20] V_MATCHES */
2839 timeout_count = 100;
2840 while (((HDMI_INP_ND(0x011C) & (1 << 20)) != (1 << 20))
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002841 && --timeout_count) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002842 msleep(20);
Aravind Venkateswaranfa14cb02011-10-19 13:00:16 -07002843 }
2844
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002845 if (!timeout_count) {
2846 ret = -ETIMEDOUT;
2847 DEV_ERR("%s(%d): timedout", __func__, __LINE__);
2848 goto error;
2849 }
2850
2851 DEV_INFO("HDCP: authentication part II, successful\n");
2852
2853hdcp_error:
2854error:
2855 return ret;
2856}
2857
2858static int hdcp_authentication_part3(uint32 found_repeater)
2859{
2860 int ret = 0;
2861 int poll = 3000;
2862 while (poll) {
2863 /* 0x011C HDCP_LINK0_STATUS
2864 [30:28] KEYS_STATE = 3 = "Valid"
2865 [24] RO_COMPUTATION_DONE [0] Not Done, [1] Done
2866 [20] V_MATCHES [0] Mismtach, [1] Match
2867 [12] RI_MATCHES [0] Mismatch, [1] Match
2868 [0] AUTH_SUCCESS */
2869 if (HDMI_INP_ND(0x011C) != (0x31001001 |
2870 (found_repeater << 20))) {
2871 DEV_ERR("HDCP: autentication part III, FAILED, "
2872 "Link Status=%08x\n", HDMI_INP(0x011C));
2873 ret = -EINVAL;
2874 goto error;
2875 }
2876 poll--;
2877 }
2878
2879 DEV_INFO("HDCP: authentication part III, successful\n");
2880
2881error:
2882 return ret;
2883}
2884
2885static void hdmi_msm_hdcp_enable(void)
2886{
2887 int ret = 0;
2888 uint8 bcaps;
2889 uint32 found_repeater = 0x0;
2890 char *envp[2];
2891
2892 if (!hdmi_msm_has_hdcp())
2893 return;
2894
2895 mutex_lock(&hdmi_msm_state_mutex);
2896 hdmi_msm_state->hdcp_activating = TRUE;
2897 mutex_unlock(&hdmi_msm_state_mutex);
2898
2899 fill_black_screen();
2900
2901 mutex_lock(&hdcp_auth_state_mutex);
2902 /*
2903 * Initialize this to zero here to make
2904 * sure HPD has not happened yet
2905 */
2906 hdmi_msm_state->hpd_during_auth = FALSE;
2907 /* This flag prevents other threads from re-authenticating
2908 * after we've just authenticated (i.e., finished part3)
2909 * We probably need to protect this in a mutex lock */
2910 hdmi_msm_state->full_auth_done = FALSE;
2911 mutex_unlock(&hdcp_auth_state_mutex);
2912
2913 /* PART I Authentication*/
2914 ret = hdcp_authentication_part1();
2915 if (ret)
2916 goto error;
2917
2918 /* PART II Authentication*/
2919 /* read Bcaps at 0x40 in HDCP Port */
2920 ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps", FALSE);
2921 if (ret) {
2922 DEV_ERR("%s(%d): Read Bcaps failed\n", __func__, __LINE__);
2923 goto error;
2924 }
2925 DEV_DBG("HDCP: Bcaps=0x%02x (%s)\n", bcaps,
2926 (bcaps & BIT(6)) ? "repeater" : "no repeater");
2927
2928 /* if REPEATER (Bit 6), perform Part2 Authentication */
2929 if (bcaps & BIT(6)) {
2930 found_repeater = 0x1;
2931 ret = hdcp_authentication_part2();
2932 if (ret)
2933 goto error;
2934 } else
2935 DEV_INFO("HDCP: authentication part II skipped, no repeater\n");
2936
2937 /* PART III Authentication*/
2938 ret = hdcp_authentication_part3(found_repeater);
2939 if (ret)
2940 goto error;
2941
2942 unfill_black_screen();
2943
2944 external_common_state->hdcp_active = TRUE;
2945 mutex_lock(&hdmi_msm_state_mutex);
2946 hdmi_msm_state->hdcp_activating = FALSE;
2947 mutex_unlock(&hdmi_msm_state_mutex);
2948
2949 mutex_lock(&hdcp_auth_state_mutex);
2950 /*
2951 * This flag prevents other threads from re-authenticating
2952 * after we've just authenticated (i.e., finished part3)
2953 */
2954 hdmi_msm_state->full_auth_done = TRUE;
2955 mutex_unlock(&hdcp_auth_state_mutex);
2956
2957 if (!hdmi_msm_is_dvi_mode()) {
2958 DEV_INFO("HDMI HPD: sense : send HDCP_PASS\n");
2959 envp[0] = "HDCP_STATE=PASS";
2960 envp[1] = NULL;
2961 kobject_uevent_env(external_common_state->uevent_kobj,
2962 KOBJ_CHANGE, envp);
2963 }
2964 return;
2965
2966error:
2967 mutex_lock(&hdmi_msm_state_mutex);
2968 hdmi_msm_state->hdcp_activating = FALSE;
2969 mutex_unlock(&hdmi_msm_state_mutex);
2970 if (hdmi_msm_state->hpd_during_auth) {
Aravind Venkateswarane88f8f52011-12-13 19:07:20 -08002971 DEV_WARN("Calling Deauthentication: HPD occured during "
2972 "authentication from [%s]\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002973 hdcp_deauthenticate();
2974 mutex_lock(&hdcp_auth_state_mutex);
2975 hdmi_msm_state->hpd_during_auth = FALSE;
2976 mutex_unlock(&hdcp_auth_state_mutex);
2977 } else {
2978 DEV_WARN("[DEV_DBG]: Calling reauth from [%s]\n", __func__);
2979 if (hdmi_msm_state->panel_power_on)
2980 queue_work(hdmi_work_queue,
2981 &hdmi_msm_state->hdcp_reauth_work);
2982 }
2983}
2984#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
2985
2986static void hdmi_msm_video_setup(int video_format)
2987{
2988 uint32 total_v = 0;
2989 uint32 total_h = 0;
2990 uint32 start_h = 0;
2991 uint32 end_h = 0;
2992 uint32 start_v = 0;
2993 uint32 end_v = 0;
2994 const struct hdmi_disp_mode_timing_type *timing =
2995 hdmi_common_get_supported_mode(video_format);
2996
2997 /* timing register setup */
2998 if (timing == NULL) {
2999 DEV_ERR("video format not supported: %d\n", video_format);
3000 return;
3001 }
3002
3003 /* Hsync Total and Vsync Total */
3004 total_h = timing->active_h + timing->front_porch_h
3005 + timing->back_porch_h + timing->pulse_width_h - 1;
3006 total_v = timing->active_v + timing->front_porch_v
3007 + timing->back_porch_v + timing->pulse_width_v - 1;
3008 /* 0x02C0 HDMI_TOTAL
3009 [27:16] V_TOTAL Vertical Total
3010 [11:0] H_TOTAL Horizontal Total */
3011 HDMI_OUTP(0x02C0, ((total_v << 16) & 0x0FFF0000)
3012 | ((total_h << 0) & 0x00000FFF));
3013
3014 /* Hsync Start and Hsync End */
3015 start_h = timing->back_porch_h + timing->pulse_width_h;
3016 end_h = (total_h + 1) - timing->front_porch_h;
3017 /* 0x02B4 HDMI_ACTIVE_H
3018 [27:16] END Horizontal end
3019 [11:0] START Horizontal start */
3020 HDMI_OUTP(0x02B4, ((end_h << 16) & 0x0FFF0000)
3021 | ((start_h << 0) & 0x00000FFF));
3022
3023 start_v = timing->back_porch_v + timing->pulse_width_v - 1;
3024 end_v = total_v - timing->front_porch_v;
3025 /* 0x02B8 HDMI_ACTIVE_V
3026 [27:16] END Vertical end
3027 [11:0] START Vertical start */
3028 HDMI_OUTP(0x02B8, ((end_v << 16) & 0x0FFF0000)
3029 | ((start_v << 0) & 0x00000FFF));
3030
3031 if (timing->interlaced) {
3032 /* 0x02C4 HDMI_V_TOTAL_F2
3033 [11:0] V_TOTAL_F2 Vertical total for field2 */
3034 HDMI_OUTP(0x02C4, ((total_v + 1) << 0) & 0x00000FFF);
3035
3036 /* 0x02BC HDMI_ACTIVE_V_F2
3037 [27:16] END_F2 Vertical end for field2
3038 [11:0] START_F2 Vertical start for Field2 */
3039 HDMI_OUTP(0x02BC,
3040 (((start_v + 1) << 0) & 0x00000FFF)
3041 | (((end_v + 1) << 16) & 0x0FFF0000));
3042 } else {
3043 /* HDMI_V_TOTAL_F2 */
3044 HDMI_OUTP(0x02C4, 0);
3045 /* HDMI_ACTIVE_V_F2 */
3046 HDMI_OUTP(0x02BC, 0);
3047 }
3048
3049 hdmi_frame_ctrl_cfg(timing);
3050}
3051
3052struct hdmi_msm_audio_acr {
3053 uint32 n; /* N parameter for clock regeneration */
3054 uint32 cts; /* CTS parameter for clock regeneration */
3055};
3056
3057struct hdmi_msm_audio_arcs {
3058 uint32 pclk;
3059 struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX];
3060};
3061
3062#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { pclk, __VA_ARGS__ }
3063
3064/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
3065/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
3066static const struct hdmi_msm_audio_arcs hdmi_msm_audio_acr_lut[] = {
3067 /* 25.200MHz */
3068 HDMI_MSM_AUDIO_ARCS(25200, {
3069 {4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
3070 {12288, 25200}, {25088, 28000}, {24576, 25200} }),
3071 /* 27.000MHz */
3072 HDMI_MSM_AUDIO_ARCS(27000, {
3073 {4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
3074 {12288, 27000}, {25088, 30000}, {24576, 27000} }),
3075 /* 27.030MHz */
3076 HDMI_MSM_AUDIO_ARCS(27030, {
3077 {4096, 27030}, {6272, 30030}, {6144, 27030}, {12544, 30030},
3078 {12288, 27030}, {25088, 30030}, {24576, 27030} }),
3079 /* 74.250MHz */
3080 HDMI_MSM_AUDIO_ARCS(74250, {
3081 {4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
3082 {12288, 74250}, {25088, 82500}, {24576, 74250} }),
3083 /* 148.500MHz */
3084 HDMI_MSM_AUDIO_ARCS(148500, {
3085 {4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
3086 {12288, 148500}, {25088, 165000}, {24576, 148500} }),
3087};
3088
3089static void hdmi_msm_audio_acr_setup(boolean enabled, int video_format,
3090 int audio_sample_rate, int num_of_channels)
3091{
3092 /* Read first before writing */
3093 /* HDMI_ACR_PKT_CTRL[0x0024] */
3094 uint32 acr_pck_ctrl_reg = HDMI_INP(0x0024);
3095
3096 if (enabled) {
3097 const struct hdmi_disp_mode_timing_type *timing =
3098 hdmi_common_get_supported_mode(video_format);
3099 const struct hdmi_msm_audio_arcs *audio_arc =
3100 &hdmi_msm_audio_acr_lut[0];
3101 const int lut_size = sizeof(hdmi_msm_audio_acr_lut)
3102 /sizeof(*hdmi_msm_audio_acr_lut);
3103 uint32 i, n, cts, layout, multiplier, aud_pck_ctrl_2_reg;
3104
3105 if (timing == NULL) {
3106 DEV_WARN("%s: video format %d not supported\n",
3107 __func__, video_format);
3108 return;
3109 }
3110
3111 for (i = 0; i < lut_size;
3112 audio_arc = &hdmi_msm_audio_acr_lut[++i]) {
3113 if (audio_arc->pclk == timing->pixel_freq)
3114 break;
3115 }
3116 if (i >= lut_size) {
3117 DEV_WARN("%s: pixel clock %d not supported\n", __func__,
3118 timing->pixel_freq);
3119 return;
3120 }
3121
3122 n = audio_arc->lut[audio_sample_rate].n;
3123 cts = audio_arc->lut[audio_sample_rate].cts;
3124 layout = (MSM_HDMI_AUDIO_CHANNEL_2 == num_of_channels) ? 0 : 1;
3125
3126 if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio_sample_rate) ||
3127 (MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio_sample_rate)) {
3128 multiplier = 4;
3129 n >>= 2; /* divide N by 4 and use multiplier */
3130 } else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio_sample_rate) ||
3131 (MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio_sample_rate)) {
3132 multiplier = 2;
3133 n >>= 1; /* divide N by 2 and use multiplier */
3134 } else {
3135 multiplier = 1;
3136 }
3137 DEV_DBG("%s: n=%u, cts=%u, layout=%u\n", __func__, n, cts,
3138 layout);
3139
3140 /* AUDIO_PRIORITY | SOURCE */
3141 acr_pck_ctrl_reg |= 0x80000100;
3142 /* N_MULTIPLE(multiplier) */
3143 acr_pck_ctrl_reg |= (multiplier & 7) << 16;
3144
3145 if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio_sample_rate) ||
3146 (MSM_HDMI_SAMPLE_RATE_96KHZ == audio_sample_rate) ||
3147 (MSM_HDMI_SAMPLE_RATE_192KHZ == audio_sample_rate)) {
3148 /* SELECT(3) */
3149 acr_pck_ctrl_reg |= 3 << 4;
3150 /* CTS_48 */
3151 cts <<= 12;
3152
3153 /* CTS: need to determine how many fractional bits */
3154 /* HDMI_ACR_48_0 */
3155 HDMI_OUTP(0x00D4, cts);
3156 /* N */
3157 /* HDMI_ACR_48_1 */
3158 HDMI_OUTP(0x00D8, n);
3159 } else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio_sample_rate)
3160 || (MSM_HDMI_SAMPLE_RATE_88_2KHZ ==
3161 audio_sample_rate)
3162 || (MSM_HDMI_SAMPLE_RATE_176_4KHZ ==
3163 audio_sample_rate)) {
3164 /* SELECT(2) */
3165 acr_pck_ctrl_reg |= 2 << 4;
3166 /* CTS_44 */
3167 cts <<= 12;
3168
3169 /* CTS: need to determine how many fractional bits */
3170 /* HDMI_ACR_44_0 */
3171 HDMI_OUTP(0x00CC, cts);
3172 /* N */
3173 /* HDMI_ACR_44_1 */
3174 HDMI_OUTP(0x00D0, n);
3175 } else { /* default to 32k */
3176 /* SELECT(1) */
3177 acr_pck_ctrl_reg |= 1 << 4;
3178 /* CTS_32 */
3179 cts <<= 12;
3180
3181 /* CTS: need to determine how many fractional bits */
3182 /* HDMI_ACR_32_0 */
3183 HDMI_OUTP(0x00C4, cts);
3184 /* N */
3185 /* HDMI_ACR_32_1 */
3186 HDMI_OUTP(0x00C8, n);
3187 }
3188 /* Payload layout depends on number of audio channels */
3189 /* LAYOUT_SEL(layout) */
3190 aud_pck_ctrl_2_reg = 1 | (layout << 1);
3191 /* override | layout */
3192 /* HDMI_AUDIO_PKT_CTRL2[0x00044] */
3193 HDMI_OUTP(0x00044, aud_pck_ctrl_2_reg);
3194
3195 /* SEND | CONT */
3196 acr_pck_ctrl_reg |= 0x00000003;
3197 } else {
3198 /* ~(SEND | CONT) */
3199 acr_pck_ctrl_reg &= ~0x00000003;
3200 }
3201 /* HDMI_ACR_PKT_CTRL[0x0024] */
3202 HDMI_OUTP(0x0024, acr_pck_ctrl_reg);
3203}
3204
3205static void hdmi_msm_outpdw_chk(uint32 offset, uint32 data)
3206{
3207 uint32 check, i = 0;
3208
3209#ifdef DEBUG
3210 HDMI_OUTP(offset, data);
3211#endif
3212 do {
3213 outpdw(MSM_HDMI_BASE+offset, data);
3214 check = inpdw(MSM_HDMI_BASE+offset);
3215 } while (check != data && i++ < 10);
3216
3217 if (check != data)
3218 DEV_ERR("%s: failed addr=%08x, data=%x, check=%x",
3219 __func__, offset, data, check);
3220}
3221
3222static void hdmi_msm_rmw32or(uint32 offset, uint32 data)
3223{
3224 uint32 reg_data;
3225 reg_data = inpdw(MSM_HDMI_BASE+offset);
3226 reg_data = inpdw(MSM_HDMI_BASE+offset);
3227 hdmi_msm_outpdw_chk(offset, reg_data | data);
3228}
3229
3230
3231#define HDMI_AUDIO_CFG 0x01D0
3232#define HDMI_AUDIO_ENGINE_ENABLE 1
3233#define HDMI_AUDIO_FIFO_MASK 0x000000F0
3234#define HDMI_AUDIO_FIFO_WATERMARK_SHIFT 4
3235#define HDMI_AUDIO_FIFO_MAX_WATER_MARK 8
3236
3237
3238int hdmi_audio_enable(bool on , u32 fifo_water_mark)
3239{
3240 u32 hdmi_audio_config;
3241
3242 hdmi_audio_config = HDMI_INP(HDMI_AUDIO_CFG);
3243
3244 if (on) {
3245
3246 if (fifo_water_mark > HDMI_AUDIO_FIFO_MAX_WATER_MARK) {
3247 pr_err("%s : HDMI audio fifo water mark can not be more"
3248 " than %u\n", __func__,
3249 HDMI_AUDIO_FIFO_MAX_WATER_MARK);
3250 return -EINVAL;
3251 }
3252
3253 /*
3254 * Enable HDMI Audio engine.
3255 * MUST be enabled after Audio DMA is enabled.
3256 */
3257 hdmi_audio_config &= ~(HDMI_AUDIO_FIFO_MASK);
3258
3259 hdmi_audio_config |= (HDMI_AUDIO_ENGINE_ENABLE |
3260 (fifo_water_mark << HDMI_AUDIO_FIFO_WATERMARK_SHIFT));
3261
3262 } else
3263 hdmi_audio_config &= ~(HDMI_AUDIO_ENGINE_ENABLE);
3264
3265 HDMI_OUTP(HDMI_AUDIO_CFG, hdmi_audio_config);
3266
Deepa Madiregama6a3a01a2011-10-28 06:34:17 +05303267 mb();
3268 pr_info("%s :HDMI_AUDIO_CFG 0x%08x\n", __func__,
3269 HDMI_INP(HDMI_AUDIO_CFG));
3270
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003271 return 0;
3272}
3273EXPORT_SYMBOL(hdmi_audio_enable);
3274
Deepa Madiregama6a3a01a2011-10-28 06:34:17 +05303275#define HDMI_AUDIO_PKT_CTRL 0x0020
3276#define HDMI_AUDIO_SAMPLE_SEND_ENABLE 1
3277
3278int hdmi_audio_packet_enable(bool on)
3279{
3280 u32 hdmi_audio_pkt_ctrl;
3281 hdmi_audio_pkt_ctrl = HDMI_INP(HDMI_AUDIO_PKT_CTRL);
3282
3283 if (on)
3284 hdmi_audio_pkt_ctrl |= HDMI_AUDIO_SAMPLE_SEND_ENABLE;
3285 else
3286 hdmi_audio_pkt_ctrl &= ~(HDMI_AUDIO_SAMPLE_SEND_ENABLE);
3287
3288 HDMI_OUTP(HDMI_AUDIO_PKT_CTRL, hdmi_audio_pkt_ctrl);
3289
3290 mb();
3291 pr_info("%s : HDMI_AUDIO_PKT_CTRL 0x%08x\n", __func__,
3292 HDMI_INP(HDMI_AUDIO_PKT_CTRL));
3293 return 0;
3294}
3295EXPORT_SYMBOL(hdmi_audio_packet_enable);
3296
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003297static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
3298 int level_shift, boolean down_mix)
3299{
3300 uint32 channel_allocation = 0; /* Default to FR,FL */
3301 uint32 channel_count = 1; /* Default to 2 channels
3302 -> See Table 17 in CEA-D spec */
3303 uint32 check_sum, audio_info_0_reg, audio_info_1_reg;
3304 uint32 audio_info_ctrl_reg;
3305
3306 /* Please see table 20 Audio InfoFrame in HDMI spec
3307 FL = front left
3308 FC = front Center
3309 FR = front right
3310 FLC = front left center
3311 FRC = front right center
3312 RL = rear left
3313 RC = rear center
3314 RR = rear right
3315 RLC = rear left center
3316 RRC = rear right center
3317 LFE = low frequency effect
3318 */
3319
3320 /* Read first then write because it is bundled with other controls */
3321 /* HDMI_INFOFRAME_CTRL0[0x002C] */
3322 audio_info_ctrl_reg = HDMI_INP(0x002C);
3323
3324 if (enabled) {
3325 switch (num_of_channels) {
3326 case MSM_HDMI_AUDIO_CHANNEL_2:
3327 break;
3328 case MSM_HDMI_AUDIO_CHANNEL_4:
3329 channel_count = 3;
3330 /* FC,LFE,FR,FL */
3331 channel_allocation = 0x3;
3332 break;
3333 case MSM_HDMI_AUDIO_CHANNEL_6:
3334 channel_count = 5;
3335 /* RR,RL,FC,LFE,FR,FL */
3336 channel_allocation = 0xB;
3337 break;
3338 case MSM_HDMI_AUDIO_CHANNEL_8:
3339 channel_count = 7;
3340 /* FRC,FLC,RR,RL,FC,LFE,FR,FL */
3341 channel_allocation = 0x1f;
3342 break;
3343 default:
3344 break;
3345 }
3346
3347 /* Program the Channel-Speaker allocation */
3348 audio_info_1_reg = 0;
3349 /* CA(channel_allocation) */
3350 audio_info_1_reg |= channel_allocation & 0xff;
3351 /* Program the Level shifter */
3352 /* LSV(level_shift) */
3353 audio_info_1_reg |= (level_shift << 11) & 0x00007800;
3354 /* Program the Down-mix Inhibit Flag */
3355 /* DM_INH(down_mix) */
3356 audio_info_1_reg |= (down_mix << 15) & 0x00008000;
3357
3358 /* HDMI_AUDIO_INFO1[0x00E8] */
3359 HDMI_OUTP(0x00E8, audio_info_1_reg);
3360
3361 /* Calculate CheckSum
3362 Sum of all the bytes in the Audio Info Packet bytes
3363 (See table 8.4 in HDMI spec) */
3364 check_sum = 0;
3365 /* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_TYPE[0x84] */
3366 check_sum += 0x84;
3367 /* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_VERSION[0x01] */
3368 check_sum += 1;
3369 /* HDMI_AUDIO_INFO_FRAME_PACKET_LENGTH[0x0A] */
3370 check_sum += 0x0A;
3371 check_sum += channel_count;
3372 check_sum += channel_allocation;
3373 /* See Table 8.5 in HDMI spec */
3374 check_sum += (level_shift & 0xF) << 3 | (down_mix & 0x1) << 7;
3375 check_sum &= 0xFF;
3376 check_sum = (uint8) (256 - check_sum);
3377
3378 audio_info_0_reg = 0;
3379 /* CHECKSUM(check_sum) */
3380 audio_info_0_reg |= check_sum & 0xff;
3381 /* CC(channel_count) */
3382 audio_info_0_reg |= (channel_count << 8) & 0x00000700;
3383
3384 /* HDMI_AUDIO_INFO0[0x00E4] */
3385 HDMI_OUTP(0x00E4, audio_info_0_reg);
3386
3387 /* Set these flags */
3388 /* AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
3389 | AUDIO_INFO_SEND */
3390 audio_info_ctrl_reg |= 0x000000F0;
3391 } else {
3392 /* Clear these flags */
3393 /* ~(AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
3394 | AUDIO_INFO_SEND) */
3395 audio_info_ctrl_reg &= ~0x000000F0;
3396 }
3397 /* HDMI_INFOFRAME_CTRL0[0x002C] */
3398 HDMI_OUTP(0x002C, audio_info_ctrl_reg);
3399}
3400
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003401static void hdmi_msm_en_gc_packet(boolean av_mute_is_requested)
3402{
3403 /* HDMI_GC[0x0040] */
3404 HDMI_OUTP(0x0040, av_mute_is_requested ? 1 : 0);
3405
3406 /* GC packet enable (every frame) */
3407 /* HDMI_VBI_PKT_CTRL[0x0028] */
3408 hdmi_msm_rmw32or(0x0028, 3 << 4);
3409}
3410
Manoj Raoc2f19592011-08-05 17:54:25 -07003411#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_ISRC_ACP_SUPPORT
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003412static void hdmi_msm_en_isrc_packet(boolean isrc_is_continued)
3413{
3414 static const char isrc_psuedo_data[] =
3415 "ISRC1:0123456789isrc2=ABCDEFGHIJ";
3416 const uint32 * isrc_data = (const uint32 *) isrc_psuedo_data;
3417
3418 /* ISRC_STATUS =0b010 | ISRC_CONTINUE | ISRC_VALID */
3419 /* HDMI_ISRC1_0[0x00048] */
3420 HDMI_OUTP(0x00048, 2 | (isrc_is_continued ? 1 : 0) << 6 | 0 << 7);
3421
3422 /* HDMI_ISRC1_1[0x004C] */
3423 HDMI_OUTP(0x004C, *isrc_data++);
3424 /* HDMI_ISRC1_2[0x0050] */
3425 HDMI_OUTP(0x0050, *isrc_data++);
3426 /* HDMI_ISRC1_3[0x0054] */
3427 HDMI_OUTP(0x0054, *isrc_data++);
3428 /* HDMI_ISRC1_4[0x0058] */
3429 HDMI_OUTP(0x0058, *isrc_data++);
3430
3431 /* HDMI_ISRC2_0[0x005C] */
3432 HDMI_OUTP(0x005C, *isrc_data++);
3433 /* HDMI_ISRC2_1[0x0060] */
3434 HDMI_OUTP(0x0060, *isrc_data++);
3435 /* HDMI_ISRC2_2[0x0064] */
3436 HDMI_OUTP(0x0064, *isrc_data++);
3437 /* HDMI_ISRC2_3[0x0068] */
3438 HDMI_OUTP(0x0068, *isrc_data);
3439
3440 /* HDMI_VBI_PKT_CTRL[0x0028] */
3441 /* ISRC Send + Continuous */
3442 hdmi_msm_rmw32or(0x0028, 3 << 8);
3443}
Manoj Raoc2f19592011-08-05 17:54:25 -07003444#else
3445static void hdmi_msm_en_isrc_packet(boolean isrc_is_continued)
3446{
3447 /*
3448 * Until end-to-end support for various audio packets
3449 */
3450}
3451#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003452
Manoj Raoc2f19592011-08-05 17:54:25 -07003453#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_ISRC_ACP_SUPPORT
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003454static void hdmi_msm_en_acp_packet(uint32 byte1)
3455{
3456 /* HDMI_ACP[0x003C] */
3457 HDMI_OUTP(0x003C, 2 | 1 << 8 | byte1 << 16);
3458
3459 /* HDMI_VBI_PKT_CTRL[0x0028] */
3460 /* ACP send, s/w source */
3461 hdmi_msm_rmw32or(0x0028, 3 << 12);
3462}
Manoj Raoc2f19592011-08-05 17:54:25 -07003463#else
3464static void hdmi_msm_en_acp_packet(uint32 byte1)
3465{
3466 /*
3467 * Until end-to-end support for various audio packets
3468 */
3469}
3470#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003471
Ajay Singh Parmar0fc5d362011-11-16 05:48:33 +05303472int hdmi_msm_audio_get_sample_rate(void)
3473{
3474 return msm_hdmi_sample_rate;
3475}
3476EXPORT_SYMBOL(hdmi_msm_audio_get_sample_rate);
3477
3478void hdmi_msm_audio_sample_rate_reset(int rate)
3479{
3480 msm_hdmi_sample_rate = rate;
Ajay Singh Parmar8863118c2011-11-28 23:55:53 +05303481
Abhishek Kharbandab7b13f02011-11-18 11:20:08 -08003482#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
Ajay Singh Parmar8863118c2011-11-28 23:55:53 +05303483 if (hdmi_msm_has_hdcp())
3484 hdcp_deauthenticate();
3485 else
Abhishek Kharbandab7b13f02011-11-18 11:20:08 -08003486#endif
Ajay Singh Parmar8863118c2011-11-28 23:55:53 +05303487 hdmi_msm_turn_on();
Ajay Singh Parmar0fc5d362011-11-16 05:48:33 +05303488}
3489EXPORT_SYMBOL(hdmi_msm_audio_sample_rate_reset);
3490
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003491static void hdmi_msm_audio_setup(void)
3492{
3493 const int channels = MSM_HDMI_AUDIO_CHANNEL_2;
3494
3495 /* (0) for clr_avmute, (1) for set_avmute */
3496 hdmi_msm_en_gc_packet(0);
3497 /* (0) for isrc1 only, (1) for isrc1 and isrc2 */
3498 hdmi_msm_en_isrc_packet(1);
3499 /* arbitrary bit pattern for byte1 */
3500 hdmi_msm_en_acp_packet(0x5a);
Manoj Raoc2f19592011-08-05 17:54:25 -07003501 DEV_DBG("Not setting ACP, ISRC1, ISRC2 packets\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003502 hdmi_msm_audio_acr_setup(TRUE,
3503 external_common_state->video_resolution,
Ajay Singh Parmar0fc5d362011-11-16 05:48:33 +05303504 msm_hdmi_sample_rate, channels);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003505 hdmi_msm_audio_info_setup(TRUE, channels, 0, FALSE);
Deepa Madiregama6a3a01a2011-10-28 06:34:17 +05303506
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003507 /* Turn on Audio FIFO and SAM DROP ISR */
3508 HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3));
3509 DEV_INFO("HDMI Audio: Enabled\n");
3510}
3511
3512static int hdmi_msm_audio_off(void)
3513{
3514 uint32 audio_pkt_ctrl, audio_cfg;
3515 /* Number of wait iterations */
3516 int i = 10;
3517 audio_pkt_ctrl = HDMI_INP_ND(0x0020);
3518 audio_cfg = HDMI_INP_ND(0x01D0);
3519
3520 /* Checking BIT[0] of AUDIO PACKET CONTROL and */
3521 /* AUDIO CONFIGURATION register */
3522 while (((audio_pkt_ctrl & 0x00000001) || (audio_cfg & 0x00000001))
3523 && (i--)) {
3524 audio_pkt_ctrl = HDMI_INP_ND(0x0020);
3525 audio_cfg = HDMI_INP_ND(0x01D0);
3526 DEV_DBG("%d times :: HDMI AUDIO PACKET is %08x and "
3527 "AUDIO CFG is %08x", i, audio_pkt_ctrl, audio_cfg);
3528 msleep(100);
3529 if (!i) {
3530 DEV_ERR("%s:failed to set BIT[0] AUDIO PACKET"
3531 "CONTROL or AUDIO CONFIGURATION REGISTER\n",
3532 __func__);
3533 return -ETIMEDOUT;
3534 }
3535 }
3536 hdmi_msm_audio_info_setup(FALSE, 0, 0, FALSE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003537 hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0);
3538 DEV_INFO("HDMI Audio: Disabled\n");
3539 return 0;
3540}
3541
3542
Aravind Venkateswaran38753792011-11-18 13:14:08 -08003543static uint8 hdmi_msm_avi_iframe_lut[][16] = {
3544/* 480p60 480i60 576p50 576i50 720p60 720p50 1080p60 1080i60 1080p50
3545 1080i50 1080p24 1080p30 1080p25 640x480p 480p60_16_9 576p50_4_3 */
3546 {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
3547 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, /*00*/
3548 {0x18, 0x18, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
3549 0x28, 0x28, 0x28, 0x28, 0x18, 0x28, 0x18}, /*01*/
3550 {0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
3551 0x04, 0x04, 0x04, 0x04, 0x88, 0x04, 0x04}, /*02*/
3552 {0x02, 0x06, 0x11, 0x15, 0x04, 0x13, 0x10, 0x05, 0x1F,
3553 0x14, 0x20, 0x22, 0x21, 0x01, 0x03, 0x11}, /*03*/
3554 {0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
3555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*04*/
3556 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*05*/
3558 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*06*/
3560 {0xE1, 0xE1, 0x41, 0x41, 0xD1, 0xd1, 0x39, 0x39, 0x39,
3561 0x39, 0x39, 0x39, 0x39, 0xe1, 0xE1, 0x41}, /*07*/
3562 {0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04,
3563 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x02}, /*08*/
3564 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*09*/
3566 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*10*/
3568 {0xD1, 0xD1, 0xD1, 0xD1, 0x01, 0x01, 0x81, 0x81, 0x81,
3569 0x81, 0x81, 0x81, 0x81, 0x81, 0xD1, 0xD1}, /*11*/
3570 {0x02, 0x02, 0x02, 0x02, 0x05, 0x05, 0x07, 0x07, 0x07,
3571 0x07, 0x07, 0x07, 0x07, 0x02, 0x02, 0x02} /*12*/
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003572};
3573
3574static void hdmi_msm_avi_info_frame(void)
3575{
3576 /* two header + length + 13 data */
3577 uint8 aviInfoFrame[16];
3578 uint8 checksum;
3579 uint32 sum;
3580 uint32 regVal;
3581 int i;
3582 int mode = 0;
3583
3584 switch (external_common_state->video_resolution) {
Manoj Raobbf9a472011-06-14 21:05:18 -07003585 case HDMI_VFRMT_720x480p60_4_3:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003586 mode = 0;
3587 break;
3588 case HDMI_VFRMT_720x480i60_16_9:
3589 mode = 1;
3590 break;
3591 case HDMI_VFRMT_720x576p50_16_9:
3592 mode = 2;
3593 break;
3594 case HDMI_VFRMT_720x576i50_16_9:
3595 mode = 3;
3596 break;
3597 case HDMI_VFRMT_1280x720p60_16_9:
3598 mode = 4;
3599 break;
3600 case HDMI_VFRMT_1280x720p50_16_9:
3601 mode = 5;
3602 break;
3603 case HDMI_VFRMT_1920x1080p60_16_9:
3604 mode = 6;
3605 break;
3606 case HDMI_VFRMT_1920x1080i60_16_9:
3607 mode = 7;
3608 break;
3609 case HDMI_VFRMT_1920x1080p50_16_9:
3610 mode = 8;
3611 break;
3612 case HDMI_VFRMT_1920x1080i50_16_9:
3613 mode = 9;
3614 break;
3615 case HDMI_VFRMT_1920x1080p24_16_9:
3616 mode = 10;
3617 break;
3618 case HDMI_VFRMT_1920x1080p30_16_9:
3619 mode = 11;
3620 break;
3621 case HDMI_VFRMT_1920x1080p25_16_9:
3622 mode = 12;
3623 break;
3624 case HDMI_VFRMT_640x480p60_4_3:
3625 mode = 13;
3626 break;
Manoj Raobbf9a472011-06-14 21:05:18 -07003627 case HDMI_VFRMT_720x480p60_16_9:
3628 mode = 14;
3629 break;
Aravind Venkateswaran38753792011-11-18 13:14:08 -08003630 case HDMI_VFRMT_720x576p50_4_3:
3631 mode = 15;
3632 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003633 default:
3634 DEV_INFO("%s: mode %d not supported\n", __func__,
3635 external_common_state->video_resolution);
3636 return;
3637 }
3638
3639 /* InfoFrame Type = 82 */
3640 aviInfoFrame[0] = 0x82;
3641 /* Version = 2 */
3642 aviInfoFrame[1] = 2;
3643 /* Length of AVI InfoFrame = 13 */
3644 aviInfoFrame[2] = 13;
3645
3646 /* Data Byte 01: 0 Y1 Y0 A0 B1 B0 S1 S0 */
3647 aviInfoFrame[3] = hdmi_msm_avi_iframe_lut[0][mode];
3648 /* Data Byte 02: C1 C0 M1 M0 R3 R2 R1 R0 */
3649 aviInfoFrame[4] = hdmi_msm_avi_iframe_lut[1][mode];
3650 /* Data Byte 03: ITC EC2 EC1 EC0 Q1 Q0 SC1 SC0 */
3651 aviInfoFrame[5] = hdmi_msm_avi_iframe_lut[2][mode];
3652 /* Data Byte 04: 0 VIC6 VIC5 VIC4 VIC3 VIC2 VIC1 VIC0 */
3653 aviInfoFrame[6] = hdmi_msm_avi_iframe_lut[3][mode];
3654 /* Data Byte 05: 0 0 0 0 PR3 PR2 PR1 PR0 */
3655 aviInfoFrame[7] = hdmi_msm_avi_iframe_lut[4][mode];
3656 /* Data Byte 06: LSB Line No of End of Top Bar */
3657 aviInfoFrame[8] = hdmi_msm_avi_iframe_lut[5][mode];
3658 /* Data Byte 07: MSB Line No of End of Top Bar */
3659 aviInfoFrame[9] = hdmi_msm_avi_iframe_lut[6][mode];
3660 /* Data Byte 08: LSB Line No of Start of Bottom Bar */
3661 aviInfoFrame[10] = hdmi_msm_avi_iframe_lut[7][mode];
3662 /* Data Byte 09: MSB Line No of Start of Bottom Bar */
3663 aviInfoFrame[11] = hdmi_msm_avi_iframe_lut[8][mode];
3664 /* Data Byte 10: LSB Pixel Number of End of Left Bar */
3665 aviInfoFrame[12] = hdmi_msm_avi_iframe_lut[9][mode];
3666 /* Data Byte 11: MSB Pixel Number of End of Left Bar */
3667 aviInfoFrame[13] = hdmi_msm_avi_iframe_lut[10][mode];
3668 /* Data Byte 12: LSB Pixel Number of Start of Right Bar */
3669 aviInfoFrame[14] = hdmi_msm_avi_iframe_lut[11][mode];
3670 /* Data Byte 13: MSB Pixel Number of Start of Right Bar */
3671 aviInfoFrame[15] = hdmi_msm_avi_iframe_lut[12][mode];
3672
3673 sum = 0;
3674 for (i = 0; i < 16; i++)
3675 sum += aviInfoFrame[i];
3676 sum &= 0xFF;
3677 sum = 256 - sum;
3678 checksum = (uint8) sum;
3679
3680 regVal = aviInfoFrame[5];
3681 regVal = regVal << 8 | aviInfoFrame[4];
3682 regVal = regVal << 8 | aviInfoFrame[3];
3683 regVal = regVal << 8 | checksum;
3684 HDMI_OUTP(0x006C, regVal);
3685
3686 regVal = aviInfoFrame[9];
3687 regVal = regVal << 8 | aviInfoFrame[8];
3688 regVal = regVal << 8 | aviInfoFrame[7];
3689 regVal = regVal << 8 | aviInfoFrame[6];
3690 HDMI_OUTP(0x0070, regVal);
3691
3692 regVal = aviInfoFrame[13];
3693 regVal = regVal << 8 | aviInfoFrame[12];
3694 regVal = regVal << 8 | aviInfoFrame[11];
3695 regVal = regVal << 8 | aviInfoFrame[10];
3696 HDMI_OUTP(0x0074, regVal);
3697
3698 regVal = aviInfoFrame[1];
3699 regVal = regVal << 16 | aviInfoFrame[15];
3700 regVal = regVal << 8 | aviInfoFrame[14];
3701 HDMI_OUTP(0x0078, regVal);
3702
3703 /* INFOFRAME_CTRL0[0x002C] */
3704 /* 0x3 for AVI InfFrame enable (every frame) */
3705 HDMI_OUTP(0x002C, HDMI_INP(0x002C) | 0x00000003L);
3706}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003707
3708#ifdef CONFIG_FB_MSM_HDMI_3D
3709static void hdmi_msm_vendor_infoframe_packetsetup(void)
3710{
3711 uint32 packet_header = 0;
3712 uint32 check_sum = 0;
3713 uint32 packet_payload = 0;
3714
3715 if (!external_common_state->format_3d) {
3716 HDMI_OUTP(0x0034, 0);
3717 return;
3718 }
3719
3720 /* 0x0084 GENERIC0_HDR
3721 * HB0 7:0 NUM
3722 * HB1 15:8 NUM
3723 * HB2 23:16 NUM */
3724 /* Setup Packet header and payload */
3725 /* 0x81 VS_INFO_FRAME_ID
3726 0x01 VS_INFO_FRAME_VERSION
3727 0x1B VS_INFO_FRAME_PAYLOAD_LENGTH */
3728 packet_header = 0x81 | (0x01 << 8) | (0x1B << 16);
3729 HDMI_OUTP(0x0084, packet_header);
3730
3731 check_sum = packet_header & 0xff;
3732 check_sum += (packet_header >> 8) & 0xff;
3733 check_sum += (packet_header >> 16) & 0xff;
3734
3735 /* 0x008C GENERIC0_1
3736 * BYTE4 7:0 NUM
3737 * BYTE5 15:8 NUM
3738 * BYTE6 23:16 NUM
3739 * BYTE7 31:24 NUM */
3740 /* 0x02 VS_INFO_FRAME_3D_PRESENT */
3741 packet_payload = 0x02 << 5;
3742 switch (external_common_state->format_3d) {
3743 case 1:
3744 /* 0b1000 VIDEO_3D_FORMAT_SIDE_BY_SIDE_HALF */
3745 packet_payload |= (0x08 << 8) << 4;
3746 break;
3747 case 2:
3748 /* 0b0110 VIDEO_3D_FORMAT_TOP_AND_BOTTOM_HALF */
3749 packet_payload |= (0x06 << 8) << 4;
3750 break;
3751 }
3752 HDMI_OUTP(0x008C, packet_payload);
3753
3754 check_sum += packet_payload & 0xff;
3755 check_sum += (packet_payload >> 8) & 0xff;
3756
3757 #define IEEE_REGISTRATION_ID 0xC03
3758 /* Next 3 bytes are IEEE Registration Identifcation */
3759 /* 0x0088 GENERIC0_0
3760 * BYTE0 7:0 NUM (checksum)
3761 * BYTE1 15:8 NUM
3762 * BYTE2 23:16 NUM
3763 * BYTE3 31:24 NUM */
3764 check_sum += IEEE_REGISTRATION_ID & 0xff;
3765 check_sum += (IEEE_REGISTRATION_ID >> 8) & 0xff;
3766 check_sum += (IEEE_REGISTRATION_ID >> 16) & 0xff;
3767
3768 HDMI_OUTP(0x0088, (0x100 - (0xff & check_sum))
3769 | ((IEEE_REGISTRATION_ID & 0xff) << 8)
3770 | (((IEEE_REGISTRATION_ID >> 8) & 0xff) << 16)
3771 | (((IEEE_REGISTRATION_ID >> 16) & 0xff) << 24));
3772
3773 /* 0x0034 GEN_PKT_CTRL
3774 * GENERIC0_SEND 0 0 = Disable Generic0 Packet Transmission
3775 * 1 = Enable Generic0 Packet Transmission
3776 * GENERIC0_CONT 1 0 = Send Generic0 Packet on next frame only
3777 * 1 = Send Generic0 Packet on every frame
3778 * GENERIC0_UPDATE 2 NUM
3779 * GENERIC1_SEND 4 0 = Disable Generic1 Packet Transmission
3780 * 1 = Enable Generic1 Packet Transmission
3781 * GENERIC1_CONT 5 0 = Send Generic1 Packet on next frame only
3782 * 1 = Send Generic1 Packet on every frame
3783 * GENERIC0_LINE 21:16 NUM
3784 * GENERIC1_LINE 29:24 NUM
3785 */
3786 /* GENERIC0_LINE | GENERIC0_UPDATE | GENERIC0_CONT | GENERIC0_SEND
3787 * Setup HDMI TX generic packet control
3788 * Enable this packet to transmit every frame
3789 * Enable this packet to transmit every frame
3790 * Enable HDMI TX engine to transmit Generic packet 0 */
3791 HDMI_OUTP(0x0034, (1 << 16) | (1 << 2) | BIT(1) | BIT(0));
3792}
3793
3794static void hdmi_msm_switch_3d(boolean on)
3795{
3796 mutex_lock(&external_common_state_hpd_mutex);
3797 if (external_common_state->hpd_state)
3798 hdmi_msm_vendor_infoframe_packetsetup();
3799 mutex_unlock(&external_common_state_hpd_mutex);
3800}
3801#endif
3802
Ravishangar Kalyanam49a83b22011-07-20 15:28:44 -07003803int hdmi_msm_clk(int on)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003804{
3805 int rc;
3806
3807 DEV_DBG("HDMI Clk: %s\n", on ? "Enable" : "Disable");
3808 if (on) {
3809 rc = clk_enable(hdmi_msm_state->hdmi_app_clk);
3810 if (rc) {
3811 DEV_ERR("'hdmi_app_clk' clock enable failed, rc=%d\n",
3812 rc);
3813 return rc;
3814 }
3815
3816 rc = clk_enable(hdmi_msm_state->hdmi_m_pclk);
3817 if (rc) {
3818 DEV_ERR("'hdmi_m_pclk' clock enable failed, rc=%d\n",
3819 rc);
3820 return rc;
3821 }
3822
3823 rc = clk_enable(hdmi_msm_state->hdmi_s_pclk);
3824 if (rc) {
3825 DEV_ERR("'hdmi_s_pclk' clock enable failed, rc=%d\n",
3826 rc);
3827 return rc;
3828 }
3829 } else {
3830 clk_disable(hdmi_msm_state->hdmi_app_clk);
3831 clk_disable(hdmi_msm_state->hdmi_m_pclk);
3832 clk_disable(hdmi_msm_state->hdmi_s_pclk);
3833 }
3834
3835 return 0;
3836}
3837
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003838static void hdmi_msm_turn_on(void)
3839{
3840 uint32 hpd_ctrl;
Abhishek Kharbandaa077d002011-11-04 14:25:48 -07003841 uint32 audio_pkt_ctrl, audio_cfg;
3842 /*
3843 * Number of wait iterations for QDSP to disable Audio Engine
3844 * before resetting HDMI core
3845 */
3846 int i = 10;
3847 audio_pkt_ctrl = HDMI_INP_ND(0x0020);
3848 audio_cfg = HDMI_INP_ND(0x01D0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003849
Abhishek Kharbandaa077d002011-11-04 14:25:48 -07003850 /*
3851 * Checking BIT[0] of AUDIO PACKET CONTROL and
3852 * AUDIO CONFIGURATION register
3853 */
3854 while (((audio_pkt_ctrl & 0x00000001) || (audio_cfg & 0x00000001))
3855 && (i--)) {
3856 audio_pkt_ctrl = HDMI_INP_ND(0x0020);
3857 audio_cfg = HDMI_INP_ND(0x01D0);
3858 DEV_DBG("%d times :: HDMI AUDIO PACKET is %08x and "
3859 "AUDIO CFG is %08x", i, audio_pkt_ctrl, audio_cfg);
3860 msleep(20);
3861 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003862 hdmi_msm_reset_core();
3863 hdmi_msm_init_phy(external_common_state->video_resolution);
3864 /* HDMI_USEC_REFTIMER[0x0208] */
3865 HDMI_OUTP(0x0208, 0x0001001B);
3866
3867 hdmi_msm_video_setup(external_common_state->video_resolution);
3868 if (!hdmi_msm_is_dvi_mode())
3869 hdmi_msm_audio_setup();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003870 hdmi_msm_avi_info_frame();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003871#ifdef CONFIG_FB_MSM_HDMI_3D
3872 hdmi_msm_vendor_infoframe_packetsetup();
3873#endif
3874
3875 /* set timeout to 4.1ms (max) for hardware debounce */
3876 hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
3877
3878 /* Toggle HPD circuit to trigger HPD sense */
3879 HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
3880 HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
3881
3882 hdmi_msm_set_mode(TRUE);
3883
3884 /* Setup HPD IRQ */
3885 HDMI_OUTP(0x0254, 4 | (external_common_state->hpd_state ? 0 : 2));
3886
3887#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
3888 if (hdmi_msm_state->reauth) {
3889 hdmi_msm_hdcp_enable();
3890 hdmi_msm_state->reauth = FALSE ;
3891 }
3892#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
Manoj Raoa2c27672011-08-30 17:19:39 -07003893
3894#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
3895 /* re-initialize CEC if enabled */
3896 mutex_lock(&hdmi_msm_state_mutex);
3897 if (hdmi_msm_state->cec_enabled == true) {
3898 hdmi_msm_cec_init();
3899 hdmi_msm_cec_write_logical_addr(
3900 hdmi_msm_state->cec_logical_addr);
3901 }
3902 mutex_unlock(&hdmi_msm_state_mutex);
3903#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003904 DEV_INFO("HDMI Core: Initialized\n");
3905}
3906
3907static void hdmi_msm_hpd_state_timer(unsigned long data)
3908{
3909 queue_work(hdmi_work_queue, &hdmi_msm_state->hpd_state_work);
3910}
3911
3912#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
3913static void hdmi_msm_hdcp_timer(unsigned long data)
3914{
3915 queue_work(hdmi_work_queue, &hdmi_msm_state->hdcp_work);
3916}
3917#endif
3918
3919static void hdmi_msm_hpd_read_work(struct work_struct *work)
3920{
3921 uint32 hpd_ctrl;
3922
3923 clk_enable(hdmi_msm_state->hdmi_app_clk);
3924 hdmi_msm_state->pd->core_power(1, 1);
3925 hdmi_msm_state->pd->enable_5v(1);
3926 hdmi_msm_set_mode(FALSE);
3927 hdmi_msm_init_phy(external_common_state->video_resolution);
3928 /* HDMI_USEC_REFTIMER[0x0208] */
3929 HDMI_OUTP(0x0208, 0x0001001B);
3930 hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
3931
3932 /* Toggle HPD circuit to trigger HPD sense */
3933 HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
3934 HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
3935
3936 hdmi_msm_set_mode(TRUE);
3937 msleep(1000);
3938 external_common_state->hpd_state = (HDMI_INP(0x0250) & 0x2) >> 1;
3939 if (external_common_state->hpd_state) {
3940 hdmi_msm_read_edid();
3941 DEV_DBG("%s: sense CONNECTED: send ONLINE\n", __func__);
3942 kobject_uevent(external_common_state->uevent_kobj,
3943 KOBJ_ONLINE);
3944 }
3945 hdmi_msm_hpd_off();
3946 hdmi_msm_set_mode(FALSE);
3947 hdmi_msm_state->pd->core_power(0, 1);
3948 hdmi_msm_state->pd->enable_5v(0);
3949 clk_disable(hdmi_msm_state->hdmi_app_clk);
3950}
3951
3952static void hdmi_msm_hpd_off(void)
3953{
3954 DEV_DBG("%s: (timer, clk, 5V, core, IRQ off)\n", __func__);
3955 del_timer(&hdmi_msm_state->hpd_state_timer);
3956 disable_irq(hdmi_msm_state->irq);
3957
3958 hdmi_msm_set_mode(FALSE);
3959 HDMI_OUTP_ND(0x0308, 0x7F); /*0b01111111*/
3960 hdmi_msm_state->hpd_initialized = FALSE;
Manoj Raoa2c27672011-08-30 17:19:39 -07003961 hdmi_msm_state->pd->cec_power(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003962 hdmi_msm_state->pd->enable_5v(0);
3963 hdmi_msm_state->pd->core_power(0, 1);
3964 hdmi_msm_clk(0);
3965 hdmi_msm_state->hpd_initialized = FALSE;
3966}
3967
Manoj Rao668d6d52011-08-16 19:12:31 -07003968static void hdmi_msm_dump_regs(const char *prefix)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003969{
3970#ifdef REG_DUMP
3971 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 32, 4,
3972 (void *)MSM_HDMI_BASE, 0x0334, false);
3973#endif
3974}
3975
3976static int hdmi_msm_hpd_on(bool trigger_handler)
3977{
3978 static int phy_reset_done;
3979
3980 hdmi_msm_clk(1);
3981 hdmi_msm_state->pd->core_power(1, 1);
3982 hdmi_msm_state->pd->enable_5v(1);
Manoj Raoa2c27672011-08-30 17:19:39 -07003983 hdmi_msm_state->pd->cec_power(1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003984 hdmi_msm_dump_regs("HDMI-INIT: ");
3985 hdmi_msm_set_mode(FALSE);
3986
3987 if (!phy_reset_done) {
3988 hdmi_phy_reset();
3989 phy_reset_done = 1;
3990 }
3991
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003992 /* HDMI_USEC_REFTIMER[0x0208] */
3993 HDMI_OUTP(0x0208, 0x0001001B);
3994
3995 /* Check HPD State */
3996 if (!hdmi_msm_state->hpd_initialized) {
3997 uint32 hpd_ctrl;
3998 enable_irq(hdmi_msm_state->irq);
3999
4000 /* set timeout to 4.1ms (max) for hardware debounce */
4001 hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
4002
4003 /* Toggle HPD circuit to trigger HPD sense */
4004 HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
4005 HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
4006
4007 DEV_DBG("%s: (clk, 5V, core, IRQ on) <trigger:%s>\n", __func__,
4008 trigger_handler ? "true" : "false");
4009
4010 if (trigger_handler) {
4011 /* Set HPD state machine: ensure at least 2 readouts */
4012 mutex_lock(&hdmi_msm_state_mutex);
4013 hdmi_msm_state->hpd_stable = 0;
4014 hdmi_msm_state->hpd_prev_state = TRUE;
4015 mutex_lock(&external_common_state_hpd_mutex);
4016 external_common_state->hpd_state = FALSE;
4017 mutex_unlock(&external_common_state_hpd_mutex);
4018 hdmi_msm_state->hpd_cable_chg_detected = TRUE;
4019 mutex_unlock(&hdmi_msm_state_mutex);
4020 mod_timer(&hdmi_msm_state->hpd_state_timer,
4021 jiffies + HZ/2);
4022 }
4023
4024 hdmi_msm_state->hpd_initialized = TRUE;
4025 }
4026 hdmi_msm_set_mode(TRUE);
4027
4028 return 0;
4029}
4030
4031static int hdmi_msm_power_on(struct platform_device *pdev)
4032{
4033 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
4034 bool changed;
4035
4036 if (!hdmi_msm_state || !hdmi_msm_state->hdmi_app_clk || !MSM_HDMI_BASE)
4037 return -ENODEV;
4038#ifdef CONFIG_SUSPEND
4039 mutex_lock(&hdmi_msm_state_mutex);
4040 if (hdmi_msm_state->pm_suspended) {
4041 mutex_unlock(&hdmi_msm_state_mutex);
4042 DEV_WARN("%s: ignored, pm_suspended\n", __func__);
4043 return -ENODEV;
4044 }
4045 mutex_unlock(&hdmi_msm_state_mutex);
4046#endif
4047
4048 DEV_INFO("power: ON (%dx%d %d)\n", mfd->var_xres, mfd->var_yres,
4049 mfd->var_pixclock);
4050
4051#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4052 mutex_lock(&hdmi_msm_state_mutex);
4053 if (hdmi_msm_state->hdcp_activating) {
4054 hdmi_msm_state->panel_power_on = TRUE;
4055 DEV_INFO("HDCP: activating, returning\n");
4056 }
4057 mutex_unlock(&hdmi_msm_state_mutex);
4058#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4059
4060 changed = hdmi_common_get_video_format_from_drv_data(mfd);
4061 if (!external_common_state->hpd_feature_on) {
4062 int rc = hdmi_msm_hpd_on(true);
4063 DEV_INFO("HPD: panel power without 'hpd' feature on\n");
4064 if (rc) {
4065 DEV_WARN("HPD: activation failed: rc=%d\n", rc);
4066 return rc;
4067 }
4068 }
4069 hdmi_msm_audio_info_setup(TRUE, 0, 0, FALSE);
4070
4071 mutex_lock(&external_common_state_hpd_mutex);
4072 hdmi_msm_state->panel_power_on = TRUE;
4073 if ((external_common_state->hpd_state && !hdmi_msm_is_power_on())
4074 || changed) {
4075 mutex_unlock(&external_common_state_hpd_mutex);
4076 hdmi_msm_turn_on();
4077 } else
4078 mutex_unlock(&external_common_state_hpd_mutex);
4079
4080 hdmi_msm_dump_regs("HDMI-ON: ");
4081
4082 DEV_INFO("power=%s DVI= %s\n",
4083 hdmi_msm_is_power_on() ? "ON" : "OFF" ,
4084 hdmi_msm_is_dvi_mode() ? "ON" : "OFF");
4085 return 0;
4086}
4087
4088/* Note that power-off will also be called when the cable-remove event is
4089 * processed on the user-space and as a result the framebuffer is powered
4090 * down. However, we are still required to be able to detect a cable-insert
4091 * event; so for now leave the HDMI engine running; so that the HPD IRQ is
4092 * still being processed.
4093 */
4094static int hdmi_msm_power_off(struct platform_device *pdev)
4095{
4096 if (!hdmi_msm_state->hdmi_app_clk)
4097 return -ENODEV;
4098#ifdef CONFIG_SUSPEND
4099 mutex_lock(&hdmi_msm_state_mutex);
4100 if (hdmi_msm_state->pm_suspended) {
4101 mutex_unlock(&hdmi_msm_state_mutex);
4102 DEV_WARN("%s: ignored, pm_suspended\n", __func__);
4103 return -ENODEV;
4104 }
4105 mutex_unlock(&hdmi_msm_state_mutex);
4106#endif
4107
4108#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4109 mutex_lock(&hdmi_msm_state_mutex);
4110 if (hdmi_msm_state->hdcp_activating) {
4111 hdmi_msm_state->panel_power_on = FALSE;
4112 mutex_unlock(&hdmi_msm_state_mutex);
4113 DEV_INFO("HDCP: activating, returning\n");
4114 return 0;
4115 }
4116 mutex_unlock(&hdmi_msm_state_mutex);
4117#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4118
4119 DEV_INFO("power: OFF (audio off, Reset Core)\n");
4120 hdmi_msm_audio_off();
4121#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4122 hdcp_deauthenticate();
4123#endif
4124 hdmi_msm_hpd_off();
4125 hdmi_msm_powerdown_phy();
4126 hdmi_msm_dump_regs("HDMI-OFF: ");
Manoj Rao53ac99d2011-10-10 17:32:28 -07004127 hdmi_msm_hpd_on(true);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004128
4129 mutex_lock(&external_common_state_hpd_mutex);
4130 if (!external_common_state->hpd_feature_on)
4131 hdmi_msm_hpd_off();
4132 mutex_unlock(&external_common_state_hpd_mutex);
4133
4134 hdmi_msm_state->panel_power_on = FALSE;
4135 return 0;
4136}
4137
4138static int __devinit hdmi_msm_probe(struct platform_device *pdev)
4139{
4140 int rc;
4141 struct platform_device *fb_dev;
4142
Stepan Moskovchenko164fe8a2011-08-05 18:10:54 -07004143 if (cpu_is_apq8064())
4144 return -ENODEV;
4145
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004146 if (!hdmi_msm_state) {
4147 pr_err("%s: hdmi_msm_state is NULL\n", __func__);
4148 return -ENOMEM;
4149 }
4150
4151 external_common_state->dev = &pdev->dev;
4152 DEV_DBG("probe\n");
4153 if (pdev->id == 0) {
4154 struct resource *res;
4155
4156 #define GET_RES(name, mode) do { \
4157 res = platform_get_resource_byname(pdev, mode, name); \
4158 if (!res) { \
4159 DEV_ERR("'" name "' resource not found\n"); \
4160 rc = -ENODEV; \
4161 goto error; \
4162 } \
4163 } while (0)
4164
4165 #define IO_REMAP(var, name) do { \
4166 GET_RES(name, IORESOURCE_MEM); \
4167 var = ioremap(res->start, resource_size(res)); \
4168 if (!var) { \
4169 DEV_ERR("'" name "' ioremap failed\n"); \
4170 rc = -ENOMEM; \
4171 goto error; \
4172 } \
4173 } while (0)
4174
4175 #define GET_IRQ(var, name) do { \
4176 GET_RES(name, IORESOURCE_IRQ); \
4177 var = res->start; \
4178 } while (0)
4179
4180 IO_REMAP(hdmi_msm_state->qfprom_io, "hdmi_msm_qfprom_addr");
4181 hdmi_msm_state->hdmi_io = MSM_HDMI_BASE;
4182 GET_IRQ(hdmi_msm_state->irq, "hdmi_msm_irq");
4183
4184 hdmi_msm_state->pd = pdev->dev.platform_data;
4185
4186 #undef GET_RES
4187 #undef IO_REMAP
4188 #undef GET_IRQ
4189 return 0;
4190 }
4191
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004192 hdmi_msm_state->hdmi_app_clk = clk_get(&pdev->dev, "core_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004193 if (IS_ERR(hdmi_msm_state->hdmi_app_clk)) {
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004194 DEV_ERR("'core_clk' clk not found\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004195 rc = IS_ERR(hdmi_msm_state->hdmi_app_clk);
4196 goto error;
4197 }
4198
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004199 hdmi_msm_state->hdmi_m_pclk = clk_get(&pdev->dev, "master_iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004200 if (IS_ERR(hdmi_msm_state->hdmi_m_pclk)) {
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004201 DEV_ERR("'master_iface_clk' clk not found\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004202 rc = IS_ERR(hdmi_msm_state->hdmi_m_pclk);
4203 goto error;
4204 }
4205
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004206 hdmi_msm_state->hdmi_s_pclk = clk_get(&pdev->dev, "slave_iface_clk");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004207 if (IS_ERR(hdmi_msm_state->hdmi_s_pclk)) {
Matt Wagantall5a4f1ba2011-08-18 18:13:03 -07004208 DEV_ERR("'slave_iface_clk' clk not found\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004209 rc = IS_ERR(hdmi_msm_state->hdmi_s_pclk);
4210 goto error;
4211 }
4212
4213 rc = check_hdmi_features();
4214 if (rc) {
4215 DEV_ERR("Init FAILED: check_hdmi_features rc=%d\n", rc);
4216 goto error;
4217 }
4218
4219 if (!hdmi_msm_state->pd->core_power) {
4220 DEV_ERR("Init FAILED: core_power function missing\n");
4221 rc = -ENODEV;
4222 goto error;
4223 }
4224 if (!hdmi_msm_state->pd->enable_5v) {
4225 DEV_ERR("Init FAILED: enable_5v function missing\n");
4226 rc = -ENODEV;
4227 goto error;
4228 }
4229
Manoj Raoa2c27672011-08-30 17:19:39 -07004230 if (!hdmi_msm_state->pd->cec_power) {
4231 DEV_ERR("Init FAILED: cec_power function missing\n");
4232 rc = -ENODEV;
4233 goto error;
4234 }
4235
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004236 rc = request_threaded_irq(hdmi_msm_state->irq, NULL, &hdmi_msm_isr,
4237 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "hdmi_msm_isr", NULL);
4238 if (rc) {
4239 DEV_ERR("Init FAILED: IRQ request, rc=%d\n", rc);
4240 goto error;
4241 }
4242 disable_irq(hdmi_msm_state->irq);
4243
4244 init_timer(&hdmi_msm_state->hpd_state_timer);
4245 hdmi_msm_state->hpd_state_timer.function =
4246 hdmi_msm_hpd_state_timer;
4247 hdmi_msm_state->hpd_state_timer.data = (uint32)NULL;
4248
4249 hdmi_msm_state->hpd_state_timer.expires = 0xffffffffL;
4250 add_timer(&hdmi_msm_state->hpd_state_timer);
4251
4252#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4253 init_timer(&hdmi_msm_state->hdcp_timer);
4254 hdmi_msm_state->hdcp_timer.function =
4255 hdmi_msm_hdcp_timer;
4256 hdmi_msm_state->hdcp_timer.data = (uint32)NULL;
4257
4258 hdmi_msm_state->hdcp_timer.expires = 0xffffffffL;
4259 add_timer(&hdmi_msm_state->hdcp_timer);
4260#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4261
4262 fb_dev = msm_fb_add_device(pdev);
4263 if (fb_dev) {
4264 rc = external_common_state_create(fb_dev);
4265 if (rc) {
4266 DEV_ERR("Init FAILED: hdmi_msm_state_create, rc=%d\n",
4267 rc);
4268 goto error;
4269 }
4270 } else
4271 DEV_ERR("Init FAILED: failed to add fb device\n");
4272
4273 DEV_INFO("HDMI HPD: ON\n");
4274
4275 rc = hdmi_msm_hpd_on(true);
4276 if (rc)
4277 goto error;
4278
Abhishek Kharbandab7b13f02011-11-18 11:20:08 -08004279 if (hdmi_msm_has_hdcp()) {
4280 /* Don't Set Encryption in case of non HDCP builds */
4281 external_common_state->present_hdcp = FALSE;
4282#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004283 external_common_state->present_hdcp = TRUE;
Abhishek Kharbandab7b13f02011-11-18 11:20:08 -08004284#endif
4285 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004286 external_common_state->present_hdcp = FALSE;
4287#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4288 /*
4289 * If the device is not hdcp capable do
4290 * not start hdcp timer.
4291 */
4292 del_timer(&hdmi_msm_state->hdcp_timer);
4293#endif
4294 }
4295
4296 queue_work(hdmi_work_queue, &hdmi_msm_state->hpd_read_work);
4297 return 0;
4298
4299error:
4300 if (hdmi_msm_state->qfprom_io)
4301 iounmap(hdmi_msm_state->qfprom_io);
4302 hdmi_msm_state->qfprom_io = NULL;
4303
4304 if (hdmi_msm_state->hdmi_io)
4305 iounmap(hdmi_msm_state->hdmi_io);
4306 hdmi_msm_state->hdmi_io = NULL;
4307
4308 external_common_state_remove();
4309
4310 if (hdmi_msm_state->hdmi_app_clk)
4311 clk_put(hdmi_msm_state->hdmi_app_clk);
4312 if (hdmi_msm_state->hdmi_m_pclk)
4313 clk_put(hdmi_msm_state->hdmi_m_pclk);
4314 if (hdmi_msm_state->hdmi_s_pclk)
4315 clk_put(hdmi_msm_state->hdmi_s_pclk);
4316
4317 hdmi_msm_state->hdmi_app_clk = NULL;
4318 hdmi_msm_state->hdmi_m_pclk = NULL;
4319 hdmi_msm_state->hdmi_s_pclk = NULL;
4320
4321 return rc;
4322}
4323
4324static int __devexit hdmi_msm_remove(struct platform_device *pdev)
4325{
4326 DEV_INFO("HDMI device: remove\n");
4327
4328 DEV_INFO("HDMI HPD: OFF\n");
4329 hdmi_msm_hpd_off();
4330 free_irq(hdmi_msm_state->irq, NULL);
4331
4332 if (hdmi_msm_state->qfprom_io)
4333 iounmap(hdmi_msm_state->qfprom_io);
4334 hdmi_msm_state->qfprom_io = NULL;
4335
4336 if (hdmi_msm_state->hdmi_io)
4337 iounmap(hdmi_msm_state->hdmi_io);
4338 hdmi_msm_state->hdmi_io = NULL;
4339
4340 external_common_state_remove();
4341
4342 if (hdmi_msm_state->hdmi_app_clk)
4343 clk_put(hdmi_msm_state->hdmi_app_clk);
4344 if (hdmi_msm_state->hdmi_m_pclk)
4345 clk_put(hdmi_msm_state->hdmi_m_pclk);
4346 if (hdmi_msm_state->hdmi_s_pclk)
4347 clk_put(hdmi_msm_state->hdmi_s_pclk);
4348
4349 hdmi_msm_state->hdmi_app_clk = NULL;
4350 hdmi_msm_state->hdmi_m_pclk = NULL;
4351 hdmi_msm_state->hdmi_s_pclk = NULL;
4352
4353 kfree(hdmi_msm_state);
4354 hdmi_msm_state = NULL;
4355
4356 return 0;
4357}
4358
4359static int hdmi_msm_hpd_feature(int on)
4360{
4361 int rc = 0;
4362
4363 DEV_INFO("%s: %d\n", __func__, on);
4364 if (on)
4365 rc = hdmi_msm_hpd_on(true);
4366 else
4367 hdmi_msm_hpd_off();
4368
4369 return rc;
4370}
4371
4372
4373#ifdef CONFIG_SUSPEND
4374static int hdmi_msm_device_pm_suspend(struct device *dev)
4375{
4376 mutex_lock(&hdmi_msm_state_mutex);
4377 if (hdmi_msm_state->pm_suspended) {
4378 mutex_unlock(&hdmi_msm_state_mutex);
4379 return 0;
4380 }
4381
4382 DEV_DBG("pm_suspend\n");
4383
4384 del_timer(&hdmi_msm_state->hpd_state_timer);
4385#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4386 del_timer(&hdmi_msm_state->hdcp_timer);
4387#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4388
4389 disable_irq(hdmi_msm_state->irq);
Ravishangar Kalyanam18337542011-08-12 10:26:35 -07004390 if (external_common_state->hpd_feature_on)
4391 hdmi_msm_clk(0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004392
4393 hdmi_msm_state->pm_suspended = TRUE;
4394 mutex_unlock(&hdmi_msm_state_mutex);
4395
4396 hdmi_msm_powerdown_phy();
4397 hdmi_msm_state->pd->enable_5v(0);
4398 hdmi_msm_state->pd->core_power(0, 1);
4399 return 0;
4400}
4401
4402static int hdmi_msm_device_pm_resume(struct device *dev)
4403{
4404 mutex_lock(&hdmi_msm_state_mutex);
4405 if (!hdmi_msm_state->pm_suspended) {
4406 mutex_unlock(&hdmi_msm_state_mutex);
4407 return 0;
4408 }
4409
4410 DEV_DBG("pm_resume\n");
4411
4412 hdmi_msm_state->pd->core_power(1, 1);
4413 hdmi_msm_state->pd->enable_5v(1);
Ravishangar Kalyanam18337542011-08-12 10:26:35 -07004414 if (external_common_state->hpd_feature_on)
4415 hdmi_msm_clk(1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004416
4417 hdmi_msm_state->pm_suspended = FALSE;
4418 mutex_unlock(&hdmi_msm_state_mutex);
4419 enable_irq(hdmi_msm_state->irq);
4420 return 0;
4421}
4422#else
4423#define hdmi_msm_device_pm_suspend NULL
4424#define hdmi_msm_device_pm_resume NULL
4425#endif
4426
4427static const struct dev_pm_ops hdmi_msm_device_pm_ops = {
4428 .suspend = hdmi_msm_device_pm_suspend,
4429 .resume = hdmi_msm_device_pm_resume,
4430};
4431
4432static struct platform_driver this_driver = {
4433 .probe = hdmi_msm_probe,
4434 .remove = hdmi_msm_remove,
4435 .driver.name = "hdmi_msm",
4436 .driver.pm = &hdmi_msm_device_pm_ops,
4437};
4438
4439static struct msm_fb_panel_data hdmi_msm_panel_data = {
4440 .on = hdmi_msm_power_on,
4441 .off = hdmi_msm_power_off,
4442};
4443
4444static struct platform_device this_device = {
4445 .name = "hdmi_msm",
4446 .id = 1,
4447 .dev.platform_data = &hdmi_msm_panel_data,
4448};
4449
4450static int __init hdmi_msm_init(void)
4451{
4452 int rc;
4453
Ajay Dudani52e88232011-12-13 13:33:10 -08004454 if (cpu_is_msm8930())
Ajay Singh Parmar2aab6fd2011-12-07 07:23:34 +05304455 return 0;
4456
Ravishangar Kalyanamc719c542011-07-28 16:49:25 -07004457 if (msm_fb_detect_client("hdmi_msm"))
4458 return 0;
4459
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004460 hdmi_msm_setup_video_mode_lut();
4461 hdmi_msm_state = kzalloc(sizeof(*hdmi_msm_state), GFP_KERNEL);
4462 if (!hdmi_msm_state) {
4463 pr_err("hdmi_msm_init FAILED: out of memory\n");
4464 rc = -ENOMEM;
4465 goto init_exit;
4466 }
4467
4468 external_common_state = &hdmi_msm_state->common;
4469 external_common_state->video_resolution = HDMI_VFRMT_1920x1080p60_16_9;
4470#ifdef CONFIG_FB_MSM_HDMI_3D
4471 external_common_state->switch_3d = hdmi_msm_switch_3d;
4472#endif
4473
Manoj Raoa2c27672011-08-30 17:19:39 -07004474#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
4475 hdmi_msm_state->cec_queue_start =
4476 kzalloc(sizeof(struct hdmi_msm_cec_msg)*CEC_QUEUE_SIZE,
4477 GFP_KERNEL);
4478 if (!hdmi_msm_state->cec_queue_start) {
4479 pr_err("hdmi_msm_init FAILED: CEC queue out of memory\n");
4480 rc = -ENOMEM;
4481 goto init_exit;
4482 }
4483
4484 hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
4485 hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
4486 hdmi_msm_state->cec_queue_full = false;
4487#endif
4488
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004489 /*
4490 * Create your work queue
4491 * allocs and returns ptr
4492 */
4493 hdmi_work_queue = create_workqueue("hdmi_hdcp");
4494 external_common_state->hpd_feature = hdmi_msm_hpd_feature;
4495
4496 rc = platform_driver_register(&this_driver);
4497 if (rc) {
4498 pr_err("hdmi_msm_init FAILED: platform_driver_register rc=%d\n",
4499 rc);
4500 goto init_exit;
4501 }
4502
4503 hdmi_common_init_panel_info(&hdmi_msm_panel_data.panel_info);
4504 init_completion(&hdmi_msm_state->ddc_sw_done);
4505 INIT_WORK(&hdmi_msm_state->hpd_state_work, hdmi_msm_hpd_state_work);
4506 INIT_WORK(&hdmi_msm_state->hpd_read_work, hdmi_msm_hpd_read_work);
4507#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4508 init_completion(&hdmi_msm_state->hdcp_success_done);
4509 INIT_WORK(&hdmi_msm_state->hdcp_reauth_work, hdmi_msm_hdcp_reauth_work);
4510 INIT_WORK(&hdmi_msm_state->hdcp_work, hdmi_msm_hdcp_work);
4511#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4512
Manoj Raoa2c27672011-08-30 17:19:39 -07004513#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
4514 init_completion(&hdmi_msm_state->cec_frame_wr_done);
4515#endif
4516
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004517 rc = platform_device_register(&this_device);
4518 if (rc) {
4519 pr_err("hdmi_msm_init FAILED: platform_device_register rc=%d\n",
4520 rc);
4521 platform_driver_unregister(&this_driver);
4522 goto init_exit;
4523 }
4524
4525 pr_debug("%s: success:"
4526#ifdef DEBUG
4527 " DEBUG"
4528#else
4529 " RELEASE"
4530#endif
4531 " AUDIO EDID HPD HDCP"
4532#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
4533 ":0"
4534#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
4535 " DVI"
4536#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT
4537 ":0"
4538#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT */
4539 "\n", __func__);
4540
4541 return 0;
4542
4543init_exit:
4544 kfree(hdmi_msm_state);
4545 hdmi_msm_state = NULL;
4546
4547 return rc;
4548}
4549
4550static void __exit hdmi_msm_exit(void)
4551{
4552 platform_device_unregister(&this_device);
4553 platform_driver_unregister(&this_driver);
4554}
4555
4556module_init(hdmi_msm_init);
4557module_exit(hdmi_msm_exit);
4558
4559MODULE_LICENSE("GPL v2");
4560MODULE_VERSION("0.3");
4561MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
4562MODULE_DESCRIPTION("HDMI MSM TX driver");