Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 Red Hat
0004  * Author: Rob Clark <robdclark@gmail.com>
0005  */
0006 
0007 #include <linux/hdmi.h>
0008 #include "hdmi.h"
0009 
0010 /* maps MSM_HDMI_AUDIO_CHANNEL_n consts used by audio driver to # of channels: */
0011 static int nchannels[] = { 2, 4, 6, 8 };
0012 
0013 /* Supported HDMI Audio sample rates */
0014 #define MSM_HDMI_SAMPLE_RATE_32KHZ      0
0015 #define MSM_HDMI_SAMPLE_RATE_44_1KHZ        1
0016 #define MSM_HDMI_SAMPLE_RATE_48KHZ      2
0017 #define MSM_HDMI_SAMPLE_RATE_88_2KHZ        3
0018 #define MSM_HDMI_SAMPLE_RATE_96KHZ      4
0019 #define MSM_HDMI_SAMPLE_RATE_176_4KHZ       5
0020 #define MSM_HDMI_SAMPLE_RATE_192KHZ     6
0021 #define MSM_HDMI_SAMPLE_RATE_MAX        7
0022 
0023 
0024 struct hdmi_msm_audio_acr {
0025     uint32_t n; /* N parameter for clock regeneration */
0026     uint32_t cts;   /* CTS parameter for clock regeneration */
0027 };
0028 
0029 struct hdmi_msm_audio_arcs {
0030     unsigned long int pixclock;
0031     struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX];
0032 };
0033 
0034 #define HDMI_MSM_AUDIO_ARCS(pclk, ...) { (1000 * (pclk)), __VA_ARGS__ }
0035 
0036 /* Audio constants lookup table for hdmi_msm_audio_acr_setup */
0037 /* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
0038 static const struct hdmi_msm_audio_arcs acr_lut[] = {
0039     /*  25.200MHz  */
0040     HDMI_MSM_AUDIO_ARCS(25200, {
0041         {4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
0042         {12288, 25200}, {25088, 28000}, {24576, 25200} }),
0043     /*  27.000MHz  */
0044     HDMI_MSM_AUDIO_ARCS(27000, {
0045         {4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
0046         {12288, 27000}, {25088, 30000}, {24576, 27000} }),
0047     /*  27.027MHz */
0048     HDMI_MSM_AUDIO_ARCS(27030, {
0049         {4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
0050         {12288, 27027}, {25088, 30030}, {24576, 27027} }),
0051     /*  74.250MHz */
0052     HDMI_MSM_AUDIO_ARCS(74250, {
0053         {4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
0054         {12288, 74250}, {25088, 82500}, {24576, 74250} }),
0055     /* 148.500MHz */
0056     HDMI_MSM_AUDIO_ARCS(148500, {
0057         {4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
0058         {12288, 148500}, {25088, 165000}, {24576, 148500} }),
0059 };
0060 
0061 static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock)
0062 {
0063     int i;
0064 
0065     for (i = 0; i < ARRAY_SIZE(acr_lut); i++) {
0066         const struct hdmi_msm_audio_arcs *arcs = &acr_lut[i];
0067         if (arcs->pixclock == pixclock)
0068             return arcs;
0069     }
0070 
0071     return NULL;
0072 }
0073 
0074 int msm_hdmi_audio_update(struct hdmi *hdmi)
0075 {
0076     struct hdmi_audio *audio = &hdmi->audio;
0077     struct hdmi_audio_infoframe *info = &audio->infoframe;
0078     const struct hdmi_msm_audio_arcs *arcs = NULL;
0079     bool enabled = audio->enabled;
0080     uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
0081     uint32_t infofrm_ctrl, audio_config;
0082 
0083     DBG("audio: enabled=%d, channels=%d, channel_allocation=0x%x, "
0084         "level_shift_value=%d, downmix_inhibit=%d, rate=%d",
0085         audio->enabled, info->channels,  info->channel_allocation,
0086         info->level_shift_value, info->downmix_inhibit, audio->rate);
0087     DBG("video: power_on=%d, pixclock=%lu", hdmi->power_on, hdmi->pixclock);
0088 
0089     if (enabled && !(hdmi->power_on && hdmi->pixclock)) {
0090         DBG("disabling audio: no video");
0091         enabled = false;
0092     }
0093 
0094     if (enabled) {
0095         arcs = get_arcs(hdmi->pixclock);
0096         if (!arcs) {
0097             DBG("disabling audio: unsupported pixclock: %lu",
0098                     hdmi->pixclock);
0099             enabled = false;
0100         }
0101     }
0102 
0103     /* Read first before writing */
0104     acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);
0105     vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL);
0106     aud_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_AUDIO_PKT_CTRL1);
0107     infofrm_ctrl = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
0108     audio_config = hdmi_read(hdmi, REG_HDMI_AUDIO_CFG);
0109 
0110     /* Clear N/CTS selection bits */
0111     acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SELECT__MASK;
0112 
0113     if (enabled) {
0114         uint32_t n, cts, multiplier;
0115         enum hdmi_acr_cts select;
0116         uint8_t buf[14];
0117 
0118         n   = arcs->lut[audio->rate].n;
0119         cts = arcs->lut[audio->rate].cts;
0120 
0121         if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate) ||
0122                 (MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate)) {
0123             multiplier = 4;
0124             n >>= 2; /* divide N by 4 and use multiplier */
0125         } else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
0126                 (MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate)) {
0127             multiplier = 2;
0128             n >>= 1; /* divide N by 2 and use multiplier */
0129         } else {
0130             multiplier = 1;
0131         }
0132 
0133         DBG("n=%u, cts=%u, multiplier=%u", n, cts, multiplier);
0134 
0135         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SOURCE;
0136         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY;
0137         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_N_MULTIPLIER(multiplier);
0138 
0139         if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio->rate) ||
0140                 (MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
0141                 (MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate))
0142             select = ACR_48;
0143         else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio->rate) ||
0144                 (MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate) ||
0145                 (MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate))
0146             select = ACR_44;
0147         else /* default to 32k */
0148             select = ACR_32;
0149 
0150         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SELECT(select);
0151 
0152         hdmi_write(hdmi, REG_HDMI_ACR_0(select - 1),
0153                 HDMI_ACR_0_CTS(cts));
0154         hdmi_write(hdmi, REG_HDMI_ACR_1(select - 1),
0155                 HDMI_ACR_1_N(n));
0156 
0157         hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL2,
0158                 COND(info->channels != 2, HDMI_AUDIO_PKT_CTRL2_LAYOUT) |
0159                 HDMI_AUDIO_PKT_CTRL2_OVERRIDE);
0160 
0161         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_CONT;
0162         acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SEND;
0163 
0164         /* configure infoframe: */
0165         hdmi_audio_infoframe_pack(info, buf, sizeof(buf));
0166         hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0,
0167                 (buf[3] <<  0) | (buf[4] <<  8) |
0168                 (buf[5] << 16) | (buf[6] << 24));
0169         hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1,
0170                 (buf[7] <<  0) | (buf[8] << 8));
0171 
0172         hdmi_write(hdmi, REG_HDMI_GC, 0);
0173 
0174         vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_ENABLE;
0175         vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
0176 
0177         aud_pkt_ctrl |= HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
0178 
0179         infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
0180         infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
0181         infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
0182         infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
0183 
0184         audio_config &= ~HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK;
0185         audio_config |= HDMI_AUDIO_CFG_FIFO_WATERMARK(4);
0186         audio_config |= HDMI_AUDIO_CFG_ENGINE_ENABLE;
0187     } else {
0188         acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_CONT;
0189         acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SEND;
0190         vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_ENABLE;
0191         vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
0192         aud_pkt_ctrl &= ~HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
0193         infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
0194         infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
0195         infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
0196         infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
0197         audio_config &= ~HDMI_AUDIO_CFG_ENGINE_ENABLE;
0198     }
0199 
0200     hdmi_write(hdmi, REG_HDMI_ACR_PKT_CTRL, acr_pkt_ctrl);
0201     hdmi_write(hdmi, REG_HDMI_VBI_PKT_CTRL, vbi_pkt_ctrl);
0202     hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL1, aud_pkt_ctrl);
0203     hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, infofrm_ctrl);
0204 
0205     hdmi_write(hdmi, REG_HDMI_AUD_INT,
0206             COND(enabled, HDMI_AUD_INT_AUD_FIFO_URUN_INT) |
0207             COND(enabled, HDMI_AUD_INT_AUD_SAM_DROP_INT));
0208 
0209     hdmi_write(hdmi, REG_HDMI_AUDIO_CFG, audio_config);
0210 
0211 
0212     DBG("audio %sabled", enabled ? "en" : "dis");
0213 
0214     return 0;
0215 }
0216 
0217 int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
0218     uint32_t num_of_channels, uint32_t channel_allocation,
0219     uint32_t level_shift, bool down_mix)
0220 {
0221     struct hdmi_audio *audio;
0222 
0223     if (!hdmi)
0224         return -ENXIO;
0225 
0226     audio = &hdmi->audio;
0227 
0228     if (num_of_channels >= ARRAY_SIZE(nchannels))
0229         return -EINVAL;
0230 
0231     audio->enabled = enabled;
0232     audio->infoframe.channels = nchannels[num_of_channels];
0233     audio->infoframe.channel_allocation = channel_allocation;
0234     audio->infoframe.level_shift_value = level_shift;
0235     audio->infoframe.downmix_inhibit = down_mix;
0236 
0237     return msm_hdmi_audio_update(hdmi);
0238 }
0239 
0240 void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate)
0241 {
0242     struct hdmi_audio *audio;
0243 
0244     if (!hdmi)
0245         return;
0246 
0247     audio = &hdmi->audio;
0248 
0249     if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
0250         return;
0251 
0252     audio->rate = rate;
0253     msm_hdmi_audio_update(hdmi);
0254 }