| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ |
|---|
| 5 | 6 | * Authors: Yong Zhi |
|---|
| 6 | 7 | * Mythri pk <mythripk@ti.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 9 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 10 | | - * the Free Software Foundation. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 15 | | - * more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 18 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | 8 | */ |
|---|
| 20 | 9 | |
|---|
| 21 | 10 | #define DSS_SUBSYS_NAME "HDMICORE" |
|---|
| .. | .. |
|---|
| 43 | 32 | return core->base + HDMI_CORE_AV; |
|---|
| 44 | 33 | } |
|---|
| 45 | 34 | |
|---|
| 46 | | -static int hdmi_core_ddc_init(struct hdmi_core_data *core) |
|---|
| 35 | +int hdmi4_core_ddc_init(struct hdmi_core_data *core) |
|---|
| 47 | 36 | { |
|---|
| 48 | 37 | void __iomem *base = core->base; |
|---|
| 49 | 38 | |
|---|
| .. | .. |
|---|
| 85 | 74 | return 0; |
|---|
| 86 | 75 | } |
|---|
| 87 | 76 | |
|---|
| 88 | | -static int hdmi_core_ddc_edid(struct hdmi_core_data *core, |
|---|
| 89 | | - u8 *pedid, int ext) |
|---|
| 77 | +int hdmi4_core_ddc_read(void *data, u8 *buf, unsigned int block, size_t len) |
|---|
| 90 | 78 | { |
|---|
| 79 | + struct hdmi_core_data *core = data; |
|---|
| 91 | 80 | void __iomem *base = core->base; |
|---|
| 92 | 81 | u32 i; |
|---|
| 93 | | - char checksum; |
|---|
| 94 | | - u32 offset = 0; |
|---|
| 95 | 82 | |
|---|
| 96 | 83 | /* HDMI_CORE_DDC_STATUS_IN_PROG */ |
|---|
| 97 | 84 | if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, |
|---|
| .. | .. |
|---|
| 100 | 87 | return -ETIMEDOUT; |
|---|
| 101 | 88 | } |
|---|
| 102 | 89 | |
|---|
| 103 | | - if (ext % 2 != 0) |
|---|
| 104 | | - offset = 0x80; |
|---|
| 105 | | - |
|---|
| 106 | 90 | /* Load Segment Address Register */ |
|---|
| 107 | | - REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0); |
|---|
| 91 | + REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, block / 2, 7, 0); |
|---|
| 108 | 92 | |
|---|
| 109 | 93 | /* Load Slave Address Register */ |
|---|
| 110 | 94 | REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); |
|---|
| 111 | 95 | |
|---|
| 112 | 96 | /* Load Offset Address Register */ |
|---|
| 113 | | - REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0); |
|---|
| 97 | + REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, block % 2 ? 0x80 : 0, 7, 0); |
|---|
| 114 | 98 | |
|---|
| 115 | 99 | /* Load Byte Count */ |
|---|
| 116 | | - REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); |
|---|
| 100 | + REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, len, 7, 0); |
|---|
| 117 | 101 | REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); |
|---|
| 118 | 102 | |
|---|
| 119 | 103 | /* Set DDC_CMD */ |
|---|
| 120 | | - if (ext) |
|---|
| 104 | + if (block) |
|---|
| 121 | 105 | REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); |
|---|
| 122 | 106 | else |
|---|
| 123 | 107 | REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); |
|---|
| .. | .. |
|---|
| 133 | 117 | return -EIO; |
|---|
| 134 | 118 | } |
|---|
| 135 | 119 | |
|---|
| 136 | | - for (i = 0; i < 0x80; ++i) { |
|---|
| 120 | + for (i = 0; i < len; ++i) { |
|---|
| 137 | 121 | int t; |
|---|
| 138 | 122 | |
|---|
| 139 | 123 | /* IN_PROG */ |
|---|
| .. | .. |
|---|
| 152 | 136 | udelay(1); |
|---|
| 153 | 137 | } |
|---|
| 154 | 138 | |
|---|
| 155 | | - pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); |
|---|
| 156 | | - } |
|---|
| 157 | | - |
|---|
| 158 | | - checksum = 0; |
|---|
| 159 | | - for (i = 0; i < 0x80; ++i) |
|---|
| 160 | | - checksum += pedid[i]; |
|---|
| 161 | | - |
|---|
| 162 | | - if (checksum != 0) { |
|---|
| 163 | | - DSSERR("E-EDID checksum failed!!\n"); |
|---|
| 164 | | - return -EIO; |
|---|
| 139 | + buf[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); |
|---|
| 165 | 140 | } |
|---|
| 166 | 141 | |
|---|
| 167 | 142 | return 0; |
|---|
| 168 | | -} |
|---|
| 169 | | - |
|---|
| 170 | | -int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len) |
|---|
| 171 | | -{ |
|---|
| 172 | | - int r, l; |
|---|
| 173 | | - |
|---|
| 174 | | - if (len < 128) |
|---|
| 175 | | - return -EINVAL; |
|---|
| 176 | | - |
|---|
| 177 | | - r = hdmi_core_ddc_init(core); |
|---|
| 178 | | - if (r) |
|---|
| 179 | | - return r; |
|---|
| 180 | | - |
|---|
| 181 | | - r = hdmi_core_ddc_edid(core, edid, 0); |
|---|
| 182 | | - if (r) |
|---|
| 183 | | - return r; |
|---|
| 184 | | - |
|---|
| 185 | | - l = 128; |
|---|
| 186 | | - |
|---|
| 187 | | - if (len >= 128 * 2 && edid[0x7e] > 0) { |
|---|
| 188 | | - r = hdmi_core_ddc_edid(core, edid + 0x80, 1); |
|---|
| 189 | | - if (r) |
|---|
| 190 | | - return r; |
|---|
| 191 | | - l += 128; |
|---|
| 192 | | - } |
|---|
| 193 | | - |
|---|
| 194 | | - return l; |
|---|
| 195 | 143 | } |
|---|
| 196 | 144 | |
|---|
| 197 | 145 | static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) |
|---|
| .. | .. |
|---|
| 553 | 501 | } |
|---|
| 554 | 502 | |
|---|
| 555 | 503 | /* Set ACR clock divisor */ |
|---|
| 556 | | - REG_FLD_MOD(av_base, |
|---|
| 557 | | - HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0); |
|---|
| 504 | + if (cfg->use_mclk) |
|---|
| 505 | + REG_FLD_MOD(av_base, HDMI_CORE_AV_FREQ_SVAL, |
|---|
| 506 | + cfg->mclk_mode, 2, 0); |
|---|
| 558 | 507 | |
|---|
| 559 | 508 | r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); |
|---|
| 560 | 509 | /* |
|---|
| .. | .. |
|---|
| 686 | 635 | struct hdmi_audio_format audio_format; |
|---|
| 687 | 636 | struct hdmi_audio_dma audio_dma; |
|---|
| 688 | 637 | struct hdmi_core_audio_config acore; |
|---|
| 689 | | - int err, n, cts, channel_count; |
|---|
| 638 | + int n, cts, channel_count; |
|---|
| 690 | 639 | unsigned int fs_nr; |
|---|
| 691 | 640 | bool word_length_16b = false; |
|---|
| 692 | 641 | |
|---|
| .. | .. |
|---|
| 708 | 657 | else |
|---|
| 709 | 658 | acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; |
|---|
| 710 | 659 | /* |
|---|
| 711 | | - * The I2S input word length is twice the lenght given in the IEC-60958 |
|---|
| 660 | + * The I2S input word length is twice the length given in the IEC-60958 |
|---|
| 712 | 661 | * status word. If the word size is greater than |
|---|
| 713 | 662 | * 20 bits, increment by one. |
|---|
| 714 | 663 | */ |
|---|
| .. | .. |
|---|
| 748 | 697 | return -EINVAL; |
|---|
| 749 | 698 | } |
|---|
| 750 | 699 | |
|---|
| 751 | | - err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); |
|---|
| 700 | + hdmi_compute_acr(pclk, fs_nr, &n, &cts); |
|---|
| 752 | 701 | |
|---|
| 753 | 702 | /* Audio clock regeneration settings */ |
|---|
| 754 | 703 | acore.n = n; |
|---|