Merge branches '3.19/omapdss' and '3.19/simplefb' into fbdev

Merge fbdev topic branches.
This commit is contained in:
Tomi Valkeinen
2014-12-08 09:16:31 +02:00
41 changed files with 2356 additions and 2115 deletions
@@ -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;
-7
View File
@@ -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
+1 -1
View File
@@ -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
+10 -10
View File
@@ -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();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40 -18
View File
@@ -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", &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);
+86 -37
View File
@@ -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", &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", &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
View File
@@ -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,
+42 -29
View File
@@ -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
+165 -173
View File
@@ -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;
}
+4 -7
View File
@@ -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