hdmi4_core.c (26363B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library 4 * 5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com/ 6 * Authors: Yong Zhi 7 * Mythri pk <mythripk@ti.com> 8 */ 9 10#define DSS_SUBSYS_NAME "HDMICORE" 11 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/err.h> 15#include <linux/io.h> 16#include <linux/interrupt.h> 17#include <linux/mutex.h> 18#include <linux/delay.h> 19#include <linux/platform_device.h> 20#include <linux/string.h> 21#include <linux/seq_file.h> 22#include <linux/sys_soc.h> 23#include <sound/asound.h> 24#include <sound/asoundef.h> 25 26#include "hdmi4_core.h" 27 28#define HDMI_CORE_AV 0x500 29 30static inline void __iomem *hdmi_av_base(struct hdmi_core_data *core) 31{ 32 return core->base + HDMI_CORE_AV; 33} 34 35int hdmi4_core_ddc_init(struct hdmi_core_data *core) 36{ 37 void __iomem *base = core->base; 38 39 /* Turn on CLK for DDC */ 40 REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); 41 42 /* IN_PROG */ 43 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) { 44 /* Abort transaction */ 45 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0); 46 /* IN_PROG */ 47 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 48 4, 4, 0) != 0) { 49 DSSERR("Timeout aborting DDC transaction\n"); 50 return -ETIMEDOUT; 51 } 52 } 53 54 /* Clk SCL Devices */ 55 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0); 56 57 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 58 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 59 4, 4, 0) != 0) { 60 DSSERR("Timeout starting SCL clock\n"); 61 return -ETIMEDOUT; 62 } 63 64 /* Clear FIFO */ 65 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); 66 67 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 68 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 69 4, 4, 0) != 0) { 70 DSSERR("Timeout clearing DDC fifo\n"); 71 return -ETIMEDOUT; 72 } 73 74 return 0; 75} 76 77int hdmi4_core_ddc_read(void *data, u8 *buf, unsigned int block, size_t len) 78{ 79 struct hdmi_core_data *core = data; 80 void __iomem *base = core->base; 81 u32 i; 82 83 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 84 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 85 4, 4, 0) != 0) { 86 DSSERR("Timeout waiting DDC to be ready\n"); 87 return -ETIMEDOUT; 88 } 89 90 /* Load Segment Address Register */ 91 REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, block / 2, 7, 0); 92 93 /* Load Slave Address Register */ 94 REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); 95 96 /* Load Offset Address Register */ 97 REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, block % 2 ? 0x80 : 0, 7, 0); 98 99 /* Load Byte Count */ 100 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, len, 7, 0); 101 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); 102 103 /* Set DDC_CMD */ 104 if (block) 105 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); 106 else 107 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); 108 109 /* HDMI_CORE_DDC_STATUS_BUS_LOW */ 110 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { 111 DSSERR("I2C Bus Low?\n"); 112 return -EIO; 113 } 114 /* HDMI_CORE_DDC_STATUS_NO_ACK */ 115 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { 116 DSSERR("I2C No Ack\n"); 117 return -EIO; 118 } 119 120 for (i = 0; i < len; ++i) { 121 int t; 122 123 /* IN_PROG */ 124 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) { 125 DSSERR("operation stopped when reading edid\n"); 126 return -EIO; 127 } 128 129 t = 0; 130 /* FIFO_EMPTY */ 131 while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) { 132 if (t++ > 10000) { 133 DSSERR("timeout reading edid\n"); 134 return -ETIMEDOUT; 135 } 136 udelay(1); 137 } 138 139 buf[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); 140 } 141 142 return 0; 143} 144 145static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) 146{ 147 DSSDBG("Enter hdmi_core_init\n"); 148 149 /* video core */ 150 video_cfg->ip_bus_width = HDMI_INPUT_8BIT; 151 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT; 152 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE; 153 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; 154 video_cfg->hdmi_dvi = HDMI_DVI; 155 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; 156} 157 158void hdmi4_core_powerdown_disable(struct hdmi_core_data *core) 159{ 160 DSSDBG("Enter hdmi4_core_powerdown_disable\n"); 161 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0); 162} 163 164static void hdmi_core_swreset_release(struct hdmi_core_data *core) 165{ 166 DSSDBG("Enter hdmi_core_swreset_release\n"); 167 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0); 168} 169 170static void hdmi_core_swreset_assert(struct hdmi_core_data *core) 171{ 172 DSSDBG("Enter hdmi_core_swreset_assert\n"); 173 REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0); 174} 175 176/* HDMI_CORE_VIDEO_CONFIG */ 177static void hdmi_core_video_config(struct hdmi_core_data *core, 178 struct hdmi_core_video_config *cfg) 179{ 180 u32 r = 0; 181 void __iomem *core_sys_base = core->base; 182 void __iomem *core_av_base = hdmi_av_base(core); 183 184 /* sys_ctrl1 default configuration not tunable */ 185 r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1); 186 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5); 187 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4); 188 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2); 189 r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1); 190 hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r); 191 192 REG_FLD_MOD(core_sys_base, 193 HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); 194 195 /* Vid_Mode */ 196 r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE); 197 198 /* dither truncation configuration */ 199 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { 200 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); 201 r = FLD_MOD(r, 1, 5, 5); 202 } else { 203 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); 204 r = FLD_MOD(r, 0, 5, 5); 205 } 206 hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r); 207 208 /* HDMI_Ctrl */ 209 r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL); 210 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); 211 r = FLD_MOD(r, cfg->pkt_mode, 5, 3); 212 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); 213 hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r); 214 215 /* TMDS_CTRL */ 216 REG_FLD_MOD(core_sys_base, 217 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 218} 219 220static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, 221 struct hdmi_avi_infoframe *frame) 222{ 223 void __iomem *av_base = hdmi_av_base(core); 224 u8 data[HDMI_INFOFRAME_SIZE(AVI)]; 225 int i; 226 227 hdmi_avi_infoframe_pack(frame, data, sizeof(data)); 228 229 print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data, 230 HDMI_INFOFRAME_SIZE(AVI), false); 231 232 for (i = 0; i < sizeof(data); ++i) { 233 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4, 234 data[i]); 235 } 236} 237 238static void hdmi_core_av_packet_config(struct hdmi_core_data *core, 239 struct hdmi_core_packet_enable_repeat repeat_cfg) 240{ 241 /* enable/repeat the infoframe */ 242 hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL1, 243 (repeat_cfg.audio_pkt << 5) | 244 (repeat_cfg.audio_pkt_repeat << 4) | 245 (repeat_cfg.avi_infoframe << 1) | 246 (repeat_cfg.avi_infoframe_repeat)); 247 248 /* enable/repeat the packet */ 249 hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL2, 250 (repeat_cfg.gen_cntrl_pkt << 3) | 251 (repeat_cfg.gen_cntrl_pkt_repeat << 2) | 252 (repeat_cfg.generic_pkt << 1) | 253 (repeat_cfg.generic_pkt_repeat)); 254} 255 256void hdmi4_configure(struct hdmi_core_data *core, 257 struct hdmi_wp_data *wp, struct hdmi_config *cfg) 258{ 259 /* HDMI */ 260 struct videomode vm; 261 struct hdmi_video_format video_format; 262 /* HDMI core */ 263 struct hdmi_core_video_config v_core_cfg; 264 struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 }; 265 266 hdmi_core_init(&v_core_cfg); 267 268 hdmi_wp_init_vid_fmt_timings(&video_format, &vm, cfg); 269 270 hdmi_wp_video_config_timing(wp, &vm); 271 272 /* video config */ 273 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; 274 275 hdmi_wp_video_config_format(wp, &video_format); 276 277 hdmi_wp_video_config_interface(wp, &vm); 278 279 /* 280 * configure core video part 281 * set software reset in the core 282 */ 283 hdmi_core_swreset_assert(core); 284 285 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; 286 v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode; 287 288 hdmi_core_video_config(core, &v_core_cfg); 289 290 /* release software reset in the core */ 291 hdmi_core_swreset_release(core); 292 293 if (cfg->hdmi_dvi_mode == HDMI_HDMI) { 294 hdmi_core_write_avi_infoframe(core, &cfg->infoframe); 295 296 /* enable/repeat the infoframe */ 297 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 298 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; 299 /* wakeup */ 300 repeat_cfg.audio_pkt = HDMI_PACKETENABLE; 301 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; 302 } 303 304 hdmi_core_av_packet_config(core, repeat_cfg); 305} 306 307void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s) 308{ 309 int i; 310 311#define CORE_REG(i, name) name(i) 312#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ 313 hdmi_read_reg(core->base, r)) 314#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ 315 hdmi_read_reg(hdmi_av_base(core), r)) 316#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ 317 (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \ 318 hdmi_read_reg(hdmi_av_base(core), CORE_REG(i, r))) 319 320 DUMPCORE(HDMI_CORE_SYS_VND_IDL); 321 DUMPCORE(HDMI_CORE_SYS_DEV_IDL); 322 DUMPCORE(HDMI_CORE_SYS_DEV_IDH); 323 DUMPCORE(HDMI_CORE_SYS_DEV_REV); 324 DUMPCORE(HDMI_CORE_SYS_SRST); 325 DUMPCORE(HDMI_CORE_SYS_SYS_CTRL1); 326 DUMPCORE(HDMI_CORE_SYS_SYS_STAT); 327 DUMPCORE(HDMI_CORE_SYS_SYS_CTRL3); 328 DUMPCORE(HDMI_CORE_SYS_DE_DLY); 329 DUMPCORE(HDMI_CORE_SYS_DE_CTRL); 330 DUMPCORE(HDMI_CORE_SYS_DE_TOP); 331 DUMPCORE(HDMI_CORE_SYS_DE_CNTL); 332 DUMPCORE(HDMI_CORE_SYS_DE_CNTH); 333 DUMPCORE(HDMI_CORE_SYS_DE_LINL); 334 DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); 335 DUMPCORE(HDMI_CORE_SYS_HRES_L); 336 DUMPCORE(HDMI_CORE_SYS_HRES_H); 337 DUMPCORE(HDMI_CORE_SYS_VRES_L); 338 DUMPCORE(HDMI_CORE_SYS_VRES_H); 339 DUMPCORE(HDMI_CORE_SYS_IADJUST); 340 DUMPCORE(HDMI_CORE_SYS_POLDETECT); 341 DUMPCORE(HDMI_CORE_SYS_HWIDTH1); 342 DUMPCORE(HDMI_CORE_SYS_HWIDTH2); 343 DUMPCORE(HDMI_CORE_SYS_VWIDTH); 344 DUMPCORE(HDMI_CORE_SYS_VID_CTRL); 345 DUMPCORE(HDMI_CORE_SYS_VID_ACEN); 346 DUMPCORE(HDMI_CORE_SYS_VID_MODE); 347 DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); 348 DUMPCORE(HDMI_CORE_SYS_VID_BLANK3); 349 DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); 350 DUMPCORE(HDMI_CORE_SYS_DC_HEADER); 351 DUMPCORE(HDMI_CORE_SYS_VID_DITHER); 352 DUMPCORE(HDMI_CORE_SYS_RGB2XVYCC_CT); 353 DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_LOW); 354 DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_UP); 355 DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_LOW); 356 DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_UP); 357 DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_LOW); 358 DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_UP); 359 DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_LOW); 360 DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_UP); 361 DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_LOW); 362 DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_UP); 363 DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_LOW); 364 DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_UP); 365 DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_LOW); 366 DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_UP); 367 DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_LOW); 368 DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_UP); 369 DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_LOW); 370 DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_UP); 371 DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_LOW); 372 DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_UP); 373 DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_LOW); 374 DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_UP); 375 DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_LOW); 376 DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_UP); 377 DUMPCORE(HDMI_CORE_SYS_INTR_STATE); 378 DUMPCORE(HDMI_CORE_SYS_INTR1); 379 DUMPCORE(HDMI_CORE_SYS_INTR2); 380 DUMPCORE(HDMI_CORE_SYS_INTR3); 381 DUMPCORE(HDMI_CORE_SYS_INTR4); 382 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK1); 383 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK2); 384 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK3); 385 DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK4); 386 DUMPCORE(HDMI_CORE_SYS_INTR_CTRL); 387 DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); 388 389 DUMPCORE(HDMI_CORE_DDC_ADDR); 390 DUMPCORE(HDMI_CORE_DDC_SEGM); 391 DUMPCORE(HDMI_CORE_DDC_OFFSET); 392 DUMPCORE(HDMI_CORE_DDC_COUNT1); 393 DUMPCORE(HDMI_CORE_DDC_COUNT2); 394 DUMPCORE(HDMI_CORE_DDC_STATUS); 395 DUMPCORE(HDMI_CORE_DDC_CMD); 396 DUMPCORE(HDMI_CORE_DDC_DATA); 397 398 DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL); 399 DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL); 400 DUMPCOREAV(HDMI_CORE_AV_N_SVAL1); 401 DUMPCOREAV(HDMI_CORE_AV_N_SVAL2); 402 DUMPCOREAV(HDMI_CORE_AV_N_SVAL3); 403 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1); 404 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2); 405 DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3); 406 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1); 407 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2); 408 DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3); 409 DUMPCOREAV(HDMI_CORE_AV_AUD_MODE); 410 DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL); 411 DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS); 412 DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S); 413 DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH); 414 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP); 415 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL); 416 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0); 417 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1); 418 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2); 419 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4); 420 DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5); 421 DUMPCOREAV(HDMI_CORE_AV_ASRC); 422 DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN); 423 DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL); 424 DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT); 425 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); 426 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); 427 DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); 428 DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL); 429 DUMPCOREAV(HDMI_CORE_AV_DPD); 430 DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1); 431 DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2); 432 DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE); 433 DUMPCOREAV(HDMI_CORE_AV_AVI_VERS); 434 DUMPCOREAV(HDMI_CORE_AV_AVI_LEN); 435 DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM); 436 437 for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) 438 DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE); 439 440 DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE); 441 DUMPCOREAV(HDMI_CORE_AV_SPD_VERS); 442 DUMPCOREAV(HDMI_CORE_AV_SPD_LEN); 443 DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM); 444 445 for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) 446 DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE); 447 448 DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE); 449 DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS); 450 DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN); 451 DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM); 452 453 for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) 454 DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE); 455 456 DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE); 457 DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS); 458 DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN); 459 DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM); 460 461 for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) 462 DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE); 463 464 for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) 465 DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE); 466 467 DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1); 468 469 for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) 470 DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE); 471 472 DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); 473} 474 475static void hdmi_core_audio_config(struct hdmi_core_data *core, 476 struct hdmi_core_audio_config *cfg) 477{ 478 u32 r; 479 void __iomem *av_base = hdmi_av_base(core); 480 481 /* 482 * Parameters for generation of Audio Clock Recovery packets 483 */ 484 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); 485 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); 486 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); 487 488 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { 489 REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); 490 REG_FLD_MOD(av_base, 491 HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); 492 REG_FLD_MOD(av_base, 493 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); 494 } else { 495 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, 496 cfg->aud_par_busclk, 7, 0); 497 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, 498 (cfg->aud_par_busclk >> 8), 7, 0); 499 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3, 500 (cfg->aud_par_busclk >> 16), 7, 0); 501 } 502 503 /* Set ACR clock divisor */ 504 if (cfg->use_mclk) 505 REG_FLD_MOD(av_base, HDMI_CORE_AV_FREQ_SVAL, 506 cfg->mclk_mode, 2, 0); 507 508 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); 509 /* 510 * Use TMDS clock for ACR packets. For devices that use 511 * the MCLK, this is the first part of the MCLK initialization. 512 */ 513 r = FLD_MOD(r, 0, 2, 2); 514 515 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1); 516 r = FLD_MOD(r, cfg->cts_mode, 0, 0); 517 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r); 518 519 /* For devices using MCLK, this completes its initialization. */ 520 if (cfg->use_mclk) 521 REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2); 522 523 /* Override of SPDIF sample frequency with value in I2S_CHST4 */ 524 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, 525 cfg->fs_override, 1, 1); 526 527 /* 528 * Set IEC-60958-3 channel status word. It is passed to the IP 529 * just as it is received. The user of the driver is responsible 530 * for its contents. 531 */ 532 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0, 533 cfg->iec60958_cfg->status[0]); 534 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1, 535 cfg->iec60958_cfg->status[1]); 536 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2, 537 cfg->iec60958_cfg->status[2]); 538 /* yes, this is correct: status[3] goes to CHST4 register */ 539 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4, 540 cfg->iec60958_cfg->status[3]); 541 /* yes, this is correct: status[4] goes to CHST5 register */ 542 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, 543 cfg->iec60958_cfg->status[4]); 544 545 /* set I2S parameters */ 546 r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); 547 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); 548 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); 549 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); 550 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); 551 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); 552 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); 553 554 REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, 555 cfg->i2s_cfg.in_length_bits, 3, 0); 556 557 /* Audio channels and mode parameters */ 558 REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1); 559 r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE); 560 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4); 561 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3); 562 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); 563 r = FLD_MOD(r, cfg->en_spdif, 1, 1); 564 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); 565 566 /* Audio channel mappings */ 567 /* TODO: Make channel mapping dynamic. For now, map channels 568 * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as 569 * HDMI speaker order is different. See CEA-861 Section 6.6.2. 570 */ 571 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78); 572 REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5); 573} 574 575static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core, 576 struct snd_cea_861_aud_if *info_aud) 577{ 578 u8 sum = 0, checksum = 0; 579 void __iomem *av_base = hdmi_av_base(core); 580 581 /* 582 * Set audio info frame type, version and length as 583 * described in HDMI 1.4a Section 8.2.2 specification. 584 * Checksum calculation is defined in Section 5.3.5. 585 */ 586 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84); 587 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01); 588 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); 589 sum += 0x84 + 0x001 + 0x00a; 590 591 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), 592 info_aud->db1_ct_cc); 593 sum += info_aud->db1_ct_cc; 594 595 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), 596 info_aud->db2_sf_ss); 597 sum += info_aud->db2_sf_ss; 598 599 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); 600 sum += info_aud->db3; 601 602 /* 603 * The OMAP HDMI IP requires to use the 8-channel channel code when 604 * transmitting more than two channels. 605 */ 606 if (info_aud->db4_ca != 0x00) 607 info_aud->db4_ca = 0x13; 608 609 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); 610 sum += info_aud->db4_ca; 611 612 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), 613 info_aud->db5_dminh_lsv); 614 sum += info_aud->db5_dminh_lsv; 615 616 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); 617 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); 618 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00); 619 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00); 620 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00); 621 622 checksum = 0x100 - sum; 623 hdmi_write_reg(av_base, 624 HDMI_CORE_AV_AUDIO_CHSUM, checksum); 625 626 /* 627 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing 628 * is available. 629 */ 630} 631 632int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, 633 struct omap_dss_audio *audio, u32 pclk) 634{ 635 struct hdmi_audio_format audio_format; 636 struct hdmi_audio_dma audio_dma; 637 struct hdmi_core_audio_config acore; 638 int n, cts, channel_count; 639 unsigned int fs_nr; 640 bool word_length_16b = false; 641 642 if (!audio || !audio->iec || !audio->cea || !core) 643 return -EINVAL; 644 645 acore.iec60958_cfg = audio->iec; 646 /* 647 * In the IEC-60958 status word, check if the audio sample word length 648 * is 16-bit as several optimizations can be performed in such case. 649 */ 650 if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)) 651 if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16) 652 word_length_16b = true; 653 654 /* I2S configuration. See Phillips' specification */ 655 if (word_length_16b) 656 acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; 657 else 658 acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 659 /* 660 * The I2S input word length is twice the length given in the IEC-60958 661 * status word. If the word size is greater than 662 * 20 bits, increment by one. 663 */ 664 acore.i2s_cfg.in_length_bits = audio->iec->status[4] 665 & IEC958_AES4_CON_WORDLEN; 666 if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) 667 acore.i2s_cfg.in_length_bits++; 668 acore.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; 669 acore.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; 670 acore.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; 671 acore.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; 672 673 /* convert sample frequency to a number */ 674 switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { 675 case IEC958_AES3_CON_FS_32000: 676 fs_nr = 32000; 677 break; 678 case IEC958_AES3_CON_FS_44100: 679 fs_nr = 44100; 680 break; 681 case IEC958_AES3_CON_FS_48000: 682 fs_nr = 48000; 683 break; 684 case IEC958_AES3_CON_FS_88200: 685 fs_nr = 88200; 686 break; 687 case IEC958_AES3_CON_FS_96000: 688 fs_nr = 96000; 689 break; 690 case IEC958_AES3_CON_FS_176400: 691 fs_nr = 176400; 692 break; 693 case IEC958_AES3_CON_FS_192000: 694 fs_nr = 192000; 695 break; 696 default: 697 return -EINVAL; 698 } 699 700 hdmi_compute_acr(pclk, fs_nr, &n, &cts); 701 702 /* Audio clock regeneration settings */ 703 acore.n = n; 704 acore.cts = cts; 705 if (core->cts_swmode) { 706 acore.aud_par_busclk = 0; 707 acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 708 acore.use_mclk = core->audio_use_mclk; 709 } else { 710 acore.aud_par_busclk = (((128 * 31) - 1) << 8); 711 acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 712 acore.use_mclk = true; 713 } 714 715 if (acore.use_mclk) 716 acore.mclk_mode = HDMI_AUDIO_MCLK_128FS; 717 718 /* Audio channels settings */ 719 channel_count = (audio->cea->db1_ct_cc & 720 CEA861_AUDIO_INFOFRAME_DB1CC) + 1; 721 722 switch (channel_count) { 723 case 2: 724 audio_format.active_chnnls_msk = 0x03; 725 break; 726 case 3: 727 audio_format.active_chnnls_msk = 0x07; 728 break; 729 case 4: 730 audio_format.active_chnnls_msk = 0x0f; 731 break; 732 case 5: 733 audio_format.active_chnnls_msk = 0x1f; 734 break; 735 case 6: 736 audio_format.active_chnnls_msk = 0x3f; 737 break; 738 case 7: 739 audio_format.active_chnnls_msk = 0x7f; 740 break; 741 case 8: 742 audio_format.active_chnnls_msk = 0xff; 743 break; 744 default: 745 return -EINVAL; 746 } 747 748 /* 749 * the HDMI IP needs to enable four stereo channels when transmitting 750 * more than 2 audio channels. Similarly, the channel count in the 751 * Audio InfoFrame has to match the sample_present bits (some channels 752 * are padded with zeroes) 753 */ 754 if (channel_count == 2) { 755 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; 756 acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; 757 acore.layout = HDMI_AUDIO_LAYOUT_2CH; 758 } else { 759 audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; 760 acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | 761 HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | 762 HDMI_AUDIO_I2S_SD3_EN; 763 acore.layout = HDMI_AUDIO_LAYOUT_8CH; 764 audio->cea->db1_ct_cc = 7; 765 } 766 767 acore.en_spdif = false; 768 /* use sample frequency from channel status word */ 769 acore.fs_override = true; 770 /* enable ACR packets */ 771 acore.en_acr_pkt = true; 772 /* disable direct streaming digital audio */ 773 acore.en_dsd_audio = false; 774 /* use parallel audio interface */ 775 acore.en_parallel_aud_input = true; 776 777 /* DMA settings */ 778 if (word_length_16b) 779 audio_dma.transfer_size = 0x10; 780 else 781 audio_dma.transfer_size = 0x20; 782 audio_dma.block_size = 0xC0; 783 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; 784 audio_dma.fifo_threshold = 0x20; /* in number of samples */ 785 786 /* audio FIFO format settings */ 787 if (word_length_16b) { 788 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; 789 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; 790 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; 791 } else { 792 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; 793 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; 794 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 795 } 796 audio_format.type = HDMI_AUDIO_TYPE_LPCM; 797 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; 798 /* disable start/stop signals of IEC 60958 blocks */ 799 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; 800 801 /* configure DMA and audio FIFO format*/ 802 hdmi_wp_audio_config_dma(wp, &audio_dma); 803 hdmi_wp_audio_config_format(wp, &audio_format); 804 805 /* configure the core*/ 806 hdmi_core_audio_config(core, &acore); 807 808 /* configure CEA 861 audio infoframe*/ 809 hdmi_core_audio_infoframe_cfg(core, audio->cea); 810 811 return 0; 812} 813 814int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp) 815{ 816 REG_FLD_MOD(hdmi_av_base(core), 817 HDMI_CORE_AV_AUD_MODE, true, 0, 0); 818 819 hdmi_wp_audio_core_req_enable(wp, true); 820 821 return 0; 822} 823 824void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp) 825{ 826 REG_FLD_MOD(hdmi_av_base(core), 827 HDMI_CORE_AV_AUD_MODE, false, 0, 0); 828 829 hdmi_wp_audio_core_req_enable(wp, false); 830} 831 832struct hdmi4_features { 833 bool cts_swmode; 834 bool audio_use_mclk; 835}; 836 837static const struct hdmi4_features hdmi4430_es1_features = { 838 .cts_swmode = false, 839 .audio_use_mclk = false, 840}; 841 842static const struct hdmi4_features hdmi4430_es2_features = { 843 .cts_swmode = true, 844 .audio_use_mclk = false, 845}; 846 847static const struct hdmi4_features hdmi4_features = { 848 .cts_swmode = true, 849 .audio_use_mclk = true, 850}; 851 852static const struct soc_device_attribute hdmi4_soc_devices[] = { 853 { 854 .machine = "OMAP4430", 855 .revision = "ES1.?", 856 .data = &hdmi4430_es1_features, 857 }, 858 { 859 .machine = "OMAP4430", 860 .revision = "ES2.?", 861 .data = &hdmi4430_es2_features, 862 }, 863 { 864 .family = "OMAP4", 865 .data = &hdmi4_features, 866 }, 867 { /* sentinel */ } 868}; 869 870int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) 871{ 872 const struct hdmi4_features *features; 873 const struct soc_device_attribute *soc; 874 875 soc = soc_device_match(hdmi4_soc_devices); 876 if (!soc) 877 return -ENODEV; 878 879 features = soc->data; 880 core->cts_swmode = features->cts_swmode; 881 core->audio_use_mclk = features->audio_use_mclk; 882 883 core->base = devm_platform_ioremap_resource_byname(pdev, "core"); 884 if (IS_ERR(core->base)) 885 return PTR_ERR(core->base); 886 887 return 0; 888}