You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branches '3.19/omapdss' and '3.19/simplefb' into fbdev
Merge fbdev topic branches.
This commit is contained in:
@@ -170,98 +170,6 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
|
||||
return in->ops.hdmi->detect(in);
|
||||
}
|
||||
|
||||
static int hdmic_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
/* enable audio only if the display is active */
|
||||
if (!omapdss_device_is_enabled(dssdev))
|
||||
return -EPERM;
|
||||
|
||||
r = in->ops.hdmi->audio_enable(in);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmic_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
in->ops.hdmi->audio_disable(in);
|
||||
|
||||
dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
|
||||
}
|
||||
|
||||
static int hdmic_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* No need to check the panel state. It was checked when trasitioning
|
||||
* to AUDIO_ENABLED.
|
||||
*/
|
||||
if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED)
|
||||
return -EPERM;
|
||||
|
||||
r = in->ops.hdmi->audio_start(in);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmic_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
in->ops.hdmi->audio_stop(in);
|
||||
|
||||
dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
|
||||
}
|
||||
|
||||
static bool hdmic_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
if (!omapdss_device_is_enabled(dssdev))
|
||||
return false;
|
||||
|
||||
return in->ops.hdmi->audio_supported(in);
|
||||
}
|
||||
|
||||
static int hdmic_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
/* config audio only if the display is active */
|
||||
if (!omapdss_device_is_enabled(dssdev))
|
||||
return -EPERM;
|
||||
|
||||
r = in->ops.hdmi->audio_config(in, audio);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
@@ -296,13 +204,6 @@ static struct omap_dss_driver hdmic_driver = {
|
||||
.detect = hdmic_detect,
|
||||
.set_hdmi_mode = hdmic_set_hdmi_mode,
|
||||
.set_hdmi_infoframe = hdmic_set_infoframe,
|
||||
|
||||
.audio_enable = hdmic_audio_enable,
|
||||
.audio_disable = hdmic_audio_disable,
|
||||
.audio_start = hdmic_audio_start,
|
||||
.audio_stop = hdmic_audio_stop,
|
||||
.audio_supported = hdmic_audio_supported,
|
||||
.audio_config = hdmic_audio_config,
|
||||
};
|
||||
|
||||
static int hdmic_probe_pdata(struct platform_device *pdev)
|
||||
|
||||
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
|
||||
dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
|
||||
dssdev->owner = THIS_MODULE;
|
||||
dssdev->phy.dpi.data_lines = ddata->data_lines;
|
||||
dssdev->port_num = 1;
|
||||
|
||||
r = omapdss_register_output(dssdev);
|
||||
if (r) {
|
||||
|
||||
@@ -193,55 +193,6 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
|
||||
return gpio_get_value_cansleep(ddata->hpd_gpio);
|
||||
}
|
||||
|
||||
static int tpd_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->audio_enable(in);
|
||||
}
|
||||
|
||||
static void tpd_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
in->ops.hdmi->audio_disable(in);
|
||||
}
|
||||
|
||||
static int tpd_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->audio_start(in);
|
||||
}
|
||||
|
||||
static void tpd_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
in->ops.hdmi->audio_stop(in);
|
||||
}
|
||||
|
||||
static bool tpd_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->audio_supported(in);
|
||||
}
|
||||
|
||||
static int tpd_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->audio_config(in, audio);
|
||||
}
|
||||
|
||||
static int tpd_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
@@ -275,13 +226,6 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
|
||||
.detect = tpd_detect,
|
||||
.set_infoframe = tpd_set_infoframe,
|
||||
.set_hdmi_mode = tpd_set_hdmi_mode,
|
||||
|
||||
.audio_enable = tpd_audio_enable,
|
||||
.audio_disable = tpd_audio_disable,
|
||||
.audio_start = tpd_audio_start,
|
||||
.audio_stop = tpd_audio_stop,
|
||||
.audio_supported = tpd_audio_supported,
|
||||
.audio_config = tpd_audio_config,
|
||||
};
|
||||
|
||||
static int tpd_probe_pdata(struct platform_device *pdev)
|
||||
@@ -409,6 +353,7 @@ static int tpd_probe(struct platform_device *pdev)
|
||||
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
|
||||
dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
|
||||
dssdev->owner = THIS_MODULE;
|
||||
dssdev->port_num = 1;
|
||||
|
||||
in = ddata->in;
|
||||
|
||||
|
||||
@@ -74,9 +74,6 @@ config OMAP4_DSS_HDMI
|
||||
help
|
||||
HDMI support for OMAP4 based SoCs.
|
||||
|
||||
config OMAP4_DSS_HDMI_AUDIO
|
||||
bool
|
||||
|
||||
config OMAP5_DSS_HDMI
|
||||
bool "HDMI support for OMAP5"
|
||||
default n
|
||||
@@ -86,10 +83,6 @@ config OMAP5_DSS_HDMI
|
||||
Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI
|
||||
specification.
|
||||
|
||||
config OMAP5_DSS_HDMI_AUDIO
|
||||
depends on OMAP5_DSS_HDMI
|
||||
bool
|
||||
|
||||
config OMAP2_DSS_SDI
|
||||
bool "SDI support"
|
||||
default n
|
||||
|
||||
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
|
||||
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
|
||||
# Core DSS files
|
||||
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
|
||||
output.o dss-of.o
|
||||
output.o dss-of.o pll.o
|
||||
# DSS compat layer files
|
||||
omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
|
||||
dispc-compat.o display-sysfs.o
|
||||
|
||||
@@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
|
||||
|
||||
unsigned long dispc_fclk_rate(void)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
struct dss_pll *pll;
|
||||
unsigned long r = 0;
|
||||
|
||||
switch (dss_get_dispc_clk_source()) {
|
||||
@@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void)
|
||||
r = dss_get_dispc_clk_rate();
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
|
||||
pll = dss_pll_find("dsi0");
|
||||
r = pll->cinfo.clkout[0];
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
|
||||
pll = dss_pll_find("dsi1");
|
||||
r = pll->cinfo.clkout[0];
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
@@ -3053,7 +3053,7 @@ unsigned long dispc_fclk_rate(void)
|
||||
|
||||
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
struct dss_pll *pll;
|
||||
int lcd;
|
||||
unsigned long r;
|
||||
u32 l;
|
||||
@@ -3068,12 +3068,12 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
|
||||
r = dss_get_dispc_clk_rate();
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
|
||||
pll = dss_pll_find("dsi0");
|
||||
r = pll->cinfo.clkout[0];
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
|
||||
pll = dss_pll_find("dsi1");
|
||||
r = pll->cinfo.clkout[0];
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
||||
+202
-125
File diff suppressed because it is too large
Load Diff
+240
-419
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
struct device_node *
|
||||
omapdss_of_get_next_port(const struct device_node *parent,
|
||||
struct device_node *prev)
|
||||
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node *parent,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
|
||||
|
||||
static struct device_node *
|
||||
omapdss_of_get_remote_device_node(const struct device_node *node)
|
||||
struct device_node *dss_of_port_get_parent_device(struct device_node *port)
|
||||
{
|
||||
struct device_node *np;
|
||||
int i;
|
||||
|
||||
np = of_parse_phandle(node, "remote-endpoint", 0);
|
||||
|
||||
if (!np)
|
||||
if (!port)
|
||||
return NULL;
|
||||
|
||||
np = of_get_next_parent(np);
|
||||
np = of_get_next_parent(port);
|
||||
|
||||
for (i = 0; i < 3 && np; ++i) {
|
||||
for (i = 0; i < 2 && np; ++i) {
|
||||
struct property *prop;
|
||||
|
||||
prop = of_find_property(np, "compatible", NULL);
|
||||
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node *node)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 dss_of_port_get_port_number(struct device_node *port)
|
||||
{
|
||||
int r;
|
||||
u32 reg;
|
||||
|
||||
r = of_property_read_u32(port, "reg", ®);
|
||||
if (r)
|
||||
reg = 0;
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_parse_phandle(node, "remote-endpoint", 0);
|
||||
if (!np)
|
||||
return NULL;
|
||||
|
||||
np = of_get_next_parent(np);
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
struct device_node *
|
||||
omapdss_of_get_first_endpoint(const struct device_node *parent)
|
||||
{
|
||||
@@ -133,27 +157,25 @@ struct omap_dss_device *
|
||||
omapdss_of_find_source_for_first_ep(struct device_node *node)
|
||||
{
|
||||
struct device_node *ep;
|
||||
struct device_node *src_node;
|
||||
struct device_node *src_port;
|
||||
struct omap_dss_device *src;
|
||||
|
||||
ep = omapdss_of_get_first_endpoint(node);
|
||||
if (!ep)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
src_node = omapdss_of_get_remote_device_node(ep);
|
||||
src_port = omapdss_of_get_remote_port(ep);
|
||||
if (!src_port) {
|
||||
of_node_put(ep);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
of_node_put(ep);
|
||||
|
||||
if (!src_node)
|
||||
return ERR_PTR(-EINVAL);
|
||||
src = omap_dss_find_output_by_port_node(src_port);
|
||||
|
||||
src = omap_dss_find_output_by_node(src_node);
|
||||
of_node_put(src_port);
|
||||
|
||||
of_node_put(src_node);
|
||||
|
||||
if (!src)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
return src;
|
||||
return src ? src : ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
|
||||
|
||||
@@ -70,7 +70,9 @@ struct dss_features {
|
||||
u8 fck_div_max;
|
||||
u8 dss_fck_multiplier;
|
||||
const char *parent_clk_name;
|
||||
int (*dpi_select_source)(enum omap_channel channel);
|
||||
enum omap_display_type *ports;
|
||||
int num_ports;
|
||||
int (*dpi_select_source)(int port, enum omap_channel channel);
|
||||
};
|
||||
|
||||
static struct {
|
||||
@@ -294,7 +296,6 @@ static void dss_dump_regs(struct seq_file *s)
|
||||
|
||||
static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b;
|
||||
u8 start, end;
|
||||
|
||||
@@ -304,13 +305,9 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
b = 2;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
@@ -327,7 +324,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
|
||||
void dss_select_dsi_clk_source(int dsi_module,
|
||||
enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b, pos;
|
||||
|
||||
switch (clk_src) {
|
||||
@@ -337,14 +333,10 @@ void dss_select_dsi_clk_source(int dsi_module,
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
|
||||
BUG_ON(dsi_module != 0);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dsi_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
|
||||
BUG_ON(dsi_module != 1);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dsi_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
@@ -360,7 +352,6 @@ void dss_select_dsi_clk_source(int dsi_module,
|
||||
void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b, ix, pos;
|
||||
|
||||
if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
|
||||
@@ -375,15 +366,11 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
|
||||
channel != OMAP_DSS_CHANNEL_LCD3);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
@@ -564,7 +551,7 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
|
||||
return REG_GET(DSS_CONTROL, 15, 15);
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
|
||||
static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
|
||||
{
|
||||
if (channel != OMAP_DSS_CHANNEL_LCD)
|
||||
return -EINVAL;
|
||||
@@ -572,7 +559,7 @@ static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap4(enum omap_channel channel)
|
||||
static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
|
||||
{
|
||||
int val;
|
||||
|
||||
@@ -592,7 +579,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap5(enum omap_channel channel)
|
||||
static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
|
||||
{
|
||||
int val;
|
||||
|
||||
@@ -618,9 +605,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_dpi_select_source(enum omap_channel channel)
|
||||
int dss_dpi_select_source(int port, enum omap_channel channel)
|
||||
{
|
||||
return dss.feat->dpi_select_source(channel);
|
||||
return dss.feat->dpi_select_source(port, channel);
|
||||
}
|
||||
|
||||
static int dss_get_clocks(void)
|
||||
@@ -689,6 +676,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static enum omap_display_type omap2plus_ports[] = {
|
||||
OMAP_DISPLAY_TYPE_DPI,
|
||||
};
|
||||
|
||||
static enum omap_display_type omap34xx_ports[] = {
|
||||
OMAP_DISPLAY_TYPE_DPI,
|
||||
OMAP_DISPLAY_TYPE_SDI,
|
||||
};
|
||||
|
||||
static const struct dss_features omap24xx_dss_feats __initconst = {
|
||||
/*
|
||||
* fck div max is really 16, but the divider range has gaps. The range
|
||||
@@ -698,6 +695,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 2,
|
||||
.parent_clk_name = "core_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
.ports = omap2plus_ports,
|
||||
.num_ports = ARRAY_SIZE(omap2plus_ports),
|
||||
};
|
||||
|
||||
static const struct dss_features omap34xx_dss_feats __initconst = {
|
||||
@@ -705,6 +704,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 2,
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
.ports = omap34xx_ports,
|
||||
.num_ports = ARRAY_SIZE(omap34xx_ports),
|
||||
};
|
||||
|
||||
static const struct dss_features omap3630_dss_feats __initconst = {
|
||||
@@ -712,6 +713,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 1,
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
.ports = omap2plus_ports,
|
||||
.num_ports = ARRAY_SIZE(omap2plus_ports),
|
||||
};
|
||||
|
||||
static const struct dss_features omap44xx_dss_feats __initconst = {
|
||||
@@ -719,6 +722,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 1,
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap4,
|
||||
.ports = omap2plus_ports,
|
||||
.num_ports = ARRAY_SIZE(omap2plus_ports),
|
||||
};
|
||||
|
||||
static const struct dss_features omap54xx_dss_feats __initconst = {
|
||||
@@ -726,6 +731,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 1,
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap5,
|
||||
.ports = omap2plus_ports,
|
||||
.num_ports = ARRAY_SIZE(omap2plus_ports),
|
||||
};
|
||||
|
||||
static const struct dss_features am43xx_dss_feats __initconst = {
|
||||
@@ -733,6 +740,8 @@ static const struct dss_features am43xx_dss_feats __initconst = {
|
||||
.dss_fck_multiplier = 0,
|
||||
.parent_clk_name = NULL,
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
.ports = omap2plus_ports,
|
||||
.num_ports = ARRAY_SIZE(omap2plus_ports),
|
||||
};
|
||||
|
||||
static int __init dss_init_features(struct platform_device *pdev)
|
||||
@@ -798,37 +807,77 @@ static int __init dss_init_ports(struct platform_device *pdev)
|
||||
if (!port)
|
||||
return 0;
|
||||
|
||||
if (dss.feat->num_ports == 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
enum omap_display_type port_type;
|
||||
u32 reg;
|
||||
|
||||
r = of_property_read_u32(port, "reg", ®);
|
||||
if (r)
|
||||
reg = 0;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
if (reg == 0)
|
||||
if (reg >= dss.feat->num_ports)
|
||||
continue;
|
||||
|
||||
port_type = dss.feat->ports[reg];
|
||||
|
||||
switch (port_type) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
dpi_init_port(pdev, port);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
if (reg == 1)
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
sdi_init_port(pdev, port);
|
||||
#endif
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit dss_uninit_ports(void)
|
||||
static void __exit dss_uninit_ports(struct platform_device *pdev)
|
||||
{
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
dpi_uninit_port();
|
||||
#endif
|
||||
struct device_node *parent = pdev->dev.of_node;
|
||||
struct device_node *port;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
sdi_uninit_port();
|
||||
#endif
|
||||
if (parent == NULL)
|
||||
return;
|
||||
|
||||
port = omapdss_of_get_next_port(parent, NULL);
|
||||
if (!port)
|
||||
return;
|
||||
|
||||
if (dss.feat->num_ports == 0)
|
||||
return;
|
||||
|
||||
do {
|
||||
enum omap_display_type port_type;
|
||||
u32 reg;
|
||||
int r;
|
||||
|
||||
r = of_property_read_u32(port, "reg", ®);
|
||||
if (r)
|
||||
reg = 0;
|
||||
|
||||
if (reg >= dss.feat->num_ports)
|
||||
continue;
|
||||
|
||||
port_type = dss.feat->ports[reg];
|
||||
|
||||
switch (port_type) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
dpi_uninit_port(port);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
sdi_uninit_port(port);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
|
||||
}
|
||||
|
||||
/* DSS HW IP initialisation */
|
||||
@@ -910,7 +959,7 @@ err_setup_clocks:
|
||||
|
||||
static int __exit omap_dsshw_remove(struct platform_device *pdev)
|
||||
{
|
||||
dss_uninit_ports();
|
||||
dss_uninit_ports(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
|
||||
+117
-108
@@ -100,6 +100,69 @@ enum dss_writeback_channel {
|
||||
DSS_WB_LCD3_MGR = 7,
|
||||
};
|
||||
|
||||
struct dss_pll;
|
||||
|
||||
#define DSS_PLL_MAX_HSDIVS 4
|
||||
|
||||
/*
|
||||
* Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
|
||||
* Type-B PLLs: clkout[0] refers to m2.
|
||||
*/
|
||||
struct dss_pll_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fint;
|
||||
unsigned long clkdco;
|
||||
unsigned long clkout[DSS_PLL_MAX_HSDIVS];
|
||||
|
||||
/* dividers */
|
||||
u16 n;
|
||||
u16 m;
|
||||
u32 mf;
|
||||
u16 mX[DSS_PLL_MAX_HSDIVS];
|
||||
u16 sd;
|
||||
};
|
||||
|
||||
struct dss_pll_ops {
|
||||
int (*enable)(struct dss_pll *pll);
|
||||
void (*disable)(struct dss_pll *pll);
|
||||
int (*set_config)(struct dss_pll *pll,
|
||||
const struct dss_pll_clock_info *cinfo);
|
||||
};
|
||||
|
||||
struct dss_pll_hw {
|
||||
unsigned n_max;
|
||||
unsigned m_min;
|
||||
unsigned m_max;
|
||||
unsigned mX_max;
|
||||
|
||||
unsigned long fint_min, fint_max;
|
||||
unsigned long clkdco_min, clkdco_low, clkdco_max;
|
||||
|
||||
u8 n_msb, n_lsb;
|
||||
u8 m_msb, m_lsb;
|
||||
u8 mX_msb[DSS_PLL_MAX_HSDIVS], mX_lsb[DSS_PLL_MAX_HSDIVS];
|
||||
|
||||
bool has_stopmode;
|
||||
bool has_freqsel;
|
||||
bool has_selfreqdco;
|
||||
bool has_refsel;
|
||||
};
|
||||
|
||||
struct dss_pll {
|
||||
const char *name;
|
||||
|
||||
struct clk *clkin;
|
||||
struct regulator *regulator;
|
||||
|
||||
void __iomem *base;
|
||||
|
||||
const struct dss_pll_hw *hw;
|
||||
|
||||
const struct dss_pll_ops *ops;
|
||||
|
||||
struct dss_pll_clock_info cinfo;
|
||||
};
|
||||
|
||||
struct dispc_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long lck;
|
||||
@@ -110,27 +173,6 @@ struct dispc_clock_info {
|
||||
u16 pck_div;
|
||||
};
|
||||
|
||||
struct dsi_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fint;
|
||||
unsigned long clkin4ddr;
|
||||
unsigned long clkin;
|
||||
unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
|
||||
* OMAP4: PLLx_CLK1 */
|
||||
unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
|
||||
* OMAP4: PLLx_CLK2 */
|
||||
unsigned long lp_clk;
|
||||
|
||||
/* dividers */
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u16 regm_dispc; /* OMAP3: REGM3
|
||||
* OMAP4: REGM4 */
|
||||
u16 regm_dsi; /* OMAP3: REGM4
|
||||
* OMAP4: REGM5 */
|
||||
u16 lp_clk_div;
|
||||
};
|
||||
|
||||
struct dss_lcd_mgr_config {
|
||||
enum dss_io_pad_mode io_pad_mode;
|
||||
|
||||
@@ -209,12 +251,16 @@ int dss_init_platform_driver(void) __init;
|
||||
void dss_uninit_platform_driver(void);
|
||||
|
||||
unsigned long dss_get_dispc_clk_rate(void);
|
||||
int dss_dpi_select_source(enum omap_channel channel);
|
||||
int dss_dpi_select_source(int port, enum omap_channel channel);
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
|
||||
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
|
||||
/* dss-of */
|
||||
struct device_node *dss_of_port_get_parent_device(struct device_node *port);
|
||||
u32 dss_of_port_get_port_number(struct device_node *port);
|
||||
|
||||
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
|
||||
void dss_debug_dump_clocks(struct seq_file *s);
|
||||
#endif
|
||||
@@ -244,16 +290,22 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
|
||||
int sdi_init_platform_driver(void) __init;
|
||||
void sdi_uninit_platform_driver(void) __exit;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init;
|
||||
void sdi_uninit_port(void) __exit;
|
||||
void sdi_uninit_port(struct device_node *port) __exit;
|
||||
#else
|
||||
static inline int __init sdi_init_port(struct platform_device *pdev,
|
||||
struct device_node *port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void __exit sdi_uninit_port(struct device_node *port)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DSI */
|
||||
|
||||
typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
|
||||
unsigned long pll, void *data);
|
||||
typedef bool (*dsi_hsdiv_calc_func)(int regm_dispc, unsigned long dispc,
|
||||
void *data);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
|
||||
struct dentry;
|
||||
@@ -262,104 +314,36 @@ struct file_operations;
|
||||
int dsi_init_platform_driver(void) __init;
|
||||
void dsi_uninit_platform_driver(void) __exit;
|
||||
|
||||
int dsi_runtime_get(struct platform_device *dsidev);
|
||||
void dsi_runtime_put(struct platform_device *dsidev);
|
||||
|
||||
void dsi_dump_clocks(struct seq_file *s);
|
||||
|
||||
void dsi_irq_handler(void);
|
||||
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
|
||||
|
||||
unsigned long dsi_get_pll_clkin(struct platform_device *dsidev);
|
||||
|
||||
bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
|
||||
unsigned long out_min, dsi_hsdiv_calc_func func, void *data);
|
||||
bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
|
||||
unsigned long pll_min, unsigned long pll_max,
|
||||
dsi_pll_calc_func func, void *data);
|
||||
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
|
||||
int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
||||
struct dsi_clock_info *cinfo);
|
||||
int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
|
||||
bool enable_hsdiv);
|
||||
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
|
||||
void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
|
||||
void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
|
||||
struct platform_device *dsi_get_dsidev_from_id(int module);
|
||||
#else
|
||||
static inline int dsi_runtime_get(struct platform_device *dsidev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dsi_runtime_put(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
||||
struct dsi_clock_info *cinfo)
|
||||
{
|
||||
WARN("%s: DSI not compiled in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int dsi_pll_init(struct platform_device *dsidev,
|
||||
bool enable_hsclk, bool enable_hsdiv)
|
||||
{
|
||||
WARN("%s: DSI not compiled in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void dsi_pll_uninit(struct platform_device *dsidev,
|
||||
bool disconnect_lanes)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline struct platform_device *dsi_get_dsidev_from_id(int module)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool dsi_hsdiv_calc(struct platform_device *dsidev,
|
||||
unsigned long pll, unsigned long out_min,
|
||||
dsi_hsdiv_calc_func func, void *data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool dsi_pll_calc(struct platform_device *dsidev,
|
||||
unsigned long clkin,
|
||||
unsigned long pll_min, unsigned long pll_max,
|
||||
dsi_pll_calc_func func, void *data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* DPI */
|
||||
int dpi_init_platform_driver(void) __init;
|
||||
void dpi_uninit_platform_driver(void) __exit;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
|
||||
void dpi_uninit_port(void) __exit;
|
||||
void dpi_uninit_port(struct device_node *port) __exit;
|
||||
#else
|
||||
static inline int __init dpi_init_port(struct platform_device *pdev,
|
||||
struct device_node *port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void __exit dpi_uninit_port(struct device_node *port)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DISPC */
|
||||
int dispc_init_platform_driver(void) __init;
|
||||
@@ -438,4 +422,29 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PLL */
|
||||
typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint,
|
||||
unsigned long clkdco, void *data);
|
||||
typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
|
||||
void *data);
|
||||
|
||||
int dss_pll_register(struct dss_pll *pll);
|
||||
void dss_pll_unregister(struct dss_pll *pll);
|
||||
struct dss_pll *dss_pll_find(const char *name);
|
||||
int dss_pll_enable(struct dss_pll *pll);
|
||||
void dss_pll_disable(struct dss_pll *pll);
|
||||
int dss_pll_set_config(struct dss_pll *pll,
|
||||
const struct dss_pll_clock_info *cinfo);
|
||||
|
||||
bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
|
||||
unsigned long out_min, unsigned long out_max,
|
||||
dss_hsdiv_calc_func func, void *data);
|
||||
bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
|
||||
unsigned long pll_min, unsigned long pll_max,
|
||||
dss_pll_calc_func func, void *data);
|
||||
int dss_pll_write_config_type_a(struct dss_pll *pll,
|
||||
const struct dss_pll_clock_info *cinfo);
|
||||
int dss_pll_write_config_type_b(struct dss_pll *pll,
|
||||
const struct dss_pll_clock_info *cinfo);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -72,10 +72,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
|
||||
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 25, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field omap3_dss_reg_fields[] = {
|
||||
@@ -87,10 +83,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
|
||||
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 25, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 7, 1 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 18, 8 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field am43xx_dss_reg_fields[] = {
|
||||
@@ -113,10 +105,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
|
||||
[FEAT_REG_HORIZONTALACCU] = { 10, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 26, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 8, 1 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 20, 9 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field omap5_dss_reg_fields[] = {
|
||||
@@ -128,10 +116,6 @@ static const struct dss_reg_field omap5_dss_reg_fields[] = {
|
||||
[FEAT_REG_HORIZONTALACCU] = { 10, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 26, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 8, 1 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 20, 9 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
|
||||
};
|
||||
|
||||
static const enum omap_display_type omap2_dss_supported_displays[] = {
|
||||
@@ -437,12 +421,6 @@ static const char * const omap5_dss_clk_source_names[] = {
|
||||
static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
|
||||
/*
|
||||
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
|
||||
@@ -454,11 +432,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
static const struct dss_param_range omap3_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
@@ -475,11 +448,6 @@ static const struct dss_param_range am43xx_dss_param_range[] = {
|
||||
static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
@@ -489,11 +457,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
static const struct dss_param_range omap5_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
@@ -517,7 +480,6 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
|
||||
FEAT_LINEBUFFERSPLIT,
|
||||
FEAT_ROWREPEATENABLE,
|
||||
FEAT_RESIZECONF,
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_DSI_REVERSE_TXCLKESC,
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK,
|
||||
FEAT_CPR,
|
||||
@@ -537,7 +499,6 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {
|
||||
FEAT_LINEBUFFERSPLIT,
|
||||
FEAT_ROWREPEATENABLE,
|
||||
FEAT_RESIZECONF,
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_DSI_REVERSE_TXCLKESC,
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK,
|
||||
FEAT_CPR,
|
||||
@@ -572,7 +533,6 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
|
||||
FEAT_ROWREPEATENABLE,
|
||||
FEAT_RESIZECONF,
|
||||
FEAT_DSI_PLL_PWR_BUG,
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_CPR,
|
||||
FEAT_PRELOAD,
|
||||
FEAT_FIR_COEF_V,
|
||||
@@ -654,8 +614,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
|
||||
FEAT_ALPHA_FREE_ZORDER,
|
||||
FEAT_FIFO_MERGE,
|
||||
FEAT_BURST_2D,
|
||||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
|
||||
@@ -41,7 +41,6 @@ enum dss_feat_id {
|
||||
FEAT_LCD_CLK_SRC,
|
||||
/* DSI-PLL power command 0x3 is not working */
|
||||
FEAT_DSI_PLL_PWR_BUG,
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC,
|
||||
FEAT_DSI_VC_OCP_WIDTH,
|
||||
FEAT_DSI_REVERSE_TXCLKESC,
|
||||
@@ -61,8 +60,6 @@ enum dss_feat_id {
|
||||
/* An unknown HW bug causing the normal FIFO thresholds not to work */
|
||||
FEAT_OMAP3_DSI_FIFO_BUG,
|
||||
FEAT_BURST_2D,
|
||||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
@@ -77,20 +74,11 @@ enum dss_feat_reg_field {
|
||||
FEAT_REG_HORIZONTALACCU,
|
||||
FEAT_REG_VERTICALACCU,
|
||||
FEAT_REG_DISPC_CLK_SWITCH,
|
||||
FEAT_REG_DSIPLL_REGN,
|
||||
FEAT_REG_DSIPLL_REGM,
|
||||
FEAT_REG_DSIPLL_REGM_DISPC,
|
||||
FEAT_REG_DSIPLL_REGM_DSI,
|
||||
};
|
||||
|
||||
enum dss_range_param {
|
||||
FEAT_PARAM_DSS_FCK,
|
||||
FEAT_PARAM_DSS_PCD,
|
||||
FEAT_PARAM_DSIPLL_REGN,
|
||||
FEAT_PARAM_DSIPLL_REGM,
|
||||
FEAT_PARAM_DSIPLL_REGM_DISPC,
|
||||
FEAT_PARAM_DSIPLL_REGM_DSI,
|
||||
FEAT_PARAM_DSIPLL_FINT,
|
||||
FEAT_PARAM_DSIPLL_LPDIV,
|
||||
FEAT_PARAM_DSI_FCK,
|
||||
FEAT_PARAM_DOWNSCALE,
|
||||
|
||||
@@ -101,13 +101,6 @@ enum hdmi_core_hdmi_dvi {
|
||||
HDMI_HDMI = 1
|
||||
};
|
||||
|
||||
enum hdmi_clk_refsel {
|
||||
HDMI_REFSEL_PCLK = 0,
|
||||
HDMI_REFSEL_REF1 = 1,
|
||||
HDMI_REFSEL_REF2 = 2,
|
||||
HDMI_REFSEL_SYSCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_packing_mode {
|
||||
HDMI_PACK_10b_RGB_YUV444 = 0,
|
||||
HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
|
||||
@@ -160,7 +153,8 @@ enum hdmi_audio_blk_strt_end_sig {
|
||||
|
||||
enum hdmi_core_audio_layout {
|
||||
HDMI_AUDIO_LAYOUT_2CH = 0,
|
||||
HDMI_AUDIO_LAYOUT_8CH = 1
|
||||
HDMI_AUDIO_LAYOUT_8CH = 1,
|
||||
HDMI_AUDIO_LAYOUT_6CH = 2
|
||||
};
|
||||
|
||||
enum hdmi_core_cts_mode {
|
||||
@@ -191,17 +185,6 @@ struct hdmi_config {
|
||||
enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
|
||||
};
|
||||
|
||||
/* HDMI PLL structure */
|
||||
struct hdmi_pll_info {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u32 regmf;
|
||||
u16 regm2;
|
||||
u16 regsd;
|
||||
u16 dcofreq;
|
||||
enum hdmi_clk_refsel refsel;
|
||||
};
|
||||
|
||||
struct hdmi_audio_format {
|
||||
enum hdmi_stereo_channels stereo_channels;
|
||||
u8 active_chnnls_msk;
|
||||
@@ -249,12 +232,15 @@ struct hdmi_core_audio_config {
|
||||
|
||||
struct hdmi_wp_data {
|
||||
void __iomem *base;
|
||||
phys_addr_t phys_base;
|
||||
};
|
||||
|
||||
struct hdmi_pll_data {
|
||||
struct dss_pll pll;
|
||||
|
||||
void __iomem *base;
|
||||
|
||||
struct hdmi_pll_info info;
|
||||
struct hdmi_wp_data *wp;
|
||||
};
|
||||
|
||||
struct hdmi_phy_data {
|
||||
@@ -316,16 +302,19 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
||||
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
|
||||
struct omap_video_timings *timings, struct hdmi_config *param);
|
||||
int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
|
||||
phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
|
||||
|
||||
/* HDMI PLL funcs */
|
||||
int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
|
||||
void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
|
||||
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
|
||||
void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy);
|
||||
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
|
||||
void hdmi_pll_compute(struct hdmi_pll_data *pll,
|
||||
unsigned long target_tmds, struct dss_pll_clock_info *pi);
|
||||
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
|
||||
struct hdmi_wp_data *wp);
|
||||
void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
|
||||
|
||||
/* HDMI PHY funcs */
|
||||
int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg);
|
||||
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
|
||||
unsigned long lfbitclk);
|
||||
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
|
||||
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
|
||||
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
|
||||
@@ -334,7 +323,7 @@ int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
|
||||
int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
|
||||
struct hdmi_phy_data *phy);
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
|
||||
/* Audio funcs */
|
||||
int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts);
|
||||
int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable);
|
||||
int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable);
|
||||
@@ -342,9 +331,33 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
|
||||
struct hdmi_audio_format *aud_fmt);
|
||||
void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
|
||||
struct hdmi_audio_dma *aud_dma);
|
||||
static inline bool hdmi_mode_has_audio(int mode)
|
||||
static inline bool hdmi_mode_has_audio(struct hdmi_config *cfg)
|
||||
{
|
||||
return mode == HDMI_HDMI ? true : false;
|
||||
return cfg->hdmi_dvi_mode == HDMI_HDMI ? true : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* HDMI DRV data */
|
||||
struct omap_hdmi {
|
||||
struct mutex lock;
|
||||
struct platform_device *pdev;
|
||||
|
||||
struct hdmi_wp_data wp;
|
||||
struct hdmi_pll_data pll;
|
||||
struct hdmi_phy_data phy;
|
||||
struct hdmi_core_data core;
|
||||
|
||||
struct hdmi_config cfg;
|
||||
|
||||
struct regulator *vdda_reg;
|
||||
|
||||
bool core_enabled;
|
||||
bool display_enabled;
|
||||
|
||||
struct omap_dss_device output;
|
||||
|
||||
struct platform_device *audio_pdev;
|
||||
void (*audio_abort_cb)(struct device *dev);
|
||||
int wp_idlemode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,10 +31,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/seq_file.h>
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
#include <sound/asound.h>
|
||||
#include <sound/asoundef.h>
|
||||
#endif
|
||||
|
||||
#include "hdmi4_core.h"
|
||||
#include "dss_features.h"
|
||||
@@ -530,7 +528,6 @@ void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
|
||||
DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
static void hdmi_core_audio_config(struct hdmi_core_data *core,
|
||||
struct hdmi_core_audio_config *cfg)
|
||||
{
|
||||
@@ -877,17 +874,6 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
|
||||
hdmi_wp_audio_core_req_enable(wp, false);
|
||||
}
|
||||
|
||||
int hdmi4_audio_get_dma_port(u32 *offset, u32 *size)
|
||||
{
|
||||
if (!offset || !size)
|
||||
return -EINVAL;
|
||||
*offset = HDMI_WP_AUDIO_DATA;
|
||||
*size = 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
@@ -266,12 +266,8 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s);
|
||||
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
|
||||
int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
|
||||
void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
|
||||
int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct omap_dss_audio *audio, u32 pclk);
|
||||
int hdmi4_audio_get_dma_port(u32 *offset, u32 *size);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,29 +38,13 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <sound/omap-hdmi-audio.h>
|
||||
|
||||
#include "hdmi5_core.h"
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
struct platform_device *pdev;
|
||||
|
||||
struct hdmi_wp_data wp;
|
||||
struct hdmi_pll_data pll;
|
||||
struct hdmi_phy_data phy;
|
||||
struct hdmi_core_data core;
|
||||
|
||||
struct hdmi_config cfg;
|
||||
|
||||
struct clk *sys_clk;
|
||||
struct regulator *vdda_reg;
|
||||
|
||||
bool core_enabled;
|
||||
|
||||
struct omap_dss_device output;
|
||||
} hdmi;
|
||||
static struct omap_hdmi hdmi;
|
||||
|
||||
static int hdmi_runtime_get(void)
|
||||
{
|
||||
@@ -198,7 +182,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
||||
int r;
|
||||
struct omap_video_timings *p;
|
||||
struct omap_overlay_manager *mgr = hdmi.output.manager;
|
||||
unsigned long phy;
|
||||
struct dss_pll_clock_info hdmi_cinfo = { 0 };
|
||||
|
||||
r = hdmi_power_on_core(dssdev);
|
||||
if (r)
|
||||
@@ -208,24 +192,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
||||
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||
|
||||
/* the functions below use kHz pixel clock. TODO: change to Hz */
|
||||
phy = p->pixelclock / 1000;
|
||||
|
||||
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
|
||||
hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
|
||||
|
||||
/* disable and clear irqs */
|
||||
hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
|
||||
hdmi_wp_set_irqstatus(&hdmi.wp,
|
||||
hdmi_wp_get_irqstatus(&hdmi.wp));
|
||||
|
||||
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
|
||||
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
|
||||
r = dss_pll_enable(&hdmi.pll.pll);
|
||||
if (r) {
|
||||
DSSDBG("Failed to lock PLL\n");
|
||||
DSSERR("Failed to enable PLL\n");
|
||||
goto err_pll_enable;
|
||||
}
|
||||
|
||||
r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
|
||||
r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
|
||||
if (r) {
|
||||
DSSERR("Failed to configure PLL\n");
|
||||
goto err_pll_cfg;
|
||||
}
|
||||
|
||||
r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
|
||||
hdmi_cinfo.clkout[0]);
|
||||
if (r) {
|
||||
DSSDBG("Failed to start PHY\n");
|
||||
goto err_phy_cfg;
|
||||
@@ -262,7 +249,8 @@ err_vid_enable:
|
||||
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
|
||||
err_phy_pwr:
|
||||
err_phy_cfg:
|
||||
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
|
||||
err_pll_cfg:
|
||||
dss_pll_disable(&hdmi.pll.pll);
|
||||
err_pll_enable:
|
||||
hdmi_power_off_core(dssdev);
|
||||
return -EIO;
|
||||
@@ -280,7 +268,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
|
||||
|
||||
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
|
||||
|
||||
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
|
||||
dss_pll_disable(&hdmi.pll.pll);
|
||||
|
||||
hdmi_power_off_core(dssdev);
|
||||
}
|
||||
@@ -290,6 +278,10 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
{
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
/* TODO: proper interlace support */
|
||||
if (timings->interlace)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -377,6 +369,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
|
||||
goto err0;
|
||||
}
|
||||
|
||||
hdmi.display_enabled = true;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
@@ -391,8 +385,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (hdmi.audio_pdev && hdmi.audio_abort_cb)
|
||||
hdmi.audio_abort_cb(&hdmi.audio_pdev->dev);
|
||||
|
||||
hdmi_power_off_full(dssdev);
|
||||
|
||||
hdmi.display_enabled = false;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
@@ -429,21 +428,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static int hdmi_get_clocks(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "sys_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get sys_clk\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
hdmi.sys_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_connect(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_device *dst)
|
||||
{
|
||||
@@ -509,112 +493,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
|
||||
static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = hdmi_wp_audio_enable(&hdmi.wp, true);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
hdmi_wp_audio_enable(&hdmi.wp, false);
|
||||
}
|
||||
|
||||
static int hdmi_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return hdmi_wp_audio_core_req_enable(&hdmi.wp, true);
|
||||
}
|
||||
|
||||
static void hdmi_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
hdmi_wp_audio_core_req_enable(&hdmi.wp, false);
|
||||
}
|
||||
|
||||
static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
bool r;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
int r;
|
||||
u32 pclk = hdmi.cfg.timings.pixelclock;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, audio, pclk);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static void hdmi_audio_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
}
|
||||
|
||||
static int hdmi_audio_start(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static void hdmi_audio_stop(struct omap_dss_device *dssdev)
|
||||
{
|
||||
}
|
||||
|
||||
static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
struct omap_dss_audio *audio)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
@@ -643,13 +521,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.read_edid = hdmi_read_edid,
|
||||
.set_infoframe = hdmi_set_infoframe,
|
||||
.set_hdmi_mode = hdmi_set_hdmi_mode,
|
||||
|
||||
.audio_enable = hdmi_audio_enable,
|
||||
.audio_disable = hdmi_audio_disable,
|
||||
.audio_start = hdmi_audio_start,
|
||||
.audio_stop = hdmi_audio_stop,
|
||||
.audio_supported = hdmi_audio_supported,
|
||||
.audio_config = hdmi_audio_config,
|
||||
};
|
||||
|
||||
static void hdmi_init_output(struct platform_device *pdev)
|
||||
@@ -667,7 +538,7 @@ static void hdmi_init_output(struct platform_device *pdev)
|
||||
omapdss_register_output(out);
|
||||
}
|
||||
|
||||
static void __exit hdmi_uninit_output(struct platform_device *pdev)
|
||||
static void hdmi_uninit_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
@@ -696,6 +567,119 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Audio callbacks */
|
||||
static int hdmi_audio_startup(struct device *dev,
|
||||
void (*abort_cb)(struct device *dev))
|
||||
{
|
||||
struct omap_hdmi *hd = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hd->lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
hd->audio_abort_cb = abort_cb;
|
||||
|
||||
out:
|
||||
mutex_unlock(&hd->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hdmi_audio_shutdown(struct device *dev)
|
||||
{
|
||||
struct omap_hdmi *hd = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&hd->lock);
|
||||
hd->audio_abort_cb = NULL;
|
||||
mutex_unlock(&hd->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_audio_start(struct device *dev)
|
||||
{
|
||||
struct omap_hdmi *hd = dev_get_drvdata(dev);
|
||||
|
||||
WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
|
||||
WARN_ON(!hd->display_enabled);
|
||||
|
||||
/* No-idle while playing audio, store the old value */
|
||||
hd->wp_idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
|
||||
REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
|
||||
|
||||
hdmi_wp_audio_enable(&hd->wp, true);
|
||||
hdmi_wp_audio_core_req_enable(&hd->wp, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_audio_stop(struct device *dev)
|
||||
{
|
||||
struct omap_hdmi *hd = dev_get_drvdata(dev);
|
||||
|
||||
WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
|
||||
WARN_ON(!hd->display_enabled);
|
||||
|
||||
hdmi_wp_audio_core_req_enable(&hd->wp, false);
|
||||
hdmi_wp_audio_enable(&hd->wp, false);
|
||||
|
||||
/* Playback stopped, restore original idlemode */
|
||||
REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
|
||||
}
|
||||
|
||||
static int hdmi_audio_config(struct device *dev,
|
||||
struct omap_dss_audio *dss_audio)
|
||||
{
|
||||
struct omap_hdmi *hd = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&hd->lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
|
||||
hd->cfg.timings.pixelclock);
|
||||
|
||||
out:
|
||||
mutex_unlock(&hd->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
|
||||
.audio_startup = hdmi_audio_startup,
|
||||
.audio_shutdown = hdmi_audio_shutdown,
|
||||
.audio_start = hdmi_audio_start,
|
||||
.audio_stop = hdmi_audio_stop,
|
||||
.audio_config = hdmi_audio_config,
|
||||
};
|
||||
|
||||
static int hdmi_audio_register(struct device *dev)
|
||||
{
|
||||
struct omap_hdmi_audio_pdata pdata = {
|
||||
.dev = dev,
|
||||
.dss_version = omapdss_get_version(),
|
||||
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
|
||||
.ops = &hdmi_audio_ops,
|
||||
};
|
||||
|
||||
hdmi.audio_pdev = platform_device_register_data(
|
||||
dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
|
||||
&pdata, sizeof(pdata));
|
||||
|
||||
if (IS_ERR(hdmi.audio_pdev))
|
||||
return PTR_ERR(hdmi.audio_pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HDMI HW IP initialisation */
|
||||
static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -703,6 +687,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
int irq;
|
||||
|
||||
hdmi.pdev = pdev;
|
||||
dev_set_drvdata(&pdev->dev, &hdmi);
|
||||
|
||||
mutex_init(&hdmi.lock);
|
||||
|
||||
@@ -716,28 +701,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_pll_init(pdev, &hdmi.pll);
|
||||
r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_phy_init(pdev, &hdmi.phy);
|
||||
if (r)
|
||||
return r;
|
||||
goto err;
|
||||
|
||||
r = hdmi5_core_init(pdev, &hdmi.core);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_get_clocks(pdev);
|
||||
if (r) {
|
||||
DSSERR("can't get clocks\n");
|
||||
return r;
|
||||
}
|
||||
goto err;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
DSSERR("platform_get_irq failed\n");
|
||||
return -ENODEV;
|
||||
r = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = devm_request_threaded_irq(&pdev->dev, irq,
|
||||
@@ -745,22 +725,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
|
||||
if (r) {
|
||||
DSSERR("HDMI IRQ request failed\n");
|
||||
return r;
|
||||
goto err;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
hdmi_init_output(pdev);
|
||||
|
||||
r = hdmi_audio_register(&pdev->dev);
|
||||
if (r) {
|
||||
DSSERR("Registering HDMI audio failed %d\n", r);
|
||||
hdmi_uninit_output(pdev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
hdmi_pll_uninit(&hdmi.pll);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (hdmi.audio_pdev)
|
||||
platform_device_unregister(hdmi.audio_pdev);
|
||||
|
||||
hdmi_uninit_output(pdev);
|
||||
|
||||
hdmi_pll_uninit(&hdmi.pll);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
@@ -768,8 +764,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
|
||||
|
||||
static int hdmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
clk_disable_unprepare(hdmi.sys_clk);
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
return 0;
|
||||
@@ -783,8 +777,6 @@ static int hdmi_runtime_resume(struct device *dev)
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
clk_prepare_enable(hdmi.sys_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,8 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
|
||||
#include <sound/asound.h>
|
||||
#include <sound/asoundef.h>
|
||||
#endif
|
||||
|
||||
#include "hdmi5_core.h"
|
||||
|
||||
@@ -644,9 +642,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
hdmi_core_enable_interrupts(core);
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
|
||||
|
||||
static void hdmi5_core_audio_config(struct hdmi_core_data *core,
|
||||
struct hdmi_core_audio_config *cfg)
|
||||
{
|
||||
@@ -721,7 +716,7 @@ static void hdmi5_core_audio_config(struct hdmi_core_data *core,
|
||||
|
||||
/* Source number */
|
||||
val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE;
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 4);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 0);
|
||||
|
||||
/* Channel number right 0 */
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0);
|
||||
@@ -879,6 +874,9 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
/* only LPCM atm */
|
||||
audio_format.type = HDMI_AUDIO_TYPE_LPCM;
|
||||
|
||||
/* only allowed option */
|
||||
audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
|
||||
|
||||
/* disable start/stop signals of IEC 60958 blocks */
|
||||
audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON;
|
||||
|
||||
@@ -894,7 +892,6 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
|
||||
{
|
||||
|
||||
@@ -299,8 +299,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct hdmi_config *cfg);
|
||||
int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
|
||||
|
||||
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
|
||||
int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct omap_dss_audio *audio, u32 pclk);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user