blob: 8bde7b7e95ff181ea2792f94f33a7a69442a3449 [file] [log] [blame]
Mythri P K7d983f32011-09-08 19:06:23 +05301/*
2 * ti_hdmi_4xxx_ip.c
3 *
4 * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
Tomi Valkeinenac9f2422013-11-14 13:46:32 +020022#define DSS_SUBSYS_NAME "HDMICORE"
23
Mythri P K7d983f32011-09-08 19:06:23 +053024#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
Archit Taneja425f02f2013-10-08 14:16:05 +053031#include <linux/platform_device.h>
Mythri P K7d983f32011-09-08 19:06:23 +053032#include <linux/string.h>
Mythri P K162874d2011-09-22 13:37:45 +053033#include <linux/seq_file.h>
Ricardo Neri7e151f72012-03-15 14:08:03 -060034#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
Ricardo Neri199e7fd2012-03-15 10:39:00 -060035#include <sound/asound.h>
Ricardo Neri6ec355d2012-03-21 12:38:15 -060036#include <sound/asoundef.h>
Ricardo Neri199e7fd2012-03-15 10:39:00 -060037#endif
Mythri P K7d983f32011-09-08 19:06:23 +053038
Archit Tanejaef269582013-09-12 17:45:57 +053039#include "hdmi4_core.h"
Ricardo Neri6ec355d2012-03-21 12:38:15 -060040#include "dss_features.h"
Mythri P K7d983f32011-09-08 19:06:23 +053041
Archit Taneja425f02f2013-10-08 14:16:05 +053042#define HDMI_CORE_AV 0x500
43
Archit Taneja425f02f2013-10-08 14:16:05 +053044static inline void __iomem *hdmi_av_base(struct hdmi_core_data *core)
Archit Tanejaf382d9e2013-08-06 14:56:55 +053045{
Archit Taneja425f02f2013-10-08 14:16:05 +053046 return core->base + HDMI_CORE_AV;
Archit Tanejaf382d9e2013-08-06 14:56:55 +053047}
48
Archit Taneja425f02f2013-10-08 14:16:05 +053049static int hdmi_core_ddc_init(struct hdmi_core_data *core)
Archit Tanejaf382d9e2013-08-06 14:56:55 +053050{
Archit Taneja425f02f2013-10-08 14:16:05 +053051 void __iomem *base = core->base;
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +030052
53 /* Turn on CLK for DDC */
54 REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
55
56 /* IN_PROG */
57 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) {
58 /* Abort transaction */
59 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
60 /* IN_PROG */
61 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
62 4, 4, 0) != 0) {
63 DSSERR("Timeout aborting DDC transaction\n");
64 return -ETIMEDOUT;
65 }
66 }
67
68 /* Clk SCL Devices */
69 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
70
71 /* HDMI_CORE_DDC_STATUS_IN_PROG */
72 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
73 4, 4, 0) != 0) {
74 DSSERR("Timeout starting SCL clock\n");
75 return -ETIMEDOUT;
76 }
77
78 /* Clear FIFO */
79 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
80
81 /* HDMI_CORE_DDC_STATUS_IN_PROG */
82 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
83 4, 4, 0) != 0) {
84 DSSERR("Timeout clearing DDC fifo\n");
85 return -ETIMEDOUT;
86 }
87
88 return 0;
89}
90
Archit Taneja425f02f2013-10-08 14:16:05 +053091static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +030092 u8 *pedid, int ext)
93{
Archit Taneja425f02f2013-10-08 14:16:05 +053094 void __iomem *base = core->base;
Tomi Valkeinen937fce12011-08-31 11:12:40 +030095 u32 i;
96 char checksum;
Mythri P K7d983f32011-09-08 19:06:23 +053097 u32 offset = 0;
Mythri P K7d983f32011-09-08 19:06:23 +053098
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +030099 /* HDMI_CORE_DDC_STATUS_IN_PROG */
100 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
101 4, 4, 0) != 0) {
102 DSSERR("Timeout waiting DDC to be ready\n");
103 return -ETIMEDOUT;
Mythri P K7d983f32011-09-08 19:06:23 +0530104 }
105
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300106 if (ext % 2 != 0)
107 offset = 0x80;
108
Mythri P K7d983f32011-09-08 19:06:23 +0530109 /* Load Segment Address Register */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300110 REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530111
112 /* Load Slave Address Register */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300113 REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
Mythri P K7d983f32011-09-08 19:06:23 +0530114
115 /* Load Offset Address Register */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300116 REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530117
118 /* Load Byte Count */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300119 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
120 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530121
122 /* Set DDC_CMD */
123 if (ext)
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300124 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530125 else
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300126 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530127
128 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300129 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200130 DSSERR("I2C Bus Low?\n");
Mythri P K7d983f32011-09-08 19:06:23 +0530131 return -EIO;
132 }
133 /* HDMI_CORE_DDC_STATUS_NO_ACK */
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300134 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200135 DSSERR("I2C No Ack\n");
Mythri P K7d983f32011-09-08 19:06:23 +0530136 return -EIO;
137 }
138
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300139 for (i = 0; i < 0x80; ++i) {
140 int t;
Mythri P K7d983f32011-09-08 19:06:23 +0530141
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300142 /* IN_PROG */
143 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) {
144 DSSERR("operation stopped when reading edid\n");
145 return -EIO;
Mythri P K7d983f32011-09-08 19:06:23 +0530146 }
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300147
148 t = 0;
149 /* FIFO_EMPTY */
150 while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) {
151 if (t++ > 10000) {
152 DSSERR("timeout reading edid\n");
153 return -ETIMEDOUT;
154 }
155 udelay(1);
156 }
157
158 pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530159 }
160
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300161 checksum = 0;
162 for (i = 0; i < 0x80; ++i)
163 checksum += pedid[i];
Mythri P K7d983f32011-09-08 19:06:23 +0530164
165 if (checksum != 0) {
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200166 DSSERR("E-EDID checksum failed!!\n");
Mythri P K7d983f32011-09-08 19:06:23 +0530167 return -EIO;
168 }
169
170 return 0;
171}
172
Archit Taneja425f02f2013-10-08 14:16:05 +0530173int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
Mythri P K7d983f32011-09-08 19:06:23 +0530174{
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300175 int r, l;
176
177 if (len < 128)
178 return -EINVAL;
Mythri P K7d983f32011-09-08 19:06:23 +0530179
Archit Taneja425f02f2013-10-08 14:16:05 +0530180 r = hdmi_core_ddc_init(core);
Tomi Valkeinen032b8ea2011-08-22 17:47:56 +0300181 if (r)
182 return r;
183
Archit Taneja425f02f2013-10-08 14:16:05 +0530184 r = hdmi_core_ddc_edid(core, edid, 0);
Tomi Valkeinen47024562011-08-25 17:12:56 +0300185 if (r)
Mythri P K7d983f32011-09-08 19:06:23 +0530186 return r;
Mythri P K7d983f32011-09-08 19:06:23 +0530187
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300188 l = 128;
Mythri P K7d983f32011-09-08 19:06:23 +0530189
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300190 if (len >= 128 * 2 && edid[0x7e] > 0) {
Archit Taneja425f02f2013-10-08 14:16:05 +0530191 r = hdmi_core_ddc_edid(core, edid + 0x80, 1);
Tomi Valkeinen47024562011-08-25 17:12:56 +0300192 if (r)
193 return r;
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300194 l += 128;
Mythri P K7d983f32011-09-08 19:06:23 +0530195 }
Tomi Valkeinen47024562011-08-25 17:12:56 +0300196
Tomi Valkeinen937fce12011-08-31 11:12:40 +0300197 return l;
Mythri P K7d983f32011-09-08 19:06:23 +0530198}
199
200static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
201 struct hdmi_core_infoframe_avi *avi_cfg,
202 struct hdmi_core_packet_enable_repeat *repeat_cfg)
203{
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200204 DSSDBG("Enter hdmi_core_init\n");
Mythri P K7d983f32011-09-08 19:06:23 +0530205
206 /* video core */
207 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
208 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
209 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
210 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
211 video_cfg->hdmi_dvi = HDMI_DVI;
212 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
213
214 /* info frame */
215 avi_cfg->db1_format = 0;
216 avi_cfg->db1_active_info = 0;
217 avi_cfg->db1_bar_info_dv = 0;
218 avi_cfg->db1_scan_info = 0;
219 avi_cfg->db2_colorimetry = 0;
220 avi_cfg->db2_aspect_ratio = 0;
221 avi_cfg->db2_active_fmt_ar = 0;
222 avi_cfg->db3_itc = 0;
223 avi_cfg->db3_ec = 0;
224 avi_cfg->db3_q_range = 0;
225 avi_cfg->db3_nup_scaling = 0;
226 avi_cfg->db4_videocode = 0;
227 avi_cfg->db5_pixel_repeat = 0;
Archit Tanejaef269582013-09-12 17:45:57 +0530228 avi_cfg->db6_7_line_eoftop = 0;
Mythri P K7d983f32011-09-08 19:06:23 +0530229 avi_cfg->db8_9_line_sofbottom = 0;
230 avi_cfg->db10_11_pixel_eofleft = 0;
231 avi_cfg->db12_13_pixel_sofright = 0;
232
233 /* packet enable and repeat */
234 repeat_cfg->audio_pkt = 0;
235 repeat_cfg->audio_pkt_repeat = 0;
236 repeat_cfg->avi_infoframe = 0;
237 repeat_cfg->avi_infoframe_repeat = 0;
238 repeat_cfg->gen_cntrl_pkt = 0;
239 repeat_cfg->gen_cntrl_pkt_repeat = 0;
240 repeat_cfg->generic_pkt = 0;
241 repeat_cfg->generic_pkt_repeat = 0;
242}
243
Archit Taneja425f02f2013-10-08 14:16:05 +0530244static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
Mythri P K7d983f32011-09-08 19:06:23 +0530245{
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200246 DSSDBG("Enter hdmi_core_powerdown_disable\n");
Archit Taneja425f02f2013-10-08 14:16:05 +0530247 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530248}
249
Archit Taneja425f02f2013-10-08 14:16:05 +0530250static void hdmi_core_swreset_release(struct hdmi_core_data *core)
Mythri P K7d983f32011-09-08 19:06:23 +0530251{
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200252 DSSDBG("Enter hdmi_core_swreset_release\n");
Archit Taneja425f02f2013-10-08 14:16:05 +0530253 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530254}
255
Archit Taneja425f02f2013-10-08 14:16:05 +0530256static void hdmi_core_swreset_assert(struct hdmi_core_data *core)
Mythri P K7d983f32011-09-08 19:06:23 +0530257{
Tomi Valkeinenac9f2422013-11-14 13:46:32 +0200258 DSSDBG("Enter hdmi_core_swreset_assert\n");
Archit Taneja425f02f2013-10-08 14:16:05 +0530259 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);
Mythri P K7d983f32011-09-08 19:06:23 +0530260}
261
262/* HDMI_CORE_VIDEO_CONFIG */
Archit Taneja425f02f2013-10-08 14:16:05 +0530263static void hdmi_core_video_config(struct hdmi_core_data *core,
Mythri P K7d983f32011-09-08 19:06:23 +0530264 struct hdmi_core_video_config *cfg)
265{
266 u32 r = 0;
Archit Taneja425f02f2013-10-08 14:16:05 +0530267 void __iomem *core_sys_base = core->base;
268 void __iomem *core_av_base = hdmi_av_base(core);
Mythri P K7d983f32011-09-08 19:06:23 +0530269
270 /* sys_ctrl1 default configuration not tunable */
Ricardo Neri190d57c2013-09-13 15:59:36 +0530271 r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1);
272 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
273 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
274 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2);
275 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1);
276 hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r);
Mythri P K7d983f32011-09-08 19:06:23 +0530277
278 REG_FLD_MOD(core_sys_base,
279 HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
280
281 /* Vid_Mode */
282 r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE);
283
284 /* dither truncation configuration */
285 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
286 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
287 r = FLD_MOD(r, 1, 5, 5);
288 } else {
289 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
290 r = FLD_MOD(r, 0, 5, 5);
291 }
292 hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r);
293
294 /* HDMI_Ctrl */
Archit Taneja425f02f2013-10-08 14:16:05 +0530295 r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL);
Mythri P K7d983f32011-09-08 19:06:23 +0530296 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
297 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
298 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
Archit Taneja425f02f2013-10-08 14:16:05 +0530299 hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r);
Mythri P K7d983f32011-09-08 19:06:23 +0530300
301 /* TMDS_CTRL */
302 REG_FLD_MOD(core_sys_base,
303 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
304}
305
Archit Taneja425f02f2013-10-08 14:16:05 +0530306static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
Mythri P K7d983f32011-09-08 19:06:23 +0530307{
308 u32 val;
309 char sum = 0, checksum = 0;
Archit Taneja425f02f2013-10-08 14:16:05 +0530310 void __iomem *av_base = hdmi_av_base(core);
311 struct hdmi_core_infoframe_avi info_avi = core->avi_cfg;
Mythri P K7d983f32011-09-08 19:06:23 +0530312
313 sum += 0x82 + 0x002 + 0x00D;
314 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
315 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
316 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
317
318 val = (info_avi.db1_format << 5) |
319 (info_avi.db1_active_info << 4) |
320 (info_avi.db1_bar_info_dv << 2) |
321 (info_avi.db1_scan_info);
322 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
323 sum += val;
324
325 val = (info_avi.db2_colorimetry << 6) |
326 (info_avi.db2_aspect_ratio << 4) |
327 (info_avi.db2_active_fmt_ar);
328 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
329 sum += val;
330
331 val = (info_avi.db3_itc << 7) |
332 (info_avi.db3_ec << 4) |
333 (info_avi.db3_q_range << 2) |
334 (info_avi.db3_nup_scaling);
335 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
336 sum += val;
337
338 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
339 info_avi.db4_videocode);
340 sum += info_avi.db4_videocode;
341
342 val = info_avi.db5_pixel_repeat;
343 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
344 sum += val;
345
346 val = info_avi.db6_7_line_eoftop & 0x00FF;
347 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
348 sum += val;
349
350 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
351 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
352 sum += val;
353
354 val = info_avi.db8_9_line_sofbottom & 0x00FF;
355 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
356 sum += val;
357
358 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
359 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
360 sum += val;
361
362 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
363 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
364 sum += val;
365
366 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
367 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
368 sum += val;
369
370 val = info_avi.db12_13_pixel_sofright & 0x00FF;
371 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
372 sum += val;
373
374 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
375 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
376 sum += val;
377
378 checksum = 0x100 - sum;
379 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);
380}
381
Archit Taneja425f02f2013-10-08 14:16:05 +0530382static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
Mythri P K7d983f32011-09-08 19:06:23 +0530383 struct hdmi_core_packet_enable_repeat repeat_cfg)
384{
385 /* enable/repeat the infoframe */
Archit Taneja425f02f2013-10-08 14:16:05 +0530386 hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL1,
Mythri P K7d983f32011-09-08 19:06:23 +0530387 (repeat_cfg.audio_pkt << 5) |
388 (repeat_cfg.audio_pkt_repeat << 4) |
389 (repeat_cfg.avi_infoframe << 1) |
390 (repeat_cfg.avi_infoframe_repeat));
391
392 /* enable/repeat the packet */
Archit Taneja425f02f2013-10-08 14:16:05 +0530393 hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL2,
Mythri P K7d983f32011-09-08 19:06:23 +0530394 (repeat_cfg.gen_cntrl_pkt << 3) |
395 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
396 (repeat_cfg.generic_pkt << 1) |
397 (repeat_cfg.generic_pkt_repeat));
398}
399
Archit Taneja425f02f2013-10-08 14:16:05 +0530400void hdmi4_configure(struct hdmi_core_data *core,
401 struct hdmi_wp_data *wp, struct hdmi_config *cfg)
Mythri P K7d983f32011-09-08 19:06:23 +0530402{
403 /* HDMI */
404 struct omap_video_timings video_timing;
405 struct hdmi_video_format video_format;
Mythri P K7d983f32011-09-08 19:06:23 +0530406 /* HDMI core */
Archit Taneja425f02f2013-10-08 14:16:05 +0530407 struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
Mythri P K7d983f32011-09-08 19:06:23 +0530408 struct hdmi_core_video_config v_core_cfg;
409 struct hdmi_core_packet_enable_repeat repeat_cfg;
Mythri P K7d983f32011-09-08 19:06:23 +0530410
Mythri P Kfd3cd7e2012-04-11 16:38:07 +0530411 hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg);
Mythri P K7d983f32011-09-08 19:06:23 +0530412
Archit Tanejaf382d9e2013-08-06 14:56:55 +0530413 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
Mythri P K7d983f32011-09-08 19:06:23 +0530414
Archit Taneja425f02f2013-10-08 14:16:05 +0530415 hdmi_wp_video_config_timing(wp, &video_timing);
Mythri P K7d983f32011-09-08 19:06:23 +0530416
417 /* video config */
418 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
419
Archit Taneja425f02f2013-10-08 14:16:05 +0530420 hdmi_wp_video_config_format(wp, &video_format);
Mythri P K7d983f32011-09-08 19:06:23 +0530421
Archit Taneja425f02f2013-10-08 14:16:05 +0530422 hdmi_wp_video_config_interface(wp, &video_timing);
Mythri P K7d983f32011-09-08 19:06:23 +0530423
424 /*
425 * configure core video part
426 * set software reset in the core
427 */
Archit Taneja425f02f2013-10-08 14:16:05 +0530428 hdmi_core_swreset_assert(core);
Mythri P K7d983f32011-09-08 19:06:23 +0530429
430 /* power down off */
Archit Taneja425f02f2013-10-08 14:16:05 +0530431 hdmi_core_powerdown_disable(core);
Mythri P K7d983f32011-09-08 19:06:23 +0530432
433 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
434 v_core_cfg.hdmi_dvi = cfg->cm.mode;
435
Archit Taneja425f02f2013-10-08 14:16:05 +0530436 hdmi_core_video_config(core, &v_core_cfg);
Mythri P K7d983f32011-09-08 19:06:23 +0530437
438 /* release software reset in the core */
Archit Taneja425f02f2013-10-08 14:16:05 +0530439 hdmi_core_swreset_release(core);
Mythri P K7d983f32011-09-08 19:06:23 +0530440
441 /*
442 * configure packet
443 * info frame video see doc CEA861-D page 65
444 */
Mythri P Kfd3cd7e2012-04-11 16:38:07 +0530445 avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
446 avi_cfg->db1_active_info =
447 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
448 avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
449 avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
450 avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
451 avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
452 avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
453 avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
454 avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
455 avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
456 avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
457 avi_cfg->db4_videocode = cfg->cm.code;
458 avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
459 avi_cfg->db6_7_line_eoftop = 0;
460 avi_cfg->db8_9_line_sofbottom = 0;
461 avi_cfg->db10_11_pixel_eofleft = 0;
462 avi_cfg->db12_13_pixel_sofright = 0;
Mythri P K7d983f32011-09-08 19:06:23 +0530463
Archit Taneja425f02f2013-10-08 14:16:05 +0530464 hdmi_core_aux_infoframe_avi_config(core);
Mythri P K7d983f32011-09-08 19:06:23 +0530465
466 /* enable/repeat the infoframe */
467 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
468 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
469 /* wakeup */
470 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
471 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
Archit Taneja425f02f2013-10-08 14:16:05 +0530472 hdmi_core_av_packet_config(core, repeat_cfg);
Mythri P K7d983f32011-09-08 19:06:23 +0530473}
Mythri P K73341672011-09-08 19:06:24 +0530474
Archit Taneja425f02f2013-10-08 14:16:05 +0530475void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
Mythri P K162874d2011-09-22 13:37:45 +0530476{
477 int i;
478
479#define CORE_REG(i, name) name(i)
480#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\
Archit Taneja425f02f2013-10-08 14:16:05 +0530481 hdmi_read_reg(core->base, r))
Archit Taneja3c7de242012-05-07 18:50:27 +0530482#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\
Archit Taneja425f02f2013-10-08 14:16:05 +0530483 hdmi_read_reg(hdmi_av_base(core), r))
Archit Taneja3c7de242012-05-07 18:50:27 +0530484#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
Tomi Valkeinen311d5ce2012-09-28 13:58:14 +0300485 (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \
Archit Taneja425f02f2013-10-08 14:16:05 +0530486 hdmi_read_reg(hdmi_av_base(core), CORE_REG(i, r)))
Mythri P K162874d2011-09-22 13:37:45 +0530487
488 DUMPCORE(HDMI_CORE_SYS_VND_IDL);
489 DUMPCORE(HDMI_CORE_SYS_DEV_IDL);
490 DUMPCORE(HDMI_CORE_SYS_DEV_IDH);
491 DUMPCORE(HDMI_CORE_SYS_DEV_REV);
492 DUMPCORE(HDMI_CORE_SYS_SRST);
Ricardo Neri190d57c2013-09-13 15:59:36 +0530493 DUMPCORE(HDMI_CORE_SYS_SYS_CTRL1);
Mythri P K162874d2011-09-22 13:37:45 +0530494 DUMPCORE(HDMI_CORE_SYS_SYS_STAT);
Ricardo Neri78145a92013-09-13 15:59:38 +0530495 DUMPCORE(HDMI_CORE_SYS_SYS_CTRL3);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530496 DUMPCORE(HDMI_CORE_SYS_DE_DLY);
497 DUMPCORE(HDMI_CORE_SYS_DE_CTRL);
498 DUMPCORE(HDMI_CORE_SYS_DE_TOP);
499 DUMPCORE(HDMI_CORE_SYS_DE_CNTL);
500 DUMPCORE(HDMI_CORE_SYS_DE_CNTH);
501 DUMPCORE(HDMI_CORE_SYS_DE_LINL);
502 DUMPCORE(HDMI_CORE_SYS_DE_LINH_1);
Ricardo Neri78145a92013-09-13 15:59:38 +0530503 DUMPCORE(HDMI_CORE_SYS_HRES_L);
504 DUMPCORE(HDMI_CORE_SYS_HRES_H);
505 DUMPCORE(HDMI_CORE_SYS_VRES_L);
506 DUMPCORE(HDMI_CORE_SYS_VRES_H);
507 DUMPCORE(HDMI_CORE_SYS_IADJUST);
508 DUMPCORE(HDMI_CORE_SYS_POLDETECT);
509 DUMPCORE(HDMI_CORE_SYS_HWIDTH1);
510 DUMPCORE(HDMI_CORE_SYS_HWIDTH2);
511 DUMPCORE(HDMI_CORE_SYS_VWIDTH);
512 DUMPCORE(HDMI_CORE_SYS_VID_CTRL);
Mythri P K162874d2011-09-22 13:37:45 +0530513 DUMPCORE(HDMI_CORE_SYS_VID_ACEN);
514 DUMPCORE(HDMI_CORE_SYS_VID_MODE);
Ricardo Neri78145a92013-09-13 15:59:38 +0530515 DUMPCORE(HDMI_CORE_SYS_VID_BLANK1);
516 DUMPCORE(HDMI_CORE_SYS_VID_BLANK3);
517 DUMPCORE(HDMI_CORE_SYS_VID_BLANK1);
518 DUMPCORE(HDMI_CORE_SYS_DC_HEADER);
519 DUMPCORE(HDMI_CORE_SYS_VID_DITHER);
520 DUMPCORE(HDMI_CORE_SYS_RGB2XVYCC_CT);
521 DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_LOW);
522 DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_UP);
523 DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_LOW);
524 DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_UP);
525 DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_LOW);
526 DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_UP);
527 DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_LOW);
528 DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_UP);
529 DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_LOW);
530 DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_UP);
531 DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_LOW);
532 DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_UP);
533 DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_LOW);
534 DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_UP);
535 DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_LOW);
536 DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_UP);
537 DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_LOW);
538 DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_UP);
539 DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_LOW);
540 DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_UP);
541 DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_LOW);
542 DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_UP);
543 DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_LOW);
544 DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_UP);
Mythri P K162874d2011-09-22 13:37:45 +0530545 DUMPCORE(HDMI_CORE_SYS_INTR_STATE);
546 DUMPCORE(HDMI_CORE_SYS_INTR1);
547 DUMPCORE(HDMI_CORE_SYS_INTR2);
548 DUMPCORE(HDMI_CORE_SYS_INTR3);
549 DUMPCORE(HDMI_CORE_SYS_INTR4);
Ricardo Neri78145a92013-09-13 15:59:38 +0530550 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK1);
551 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK2);
552 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK3);
553 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK4);
554 DUMPCORE(HDMI_CORE_SYS_INTR_CTRL);
Mythri P K162874d2011-09-22 13:37:45 +0530555 DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL);
Mythri P K162874d2011-09-22 13:37:45 +0530556
Mythri P K162874d2011-09-22 13:37:45 +0530557 DUMPCORE(HDMI_CORE_DDC_ADDR);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530558 DUMPCORE(HDMI_CORE_DDC_SEGM);
Mythri P K162874d2011-09-22 13:37:45 +0530559 DUMPCORE(HDMI_CORE_DDC_OFFSET);
560 DUMPCORE(HDMI_CORE_DDC_COUNT1);
561 DUMPCORE(HDMI_CORE_DDC_COUNT2);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530562 DUMPCORE(HDMI_CORE_DDC_STATUS);
563 DUMPCORE(HDMI_CORE_DDC_CMD);
Mythri P K162874d2011-09-22 13:37:45 +0530564 DUMPCORE(HDMI_CORE_DDC_DATA);
Mythri P K162874d2011-09-22 13:37:45 +0530565
Archit Taneja3c7de242012-05-07 18:50:27 +0530566 DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL);
567 DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL);
568 DUMPCOREAV(HDMI_CORE_AV_N_SVAL1);
569 DUMPCOREAV(HDMI_CORE_AV_N_SVAL2);
570 DUMPCOREAV(HDMI_CORE_AV_N_SVAL3);
571 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1);
572 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2);
573 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3);
574 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1);
575 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2);
576 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3);
577 DUMPCOREAV(HDMI_CORE_AV_AUD_MODE);
578 DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL);
579 DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS);
580 DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S);
581 DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH);
582 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP);
583 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL);
584 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0);
585 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1);
586 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2);
587 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4);
588 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5);
589 DUMPCOREAV(HDMI_CORE_AV_ASRC);
590 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN);
591 DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL);
592 DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT);
593 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1);
594 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2);
595 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3);
596 DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL);
597 DUMPCOREAV(HDMI_CORE_AV_DPD);
598 DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1);
599 DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2);
600 DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE);
601 DUMPCOREAV(HDMI_CORE_AV_AVI_VERS);
602 DUMPCOREAV(HDMI_CORE_AV_AVI_LEN);
603 DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530604
605 for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++)
606 DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE);
607
Archit Taneja3c7de242012-05-07 18:50:27 +0530608 DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE);
609 DUMPCOREAV(HDMI_CORE_AV_SPD_VERS);
610 DUMPCOREAV(HDMI_CORE_AV_SPD_LEN);
611 DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530612
613 for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++)
614 DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE);
615
Archit Taneja3c7de242012-05-07 18:50:27 +0530616 DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE);
617 DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS);
618 DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN);
619 DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530620
621 for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++)
622 DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE);
623
Archit Taneja3c7de242012-05-07 18:50:27 +0530624 DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE);
625 DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS);
626 DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN);
627 DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530628
629 for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++)
630 DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE);
631
632 for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++)
633 DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE);
634
Archit Taneja3c7de242012-05-07 18:50:27 +0530635 DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1);
Archit Taneja9b9c4572012-05-07 18:50:28 +0530636
637 for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++)
638 DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE);
639
Archit Taneja3c7de242012-05-07 18:50:27 +0530640 DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);
Mythri P K162874d2011-09-22 13:37:45 +0530641}
642
Ricardo Neri7e151f72012-03-15 14:08:03 -0600643#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
Archit Taneja425f02f2013-10-08 14:16:05 +0530644static void hdmi_core_audio_config(struct hdmi_core_data *core,
Mythri P K73341672011-09-08 19:06:24 +0530645 struct hdmi_core_audio_config *cfg)
646{
647 u32 r;
Archit Taneja425f02f2013-10-08 14:16:05 +0530648 void __iomem *av_base = hdmi_av_base(core);
Mythri P K73341672011-09-08 19:06:24 +0530649
Ricardo Nerid8989d92012-01-31 13:36:06 -0600650 /*
651 * Parameters for generation of Audio Clock Recovery packets
652 */
Mythri P K73341672011-09-08 19:06:24 +0530653 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
654 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
655 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
656
657 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
658 REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
659 REG_FLD_MOD(av_base,
660 HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
661 REG_FLD_MOD(av_base,
662 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
663 } else {
Mythri P K73341672011-09-08 19:06:24 +0530664 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
665 cfg->aud_par_busclk, 7, 0);
666 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
667 (cfg->aud_par_busclk >> 8), 7, 0);
668 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
669 (cfg->aud_par_busclk >> 16), 7, 0);
670 }
671
Ricardo Nerid8989d92012-01-31 13:36:06 -0600672 /* Set ACR clock divisor */
673 REG_FLD_MOD(av_base,
674 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
675
676 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
677 /*
678 * Use TMDS clock for ACR packets. For devices that use
679 * the MCLK, this is the first part of the MCLK initialization.
680 */
681 r = FLD_MOD(r, 0, 2, 2);
682
683 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
684 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
685 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
686
687 /* For devices using MCLK, this completes its initialization. */
688 if (cfg->use_mclk)
689 REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2);
690
Mythri P K73341672011-09-08 19:06:24 +0530691 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
692 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
693 cfg->fs_override, 1, 1);
694
Ricardo Neric1164ed2012-03-19 12:27:41 -0600695 /*
696 * Set IEC-60958-3 channel status word. It is passed to the IP
697 * just as it is received. The user of the driver is responsible
698 * for its contents.
699 */
700 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0,
701 cfg->iec60958_cfg->status[0]);
702 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1,
703 cfg->iec60958_cfg->status[1]);
704 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2,
705 cfg->iec60958_cfg->status[2]);
706 /* yes, this is correct: status[3] goes to CHST4 register */
707 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4,
708 cfg->iec60958_cfg->status[3]);
709 /* yes, this is correct: status[4] goes to CHST5 register */
710 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5,
711 cfg->iec60958_cfg->status[4]);
Mythri P K73341672011-09-08 19:06:24 +0530712
Ricardo Neric1164ed2012-03-19 12:27:41 -0600713 /* set I2S parameters */
Mythri P K73341672011-09-08 19:06:24 +0530714 r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL);
Mythri P K73341672011-09-08 19:06:24 +0530715 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
Mythri P K73341672011-09-08 19:06:24 +0530716 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
Mythri P K73341672011-09-08 19:06:24 +0530717 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
718 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
719 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
720 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r);
721
Mythri P K73341672011-09-08 19:06:24 +0530722 REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN,
723 cfg->i2s_cfg.in_length_bits, 3, 0);
724
725 /* Audio channels and mode parameters */
726 REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
727 r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE);
728 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
729 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
730 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
731 r = FLD_MOD(r, cfg->en_spdif, 1, 1);
732 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r);
Ricardo Neri24ccfc52012-05-03 12:27:12 -0500733
734 /* Audio channel mappings */
735 /* TODO: Make channel mapping dynamic. For now, map channels
736 * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as
737 * HDMI speaker order is different. See CEA-861 Section 6.6.2.
738 */
739 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78);
740 REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5);
Mythri P K73341672011-09-08 19:06:24 +0530741}
742
Archit Taneja425f02f2013-10-08 14:16:05 +0530743static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core,
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600744 struct snd_cea_861_aud_if *info_aud)
Mythri P K73341672011-09-08 19:06:24 +0530745{
Mythri P K73341672011-09-08 19:06:24 +0530746 u8 sum = 0, checksum = 0;
Archit Taneja425f02f2013-10-08 14:16:05 +0530747 void __iomem *av_base = hdmi_av_base(core);
Mythri P K73341672011-09-08 19:06:24 +0530748
749 /*
750 * Set audio info frame type, version and length as
751 * described in HDMI 1.4a Section 8.2.2 specification.
752 * Checksum calculation is defined in Section 5.3.5.
753 */
754 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84);
755 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01);
756 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a);
757 sum += 0x84 + 0x001 + 0x00a;
758
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600759 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0),
760 info_aud->db1_ct_cc);
761 sum += info_aud->db1_ct_cc;
Mythri P K73341672011-09-08 19:06:24 +0530762
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600763 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1),
764 info_aud->db2_sf_ss);
765 sum += info_aud->db2_sf_ss;
Mythri P K73341672011-09-08 19:06:24 +0530766
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600767 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3);
768 sum += info_aud->db3;
Mythri P K73341672011-09-08 19:06:24 +0530769
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600770 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca);
771 sum += info_aud->db4_ca;
Mythri P K73341672011-09-08 19:06:24 +0530772
Ricardo Neri199e7fd2012-03-15 10:39:00 -0600773 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4),
774 info_aud->db5_dminh_lsv);
775 sum += info_aud->db5_dminh_lsv;
Mythri P K73341672011-09-08 19:06:24 +0530776
777 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
778 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
779 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
780 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
781 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
782
783 checksum = 0x100 - sum;
784 hdmi_write_reg(av_base,
785 HDMI_CORE_AV_AUDIO_CHSUM, checksum);
786
787 /*
788 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
789 * is available.
790 */
791}
792
Archit Taneja425f02f2013-10-08 14:16:05 +0530793int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
Archit Taneja08d83e42013-09-17 11:43:15 +0530794 struct omap_dss_audio *audio, u32 pclk)
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600795{
796 struct hdmi_audio_format audio_format;
797 struct hdmi_audio_dma audio_dma;
Archit Taneja425f02f2013-10-08 14:16:05 +0530798 struct hdmi_core_audio_config acore;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600799 int err, n, cts, channel_count;
800 unsigned int fs_nr;
801 bool word_length_16b = false;
802
Archit Taneja425f02f2013-10-08 14:16:05 +0530803 if (!audio || !audio->iec || !audio->cea || !core)
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600804 return -EINVAL;
805
Archit Taneja425f02f2013-10-08 14:16:05 +0530806 acore.iec60958_cfg = audio->iec;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600807 /*
808 * In the IEC-60958 status word, check if the audio sample word length
809 * is 16-bit as several optimizations can be performed in such case.
810 */
811 if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24))
812 if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16)
813 word_length_16b = true;
814
815 /* I2S configuration. See Phillips' specification */
816 if (word_length_16b)
Archit Taneja425f02f2013-10-08 14:16:05 +0530817 acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600818 else
Archit Taneja425f02f2013-10-08 14:16:05 +0530819 acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600820 /*
821 * The I2S input word length is twice the lenght given in the IEC-60958
822 * status word. If the word size is greater than
823 * 20 bits, increment by one.
824 */
Archit Taneja425f02f2013-10-08 14:16:05 +0530825 acore.i2s_cfg.in_length_bits = audio->iec->status[4]
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600826 & IEC958_AES4_CON_WORDLEN;
827 if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)
Archit Taneja425f02f2013-10-08 14:16:05 +0530828 acore.i2s_cfg.in_length_bits++;
829 acore.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
830 acore.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
831 acore.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
832 acore.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600833
834 /* convert sample frequency to a number */
835 switch (audio->iec->status[3] & IEC958_AES3_CON_FS) {
836 case IEC958_AES3_CON_FS_32000:
837 fs_nr = 32000;
838 break;
839 case IEC958_AES3_CON_FS_44100:
840 fs_nr = 44100;
841 break;
842 case IEC958_AES3_CON_FS_48000:
843 fs_nr = 48000;
844 break;
845 case IEC958_AES3_CON_FS_88200:
846 fs_nr = 88200;
847 break;
848 case IEC958_AES3_CON_FS_96000:
849 fs_nr = 96000;
850 break;
851 case IEC958_AES3_CON_FS_176400:
852 fs_nr = 176400;
853 break;
854 case IEC958_AES3_CON_FS_192000:
855 fs_nr = 192000;
856 break;
857 default:
858 return -EINVAL;
859 }
860
Archit Taneja08d83e42013-09-17 11:43:15 +0530861 err = hdmi_compute_acr(pclk, fs_nr, &n, &cts);
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600862
863 /* Audio clock regeneration settings */
Archit Taneja425f02f2013-10-08 14:16:05 +0530864 acore.n = n;
865 acore.cts = cts;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600866 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
Archit Taneja425f02f2013-10-08 14:16:05 +0530867 acore.aud_par_busclk = 0;
868 acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
869 acore.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600870 } else {
Archit Taneja425f02f2013-10-08 14:16:05 +0530871 acore.aud_par_busclk = (((128 * 31) - 1) << 8);
872 acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
873 acore.use_mclk = true;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600874 }
875
Archit Taneja425f02f2013-10-08 14:16:05 +0530876 if (acore.use_mclk)
877 acore.mclk_mode = HDMI_AUDIO_MCLK_128FS;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600878
879 /* Audio channels settings */
880 channel_count = (audio->cea->db1_ct_cc &
881 CEA861_AUDIO_INFOFRAME_DB1CC) + 1;
882
883 switch (channel_count) {
884 case 2:
885 audio_format.active_chnnls_msk = 0x03;
886 break;
887 case 3:
888 audio_format.active_chnnls_msk = 0x07;
889 break;
890 case 4:
891 audio_format.active_chnnls_msk = 0x0f;
892 break;
893 case 5:
894 audio_format.active_chnnls_msk = 0x1f;
895 break;
896 case 6:
897 audio_format.active_chnnls_msk = 0x3f;
898 break;
899 case 7:
900 audio_format.active_chnnls_msk = 0x7f;
901 break;
902 case 8:
903 audio_format.active_chnnls_msk = 0xff;
904 break;
905 default:
906 return -EINVAL;
907 }
908
909 /*
910 * the HDMI IP needs to enable four stereo channels when transmitting
911 * more than 2 audio channels
912 */
913 if (channel_count == 2) {
914 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
Archit Taneja425f02f2013-10-08 14:16:05 +0530915 acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
916 acore.layout = HDMI_AUDIO_LAYOUT_2CH;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600917 } else {
918 audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS;
Archit Taneja425f02f2013-10-08 14:16:05 +0530919 acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN |
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600920 HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
921 HDMI_AUDIO_I2S_SD3_EN;
Archit Taneja425f02f2013-10-08 14:16:05 +0530922 acore.layout = HDMI_AUDIO_LAYOUT_8CH;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600923 }
924
Archit Taneja425f02f2013-10-08 14:16:05 +0530925 acore.en_spdif = false;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600926 /* use sample frequency from channel status word */
Archit Taneja425f02f2013-10-08 14:16:05 +0530927 acore.fs_override = true;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600928 /* enable ACR packets */
Archit Taneja425f02f2013-10-08 14:16:05 +0530929 acore.en_acr_pkt = true;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600930 /* disable direct streaming digital audio */
Archit Taneja425f02f2013-10-08 14:16:05 +0530931 acore.en_dsd_audio = false;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600932 /* use parallel audio interface */
Archit Taneja425f02f2013-10-08 14:16:05 +0530933 acore.en_parallel_aud_input = true;
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600934
935 /* DMA settings */
936 if (word_length_16b)
937 audio_dma.transfer_size = 0x10;
938 else
939 audio_dma.transfer_size = 0x20;
940 audio_dma.block_size = 0xC0;
941 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
942 audio_dma.fifo_threshold = 0x20; /* in number of samples */
943
944 /* audio FIFO format settings */
945 if (word_length_16b) {
946 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
947 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
948 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
949 } else {
950 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
951 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
952 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
953 }
954 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
955 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
956 /* disable start/stop signals of IEC 60958 blocks */
957 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON;
958
959 /* configure DMA and audio FIFO format*/
Archit Taneja425f02f2013-10-08 14:16:05 +0530960 hdmi_wp_audio_config_dma(wp, &audio_dma);
961 hdmi_wp_audio_config_format(wp, &audio_format);
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600962
963 /* configure the core*/
Archit Taneja425f02f2013-10-08 14:16:05 +0530964 hdmi_core_audio_config(core, &acore);
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600965
966 /* configure CEA 861 audio infoframe*/
Archit Taneja425f02f2013-10-08 14:16:05 +0530967 hdmi_core_audio_infoframe_cfg(core, audio->cea);
Ricardo Neri6ec355d2012-03-21 12:38:15 -0600968
969 return 0;
970}
971
Archit Taneja425f02f2013-10-08 14:16:05 +0530972int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
Axel Castaneda Gonzalez3df9fb52012-05-03 09:00:21 -0500973{
Archit Taneja425f02f2013-10-08 14:16:05 +0530974 REG_FLD_MOD(hdmi_av_base(core),
Axel Castaneda Gonzalez3df9fb52012-05-03 09:00:21 -0500975 HDMI_CORE_AV_AUD_MODE, true, 0, 0);
Archit Tanejaf382d9e2013-08-06 14:56:55 +0530976
Archit Taneja425f02f2013-10-08 14:16:05 +0530977 hdmi_wp_audio_core_req_enable(wp, true);
Archit Tanejaf382d9e2013-08-06 14:56:55 +0530978
Axel Castaneda Gonzalez3df9fb52012-05-03 09:00:21 -0500979 return 0;
980}
981
Archit Taneja425f02f2013-10-08 14:16:05 +0530982void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
Axel Castaneda Gonzalez3df9fb52012-05-03 09:00:21 -0500983{
Archit Taneja425f02f2013-10-08 14:16:05 +0530984 REG_FLD_MOD(hdmi_av_base(core),
Axel Castaneda Gonzalez3df9fb52012-05-03 09:00:21 -0500985 HDMI_CORE_AV_AUD_MODE, false, 0, 0);
Archit Tanejaf382d9e2013-08-06 14:56:55 +0530986
Archit Taneja425f02f2013-10-08 14:16:05 +0530987 hdmi_wp_audio_core_req_enable(wp, false);
Ricardo Neri80a48592011-11-27 16:09:58 -0600988}
Ricardo Nerid7b6f442012-11-06 00:19:16 -0600989
Archit Taneja425f02f2013-10-08 14:16:05 +0530990int hdmi4_audio_get_dma_port(u32 *offset, u32 *size)
Ricardo Nerid7b6f442012-11-06 00:19:16 -0600991{
992 if (!offset || !size)
993 return -EINVAL;
994 *offset = HDMI_WP_AUDIO_DATA;
995 *size = 4;
996 return 0;
997}
Archit Tanejaf382d9e2013-08-06 14:56:55 +0530998
Mythri P K73341672011-09-08 19:06:24 +0530999#endif
Archit Taneja425f02f2013-10-08 14:16:05 +05301000
Archit Taneja425f02f2013-10-08 14:16:05 +05301001int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
1002{
1003 struct resource *res;
Archit Taneja425f02f2013-10-08 14:16:05 +05301004
Tomi Valkeinen77601502013-12-17 14:41:14 +02001005 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
Archit Taneja425f02f2013-10-08 14:16:05 +05301006 if (!res) {
Tomi Valkeinen59b3d382014-04-28 16:11:01 +03001007 DSSERR("can't get CORE mem resource\n");
1008 return -EINVAL;
Archit Taneja425f02f2013-10-08 14:16:05 +05301009 }
1010
Tomi Valkeinen59b3d382014-04-28 16:11:01 +03001011 core->base = devm_ioremap_resource(&pdev->dev, res);
Tomi Valkeinen2b22df82014-05-23 14:50:09 +03001012 if (IS_ERR(core->base)) {
Archit Taneja425f02f2013-10-08 14:16:05 +05301013 DSSERR("can't ioremap CORE\n");
Tomi Valkeinen2b22df82014-05-23 14:50:09 +03001014 return PTR_ERR(core->base);
Archit Taneja425f02f2013-10-08 14:16:05 +05301015 }
1016
1017 return 0;
1018}