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 branch 'for-3.1-rc1' of git://gitorious.org/linux-omap-dss2/linux
* 'for-3.1-rc1' of git://gitorious.org/linux-omap-dss2/linux: (31 commits) OMAP: DSS2: HDMI: fix hdmi clock name HACK: OMAP: DSS2: clk hack for OMAP2/3 OMAP: DSS2: DSS: Fix context save/restore OMAP: DSS2: DISPC: Fix context save/restore OMAP: DSS2: Remove ctx loss count from dss.c OMAP: DSS2: Remove unused code from display.c OMAP: DSS2: DISPC: remove finegrained clk enables/disables OMAP: DSS2: Remove unused opt_clock_available OMAP: DSS2: Use PM runtime & HWMOD support OMAP: DSS2: Remove CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET OMAP: DSS2: Remove core_dump_clocks OMAP: DSS2: DPI: remove unneeded SYSCK enable/disable OMAP: DSS2: Use omap_pm_get_dev_context_loss_count to get ctx loss count OMAP: DSS2: rewrite use of context_loss_count OMAP: DSS2: Remove clk optimization at dss init OMAP: DSS2: Fix init and unit sequence OMAP: DSS2: Clean up probe for DSS & DSI OMAP: DSS2: Handle dpll4_m4_ck in dss_get/put_clocks OMAP: DSS2: Fix FIFO threshold and burst size for OMAP4 OMAP: DSS2: DSI: sync when disabling a display ...
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <plat/omap_device.h>
|
||||
#include <plat/omap-pm.h>
|
||||
|
||||
static struct platform_device omap_display_device = {
|
||||
.name = "omapdss",
|
||||
@@ -42,20 +43,6 @@ static struct omap_device_pm_latency omap_dss_latency[] = {
|
||||
},
|
||||
};
|
||||
|
||||
/* oh_core is used for getting opt-clocks */
|
||||
static struct omap_hwmod *oh_core;
|
||||
|
||||
static bool opt_clock_available(const char *clk_role)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < oh_core->opt_clks_cnt; i++) {
|
||||
if (!strcmp(oh_core->opt_clks[i].role, clk_role))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct omap_dss_hwmod_data {
|
||||
const char *oh_name;
|
||||
const char *dev_name;
|
||||
@@ -109,16 +96,9 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
|
||||
oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
|
||||
}
|
||||
|
||||
/* opt_clks are always associated with dss hwmod */
|
||||
oh_core = omap_hwmod_lookup("dss_core");
|
||||
if (!oh_core) {
|
||||
pr_err("Could not look up dss_core.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata.board_data = board_data;
|
||||
pdata.board_data->get_last_off_on_transaction_id = NULL;
|
||||
pdata.opt_clock_available = opt_clock_available;
|
||||
pdata.board_data->get_context_loss_count =
|
||||
omap_pm_get_dev_context_loss_count;
|
||||
|
||||
for (i = 0; i < oh_count; i++) {
|
||||
oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
|
||||
|
||||
@@ -504,14 +504,18 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
|
||||
return 0;
|
||||
|
||||
r = omapdss_dsi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to enable DSI\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
|
||||
|
||||
r = _taal_enable_te(dssdev, true);
|
||||
if (r)
|
||||
goto err;
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to re-enable TE");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
|
||||
@@ -521,13 +525,15 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(&dssdev->dev, "exit ULPS failed");
|
||||
err2:
|
||||
dev_err(&dssdev->dev, "failed to exit ULPS");
|
||||
|
||||
r = taal_panel_reset(dssdev);
|
||||
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
td->ulps_enabled = false;
|
||||
|
||||
if (!r) {
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
td->ulps_enabled = false;
|
||||
}
|
||||
err1:
|
||||
taal_queue_ulps_work(dssdev);
|
||||
|
||||
return r;
|
||||
@@ -1241,11 +1247,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
|
||||
int r;
|
||||
|
||||
r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
|
||||
if (!r) {
|
||||
if (!r)
|
||||
r = taal_sleep_in(td);
|
||||
/* HACK: wait a bit so that the message goes through */
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev,
|
||||
@@ -1317,8 +1320,11 @@ static void taal_disable(struct omap_dss_device *dssdev)
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
taal_wake_up(dssdev);
|
||||
taal_power_off(dssdev);
|
||||
int r;
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
taal_power_off(dssdev);
|
||||
}
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
@@ -1897,20 +1903,6 @@ err:
|
||||
mutex_unlock(&td->lock);
|
||||
}
|
||||
|
||||
static int taal_set_update_mode(struct omap_dss_device *dssdev,
|
||||
enum omap_dss_update_mode mode)
|
||||
{
|
||||
if (mode != OMAP_DSS_UPDATE_MANUAL)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum omap_dss_update_mode taal_get_update_mode(
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
return OMAP_DSS_UPDATE_MANUAL;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver taal_driver = {
|
||||
.probe = taal_probe,
|
||||
.remove = __exit_p(taal_remove),
|
||||
@@ -1920,9 +1912,6 @@ static struct omap_dss_driver taal_driver = {
|
||||
.suspend = taal_suspend,
|
||||
.resume = taal_resume,
|
||||
|
||||
.set_update_mode = taal_set_update_mode,
|
||||
.get_update_mode = taal_get_update_mode,
|
||||
|
||||
.update = taal_update,
|
||||
.sync = taal_sync,
|
||||
|
||||
|
||||
@@ -117,18 +117,6 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
|
||||
Max FCK is 173MHz, so this doesn't work if your PCK
|
||||
is very high.
|
||||
|
||||
config OMAP2_DSS_SLEEP_BEFORE_RESET
|
||||
bool "Sleep 50ms before DSS reset"
|
||||
default y
|
||||
help
|
||||
For some unknown reason we may get SYNC_LOST errors from the display
|
||||
subsystem at initialization time if we don't sleep before resetting
|
||||
the DSS. See the source (dss.c) for more comments.
|
||||
|
||||
However, 50ms is quite long time to sleep, and with some
|
||||
configurations the SYNC_LOST may never happen, so the sleep can
|
||||
be disabled here.
|
||||
|
||||
config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
|
||||
bool "Sleep 20ms after VENC reset"
|
||||
default y
|
||||
|
||||
@@ -183,8 +183,11 @@ static int omap_dss_probe(struct platform_device *pdev)
|
||||
goto err_dss;
|
||||
}
|
||||
|
||||
/* keep clocks enabled to prevent context saves/restores during init */
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
r = dispc_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize dispc platform driver\n");
|
||||
goto err_dispc;
|
||||
}
|
||||
|
||||
r = rfbi_init_platform_driver();
|
||||
if (r) {
|
||||
@@ -192,12 +195,6 @@ static int omap_dss_probe(struct platform_device *pdev)
|
||||
goto err_rfbi;
|
||||
}
|
||||
|
||||
r = dispc_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize dispc platform driver\n");
|
||||
goto err_dispc;
|
||||
}
|
||||
|
||||
r = venc_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize venc platform driver\n");
|
||||
@@ -238,8 +235,6 @@ static int omap_dss_probe(struct platform_device *pdev)
|
||||
pdata->default_device = dssdev;
|
||||
}
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
@@ -268,11 +263,11 @@ static int omap_dss_remove(struct platform_device *pdev)
|
||||
|
||||
dss_uninitialize_debugfs();
|
||||
|
||||
venc_uninit_platform_driver();
|
||||
dispc_uninit_platform_driver();
|
||||
rfbi_uninit_platform_driver();
|
||||
dsi_uninit_platform_driver();
|
||||
hdmi_uninit_platform_driver();
|
||||
dsi_uninit_platform_driver();
|
||||
venc_uninit_platform_driver();
|
||||
rfbi_uninit_platform_driver();
|
||||
dispc_uninit_platform_driver();
|
||||
dss_uninit_platform_driver();
|
||||
|
||||
dss_uninit_overlays(pdev);
|
||||
|
||||
+322
-240
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static ssize_t display_enabled_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@@ -65,48 +66,6 @@ static ssize_t display_enabled_store(struct device *dev,
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t display_upd_mode_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
|
||||
if (dssdev->driver->get_update_mode)
|
||||
mode = dssdev->driver->get_update_mode(dssdev);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", mode);
|
||||
}
|
||||
|
||||
static ssize_t display_upd_mode_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
int val, r;
|
||||
enum omap_dss_update_mode mode;
|
||||
|
||||
if (!dssdev->driver->set_update_mode)
|
||||
return -EINVAL;
|
||||
|
||||
r = kstrtoint(buf, 0, &val);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
switch (val) {
|
||||
case OMAP_DSS_UPDATE_DISABLED:
|
||||
case OMAP_DSS_UPDATE_AUTO:
|
||||
case OMAP_DSS_UPDATE_MANUAL:
|
||||
mode = (enum omap_dss_update_mode)val;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = dssdev->driver->set_update_mode(dssdev, mode);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t display_tear_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@@ -294,8 +253,6 @@ static ssize_t display_wss_store(struct device *dev,
|
||||
|
||||
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
|
||||
display_enabled_show, display_enabled_store);
|
||||
static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
|
||||
display_upd_mode_show, display_upd_mode_store);
|
||||
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
|
||||
display_tear_show, display_tear_store);
|
||||
static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
|
||||
@@ -309,7 +266,6 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
|
||||
|
||||
static struct device_attribute *display_sysfs_attrs[] = {
|
||||
&dev_attr_enabled,
|
||||
&dev_attr_update_mode,
|
||||
&dev_attr_tear_elim,
|
||||
&dev_attr_timings,
|
||||
&dev_attr_rotate,
|
||||
@@ -327,16 +283,13 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
|
||||
EXPORT_SYMBOL(omapdss_default_get_resolution);
|
||||
|
||||
void default_get_overlay_fifo_thresholds(enum omap_plane plane,
|
||||
u32 fifo_size, enum omap_burst_size *burst_size,
|
||||
u32 fifo_size, u32 burst_size,
|
||||
u32 *fifo_low, u32 *fifo_high)
|
||||
{
|
||||
unsigned burst_size_bytes;
|
||||
unsigned buf_unit = dss_feat_get_buffer_size_unit();
|
||||
|
||||
*burst_size = OMAP_DSS_BURST_16x32;
|
||||
burst_size_bytes = 16 * 32 / 8;
|
||||
|
||||
*fifo_high = fifo_size - 1;
|
||||
*fifo_low = fifo_size - burst_size_bytes;
|
||||
*fifo_high = fifo_size - buf_unit;
|
||||
*fifo_low = fifo_size - burst_size;
|
||||
}
|
||||
|
||||
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#define DSS_SUBSYS_NAME "DPI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
@@ -130,8 +129,6 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
bool is_tft;
|
||||
int r = 0;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dssdev->panel.acbi, dssdev->panel.acb);
|
||||
|
||||
@@ -144,7 +141,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
|
||||
&fck, &lck_div, &pck_div);
|
||||
if (r)
|
||||
goto err0;
|
||||
return r;
|
||||
|
||||
pck = fck / lck_div / pck_div / 1000;
|
||||
|
||||
@@ -158,12 +155,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
|
||||
dispc_set_lcd_timings(dssdev->manager->id, t);
|
||||
|
||||
err0:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpi_basic_init(struct omap_dss_device *dssdev)
|
||||
static void dpi_basic_init(struct omap_dss_device *dssdev)
|
||||
{
|
||||
bool is_tft;
|
||||
|
||||
@@ -175,8 +170,6 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
|
||||
OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
|
||||
dispc_set_tft_data_lines(dssdev->manager->id,
|
||||
dssdev->phy.dpi.data_lines);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
@@ -186,31 +179,38 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
goto err0;
|
||||
goto err_start_dev;
|
||||
}
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
r = regulator_enable(dpi.vdds_dsi_reg);
|
||||
if (r)
|
||||
goto err1;
|
||||
goto err_reg_enable;
|
||||
}
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
r = dpi_basic_init(dssdev);
|
||||
r = dss_runtime_get();
|
||||
if (r)
|
||||
goto err2;
|
||||
goto err_get_dss;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
goto err_get_dispc;
|
||||
|
||||
dpi_basic_init(dssdev);
|
||||
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_clk_enable(DSS_CLK_SYSCK);
|
||||
r = dsi_runtime_get(dpi.dsidev);
|
||||
if (r)
|
||||
goto err_get_dsi;
|
||||
|
||||
r = dsi_pll_init(dpi.dsidev, 0, 1);
|
||||
if (r)
|
||||
goto err3;
|
||||
goto err_dsi_pll_init;
|
||||
}
|
||||
|
||||
r = dpi_set_mode(dssdev);
|
||||
if (r)
|
||||
goto err4;
|
||||
goto err_set_mode;
|
||||
|
||||
mdelay(2);
|
||||
|
||||
@@ -218,19 +218,22 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
err_set_mode:
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dsi_pll_uninit(dpi.dsidev, true);
|
||||
err3:
|
||||
err_dsi_pll_init:
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
err2:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
dsi_runtime_put(dpi.dsidev);
|
||||
err_get_dsi:
|
||||
dispc_runtime_put();
|
||||
err_get_dispc:
|
||||
dss_runtime_put();
|
||||
err_get_dss:
|
||||
if (cpu_is_omap34xx())
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
err1:
|
||||
err_reg_enable:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
err_start_dev:
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_dpi_display_enable);
|
||||
@@ -242,10 +245,11 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
|
||||
dsi_pll_uninit(dpi.dsidev, true);
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
dsi_runtime_put(dpi.dsidev);
|
||||
}
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
||||
if (cpu_is_omap34xx())
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
@@ -257,11 +261,26 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
|
||||
void dpi_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("dpi_set_timings\n");
|
||||
dssdev->panel.timings = *timings;
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = dss_runtime_get();
|
||||
if (r)
|
||||
return;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r) {
|
||||
dss_runtime_put();
|
||||
return;
|
||||
}
|
||||
|
||||
dpi_set_mode(dssdev);
|
||||
dispc_go(dssdev->manager->id);
|
||||
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(dpi_set_timings);
|
||||
|
||||
+181
-119
File diff suppressed because it is too large
Load Diff
+169
-482
File diff suppressed because it is too large
Load Diff
@@ -97,26 +97,12 @@ extern unsigned int dss_debug;
|
||||
#define FLD_MOD(orig, val, start, end) \
|
||||
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
|
||||
|
||||
enum omap_burst_size {
|
||||
OMAP_DSS_BURST_4x32 = 0,
|
||||
OMAP_DSS_BURST_8x32 = 1,
|
||||
OMAP_DSS_BURST_16x32 = 2,
|
||||
};
|
||||
|
||||
enum omap_parallel_interface_mode {
|
||||
OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
|
||||
OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
|
||||
OMAP_DSS_PARALLELMODE_DSI,
|
||||
};
|
||||
|
||||
enum dss_clock {
|
||||
DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
|
||||
DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
|
||||
DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
|
||||
DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
|
||||
DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
|
||||
};
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select {
|
||||
DSS_VENC_TV_CLK = 0,
|
||||
DSS_HDMI_M_PCLK = 1,
|
||||
@@ -194,7 +180,7 @@ void dss_uninit_device(struct platform_device *pdev,
|
||||
bool dss_use_replication(struct omap_dss_device *dssdev,
|
||||
enum omap_color_mode mode);
|
||||
void default_get_overlay_fifo_thresholds(enum omap_plane plane,
|
||||
u32 fifo_size, enum omap_burst_size *burst_size,
|
||||
u32 fifo_size, u32 burst_size,
|
||||
u32 *fifo_low, u32 *fifo_high);
|
||||
|
||||
/* manager */
|
||||
@@ -220,13 +206,12 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
|
||||
int dss_init_platform_driver(void);
|
||||
void dss_uninit_platform_driver(void);
|
||||
|
||||
int dss_runtime_get(void);
|
||||
void dss_runtime_put(void);
|
||||
|
||||
struct clk *dss_get_ick(void);
|
||||
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
|
||||
void dss_save_context(void);
|
||||
void dss_restore_context(void);
|
||||
void dss_clk_enable(enum dss_clock clks);
|
||||
void dss_clk_disable(enum dss_clock clks);
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk);
|
||||
int dss_need_ctx_restore(void);
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
|
||||
@@ -283,15 +268,15 @@ struct file_operations;
|
||||
int dsi_init_platform_driver(void);
|
||||
void dsi_uninit_platform_driver(void);
|
||||
|
||||
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_create_debugfs_files_irq(struct dentry *debugfs_dir,
|
||||
const struct file_operations *debug_fops);
|
||||
void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
|
||||
const struct file_operations *debug_fops);
|
||||
|
||||
void dsi_save_context(void);
|
||||
void dsi_restore_context(void);
|
||||
|
||||
int dsi_init_display(struct omap_dss_device *display);
|
||||
void dsi_irq_handler(void);
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
|
||||
@@ -304,7 +289,7 @@ 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_get_overlay_fifo_thresholds(enum omap_plane plane,
|
||||
u32 fifo_size, enum omap_burst_size *burst_size,
|
||||
u32 fifo_size, u32 burst_size,
|
||||
u32 *fifo_low, u32 *fifo_high);
|
||||
void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
|
||||
void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
|
||||
@@ -317,6 +302,13 @@ static inline int dsi_init_platform_driver(void)
|
||||
static inline void dsi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
static inline int dsi_runtime_get(struct platform_device *dsidev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dsi_runtime_put(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
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__);
|
||||
@@ -384,8 +376,8 @@ void dispc_dump_regs(struct seq_file *s);
|
||||
void dispc_irq_handler(void);
|
||||
void dispc_fake_vsync_irq(void);
|
||||
|
||||
void dispc_save_context(void);
|
||||
void dispc_restore_context(void);
|
||||
int dispc_runtime_get(void);
|
||||
void dispc_runtime_put(void);
|
||||
|
||||
void dispc_enable_sidle(void);
|
||||
void dispc_disable_sidle(void);
|
||||
@@ -398,10 +390,12 @@ void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
|
||||
void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
|
||||
void dispc_set_digit_size(u16 width, u16 height);
|
||||
u32 dispc_get_plane_fifo_size(enum omap_plane plane);
|
||||
void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
|
||||
void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
|
||||
void dispc_enable_fifomerge(bool enable);
|
||||
void dispc_set_burst_size(enum omap_plane plane,
|
||||
enum omap_burst_size burst_size);
|
||||
u32 dispc_get_burst_size(enum omap_plane plane);
|
||||
void dispc_enable_cpr(enum omap_channel channel, bool enable);
|
||||
void dispc_set_cpr_coef(enum omap_channel channel,
|
||||
struct omap_dss_cpr_coefs *coefs);
|
||||
|
||||
void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
|
||||
void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
|
||||
|
||||
@@ -49,6 +49,9 @@ struct omap_dss_features {
|
||||
const enum omap_color_mode *supported_color_modes;
|
||||
const char * const *clksrc_names;
|
||||
const struct dss_param_range *dss_params;
|
||||
|
||||
const u32 buffer_size_unit;
|
||||
const u32 burst_size_unit;
|
||||
};
|
||||
|
||||
/* This struct is assigned to one of the below during initialization */
|
||||
@@ -274,6 +277,8 @@ static const struct omap_dss_features omap2_dss_features = {
|
||||
.supported_color_modes = omap2_dss_supported_color_modes,
|
||||
.clksrc_names = omap2_dss_clk_source_names,
|
||||
.dss_params = omap2_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
.burst_size_unit = 8,
|
||||
};
|
||||
|
||||
/* OMAP3 DSS Features */
|
||||
@@ -286,7 +291,9 @@ static const struct omap_dss_features omap3430_dss_features = {
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
|
||||
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC,
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
|
||||
FEAT_FIR_COEF_V,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
@@ -294,6 +301,8 @@ static const struct omap_dss_features omap3430_dss_features = {
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
.burst_size_unit = 8,
|
||||
};
|
||||
|
||||
static const struct omap_dss_features omap3630_dss_features = {
|
||||
@@ -306,7 +315,8 @@ static const struct omap_dss_features omap3630_dss_features = {
|
||||
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
|
||||
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
|
||||
FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
|
||||
FEAT_FIR_COEF_V,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
@@ -314,6 +324,8 @@ static const struct omap_dss_features omap3630_dss_features = {
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
.buffer_size_unit = 1,
|
||||
.burst_size_unit = 8,
|
||||
};
|
||||
|
||||
/* OMAP4 DSS Features */
|
||||
@@ -327,7 +339,8 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
|
||||
FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 |
|
||||
FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
@@ -335,6 +348,8 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
.buffer_size_unit = 16,
|
||||
.burst_size_unit = 16,
|
||||
};
|
||||
|
||||
/* For all the other OMAP4 versions */
|
||||
@@ -348,7 +363,8 @@ static const struct omap_dss_features omap4_dss_features = {
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
|
||||
FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
|
||||
FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
|
||||
FEAT_PRELOAD | FEAT_FIR_COEF_V,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
@@ -356,6 +372,8 @@ static const struct omap_dss_features omap4_dss_features = {
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
.buffer_size_unit = 16,
|
||||
.burst_size_unit = 16,
|
||||
};
|
||||
|
||||
/* Functions returning values related to a DSS feature */
|
||||
@@ -401,6 +419,16 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
|
||||
return omap_current_dss_features->clksrc_names[id];
|
||||
}
|
||||
|
||||
u32 dss_feat_get_buffer_size_unit(void)
|
||||
{
|
||||
return omap_current_dss_features->buffer_size_unit;
|
||||
}
|
||||
|
||||
u32 dss_feat_get_burst_size_unit(void)
|
||||
{
|
||||
return omap_current_dss_features->burst_size_unit;
|
||||
}
|
||||
|
||||
/* DSS has_feature check */
|
||||
bool dss_has_feature(enum dss_feat_id id)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,10 @@ enum dss_feat_id {
|
||||
FEAT_HDMI_CTS_SWMODE = 1 << 19,
|
||||
FEAT_HANDLE_UV_SEPARATE = 1 << 20,
|
||||
FEAT_ATTR2 = 1 << 21,
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK = 1 << 22,
|
||||
FEAT_CPR = 1 << 23,
|
||||
FEAT_PRELOAD = 1 << 24,
|
||||
FEAT_FIR_COEF_V = 1 << 25,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
@@ -90,6 +94,9 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
enum omap_color_mode color_mode);
|
||||
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
|
||||
|
||||
u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
|
||||
u32 dss_feat_get_burst_size_unit(void); /* in bytes */
|
||||
|
||||
bool dss_has_feature(enum dss_feat_id id);
|
||||
void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
|
||||
void dss_features_init(void);
|
||||
|
||||
+122
-40
@@ -29,6 +29,9 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/clk.h>
|
||||
#include <video/omapdss.h>
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
@@ -51,6 +54,9 @@ static struct {
|
||||
u8 edid_set;
|
||||
bool custom_set;
|
||||
struct hdmi_config cfg;
|
||||
|
||||
struct clk *sys_clk;
|
||||
struct clk *hdmi_clk;
|
||||
} hdmi;
|
||||
|
||||
/*
|
||||
@@ -162,6 +168,27 @@ static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
|
||||
return val;
|
||||
}
|
||||
|
||||
static int hdmi_runtime_get(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("hdmi_runtime_get\n");
|
||||
|
||||
r = pm_runtime_get_sync(&hdmi.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
static void hdmi_runtime_put(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("hdmi_runtime_put\n");
|
||||
|
||||
r = pm_runtime_put(&hdmi.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
}
|
||||
|
||||
int hdmi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("init_display\n");
|
||||
@@ -311,30 +338,11 @@ static int hdmi_phy_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_wait_softreset(void)
|
||||
{
|
||||
/* reset W1 */
|
||||
REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
|
||||
|
||||
/* wait till SOFTRESET == 0 */
|
||||
if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
|
||||
DSSERR("sysconfig reset failed\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_pll_program(struct hdmi_pll_info *fmt)
|
||||
{
|
||||
u16 r = 0;
|
||||
enum hdmi_clk_refsel refsel;
|
||||
|
||||
/* wait for wrapper reset */
|
||||
r = hdmi_wait_softreset();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -1064,7 +1072,7 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
|
||||
unsigned long clkin, refclk;
|
||||
u32 mf;
|
||||
|
||||
clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000;
|
||||
clkin = clk_get_rate(hdmi.sys_clk) / 10000;
|
||||
/*
|
||||
* Input clock is predivided by N + 1
|
||||
* out put of which is reference clk
|
||||
@@ -1098,16 +1106,6 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
|
||||
DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
|
||||
}
|
||||
|
||||
static void hdmi_enable_clocks(int enable)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
|
||||
DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
|
||||
DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
|
||||
}
|
||||
|
||||
static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r, code = 0;
|
||||
@@ -1115,7 +1113,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
struct omap_video_timings *p;
|
||||
unsigned long phy;
|
||||
|
||||
hdmi_enable_clocks(1);
|
||||
r = hdmi_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
|
||||
|
||||
@@ -1180,7 +1180,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
|
||||
return 0;
|
||||
err:
|
||||
hdmi_enable_clocks(0);
|
||||
hdmi_runtime_put();
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1191,7 +1191,7 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
|
||||
hdmi_wp_video_start(0);
|
||||
hdmi_phy_off();
|
||||
hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
|
||||
hdmi_enable_clocks(0);
|
||||
hdmi_runtime_put();
|
||||
|
||||
hdmi.edid_set = 0;
|
||||
}
|
||||
@@ -1686,14 +1686,43 @@ static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int hdmi_get_clocks(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = 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;
|
||||
|
||||
clk = clk_get(&pdev->dev, "dss_48mhz_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get hdmi_clk\n");
|
||||
clk_put(hdmi.sys_clk);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
hdmi.hdmi_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_put_clocks(void)
|
||||
{
|
||||
if (hdmi.sys_clk)
|
||||
clk_put(hdmi.sys_clk);
|
||||
if (hdmi.hdmi_clk)
|
||||
clk_put(hdmi.hdmi_clk);
|
||||
}
|
||||
|
||||
/* HDMI HW IP initialisation */
|
||||
static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *hdmi_mem;
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
int ret;
|
||||
#endif
|
||||
int r;
|
||||
|
||||
hdmi.pdata = pdev->dev.platform_data;
|
||||
hdmi.pdev = pdev;
|
||||
@@ -1713,17 +1742,25 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = hdmi_get_clocks(pdev);
|
||||
if (r) {
|
||||
iounmap(hdmi.base_wp);
|
||||
return r;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
hdmi_panel_init();
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
|
||||
/* Register ASoC codec DAI */
|
||||
ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
|
||||
r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
|
||||
&hdmi_codec_dai_drv, 1);
|
||||
if (ret) {
|
||||
if (r) {
|
||||
DSSERR("can't register ASoC HDMI audio codec\n");
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@@ -1738,17 +1775,62 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
#endif
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
hdmi_put_clocks();
|
||||
|
||||
iounmap(hdmi.base_wp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
clk_disable(hdmi.hdmi_clk);
|
||||
clk_disable(hdmi.sys_clk);
|
||||
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_runtime_resume(struct device *dev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = dss_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dss;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dispc;
|
||||
|
||||
|
||||
clk_enable(hdmi.sys_clk);
|
||||
clk_enable(hdmi.hdmi_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_dispc:
|
||||
dss_runtime_put();
|
||||
err_get_dss:
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops hdmi_pm_ops = {
|
||||
.runtime_suspend = hdmi_runtime_suspend,
|
||||
.runtime_resume = hdmi_runtime_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver omapdss_hdmihw_driver = {
|
||||
.probe = omapdss_hdmihw_probe,
|
||||
.remove = omapdss_hdmihw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_hdmi",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &hdmi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+202
-149
File diff suppressed because it is too large
Load Diff
@@ -84,32 +84,42 @@ static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
|
||||
|
||||
old_mgr = ovl->manager;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* detach old manager */
|
||||
if (old_mgr) {
|
||||
r = ovl->unset_manager(ovl);
|
||||
if (r) {
|
||||
DSSERR("detach failed\n");
|
||||
return r;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = old_mgr->apply(old_mgr);
|
||||
if (r)
|
||||
return r;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mgr) {
|
||||
r = ovl->set_manager(ovl, mgr);
|
||||
if (r) {
|
||||
DSSERR("Failed to attach overlay\n");
|
||||
return r;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
return size;
|
||||
|
||||
err:
|
||||
dispc_runtime_put();
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
|
||||
@@ -238,6 +248,9 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -504,7 +517,6 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
||||
|
||||
ovl->manager = mgr;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
/* XXX: When there is an overlay on a DSI manual update display, and
|
||||
* the overlay is first disabled, then moved to tv, and enabled, we
|
||||
* seem to get SYNC_LOST_DIGIT error.
|
||||
@@ -518,7 +530,6 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
||||
* the overlay, but before moving the overlay to TV.
|
||||
*/
|
||||
dispc_set_channel_out(ovl->id, mgr->id);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -719,6 +730,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
||||
}
|
||||
|
||||
if (mgr) {
|
||||
dispc_runtime_get();
|
||||
|
||||
for (i = 0; i < dss_feat_get_num_ovls(); i++) {
|
||||
struct omap_overlay *ovl;
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
@@ -728,6 +741,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
||||
omap_dss_set_manager(ovl, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
dispc_runtime_put();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include "dss.h"
|
||||
@@ -120,12 +122,25 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
|
||||
return __raw_readl(rfbi.base + idx.idx);
|
||||
}
|
||||
|
||||
static void rfbi_enable_clocks(bool enable)
|
||||
static int rfbi_runtime_get(void)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
int r;
|
||||
|
||||
DSSDBG("rfbi_runtime_get\n");
|
||||
|
||||
r = pm_runtime_get_sync(&rfbi.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
static void rfbi_runtime_put(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("rfbi_runtime_put\n");
|
||||
|
||||
r = pm_runtime_put(&rfbi.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
}
|
||||
|
||||
void rfbi_bus_lock(void)
|
||||
@@ -805,7 +820,8 @@ void rfbi_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
if (rfbi_runtime_get())
|
||||
return;
|
||||
|
||||
DUMPREG(RFBI_REVISION);
|
||||
DUMPREG(RFBI_SYSCONFIG);
|
||||
@@ -836,7 +852,7 @@ void rfbi_dump_regs(struct seq_file *s)
|
||||
DUMPREG(RFBI_VSYNC_WIDTH);
|
||||
DUMPREG(RFBI_HSYNC_WIDTH);
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
rfbi_runtime_put();
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
@@ -844,7 +860,9 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
r = rfbi_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
@@ -879,6 +897,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
||||
err1:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
rfbi_runtime_put();
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_display_enable);
|
||||
@@ -889,7 +908,7 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
|
||||
DISPC_IRQ_FRAMEDONE);
|
||||
omap_dss_stop_device(dssdev);
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
rfbi_runtime_put();
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_display_disable);
|
||||
|
||||
@@ -904,8 +923,9 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
|
||||
static int omap_rfbihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 rev;
|
||||
u32 l;
|
||||
struct resource *rfbi_mem;
|
||||
struct clk *clk;
|
||||
int r;
|
||||
|
||||
rfbi.pdev = pdev;
|
||||
|
||||
@@ -914,46 +934,102 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
|
||||
rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
|
||||
if (!rfbi_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM RFBI\n");
|
||||
return -EINVAL;
|
||||
r = -EINVAL;
|
||||
goto err_ioremap;
|
||||
}
|
||||
rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
|
||||
if (!rfbi.base) {
|
||||
DSSERR("can't ioremap RFBI\n");
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
r = rfbi_runtime_get();
|
||||
if (r)
|
||||
goto err_get_rfbi;
|
||||
|
||||
msleep(10);
|
||||
|
||||
rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap3630())
|
||||
clk = dss_get_ick();
|
||||
else
|
||||
clk = clk_get(&pdev->dev, "ick");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get ick\n");
|
||||
r = PTR_ERR(clk);
|
||||
goto err_get_ick;
|
||||
}
|
||||
|
||||
/* Enable autoidle and smart-idle */
|
||||
l = rfbi_read_reg(RFBI_SYSCONFIG);
|
||||
l |= (1 << 0) | (2 << 3);
|
||||
rfbi_write_reg(RFBI_SYSCONFIG, l);
|
||||
rfbi.l4_khz = clk_get_rate(clk) / 1000;
|
||||
|
||||
clk_put(clk);
|
||||
|
||||
rev = rfbi_read_reg(RFBI_REVISION);
|
||||
dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
rfbi_runtime_put();
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_ick:
|
||||
rfbi_runtime_put();
|
||||
err_get_rfbi:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
iounmap(rfbi.base);
|
||||
err_ioremap:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omap_rfbihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
iounmap(rfbi.base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rfbi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rfbi_runtime_resume(struct device *dev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = dss_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dss;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dispc;
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_dispc:
|
||||
dss_runtime_put();
|
||||
err_get_dss:
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rfbi_pm_ops = {
|
||||
.runtime_suspend = rfbi_runtime_suspend,
|
||||
.runtime_resume = rfbi_runtime_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver omap_rfbihw_driver = {
|
||||
.probe = omap_rfbihw_probe,
|
||||
.remove = omap_rfbihw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_rfbi",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &rfbi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -20,13 +20,11 @@
|
||||
#define DSS_SUBSYS_NAME "SDI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
#include "dss.h"
|
||||
|
||||
static struct {
|
||||
@@ -60,14 +58,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
goto err0;
|
||||
goto err_start_dev;
|
||||
}
|
||||
|
||||
r = regulator_enable(sdi.vdds_sdi_reg);
|
||||
if (r)
|
||||
goto err1;
|
||||
goto err_reg_enable;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
r = dss_runtime_get();
|
||||
if (r)
|
||||
goto err_get_dss;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
goto err_get_dispc;
|
||||
|
||||
sdi_basic_init(dssdev);
|
||||
|
||||
@@ -80,7 +84,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
r = dss_calc_clock_div(1, t->pixel_clock * 1000,
|
||||
&dss_cinfo, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err2;
|
||||
goto err_calc_clock_div;
|
||||
|
||||
fck = dss_cinfo.fck;
|
||||
lck_div = dispc_cinfo.lck_div;
|
||||
@@ -101,27 +105,34 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
if (r)
|
||||
goto err2;
|
||||
goto err_set_dss_clock_div;
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err2;
|
||||
goto err_set_dispc_clock_div;
|
||||
|
||||
dss_sdi_init(dssdev->phy.sdi.datapairs);
|
||||
r = dss_sdi_enable();
|
||||
if (r)
|
||||
goto err1;
|
||||
goto err_sdi_enable;
|
||||
mdelay(2);
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
err_sdi_enable:
|
||||
err_set_dispc_clock_div:
|
||||
err_set_dss_clock_div:
|
||||
err_calc_clock_div:
|
||||
dispc_runtime_put();
|
||||
err_get_dispc:
|
||||
dss_runtime_put();
|
||||
err_get_dss:
|
||||
regulator_disable(sdi.vdds_sdi_reg);
|
||||
err1:
|
||||
err_reg_enable:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
err_start_dev:
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_sdi_display_enable);
|
||||
@@ -132,7 +143,8 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
dss_sdi_disable();
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
||||
regulator_disable(sdi.vdds_sdi_reg);
|
||||
|
||||
|
||||
+146
-37
@@ -33,11 +33,13 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
/* Venc registers */
|
||||
#define VENC_REV_ID 0x00
|
||||
@@ -292,6 +294,9 @@ static struct {
|
||||
struct mutex venc_lock;
|
||||
u32 wss_data;
|
||||
struct regulator *vdda_dac_reg;
|
||||
|
||||
struct clk *tv_clk;
|
||||
struct clk *tv_dac_clk;
|
||||
} venc;
|
||||
|
||||
static inline void venc_write_reg(int idx, u32 val)
|
||||
@@ -380,14 +385,25 @@ static void venc_reset(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void venc_enable_clocks(int enable)
|
||||
static int venc_runtime_get(void)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
|
||||
DSS_CLK_VIDFCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
|
||||
DSS_CLK_VIDFCK);
|
||||
int r;
|
||||
|
||||
DSSDBG("venc_runtime_get\n");
|
||||
|
||||
r = pm_runtime_get_sync(&venc.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
static void venc_runtime_put(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("venc_runtime_put\n");
|
||||
|
||||
r = pm_runtime_put(&venc.pdev->dev);
|
||||
WARN_ON(r < 0);
|
||||
}
|
||||
|
||||
static const struct venc_config *venc_timings_to_config(
|
||||
@@ -406,8 +422,6 @@ static void venc_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
venc_enable_clocks(1);
|
||||
|
||||
venc_reset();
|
||||
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
|
||||
|
||||
@@ -448,8 +462,6 @@ static void venc_power_off(struct omap_dss_device *dssdev)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
regulator_disable(venc.vdda_dac_reg);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -487,6 +499,10 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
r = venc_runtime_get();
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
venc_power_on(dssdev);
|
||||
|
||||
venc.wss_data = 0;
|
||||
@@ -520,6 +536,8 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
venc_power_off(dssdev);
|
||||
|
||||
venc_runtime_put();
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
omap_dss_stop_device(dssdev);
|
||||
@@ -538,20 +556,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
|
||||
return venc_panel_enable(dssdev);
|
||||
}
|
||||
|
||||
static enum omap_dss_update_mode venc_get_update_mode(
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
return OMAP_DSS_UPDATE_AUTO;
|
||||
}
|
||||
|
||||
static int venc_set_update_mode(struct omap_dss_device *dssdev,
|
||||
enum omap_dss_update_mode mode)
|
||||
{
|
||||
if (mode != OMAP_DSS_UPDATE_AUTO)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void venc_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
@@ -598,6 +602,7 @@ static u32 venc_get_wss(struct omap_dss_device *dssdev)
|
||||
static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
|
||||
{
|
||||
const struct venc_config *config;
|
||||
int r;
|
||||
|
||||
DSSDBG("venc_set_wss\n");
|
||||
|
||||
@@ -608,16 +613,19 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
|
||||
/* Invert due to VENC_L21_WC_CTL:INV=1 */
|
||||
venc.wss_data = (wss ^ 0xfffff) << 8;
|
||||
|
||||
venc_enable_clocks(1);
|
||||
r = venc_runtime_get();
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
|
||||
venc.wss_data);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
venc_runtime_put();
|
||||
|
||||
err:
|
||||
mutex_unlock(&venc.venc_lock);
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver venc_driver = {
|
||||
@@ -632,9 +640,6 @@ static struct omap_dss_driver venc_driver = {
|
||||
.get_resolution = omapdss_default_get_resolution,
|
||||
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
|
||||
|
||||
.set_update_mode = venc_set_update_mode,
|
||||
.get_update_mode = venc_get_update_mode,
|
||||
|
||||
.get_timings = venc_get_timings,
|
||||
.set_timings = venc_set_timings,
|
||||
.check_timings = venc_check_timings,
|
||||
@@ -673,7 +678,8 @@ void venc_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
|
||||
|
||||
venc_enable_clocks(1);
|
||||
if (venc_runtime_get())
|
||||
return;
|
||||
|
||||
DUMPREG(VENC_F_CONTROL);
|
||||
DUMPREG(VENC_VIDOUT_CTRL);
|
||||
@@ -717,16 +723,56 @@ void venc_dump_regs(struct seq_file *s)
|
||||
DUMPREG(VENC_OUTPUT_CONTROL);
|
||||
DUMPREG(VENC_OUTPUT_TEST);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
venc_runtime_put();
|
||||
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
static int venc_get_clocks(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get(&pdev->dev, "fck");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get fck\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
venc.tv_clk = clk;
|
||||
|
||||
if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
|
||||
if (cpu_is_omap34xx() || cpu_is_omap3630())
|
||||
clk = clk_get(&pdev->dev, "dss_96m_fck");
|
||||
else
|
||||
clk = clk_get(&pdev->dev, "tv_dac_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get tv_dac_clk\n");
|
||||
clk_put(venc.tv_clk);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
} else {
|
||||
clk = NULL;
|
||||
}
|
||||
|
||||
venc.tv_dac_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void venc_put_clocks(void)
|
||||
{
|
||||
if (venc.tv_clk)
|
||||
clk_put(venc.tv_clk);
|
||||
if (venc.tv_dac_clk)
|
||||
clk_put(venc.tv_dac_clk);
|
||||
}
|
||||
|
||||
/* VENC HW IP initialisation */
|
||||
static int omap_venchw_probe(struct platform_device *pdev)
|
||||
{
|
||||
u8 rev_id;
|
||||
struct resource *venc_mem;
|
||||
int r;
|
||||
|
||||
venc.pdev = pdev;
|
||||
|
||||
@@ -737,22 +783,40 @@ static int omap_venchw_probe(struct platform_device *pdev)
|
||||
venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
|
||||
if (!venc_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM VENC\n");
|
||||
return -EINVAL;
|
||||
r = -EINVAL;
|
||||
goto err_ioremap;
|
||||
}
|
||||
venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
|
||||
if (!venc.base) {
|
||||
DSSERR("can't ioremap VENC\n");
|
||||
return -ENOMEM;
|
||||
r = -ENOMEM;
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
venc_enable_clocks(1);
|
||||
r = venc_get_clocks(pdev);
|
||||
if (r)
|
||||
goto err_get_clk;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
r = venc_runtime_get();
|
||||
if (r)
|
||||
goto err_get_venc;
|
||||
|
||||
rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
|
||||
dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
venc_runtime_put();
|
||||
|
||||
return omap_dss_register_driver(&venc_driver);
|
||||
|
||||
err_get_venc:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
venc_put_clocks();
|
||||
err_get_clk:
|
||||
iounmap(venc.base);
|
||||
err_ioremap:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omap_venchw_remove(struct platform_device *pdev)
|
||||
@@ -763,16 +827,61 @@ static int omap_venchw_remove(struct platform_device *pdev)
|
||||
}
|
||||
omap_dss_unregister_driver(&venc_driver);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
venc_put_clocks();
|
||||
|
||||
iounmap(venc.base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int venc_runtime_suspend(struct device *dev)
|
||||
{
|
||||
if (venc.tv_dac_clk)
|
||||
clk_disable(venc.tv_dac_clk);
|
||||
clk_disable(venc.tv_clk);
|
||||
|
||||
dispc_runtime_put();
|
||||
dss_runtime_put();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int venc_runtime_resume(struct device *dev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = dss_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dss;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r < 0)
|
||||
goto err_get_dispc;
|
||||
|
||||
clk_enable(venc.tv_clk);
|
||||
if (venc.tv_dac_clk)
|
||||
clk_enable(venc.tv_dac_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_dispc:
|
||||
dss_runtime_put();
|
||||
err_get_dss:
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops venc_pm_ops = {
|
||||
.runtime_suspend = venc_runtime_suspend,
|
||||
.runtime_resume = venc_runtime_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver omap_venchw_driver = {
|
||||
.probe = omap_venchw_probe,
|
||||
.remove = omap_venchw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_venc",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &venc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -316,68 +316,68 @@ int omapfb_update_window(struct fb_info *fbi,
|
||||
}
|
||||
EXPORT_SYMBOL(omapfb_update_window);
|
||||
|
||||
static int omapfb_set_update_mode(struct fb_info *fbi,
|
||||
int omapfb_set_update_mode(struct fb_info *fbi,
|
||||
enum omapfb_update_mode mode)
|
||||
{
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
enum omap_dss_update_mode um;
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_device *fbdev = ofbi->fbdev;
|
||||
struct omapfb_display_data *d;
|
||||
int r;
|
||||
|
||||
if (!display || !display->driver->set_update_mode)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mode) {
|
||||
case OMAPFB_UPDATE_DISABLED:
|
||||
um = OMAP_DSS_UPDATE_DISABLED;
|
||||
break;
|
||||
|
||||
case OMAPFB_AUTO_UPDATE:
|
||||
um = OMAP_DSS_UPDATE_AUTO;
|
||||
break;
|
||||
|
||||
case OMAPFB_MANUAL_UPDATE:
|
||||
um = OMAP_DSS_UPDATE_MANUAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = display->driver->set_update_mode(display, um);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omapfb_get_update_mode(struct fb_info *fbi,
|
||||
enum omapfb_update_mode *mode)
|
||||
{
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
enum omap_dss_update_mode m;
|
||||
|
||||
if (!display)
|
||||
return -EINVAL;
|
||||
|
||||
if (!display->driver->get_update_mode) {
|
||||
*mode = OMAPFB_AUTO_UPDATE;
|
||||
if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
|
||||
return -EINVAL;
|
||||
|
||||
omapfb_lock(fbdev);
|
||||
|
||||
d = get_display_data(fbdev, display);
|
||||
|
||||
if (d->update_mode == mode) {
|
||||
omapfb_unlock(fbdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = display->driver->get_update_mode(display);
|
||||
r = 0;
|
||||
|
||||
switch (m) {
|
||||
case OMAP_DSS_UPDATE_DISABLED:
|
||||
*mode = OMAPFB_UPDATE_DISABLED;
|
||||
break;
|
||||
case OMAP_DSS_UPDATE_AUTO:
|
||||
*mode = OMAPFB_AUTO_UPDATE;
|
||||
break;
|
||||
case OMAP_DSS_UPDATE_MANUAL:
|
||||
*mode = OMAPFB_MANUAL_UPDATE;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
if (mode == OMAPFB_AUTO_UPDATE)
|
||||
omapfb_start_auto_update(fbdev, display);
|
||||
else /* MANUAL_UPDATE */
|
||||
omapfb_stop_auto_update(fbdev, display);
|
||||
|
||||
d->update_mode = mode;
|
||||
} else { /* AUTO_UPDATE */
|
||||
if (mode == OMAPFB_MANUAL_UPDATE)
|
||||
r = -EINVAL;
|
||||
}
|
||||
|
||||
omapfb_unlock(fbdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int omapfb_get_update_mode(struct fb_info *fbi,
|
||||
enum omapfb_update_mode *mode)
|
||||
{
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_device *fbdev = ofbi->fbdev;
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
if (!display)
|
||||
return -EINVAL;
|
||||
|
||||
omapfb_lock(fbdev);
|
||||
|
||||
d = get_display_data(fbdev, display);
|
||||
|
||||
*mode = d->update_mode;
|
||||
|
||||
omapfb_unlock(fbdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ static char *def_vram;
|
||||
static int def_vrfb;
|
||||
static int def_rotate;
|
||||
static int def_mirror;
|
||||
static bool auto_update;
|
||||
static unsigned int auto_update_freq;
|
||||
module_param(auto_update, bool, 0);
|
||||
module_param(auto_update_freq, uint, 0644);
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int omapfb_debug;
|
||||
@@ -1242,6 +1246,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_device *fbdev = ofbi->fbdev;
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
struct omapfb_display_data *d;
|
||||
int r = 0;
|
||||
|
||||
if (!display)
|
||||
@@ -1249,6 +1254,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
||||
|
||||
omapfb_lock(fbdev);
|
||||
|
||||
d = get_display_data(fbdev, display);
|
||||
|
||||
switch (blank) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
|
||||
@@ -1257,6 +1264,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
||||
if (display->driver->resume)
|
||||
r = display->driver->resume(display);
|
||||
|
||||
if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
|
||||
d->update_mode == OMAPFB_AUTO_UPDATE &&
|
||||
!d->auto_update_work_enabled)
|
||||
omapfb_start_auto_update(fbdev, display);
|
||||
|
||||
break;
|
||||
|
||||
case FB_BLANK_NORMAL:
|
||||
@@ -1268,6 +1280,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
||||
if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
goto exit;
|
||||
|
||||
if (d->auto_update_work_enabled)
|
||||
omapfb_stop_auto_update(fbdev, display);
|
||||
|
||||
if (display->driver->suspend)
|
||||
r = display->driver->suspend(display);
|
||||
|
||||
@@ -1724,6 +1739,78 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void omapfb_auto_update_work(struct work_struct *work)
|
||||
{
|
||||
struct omap_dss_device *dssdev;
|
||||
struct omap_dss_driver *dssdrv;
|
||||
struct omapfb_display_data *d;
|
||||
u16 w, h;
|
||||
unsigned int freq;
|
||||
struct omapfb2_device *fbdev;
|
||||
|
||||
d = container_of(work, struct omapfb_display_data,
|
||||
auto_update_work.work);
|
||||
|
||||
dssdev = d->dssdev;
|
||||
dssdrv = dssdev->driver;
|
||||
fbdev = d->fbdev;
|
||||
|
||||
if (!dssdrv || !dssdrv->update)
|
||||
return;
|
||||
|
||||
if (dssdrv->sync)
|
||||
dssdrv->sync(dssdev);
|
||||
|
||||
dssdrv->get_resolution(dssdev, &w, &h);
|
||||
dssdrv->update(dssdev, 0, 0, w, h);
|
||||
|
||||
freq = auto_update_freq;
|
||||
if (freq == 0)
|
||||
freq = 20;
|
||||
queue_delayed_work(fbdev->auto_update_wq,
|
||||
&d->auto_update_work, HZ / freq);
|
||||
}
|
||||
|
||||
void omapfb_start_auto_update(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *display)
|
||||
{
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
if (fbdev->auto_update_wq == NULL) {
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
wq = create_singlethread_workqueue("omapfb_auto_update");
|
||||
|
||||
if (wq == NULL) {
|
||||
dev_err(fbdev->dev, "Failed to create workqueue for "
|
||||
"auto-update\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fbdev->auto_update_wq = wq;
|
||||
}
|
||||
|
||||
d = get_display_data(fbdev, display);
|
||||
|
||||
INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work);
|
||||
|
||||
d->auto_update_work_enabled = true;
|
||||
|
||||
omapfb_auto_update_work(&d->auto_update_work.work);
|
||||
}
|
||||
|
||||
void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *display)
|
||||
{
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
d = get_display_data(fbdev, display);
|
||||
|
||||
cancel_delayed_work_sync(&d->auto_update_work);
|
||||
|
||||
d->auto_update_work_enabled = false;
|
||||
}
|
||||
|
||||
/* initialize fb_info, var, fix to something sane based on the display */
|
||||
static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
|
||||
{
|
||||
@@ -1858,10 +1945,21 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
|
||||
}
|
||||
|
||||
for (i = 0; i < fbdev->num_displays; i++) {
|
||||
if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
|
||||
fbdev->displays[i]->driver->disable(fbdev->displays[i]);
|
||||
struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
|
||||
|
||||
omap_dss_put_device(fbdev->displays[i]);
|
||||
if (fbdev->displays[i].auto_update_work_enabled)
|
||||
omapfb_stop_auto_update(fbdev, dssdev);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
|
||||
dssdev->driver->disable(dssdev);
|
||||
|
||||
omap_dss_put_device(dssdev);
|
||||
}
|
||||
|
||||
if (fbdev->auto_update_wq != NULL) {
|
||||
flush_workqueue(fbdev->auto_update_wq);
|
||||
destroy_workqueue(fbdev->auto_update_wq);
|
||||
fbdev->auto_update_wq = NULL;
|
||||
}
|
||||
|
||||
dev_set_drvdata(fbdev->dev, NULL);
|
||||
@@ -2084,14 +2182,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
|
||||
int r;
|
||||
u8 bpp;
|
||||
struct omap_video_timings timings, temp_timings;
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
|
||||
fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
|
||||
++fbdev->num_bpp_overrides;
|
||||
d = get_display_data(fbdev, display);
|
||||
d->bpp_override = bpp;
|
||||
|
||||
if (display->driver->check_timings) {
|
||||
r = display->driver->check_timings(display, &timings);
|
||||
@@ -2117,14 +2215,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
|
||||
static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
int i;
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
|
||||
|
||||
for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
|
||||
if (dssdev == fbdev->bpp_overrides[i].dssdev)
|
||||
return fbdev->bpp_overrides[i].bpp;
|
||||
}
|
||||
d = get_display_data(fbdev, dssdev);
|
||||
|
||||
if (d->bpp_override != 0)
|
||||
return d->bpp_override;
|
||||
|
||||
return dssdev->driver->get_recommended_bpp(dssdev);
|
||||
}
|
||||
@@ -2156,9 +2254,9 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
|
||||
|
||||
display = NULL;
|
||||
for (i = 0; i < fbdev->num_displays; ++i) {
|
||||
if (strcmp(fbdev->displays[i]->name,
|
||||
if (strcmp(fbdev->displays[i].dssdev->name,
|
||||
display_str) == 0) {
|
||||
display = fbdev->displays[i];
|
||||
display = fbdev->displays[i].dssdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2182,6 +2280,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_driver *dssdrv = dssdev->driver;
|
||||
struct omapfb_display_data *d;
|
||||
int r;
|
||||
|
||||
r = dssdrv->enable(dssdev);
|
||||
@@ -2191,8 +2290,20 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
return r;
|
||||
}
|
||||
|
||||
d = get_display_data(fbdev, dssdev);
|
||||
|
||||
d->fbdev = fbdev;
|
||||
|
||||
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
u16 w, h;
|
||||
|
||||
if (auto_update) {
|
||||
omapfb_start_auto_update(fbdev, dssdev);
|
||||
d->update_mode = OMAPFB_AUTO_UPDATE;
|
||||
} else {
|
||||
d->update_mode = OMAPFB_MANUAL_UPDATE;
|
||||
}
|
||||
|
||||
if (dssdrv->enable_te) {
|
||||
r = dssdrv->enable_te(dssdev, 1);
|
||||
if (r) {
|
||||
@@ -2201,16 +2312,6 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdrv->set_update_mode) {
|
||||
r = dssdrv->set_update_mode(dssdev,
|
||||
OMAP_DSS_UPDATE_MANUAL);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev,
|
||||
"Failed to set update mode\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
dssdrv->get_resolution(dssdev, &w, &h);
|
||||
r = dssdrv->update(dssdev, 0, 0, w, h);
|
||||
if (r) {
|
||||
@@ -2219,15 +2320,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (dssdrv->set_update_mode) {
|
||||
r = dssdrv->set_update_mode(dssdev,
|
||||
OMAP_DSS_UPDATE_AUTO);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev,
|
||||
"Failed to set update mode\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
d->update_mode = OMAPFB_AUTO_UPDATE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2275,6 +2368,8 @@ static int omapfb_probe(struct platform_device *pdev)
|
||||
fbdev->num_displays = 0;
|
||||
dssdev = NULL;
|
||||
for_each_dss_dev(dssdev) {
|
||||
struct omapfb_display_data *d;
|
||||
|
||||
omap_dss_get_device(dssdev);
|
||||
|
||||
if (!dssdev->driver) {
|
||||
@@ -2282,7 +2377,12 @@ static int omapfb_probe(struct platform_device *pdev)
|
||||
r = -ENODEV;
|
||||
}
|
||||
|
||||
fbdev->displays[fbdev->num_displays++] = dssdev;
|
||||
d = &fbdev->displays[fbdev->num_displays++];
|
||||
d->dssdev = dssdev;
|
||||
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
|
||||
d->update_mode = OMAPFB_MANUAL_UPDATE;
|
||||
else
|
||||
d->update_mode = OMAPFB_AUTO_UPDATE;
|
||||
}
|
||||
|
||||
if (r)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user