mirror of https://gitee.com/openkylin/linux.git
150 lines
2.7 KiB
C
150 lines
2.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#define DSS_SUBSYS_NAME "HDMI"
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/err.h>
|
|
#include <linux/of.h>
|
|
|
|
#include "omapdss.h"
|
|
#include "hdmi.h"
|
|
|
|
int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
|
|
struct hdmi_phy_data *phy)
|
|
{
|
|
struct property *prop;
|
|
int r, len;
|
|
|
|
prop = of_find_property(ep, "lanes", &len);
|
|
if (prop) {
|
|
u32 lanes[8];
|
|
|
|
if (len / sizeof(u32) != ARRAY_SIZE(lanes)) {
|
|
dev_err(&pdev->dev, "bad number of lanes\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
r = of_property_read_u32_array(ep, "lanes", lanes,
|
|
ARRAY_SIZE(lanes));
|
|
if (r) {
|
|
dev_err(&pdev->dev, "failed to read lane data\n");
|
|
return r;
|
|
}
|
|
|
|
r = hdmi_phy_parse_lanes(phy, lanes);
|
|
if (r) {
|
|
dev_err(&pdev->dev, "failed to parse lane data\n");
|
|
return r;
|
|
}
|
|
} else {
|
|
static const u32 default_lanes[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
|
|
|
r = hdmi_phy_parse_lanes(phy, default_lanes);
|
|
if (WARN_ON(r)) {
|
|
dev_err(&pdev->dev, "failed to parse lane data\n");
|
|
return r;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
|
|
{
|
|
u32 deep_color;
|
|
bool deep_color_correct = false;
|
|
|
|
if (n == NULL || cts == NULL)
|
|
return -EINVAL;
|
|
|
|
/* TODO: When implemented, query deep color mode here. */
|
|
deep_color = 100;
|
|
|
|
/*
|
|
* When using deep color, the default N value (as in the HDMI
|
|
* specification) yields to an non-integer CTS. Hence, we
|
|
* modify it while keeping the restrictions described in
|
|
* section 7.2.1 of the HDMI 1.4a specification.
|
|
*/
|
|
switch (sample_freq) {
|
|
case 32000:
|
|
case 48000:
|
|
case 96000:
|
|
case 192000:
|
|
if (deep_color == 125)
|
|
if (pclk == 27027000 || pclk == 74250000)
|
|
deep_color_correct = true;
|
|
if (deep_color == 150)
|
|
if (pclk == 27027000)
|
|
deep_color_correct = true;
|
|
break;
|
|
case 44100:
|
|
case 88200:
|
|
case 176400:
|
|
if (deep_color == 125)
|
|
if (pclk == 27027000)
|
|
deep_color_correct = true;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (deep_color_correct) {
|
|
switch (sample_freq) {
|
|
case 32000:
|
|
*n = 8192;
|
|
break;
|
|
case 44100:
|
|
*n = 12544;
|
|
break;
|
|
case 48000:
|
|
*n = 8192;
|
|
break;
|
|
case 88200:
|
|
*n = 25088;
|
|
break;
|
|
case 96000:
|
|
*n = 16384;
|
|
break;
|
|
case 176400:
|
|
*n = 50176;
|
|
break;
|
|
case 192000:
|
|
*n = 32768;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
} else {
|
|
switch (sample_freq) {
|
|
case 32000:
|
|
*n = 4096;
|
|
break;
|
|
case 44100:
|
|
*n = 6272;
|
|
break;
|
|
case 48000:
|
|
*n = 6144;
|
|
break;
|
|
case 88200:
|
|
*n = 12544;
|
|
break;
|
|
case 96000:
|
|
*n = 12288;
|
|
break;
|
|
case 176400:
|
|
*n = 25088;
|
|
break;
|
|
case 192000:
|
|
*n = 24576;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
|
|
*cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
|
|
|
|
return 0;
|
|
}
|