Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library
0004  *
0005  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com/
0006  * Authors: Yong Zhi
0007  *  Mythri pk <mythripk@ti.com>
0008  */
0009 
0010 #define DSS_SUBSYS_NAME "HDMICORE"
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/err.h>
0015 #include <linux/io.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/mutex.h>
0018 #include <linux/delay.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/string.h>
0021 #include <linux/seq_file.h>
0022 #include <linux/sys_soc.h>
0023 #include <sound/asound.h>
0024 #include <sound/asoundef.h>
0025 
0026 #include "hdmi4_core.h"
0027 
0028 #define HDMI_CORE_AV        0x500
0029 
0030 static inline void __iomem *hdmi_av_base(struct hdmi_core_data *core)
0031 {
0032     return core->base + HDMI_CORE_AV;
0033 }
0034 
0035 int hdmi4_core_ddc_init(struct hdmi_core_data *core)
0036 {
0037     void __iomem *base = core->base;
0038 
0039     /* Turn on CLK for DDC */
0040     REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
0041 
0042     /* IN_PROG */
0043     if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) {
0044         /* Abort transaction */
0045         REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
0046         /* IN_PROG */
0047         if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
0048                     4, 4, 0) != 0) {
0049             DSSERR("Timeout aborting DDC transaction\n");
0050             return -ETIMEDOUT;
0051         }
0052     }
0053 
0054     /* Clk SCL Devices */
0055     REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
0056 
0057     /* HDMI_CORE_DDC_STATUS_IN_PROG */
0058     if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
0059                 4, 4, 0) != 0) {
0060         DSSERR("Timeout starting SCL clock\n");
0061         return -ETIMEDOUT;
0062     }
0063 
0064     /* Clear FIFO */
0065     REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
0066 
0067     /* HDMI_CORE_DDC_STATUS_IN_PROG */
0068     if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
0069                 4, 4, 0) != 0) {
0070         DSSERR("Timeout clearing DDC fifo\n");
0071         return -ETIMEDOUT;
0072     }
0073 
0074     return 0;
0075 }
0076 
0077 int hdmi4_core_ddc_read(void *data, u8 *buf, unsigned int block, size_t len)
0078 {
0079     struct hdmi_core_data *core = data;
0080     void __iomem *base = core->base;
0081     u32 i;
0082 
0083     /* HDMI_CORE_DDC_STATUS_IN_PROG */
0084     if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
0085                 4, 4, 0) != 0) {
0086         DSSERR("Timeout waiting DDC to be ready\n");
0087         return -ETIMEDOUT;
0088     }
0089 
0090     /* Load Segment Address Register */
0091     REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, block / 2, 7, 0);
0092 
0093     /* Load Slave Address Register */
0094     REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
0095 
0096     /* Load Offset Address Register */
0097     REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, block % 2 ? 0x80 : 0, 7, 0);
0098 
0099     /* Load Byte Count */
0100     REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, len, 7, 0);
0101     REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
0102 
0103     /* Set DDC_CMD */
0104     if (block)
0105         REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
0106     else
0107         REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
0108 
0109     /* HDMI_CORE_DDC_STATUS_BUS_LOW */
0110     if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
0111         DSSERR("I2C Bus Low?\n");
0112         return -EIO;
0113     }
0114     /* HDMI_CORE_DDC_STATUS_NO_ACK */
0115     if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
0116         DSSERR("I2C No Ack\n");
0117         return -EIO;
0118     }
0119 
0120     for (i = 0; i < len; ++i) {
0121         int t;
0122 
0123         /* IN_PROG */
0124         if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) {
0125             DSSERR("operation stopped when reading edid\n");
0126             return -EIO;
0127         }
0128 
0129         t = 0;
0130         /* FIFO_EMPTY */
0131         while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) {
0132             if (t++ > 10000) {
0133                 DSSERR("timeout reading edid\n");
0134                 return -ETIMEDOUT;
0135             }
0136             udelay(1);
0137         }
0138 
0139         buf[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
0140     }
0141 
0142     return 0;
0143 }
0144 
0145 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
0146 {
0147     DSSDBG("Enter hdmi_core_init\n");
0148 
0149     /* video core */
0150     video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
0151     video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
0152     video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
0153     video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
0154     video_cfg->hdmi_dvi = HDMI_DVI;
0155     video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
0156 }
0157 
0158 void hdmi4_core_powerdown_disable(struct hdmi_core_data *core)
0159 {
0160     DSSDBG("Enter hdmi4_core_powerdown_disable\n");
0161     REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0);
0162 }
0163 
0164 static void hdmi_core_swreset_release(struct hdmi_core_data *core)
0165 {
0166     DSSDBG("Enter hdmi_core_swreset_release\n");
0167     REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);
0168 }
0169 
0170 static void hdmi_core_swreset_assert(struct hdmi_core_data *core)
0171 {
0172     DSSDBG("Enter hdmi_core_swreset_assert\n");
0173     REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);
0174 }
0175 
0176 /* HDMI_CORE_VIDEO_CONFIG */
0177 static void hdmi_core_video_config(struct hdmi_core_data *core,
0178                 struct hdmi_core_video_config *cfg)
0179 {
0180     u32 r = 0;
0181     void __iomem *core_sys_base = core->base;
0182     void __iomem *core_av_base = hdmi_av_base(core);
0183 
0184     /* sys_ctrl1 default configuration not tunable */
0185     r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1);
0186     r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
0187     r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
0188     r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2);
0189     r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1);
0190     hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r);
0191 
0192     REG_FLD_MOD(core_sys_base,
0193             HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
0194 
0195     /* Vid_Mode */
0196     r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE);
0197 
0198     /* dither truncation configuration */
0199     if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
0200         r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
0201         r = FLD_MOD(r, 1, 5, 5);
0202     } else {
0203         r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
0204         r = FLD_MOD(r, 0, 5, 5);
0205     }
0206     hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r);
0207 
0208     /* HDMI_Ctrl */
0209     r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL);
0210     r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
0211     r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
0212     r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
0213     hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r);
0214 
0215     /* TMDS_CTRL */
0216     REG_FLD_MOD(core_sys_base,
0217             HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
0218 }
0219 
0220 static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
0221     struct hdmi_avi_infoframe *frame)
0222 {
0223     void __iomem *av_base = hdmi_av_base(core);
0224     u8 data[HDMI_INFOFRAME_SIZE(AVI)];
0225     int i;
0226 
0227     hdmi_avi_infoframe_pack(frame, data, sizeof(data));
0228 
0229     print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
0230         HDMI_INFOFRAME_SIZE(AVI), false);
0231 
0232     for (i = 0; i < sizeof(data); ++i) {
0233         hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
0234             data[i]);
0235     }
0236 }
0237 
0238 static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
0239         struct hdmi_core_packet_enable_repeat repeat_cfg)
0240 {
0241     /* enable/repeat the infoframe */
0242     hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL1,
0243         (repeat_cfg.audio_pkt << 5) |
0244         (repeat_cfg.audio_pkt_repeat << 4) |
0245         (repeat_cfg.avi_infoframe << 1) |
0246         (repeat_cfg.avi_infoframe_repeat));
0247 
0248     /* enable/repeat the packet */
0249     hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL2,
0250         (repeat_cfg.gen_cntrl_pkt << 3) |
0251         (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
0252         (repeat_cfg.generic_pkt << 1) |
0253         (repeat_cfg.generic_pkt_repeat));
0254 }
0255 
0256 void hdmi4_configure(struct hdmi_core_data *core,
0257     struct hdmi_wp_data *wp, struct hdmi_config *cfg)
0258 {
0259     /* HDMI */
0260     struct videomode vm;
0261     struct hdmi_video_format video_format;
0262     /* HDMI core */
0263     struct hdmi_core_video_config v_core_cfg;
0264     struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 };
0265 
0266     hdmi_core_init(&v_core_cfg);
0267 
0268     hdmi_wp_init_vid_fmt_timings(&video_format, &vm, cfg);
0269 
0270     hdmi_wp_video_config_timing(wp, &vm);
0271 
0272     /* video config */
0273     video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
0274 
0275     hdmi_wp_video_config_format(wp, &video_format);
0276 
0277     hdmi_wp_video_config_interface(wp, &vm);
0278 
0279     /*
0280      * configure core video part
0281      * set software reset in the core
0282      */
0283     hdmi_core_swreset_assert(core);
0284 
0285     v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
0286     v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode;
0287 
0288     hdmi_core_video_config(core, &v_core_cfg);
0289 
0290     /* release software reset in the core */
0291     hdmi_core_swreset_release(core);
0292 
0293     if (cfg->hdmi_dvi_mode == HDMI_HDMI) {
0294         hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
0295 
0296         /* enable/repeat the infoframe */
0297         repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
0298         repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
0299         /* wakeup */
0300         repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
0301         repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
0302     }
0303 
0304     hdmi_core_av_packet_config(core, repeat_cfg);
0305 }
0306 
0307 void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
0308 {
0309     int i;
0310 
0311 #define CORE_REG(i, name) name(i)
0312 #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\
0313         hdmi_read_reg(core->base, r))
0314 #define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\
0315         hdmi_read_reg(hdmi_av_base(core), r))
0316 #define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
0317         (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \
0318         hdmi_read_reg(hdmi_av_base(core), CORE_REG(i, r)))
0319 
0320     DUMPCORE(HDMI_CORE_SYS_VND_IDL);
0321     DUMPCORE(HDMI_CORE_SYS_DEV_IDL);
0322     DUMPCORE(HDMI_CORE_SYS_DEV_IDH);
0323     DUMPCORE(HDMI_CORE_SYS_DEV_REV);
0324     DUMPCORE(HDMI_CORE_SYS_SRST);
0325     DUMPCORE(HDMI_CORE_SYS_SYS_CTRL1);
0326     DUMPCORE(HDMI_CORE_SYS_SYS_STAT);
0327     DUMPCORE(HDMI_CORE_SYS_SYS_CTRL3);
0328     DUMPCORE(HDMI_CORE_SYS_DE_DLY);
0329     DUMPCORE(HDMI_CORE_SYS_DE_CTRL);
0330     DUMPCORE(HDMI_CORE_SYS_DE_TOP);
0331     DUMPCORE(HDMI_CORE_SYS_DE_CNTL);
0332     DUMPCORE(HDMI_CORE_SYS_DE_CNTH);
0333     DUMPCORE(HDMI_CORE_SYS_DE_LINL);
0334     DUMPCORE(HDMI_CORE_SYS_DE_LINH_1);
0335     DUMPCORE(HDMI_CORE_SYS_HRES_L);
0336     DUMPCORE(HDMI_CORE_SYS_HRES_H);
0337     DUMPCORE(HDMI_CORE_SYS_VRES_L);
0338     DUMPCORE(HDMI_CORE_SYS_VRES_H);
0339     DUMPCORE(HDMI_CORE_SYS_IADJUST);
0340     DUMPCORE(HDMI_CORE_SYS_POLDETECT);
0341     DUMPCORE(HDMI_CORE_SYS_HWIDTH1);
0342     DUMPCORE(HDMI_CORE_SYS_HWIDTH2);
0343     DUMPCORE(HDMI_CORE_SYS_VWIDTH);
0344     DUMPCORE(HDMI_CORE_SYS_VID_CTRL);
0345     DUMPCORE(HDMI_CORE_SYS_VID_ACEN);
0346     DUMPCORE(HDMI_CORE_SYS_VID_MODE);
0347     DUMPCORE(HDMI_CORE_SYS_VID_BLANK1);
0348     DUMPCORE(HDMI_CORE_SYS_VID_BLANK3);
0349     DUMPCORE(HDMI_CORE_SYS_VID_BLANK1);
0350     DUMPCORE(HDMI_CORE_SYS_DC_HEADER);
0351     DUMPCORE(HDMI_CORE_SYS_VID_DITHER);
0352     DUMPCORE(HDMI_CORE_SYS_RGB2XVYCC_CT);
0353     DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_LOW);
0354     DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_UP);
0355     DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_LOW);
0356     DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_UP);
0357     DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_LOW);
0358     DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_UP);
0359     DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_LOW);
0360     DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_UP);
0361     DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_LOW);
0362     DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_UP);
0363     DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_LOW);
0364     DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_UP);
0365     DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_LOW);
0366     DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_UP);
0367     DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_LOW);
0368     DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_UP);
0369     DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_LOW);
0370     DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_UP);
0371     DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_LOW);
0372     DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_UP);
0373     DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_LOW);
0374     DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_UP);
0375     DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_LOW);
0376     DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_UP);
0377     DUMPCORE(HDMI_CORE_SYS_INTR_STATE);
0378     DUMPCORE(HDMI_CORE_SYS_INTR1);
0379     DUMPCORE(HDMI_CORE_SYS_INTR2);
0380     DUMPCORE(HDMI_CORE_SYS_INTR3);
0381     DUMPCORE(HDMI_CORE_SYS_INTR4);
0382     DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK1);
0383     DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK2);
0384     DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK3);
0385     DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK4);
0386     DUMPCORE(HDMI_CORE_SYS_INTR_CTRL);
0387     DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL);
0388 
0389     DUMPCORE(HDMI_CORE_DDC_ADDR);
0390     DUMPCORE(HDMI_CORE_DDC_SEGM);
0391     DUMPCORE(HDMI_CORE_DDC_OFFSET);
0392     DUMPCORE(HDMI_CORE_DDC_COUNT1);
0393     DUMPCORE(HDMI_CORE_DDC_COUNT2);
0394     DUMPCORE(HDMI_CORE_DDC_STATUS);
0395     DUMPCORE(HDMI_CORE_DDC_CMD);
0396     DUMPCORE(HDMI_CORE_DDC_DATA);
0397 
0398     DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL);
0399     DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL);
0400     DUMPCOREAV(HDMI_CORE_AV_N_SVAL1);
0401     DUMPCOREAV(HDMI_CORE_AV_N_SVAL2);
0402     DUMPCOREAV(HDMI_CORE_AV_N_SVAL3);
0403     DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1);
0404     DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2);
0405     DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3);
0406     DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1);
0407     DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2);
0408     DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3);
0409     DUMPCOREAV(HDMI_CORE_AV_AUD_MODE);
0410     DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL);
0411     DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS);
0412     DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S);
0413     DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH);
0414     DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP);
0415     DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL);
0416     DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0);
0417     DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1);
0418     DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2);
0419     DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4);
0420     DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5);
0421     DUMPCOREAV(HDMI_CORE_AV_ASRC);
0422     DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN);
0423     DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL);
0424     DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT);
0425     DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1);
0426     DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2);
0427     DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3);
0428     DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL);
0429     DUMPCOREAV(HDMI_CORE_AV_DPD);
0430     DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1);
0431     DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2);
0432     DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE);
0433     DUMPCOREAV(HDMI_CORE_AV_AVI_VERS);
0434     DUMPCOREAV(HDMI_CORE_AV_AVI_LEN);
0435     DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM);
0436 
0437     for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++)
0438         DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE);
0439 
0440     DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE);
0441     DUMPCOREAV(HDMI_CORE_AV_SPD_VERS);
0442     DUMPCOREAV(HDMI_CORE_AV_SPD_LEN);
0443     DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM);
0444 
0445     for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++)
0446         DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE);
0447 
0448     DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE);
0449     DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS);
0450     DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN);
0451     DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM);
0452 
0453     for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++)
0454         DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE);
0455 
0456     DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE);
0457     DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS);
0458     DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN);
0459     DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM);
0460 
0461     for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++)
0462         DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE);
0463 
0464     for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++)
0465         DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE);
0466 
0467     DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1);
0468 
0469     for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++)
0470         DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE);
0471 
0472     DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);
0473 }
0474 
0475 static void hdmi_core_audio_config(struct hdmi_core_data *core,
0476                     struct hdmi_core_audio_config *cfg)
0477 {
0478     u32 r;
0479     void __iomem *av_base = hdmi_av_base(core);
0480 
0481     /*
0482      * Parameters for generation of Audio Clock Recovery packets
0483      */
0484     REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
0485     REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
0486     REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
0487 
0488     if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
0489         REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
0490         REG_FLD_MOD(av_base,
0491                 HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
0492         REG_FLD_MOD(av_base,
0493                 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
0494     } else {
0495         REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
0496                 cfg->aud_par_busclk, 7, 0);
0497         REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
0498                 (cfg->aud_par_busclk >> 8), 7, 0);
0499         REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
0500                 (cfg->aud_par_busclk >> 16), 7, 0);
0501     }
0502 
0503     /* Set ACR clock divisor */
0504     if (cfg->use_mclk)
0505         REG_FLD_MOD(av_base, HDMI_CORE_AV_FREQ_SVAL,
0506                 cfg->mclk_mode, 2, 0);
0507 
0508     r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
0509     /*
0510      * Use TMDS clock for ACR packets. For devices that use
0511      * the MCLK, this is the first part of the MCLK initialization.
0512      */
0513     r = FLD_MOD(r, 0, 2, 2);
0514 
0515     r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
0516     r = FLD_MOD(r, cfg->cts_mode, 0, 0);
0517     hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
0518 
0519     /* For devices using MCLK, this completes its initialization. */
0520     if (cfg->use_mclk)
0521         REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2);
0522 
0523     /* Override of SPDIF sample frequency with value in I2S_CHST4 */
0524     REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
0525                         cfg->fs_override, 1, 1);
0526 
0527     /*
0528      * Set IEC-60958-3 channel status word. It is passed to the IP
0529      * just as it is received. The user of the driver is responsible
0530      * for its contents.
0531      */
0532     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0,
0533                cfg->iec60958_cfg->status[0]);
0534     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1,
0535                cfg->iec60958_cfg->status[1]);
0536     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2,
0537                cfg->iec60958_cfg->status[2]);
0538     /* yes, this is correct: status[3] goes to CHST4 register */
0539     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4,
0540                cfg->iec60958_cfg->status[3]);
0541     /* yes, this is correct: status[4] goes to CHST5 register */
0542     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5,
0543                cfg->iec60958_cfg->status[4]);
0544 
0545     /* set I2S parameters */
0546     r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL);
0547     r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
0548     r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
0549     r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
0550     r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
0551     r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
0552     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r);
0553 
0554     REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN,
0555             cfg->i2s_cfg.in_length_bits, 3, 0);
0556 
0557     /* Audio channels and mode parameters */
0558     REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
0559     r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE);
0560     r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
0561     r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
0562     r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
0563     r = FLD_MOD(r, cfg->en_spdif, 1, 1);
0564     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r);
0565 
0566     /* Audio channel mappings */
0567     /* TODO: Make channel mapping dynamic. For now, map channels
0568      * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as
0569      * HDMI speaker order is different. See CEA-861 Section 6.6.2.
0570      */
0571     hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78);
0572     REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5);
0573 }
0574 
0575 static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core,
0576         struct snd_cea_861_aud_if *info_aud)
0577 {
0578     u8 sum = 0, checksum = 0;
0579     void __iomem *av_base = hdmi_av_base(core);
0580 
0581     /*
0582      * Set audio info frame type, version and length as
0583      * described in HDMI 1.4a Section 8.2.2 specification.
0584      * Checksum calculation is defined in Section 5.3.5.
0585      */
0586     hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84);
0587     hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01);
0588     hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a);
0589     sum += 0x84 + 0x001 + 0x00a;
0590 
0591     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0),
0592                info_aud->db1_ct_cc);
0593     sum += info_aud->db1_ct_cc;
0594 
0595     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1),
0596                info_aud->db2_sf_ss);
0597     sum += info_aud->db2_sf_ss;
0598 
0599     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3);
0600     sum += info_aud->db3;
0601 
0602     /*
0603      * The OMAP HDMI IP requires to use the 8-channel channel code when
0604      * transmitting more than two channels.
0605      */
0606     if (info_aud->db4_ca != 0x00)
0607         info_aud->db4_ca = 0x13;
0608 
0609     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca);
0610     sum += info_aud->db4_ca;
0611 
0612     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4),
0613                info_aud->db5_dminh_lsv);
0614     sum += info_aud->db5_dminh_lsv;
0615 
0616     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
0617     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
0618     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
0619     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
0620     hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
0621 
0622     checksum = 0x100 - sum;
0623     hdmi_write_reg(av_base,
0624                     HDMI_CORE_AV_AUDIO_CHSUM, checksum);
0625 
0626     /*
0627      * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
0628      * is available.
0629      */
0630 }
0631 
0632 int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
0633         struct omap_dss_audio *audio, u32 pclk)
0634 {
0635     struct hdmi_audio_format audio_format;
0636     struct hdmi_audio_dma audio_dma;
0637     struct hdmi_core_audio_config acore;
0638     int n, cts, channel_count;
0639     unsigned int fs_nr;
0640     bool word_length_16b = false;
0641 
0642     if (!audio || !audio->iec || !audio->cea || !core)
0643         return -EINVAL;
0644 
0645     acore.iec60958_cfg = audio->iec;
0646     /*
0647      * In the IEC-60958 status word, check if the audio sample word length
0648      * is 16-bit as several optimizations can be performed in such case.
0649      */
0650     if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24))
0651         if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16)
0652             word_length_16b = true;
0653 
0654     /* I2S configuration. See Phillips' specification */
0655     if (word_length_16b)
0656         acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
0657     else
0658         acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
0659     /*
0660      * The I2S input word length is twice the length given in the IEC-60958
0661      * status word. If the word size is greater than
0662      * 20 bits, increment by one.
0663      */
0664     acore.i2s_cfg.in_length_bits = audio->iec->status[4]
0665         & IEC958_AES4_CON_WORDLEN;
0666     if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)
0667         acore.i2s_cfg.in_length_bits++;
0668     acore.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
0669     acore.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
0670     acore.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
0671     acore.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
0672 
0673     /* convert sample frequency to a number */
0674     switch (audio->iec->status[3] & IEC958_AES3_CON_FS) {
0675     case IEC958_AES3_CON_FS_32000:
0676         fs_nr = 32000;
0677         break;
0678     case IEC958_AES3_CON_FS_44100:
0679         fs_nr = 44100;
0680         break;
0681     case IEC958_AES3_CON_FS_48000:
0682         fs_nr = 48000;
0683         break;
0684     case IEC958_AES3_CON_FS_88200:
0685         fs_nr = 88200;
0686         break;
0687     case IEC958_AES3_CON_FS_96000:
0688         fs_nr = 96000;
0689         break;
0690     case IEC958_AES3_CON_FS_176400:
0691         fs_nr = 176400;
0692         break;
0693     case IEC958_AES3_CON_FS_192000:
0694         fs_nr = 192000;
0695         break;
0696     default:
0697         return -EINVAL;
0698     }
0699 
0700     hdmi_compute_acr(pclk, fs_nr, &n, &cts);
0701 
0702     /* Audio clock regeneration settings */
0703     acore.n = n;
0704     acore.cts = cts;
0705     if (core->cts_swmode) {
0706         acore.aud_par_busclk = 0;
0707         acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
0708         acore.use_mclk = core->audio_use_mclk;
0709     } else {
0710         acore.aud_par_busclk = (((128 * 31) - 1) << 8);
0711         acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
0712         acore.use_mclk = true;
0713     }
0714 
0715     if (acore.use_mclk)
0716         acore.mclk_mode = HDMI_AUDIO_MCLK_128FS;
0717 
0718     /* Audio channels settings */
0719     channel_count = (audio->cea->db1_ct_cc &
0720              CEA861_AUDIO_INFOFRAME_DB1CC) + 1;
0721 
0722     switch (channel_count) {
0723     case 2:
0724         audio_format.active_chnnls_msk = 0x03;
0725         break;
0726     case 3:
0727         audio_format.active_chnnls_msk = 0x07;
0728         break;
0729     case 4:
0730         audio_format.active_chnnls_msk = 0x0f;
0731         break;
0732     case 5:
0733         audio_format.active_chnnls_msk = 0x1f;
0734         break;
0735     case 6:
0736         audio_format.active_chnnls_msk = 0x3f;
0737         break;
0738     case 7:
0739         audio_format.active_chnnls_msk = 0x7f;
0740         break;
0741     case 8:
0742         audio_format.active_chnnls_msk = 0xff;
0743         break;
0744     default:
0745         return -EINVAL;
0746     }
0747 
0748     /*
0749      * the HDMI IP needs to enable four stereo channels when transmitting
0750      * more than 2 audio channels.  Similarly, the channel count in the
0751      * Audio InfoFrame has to match the sample_present bits (some channels
0752      * are padded with zeroes)
0753      */
0754     if (channel_count == 2) {
0755         audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
0756         acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
0757         acore.layout = HDMI_AUDIO_LAYOUT_2CH;
0758     } else {
0759         audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS;
0760         acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN |
0761                 HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
0762                 HDMI_AUDIO_I2S_SD3_EN;
0763         acore.layout = HDMI_AUDIO_LAYOUT_8CH;
0764         audio->cea->db1_ct_cc = 7;
0765     }
0766 
0767     acore.en_spdif = false;
0768     /* use sample frequency from channel status word */
0769     acore.fs_override = true;
0770     /* enable ACR packets */
0771     acore.en_acr_pkt = true;
0772     /* disable direct streaming digital audio */
0773     acore.en_dsd_audio = false;
0774     /* use parallel audio interface */
0775     acore.en_parallel_aud_input = true;
0776 
0777     /* DMA settings */
0778     if (word_length_16b)
0779         audio_dma.transfer_size = 0x10;
0780     else
0781         audio_dma.transfer_size = 0x20;
0782     audio_dma.block_size = 0xC0;
0783     audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
0784     audio_dma.fifo_threshold = 0x20; /* in number of samples */
0785 
0786     /* audio FIFO format settings */
0787     if (word_length_16b) {
0788         audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
0789         audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
0790         audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
0791     } else {
0792         audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
0793         audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
0794         audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
0795     }
0796     audio_format.type = HDMI_AUDIO_TYPE_LPCM;
0797     audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
0798     /* disable start/stop signals of IEC 60958 blocks */
0799     audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON;
0800 
0801     /* configure DMA and audio FIFO format*/
0802     hdmi_wp_audio_config_dma(wp, &audio_dma);
0803     hdmi_wp_audio_config_format(wp, &audio_format);
0804 
0805     /* configure the core*/
0806     hdmi_core_audio_config(core, &acore);
0807 
0808     /* configure CEA 861 audio infoframe*/
0809     hdmi_core_audio_infoframe_cfg(core, audio->cea);
0810 
0811     return 0;
0812 }
0813 
0814 int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
0815 {
0816     REG_FLD_MOD(hdmi_av_base(core),
0817             HDMI_CORE_AV_AUD_MODE, true, 0, 0);
0818 
0819     hdmi_wp_audio_core_req_enable(wp, true);
0820 
0821     return 0;
0822 }
0823 
0824 void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
0825 {
0826     REG_FLD_MOD(hdmi_av_base(core),
0827             HDMI_CORE_AV_AUD_MODE, false, 0, 0);
0828 
0829     hdmi_wp_audio_core_req_enable(wp, false);
0830 }
0831 
0832 struct hdmi4_features {
0833     bool cts_swmode;
0834     bool audio_use_mclk;
0835 };
0836 
0837 static const struct hdmi4_features hdmi4430_es1_features = {
0838     .cts_swmode = false,
0839     .audio_use_mclk = false,
0840 };
0841 
0842 static const struct hdmi4_features hdmi4430_es2_features = {
0843     .cts_swmode = true,
0844     .audio_use_mclk = false,
0845 };
0846 
0847 static const struct hdmi4_features hdmi4_features = {
0848     .cts_swmode = true,
0849     .audio_use_mclk = true,
0850 };
0851 
0852 static const struct soc_device_attribute hdmi4_soc_devices[] = {
0853     {
0854         .machine = "OMAP4430",
0855         .revision = "ES1.?",
0856         .data = &hdmi4430_es1_features,
0857     },
0858     {
0859         .machine = "OMAP4430",
0860         .revision = "ES2.?",
0861         .data = &hdmi4430_es2_features,
0862     },
0863     {
0864         .family = "OMAP4",
0865         .data = &hdmi4_features,
0866     },
0867     { /* sentinel */ }
0868 };
0869 
0870 int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
0871 {
0872     const struct hdmi4_features *features;
0873     const struct soc_device_attribute *soc;
0874 
0875     soc = soc_device_match(hdmi4_soc_devices);
0876     if (!soc)
0877         return -ENODEV;
0878 
0879     features = soc->data;
0880     core->cts_swmode = features->cts_swmode;
0881     core->audio_use_mclk = features->audio_use_mclk;
0882 
0883     core->base = devm_platform_ioremap_resource_byname(pdev, "core");
0884     if (IS_ERR(core->base))
0885         return PTR_ERR(core->base);
0886 
0887     return 0;
0888 }