Commit 6cd05430 authored by Tomi Valkeinen's avatar Tomi Valkeinen

Merge miscellaneous omapdss changes

Most important changes:

* Remove OMAP4 HDMI gpio handling from board files
* Add vdda_hdmi_dac supply for HDMI to twl-common.c
* Calculate DSI clocks dynamically
* Remove DSS clock dividers from 4430sdp board file
* vram.c no longer uses OMAP's sDMA to clear the memory
* Fifomerge has been reverted
* Swap GFX and WB fifos to avoid underflows
parents c50e86ce b2f5976c
......@@ -601,29 +601,6 @@ static void __init omap_sfh7741prox_init(void)
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
}
static struct gpio sdp4430_hdmi_gpios[] = {
{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
{
int status;
status = gpio_request_array(sdp4430_hdmi_gpios,
ARRAY_SIZE(sdp4430_hdmi_gpios));
if (status)
pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
return status;
}
static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
}
static struct nokia_dsi_panel_data dsi1_panel = {
.name = "taal",
.reset_gpio = 102,
......@@ -644,29 +621,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
.phy.dsi = {
.module = 0,
},
.clocks = {
.dispc = {
.channel = {
/* Logic Clock = 172.8 MHz */
.lck_div = 1,
/* Pixel Clock = 34.56 MHz */
.pck_div = 5,
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
},
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
},
.dsi = {
.regn = 16, /* Fint = 2.4 MHz */
.regm = 180, /* DDR Clock = 216 MHz */
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
},
},
.channel = OMAP_DSS_CHANNEL_LCD,
};
......@@ -691,33 +645,12 @@ static struct omap_dss_device sdp4430_lcd2_device = {
.module = 1,
},
.clocks = {
.dispc = {
.channel = {
/* Logic Clock = 172.8 MHz */
.lck_div = 1,
/* Pixel Clock = 34.56 MHz */
.pck_div = 5,
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
},
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
},
.dsi = {
.regn = 16, /* Fint = 2.4 MHz */
.regm = 180, /* DDR Clock = 216 MHz */
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
},
},
.channel = OMAP_DSS_CHANNEL_LCD2,
};
static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
.ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
......@@ -725,8 +658,6 @@ static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
.type = OMAP_DISPLAY_TYPE_HDMI,
.platform_enable = sdp4430_panel_enable_hdmi,
.platform_disable = sdp4430_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
.data = &sdp4430_hdmi_data,
};
......
......@@ -408,30 +408,9 @@ static struct omap_dss_device omap4_panda_dvi_device = {
.channel = OMAP_DSS_CHANNEL_LCD2,
};
static struct gpio panda_hdmi_gpios[] = {
{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
{
int status;
status = gpio_request_array(panda_hdmi_gpios,
ARRAY_SIZE(panda_hdmi_gpios));
if (status)
pr_err("Cannot request HDMI GPIOs\n");
return status;
}
static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
}
static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
.ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
......@@ -439,8 +418,6 @@ static struct omap_dss_device omap4_panda_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
.type = OMAP_DISPLAY_TYPE_HDMI,
.platform_enable = omap4_panda_panel_enable_hdmi,
.platform_disable = omap4_panda_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
.data = &omap4_panda_hdmi_data,
};
......
......@@ -258,6 +258,10 @@ static struct twl4030_usb_data omap4_usb_pdata = {
.phy_suspend = omap4430_phy_suspend,
};
static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
};
static struct regulator_init_data omap4_vdac_idata = {
.constraints = {
.min_uV = 1800000,
......@@ -267,6 +271,8 @@ static struct regulator_init_data omap4_vdac_idata = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
.consumer_supplies = omap4_vdda_hdmi_dac_supplies,
.supply_regulator = "V2V1",
};
......
......@@ -27,7 +27,6 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <plat/dma.h>
#include "omapfb.h"
#define HWA742_REV_CODE_REG 0x0
......
......@@ -28,7 +28,6 @@
#include <linux/gpio.h>
#include <plat/board-ams-delta.h>
#include <mach/hardware.h>
#include "omapfb.h"
......
......@@ -23,7 +23,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <plat/fpga.h>
#include "omapfb.h"
static int palmte_panel_init(struct lcd_panel *panel,
......
......@@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
* LCD controller and LCD DMA
* ---------------------------------------------------------------------------
*/
/* Lookup table to map elem size to elem type. */
static const int dma_elem_type[] = {
0,
OMAP_DMA_DATA_TYPE_S8,
OMAP_DMA_DATA_TYPE_S16,
0,
OMAP_DMA_DATA_TYPE_S32,
};
/*
* Allocate resources needed for LCD controller and LCD DMA operations. Video
* memory is allocated from system memory according to the virtual display
......
......@@ -489,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings.y_res = 480;
dssdev->ctrl.pixel_size = 16;
dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
memset(&props, 0, sizeof(props));
props.max_brightness = 127;
......
This diff is collapsed.
......@@ -119,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
}
if (gpio_is_valid(ddata->pd_gpio)) {
r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
"tfp410 pd");
r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
GPIOF_OUT_INIT_LOW, "tfp410 pd");
if (r) {
dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
ddata->pd_gpio);
......@@ -135,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
if (!adapter) {
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
i2c_bus_num);
r = -EINVAL;
goto err_i2c;
return -EINVAL;
}
ddata->i2c_adapter = adapter;
......@@ -145,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
dev_set_drvdata(&dssdev->dev, ddata);
return 0;
err_i2c:
if (gpio_is_valid(ddata->pd_gpio))
gpio_free(ddata->pd_gpio);
return r;
}
static void __exit tfp410_remove(struct omap_dss_device *dssdev)
......@@ -160,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev)
if (ddata->i2c_adapter)
i2c_put_adapter(ddata->i2c_adapter);
if (gpio_is_valid(ddata->pd_gpio))
gpio_free(ddata->pd_gpio);
dev_set_drvdata(&dssdev->dev, NULL);
mutex_unlock(&ddata->lock);
......
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
manager.o overlay.o apply.o
manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
......
......@@ -111,9 +111,6 @@ static struct {
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
bool fifo_merge_dirty;
bool fifo_merge;
bool irq_enabled;
} dss_data;
......@@ -677,40 +674,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
mp->shadow_extra_info_dirty = true;
}
static void dss_write_regs_common(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
int i;
if (!dss_data.fifo_merge_dirty)
return;
for (i = 0; i < num_mgrs; ++i) {
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);
if (mp->enabled) {
if (dss_data.fifo_merge_dirty) {
dispc_enable_fifomerge(dss_data.fifo_merge);
dss_data.fifo_merge_dirty = false;
}
if (mp->updating)
mp->shadow_info_dirty = true;
}
}
}
static void dss_write_regs(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
int i;
dss_write_regs_common();
for (i = 0; i < num_mgrs; ++i) {
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
......@@ -799,8 +767,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
dss_mgr_write_regs(mgr);
dss_mgr_write_regs_extra(mgr);
dss_write_regs_common();
mp->updating = true;
if (!dss_data.irq_enabled && need_isr())
......@@ -984,20 +950,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
op->extra_info_dirty = true;
}
static void dss_apply_fifo_merge(bool use_fifo_merge)
{
if (dss_data.fifo_merge == use_fifo_merge)
return;
dss_data.fifo_merge = use_fifo_merge;
dss_data.fifo_merge_dirty = true;
}
static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
bool use_fifo_merge)
static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
u32 fifo_low, fifo_high;
bool use_fifo_merge = false;
if (!op->enabled && !op->enabling)
return;
......@@ -1008,8 +965,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
}
static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
bool use_fifo_merge)
static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
{
struct omap_overlay *ovl;
struct mgr_priv_data *mp;
......@@ -1020,10 +976,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
return;
list_for_each_entry(ovl, &mgr->overlays, list)
dss_ovl_setup_fifo(ovl, use_fifo_merge);
dss_ovl_setup_fifo(ovl);
}
static void dss_setup_fifos(bool use_fifo_merge)
static void dss_setup_fifos(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
struct omap_overlay_manager *mgr;
......@@ -1031,91 +987,15 @@ static void dss_setup_fifos(bool use_fifo_merge)
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
dss_mgr_setup_fifos(mgr, use_fifo_merge);
dss_mgr_setup_fifos(mgr);
}
}
static int get_num_used_managers(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
int i;
int enabled_mgrs;
enabled_mgrs = 0;
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
mp = get_mgr_priv(mgr);
if (!mp->enabled)
continue;
enabled_mgrs++;
}
return enabled_mgrs;
}
static int get_num_used_overlays(void)
{
const int num_ovls = omap_dss_get_num_overlays();
struct omap_overlay *ovl;
struct ovl_priv_data *op;
struct mgr_priv_data *mp;
int i;
int enabled_ovls;
enabled_ovls = 0;
for (i = 0; i < num_ovls; ++i) {
ovl = omap_dss_get_overlay(i);
op = get_ovl_priv(ovl);
if (!op->enabled && !op->enabling)
continue;
mp = get_mgr_priv(ovl->manager);
if (!mp->enabled)
continue;
enabled_ovls++;
}
return enabled_ovls;
}
static bool get_use_fifo_merge(void)
{
int enabled_mgrs = get_num_used_managers();
int enabled_ovls = get_num_used_overlays();
if (!dss_has_feature(FEAT_FIFO_MERGE))
return false;
/*
* In theory the only requirement for fifomerge is enabled_ovls <= 1.
* However, if we have two managers enabled and set/unset the fifomerge,
* we need to set the GO bits in particular sequence for the managers,
* and wait in between.
*
* This is rather difficult as new apply calls can happen at any time,
* so we simplify the problem by requiring also that enabled_mgrs <= 1.
* In practice this shouldn't matter, because when only one overlay is
* enabled, most likely only one output is enabled.
*/
return enabled_mgrs <= 1 && enabled_ovls <= 1;
}
int dss_mgr_enable(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
int r;
bool fifo_merge;
mutex_lock(&apply_lock);
......@@ -1133,23 +1013,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
goto err;
}
/* step 1: setup fifos/fifomerge before enabling the manager */
fifo_merge = get_use_fifo_merge();
dss_setup_fifos(fifo_merge);
dss_apply_fifo_merge(fifo_merge);
dss_setup_fifos();
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
/* wait until fifo config is in */
wait_pending_extra_info_updates();
/* step 2: enable the manager */
spin_lock_irqsave(&data_lock, flags);
if (!mgr_manual_update(mgr))
mp->updating = true;
......@@ -1174,7 +1042,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
bool fifo_merge;
mutex_lock(&apply_lock);
......@@ -1189,16 +1056,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mp->updating = false;
mp->enabled = false;
fifo_merge = get_use_fifo_merge();
dss_setup_fifos(fifo_merge);
dss_apply_fifo_merge(fifo_merge);
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
wait_pending_extra_info_updates();
out:
mutex_unlock(&apply_lock);
}
......@@ -1314,21 +1173,19 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
{
unsigned long flags;
mutex_lock(&apply_lock);
struct mgr_priv_data *mp = get_mgr_priv(mgr);
spin_lock_irqsave(&data_lock, flags);
dss_apply_mgr_timings(mgr, timings);
dss_write_regs();
dss_set_go_bits();
if (mp->updating) {
DSSERR("cannot set timings for %s: manager needs to be disabled\n",
mgr->name);
goto out;
}
dss_apply_mgr_timings(mgr, timings);
out:
spin_unlock_irqrestore(&data_lock, flags);
wait_pending_extra_info_updates();
mutex_unlock(&apply_lock);
}
static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
......@@ -1346,7 +1203,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
unsigned long flags;
struct mgr_priv_data *mp = get_mgr_priv(mgr);
mutex_lock(&apply_lock);
spin_lock_irqsave(&data_lock, flags);
if (mp->enabled) {
DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
......@@ -1354,19 +1211,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
goto out;
}
spin_lock_irqsave(&data_lock, flags);
dss_apply_mgr_lcd_config(mgr, config);
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
wait_pending_extra_info_updates();
out:
mutex_unlock(&apply_lock);
spin_unlock_irqrestore(&data_lock, flags);
}
int dss_ovl_set_info(struct omap_overlay *ovl,
......@@ -1483,6 +1330,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
goto err;
}
spin_unlock_irqrestore(&data_lock, flags);
/* wait for pending extra_info updates to ensure the ovl is disabled */
wait_pending_extra_info_updates();
spin_lock_irqsave(&data_lock, flags);
op->channel = -1;
ovl->manager = NULL;
......@@ -1517,7 +1371,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
bool fifo_merge;
int r;
mutex_lock(&apply_lock);
......@@ -1543,22 +1396,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err2;
}
/* step 1: configure fifos/fifomerge for currently enabled ovls */
fifo_merge = get_use_fifo_merge();
dss_setup_fifos(fifo_merge);
dss_apply_fifo_merge(fifo_merge);
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
/* wait for fifo configs to go in */
wait_pending_extra_info_updates();
/* step 2: enable the overlay */
spin_lock_irqsave(&data_lock, flags);
dss_setup_fifos();
op->enabling = false;
dss_apply_ovl_enable(ovl, true);
......@@ -1568,9 +1406,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
spin_unlock_irqrestore(&data_lock, flags);
/* wait for overlay to be enabled */
wait_pending_extra_info_updates();
mutex_unlock(&apply_lock);
return 0;
......@@ -1586,7 +1421,6 @@ int dss_ovl_disable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
bool fifo_merge;
int r;
mutex_lock(&apply_lock);
......@@ -1601,34 +1435,14 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto err;
}
/* step 1: disable the overlay */
spin_lock_irqsave(&data_lock, flags);
dss_apply_ovl_enable(ovl, false);
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
/* wait for the overlay to be disabled */
wait_pending_extra_info_updates();
/* step 2: configure fifos/fifomerge */
spin_lock_irqsave(&data_lock, flags);
fifo_merge = get_use_fifo_merge();
dss_setup_fifos(fifo_merge);
dss_apply_fifo_merge(fifo_merge);
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
/* wait for fifo config to go in */
wait_pending_extra_info_updates();
mutex_unlock(&apply_lock);
return 0;
......
......@@ -37,8 +37,6 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <plat/clock.h>
#include <video/omapdss.h>
#include "dss.h"
......@@ -96,8 +94,14 @@ struct dispc_features {
u16 pos_x, unsigned long *core_clk);
unsigned long (*calc_core_clk) (enum omap_channel channel,
u16 width, u16 height, u16 out_width, u16 out_height);
u8 num_fifos;
/* swap GFX & WB fifos */
bool gfx_fifo_workaround:1;
};
#define DISPC_MAX_NR_FIFOS 5
static struct {
struct platform_device *pdev;
void __iomem *base;
......@@ -107,7 +111,9 @@ static struct {
int irq;
struct clk *dss_clk;
u32 fifo_size[MAX_DSS_OVERLAYS];
u32 fifo_size[DISPC_MAX_NR_FIFOS];
/* maps which plane is using a fifo. fifo-id -> plane-id */
int fifo_assignment[DISPC_MAX_NR_FIFOS];
spinlock_t irq_lock;
u32 irq_error_mask;
......@@ -1063,10 +1069,10 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
dispc_write_reg(DISPC_SIZE_MGR(channel), val);
}
static void dispc_read_plane_fifo_sizes(void)
static void dispc_init_fifos(void)
{
u32 size;
int plane;
int fifo;
u8 start, end;
u32 unit;
......@@ -1074,16 +1080,53 @@ static void dispc_read_plane_fifo_sizes(void)
dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
size *= unit;
dispc.fifo_size[plane] = size;
dispc.fifo_size[fifo] = size;
/*
* By default fifos are mapped directly to overlays, fifo 0 to
* ovl 0, fifo 1 to ovl 1, etc.
*/
dispc.fifo_assignment[fifo] = fifo;
}
/*
* The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
* causes problems with certain use cases, like using the tiler in 2D
* mode. The below hack swaps the fifos of GFX and WB planes, thus
* giving GFX plane a larger fifo. WB but should work fine with a
* smaller fifo.
*/
if (dispc.feat->gfx_fifo_workaround) {
u32 v;
v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
}
}
static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
{
return dispc.fifo_size[plane];
int fifo;
u32 size = 0;
for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
if (dispc.fifo_assignment[fifo] == plane)
size += dispc.fifo_size[fifo];
}
return size;
}
void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
......@@ -3710,7 +3753,7 @@ static void _omap_dispc_initial_config(void)
dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
dispc_read_plane_fifo_sizes();
dispc_init_fifos();
dispc_configure_burst_sizes();
......@@ -3726,6 +3769,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.hp_max = 256,
.calc_scaling = dispc_ovl_calc_scaling_24xx,
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
......@@ -3737,6 +3781,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.hp_max = 256,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
......@@ -3748,6 +3793,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.hp_max = 4096,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
......@@ -3759,6 +3805,8 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.hp_max = 4096,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
.gfx_fifo_workaround = true,
};
static int __init dispc_init_features(struct device *dev)
......
......@@ -36,6 +36,7 @@
#define DISPC_CONTROL2 0x0238
#define DISPC_CONFIG2 0x0620
#define DISPC_DIVISOR 0x0804
#define DISPC_GLOBAL_BUFFER 0x0800
#define DISPC_CONTROL3 0x0848
#define DISPC_CONFIG3 0x084C
......@@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
return 0x014C;
case OMAP_DSS_VIDEO3:
return 0x0300;
case OMAP_DSS_WB:
return 0x0500;
default:
BUG();
return 0;
......@@ -517,6 +520,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0018;
case OMAP_DSS_VIDEO3:
case OMAP_DSS_WB:
return 0x0088;
default:
BUG();
......
......@@ -142,7 +142,11 @@ static ssize_t display_timings_store(struct device *dev,
if (r)
return r;
dssdev->driver->disable(dssdev);
dssdev->driver->set_timings(dssdev, &t);
r = dssdev->driver->enable(dssdev);
if (r)
return r;
return size;
}
......
......@@ -31,7 +31,6 @@
#include <linux/regulator/consumer.h>
#include <video/omapdss.h>
#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
......@@ -278,26 +277,12 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
DSSDBG("dpi_set_timings\n");
mutex_lock(&dpi.lock);
dpi.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
r = dispc_runtime_get();
if (r)
return;
dpi_set_mode(dssdev);
dispc_runtime_put();
} else {
dss_mgr_set_timings(dssdev->manager, timings);
}
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_set_timings);
......
......@@ -41,7 +41,6 @@
#include <video/omapdss.h>
#include <video/mipi_display.h>
#include <plat/clock.h>
#include "dss.h"
#include "dss_features.h"
......@@ -1454,6 +1453,68 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
return 0;
}
static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
unsigned long req_clk, struct dsi_clock_info *cinfo)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dsi_clock_info cur, best;
unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck;
unsigned long req_clkin4ddr;
DSSDBG("dsi_pll_calc_ddrfreq\n");
dss_sys_clk = clk_get_rate(dsi->sys_clk);
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
memset(&best, 0, sizeof(best));
memset(&cur, 0, sizeof(cur));
cur.clkin = dss_sys_clk;
req_clkin4ddr = req_clk * 4;
for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
cur.fint = cur.clkin / cur.regn;
if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
continue;
/* DSIPHY(MHz) = (2 * regm / regn) * clkin */
for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
unsigned long a, b;
a = 2 * cur.regm * (cur.clkin/1000);
b = cur.regn;
cur.clkin4ddr = a / b * 1000;
if (cur.clkin4ddr > 1800 * 1000 * 1000)
break;
if (abs(cur.clkin4ddr - req_clkin4ddr) <
abs(best.clkin4ddr - req_clkin4ddr)) {
best = cur;
DSSDBG("best %ld\n", best.clkin4ddr);
}
if (cur.clkin4ddr == req_clkin4ddr)
goto found;
}
}
found:
best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck);
best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc;
best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck);
best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi;
if (cinfo)
*cinfo = best;
return 0;
}
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo)
{
......@@ -4110,6 +4171,70 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_dsi_configure_pins);
int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
unsigned long ddr_clk, unsigned long lp_clk)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dsi_clock_info cinfo;
struct dispc_clock_info dispc_cinfo;
unsigned lp_clk_div;
unsigned long dsi_fclk;
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
unsigned long pck;
int r;
DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
mutex_lock(&dsi->lock);
r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo);
if (r)
goto err;
dssdev->clocks.dsi.regn = cinfo.regn;
dssdev->clocks.dsi.regm = cinfo.regm;
dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
/* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
DSSDBG("finding dispc dividers for pck %lu\n", pck);
dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
dssdev->clocks.dispc.channel.lcd_clk_src =
dsi->module_id == 0 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
dssdev->clocks.dsi.dsi_fclk_src =
dsi->module_id == 0 ?
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
mutex_unlock(&dsi->lock);
return 0;
err:
mutex_unlock(&dsi->lock);
return r;
}
EXPORT_SYMBOL(omapdss_dsi_set_clocks);
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
......@@ -4740,11 +4865,6 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
DSSDBG("DSI init\n");
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
}
if (dsi->vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
......
......@@ -36,7 +36,6 @@
#include <video/omapdss.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include "dss.h"
#include "dss_features.h"
......
......@@ -254,6 +254,10 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
return false;
}
int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
struct platform_device *pdev);
void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
void dss_uninit_overlays(struct platform_device *pdev);
......@@ -265,6 +269,9 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
const struct omap_video_timings *mgr_timings);
bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
enum omap_color_mode mode);
int dss_overlay_kobj_init(struct omap_overlay *ovl,
struct platform_device *pdev);
void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
/* DSS */
int dss_init_platform_driver(void) __init;
......
......@@ -326,6 +326,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[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 },
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
......@@ -341,6 +342,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[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 },
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
......
......@@ -92,6 +92,7 @@ enum dss_range_param {
FEAT_PARAM_DSIPLL_REGM_DSI,
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DSI_FCK,
FEAT_PARAM_DOWNSCALE,
FEAT_PARAM_LINEWIDTH,
FEAT_PARAM_MGR_WIDTH,
......
......@@ -32,6 +32,8 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <video/omapdss.h>
#include "ti_hdmi.h"
......@@ -61,6 +63,11 @@ static struct {
struct hdmi_ip_data ip_data;
struct clk *sys_clk;
struct regulator *vdda_hdmi_dac_reg;
int ct_cp_hpd_gpio;
int ls_oe_gpio;
int hpd_gpio;
} hdmi;
/*
......@@ -314,12 +321,47 @@ static void hdmi_runtime_put(void)
static int __init hdmi_init_display(struct omap_dss_device *dssdev)
{
int r;
struct gpio gpios[] = {
{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
};
DSSDBG("init_display\n");
dss_init_hdmi_ip_ops(&hdmi.ip_data);
if (hdmi.vdda_hdmi_dac_reg == NULL) {
struct regulator *reg;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
return PTR_ERR(reg);
}
hdmi.vdda_hdmi_dac_reg = reg;
}
r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
if (r)
return r;
return 0;
}
static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
{
DSSDBG("uninit_display\n");
gpio_free(hdmi.ct_cp_hpd_gpio);
gpio_free(hdmi.ls_oe_gpio);
gpio_free(hdmi.hpd_gpio);
}
static const struct hdmi_config *hdmi_find_timing(
const struct hdmi_config *timings_arr,
int len)
......@@ -462,9 +504,19 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
struct omap_video_timings *p;
unsigned long phy;
gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
gpio_set_value(hdmi.ls_oe_gpio, 1);
/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
udelay(300);
r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
if (r)
goto err_vdac_enable;
r = hdmi_runtime_get();
if (r)
return r;
goto err_runtime_get;
dss_mgr_disable(dssdev->manager);
......@@ -482,7 +534,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
if (r) {
DSSDBG("Failed to lock PLL\n");
goto err;
goto err_pll_enable;
}
r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
......@@ -526,8 +578,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
err_phy_enable:
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err:
err_pll_enable:
hdmi_runtime_put();
err_runtime_get:
regulator_disable(hdmi.vdda_hdmi_dac_reg);
err_vdac_enable:
gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
gpio_set_value(hdmi.ls_oe_gpio, 0);
return -EIO;
}
......@@ -539,6 +596,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
hdmi_runtime_put();
regulator_disable(hdmi.vdda_hdmi_dac_reg);
gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
gpio_set_value(hdmi.ls_oe_gpio, 0);
}
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
......@@ -570,18 +632,6 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
if (t != NULL)
hdmi.ip_data.cfg = *t;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
int r;
hdmi_power_off(dssdev);
r = hdmi_power_on(dssdev);
if (r)
DSSERR("failed to power on device\n");
} else {
dss_mgr_set_timings(dssdev->manager, &t->timings);
}
mutex_unlock(&hdmi.lock);
}
......@@ -637,7 +687,6 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_hdmi_data *priv = dssdev->data;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
......@@ -650,7 +699,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
r = omap_dss_start_device(dssdev);
if (r) {
......@@ -658,26 +707,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r) {
DSSERR("failed to enable GPIO's\n");
goto err1;
}
}
r = hdmi_power_on(dssdev);
if (r) {
DSSERR("failed to power on device\n");
goto err2;
goto err1;
}
mutex_unlock(&hdmi.lock);
return 0;
err2:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
err1:
omap_dss_stop_device(dssdev);
err0:
......@@ -693,9 +731,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
hdmi_power_off(dssdev);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omap_dss_stop_device(dssdev);
mutex_unlock(&hdmi.lock);
......@@ -873,10 +908,15 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
struct omap_dss_hdmi_data *priv = dssdev->data;
if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
continue;
hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
hdmi.ls_oe_gpio = priv->ls_oe_gpio;
hdmi.hpd_gpio = priv->hpd_gpio;
r = hdmi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
......@@ -938,8 +978,17 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
return 0;
}
static int __exit hdmi_remove_child(struct device *dev, void *data)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
hdmi_uninit_display(dssdev);
return 0;
}
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
omap_dss_unregister_child_devices(&pdev->dev);
hdmi_panel_exit();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -26,13 +26,11 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/sysfs.h>
#include <linux/kobject.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <video/omapdss.h>
#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
......@@ -40,417 +38,6 @@
static int num_overlays;
static struct omap_overlay *overlays;
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
}
static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n",
ovl->manager ? ovl->manager->name : "<none>");
}
static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
size_t size)
{
int i, r;
struct omap_overlay_manager *mgr = NULL;
struct omap_overlay_manager *old_mgr;
int len = size;
if (buf[size-1] == '\n')
--len;
if (len > 0) {
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
mgr = omap_dss_get_overlay_manager(i);
if (sysfs_streq(buf, mgr->name))
break;
mgr = NULL;
}
}
if (len > 0 && mgr == NULL)
return -EINVAL;
if (mgr)
DSSDBG("manager %s found\n", mgr->name);
if (mgr == ovl->manager)
return size;
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");
goto err;
}
r = old_mgr->apply(old_mgr);
if (r)
goto err;
}
if (mgr) {
r = ovl->set_manager(ovl, mgr);
if (r) {
DSSERR("Failed to attach overlay\n");
goto err;
}
r = mgr->apply(mgr);
if (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)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
info.width, info.height);
}
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
}
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
info.pos_x, info.pos_y);
}
static ssize_t overlay_position_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
char *last;
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.pos_x = simple_strtoul(buf, &last, 10);
++last;
if (last - buf >= size)
return -EINVAL;
info.pos_y = simple_strtoul(last, &last, 10);
r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}
return size;
}
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
info.out_width, info.out_height);
}
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
char *last;
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.out_width = simple_strtoul(buf, &last, 10);
++last;
if (last - buf >= size)
return -EINVAL;
info.out_height = simple_strtoul(last, &last, 10);
r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}
return size;
}
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
}
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
size_t size)
{
int r;
bool enable;
r = strtobool(buf, &enable);
if (r)
return r;
if (enable)
r = ovl->enable(ovl);
else
r = ovl->disable(ovl);
if (r)
return r;
return size;
}
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d\n",
info.global_alpha);
}
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
u8 alpha;
struct omap_overlay_info info;
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
return -ENODEV;
r = kstrtou8(buf, 0, &alpha);
if (r)
return r;
ovl->get_overlay_info(ovl, &info);
info.global_alpha = alpha;
r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}
return size;
}
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d\n",
info.pre_mult_alpha);
}
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
u8 alpha;
struct omap_overlay_info info;
if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
return -ENODEV;
r = kstrtou8(buf, 0, &alpha);
if (r)
return r;
ovl->get_overlay_info(ovl, &info);
info.pre_mult_alpha = alpha;
r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}
return size;
}
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
{
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
}
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
u8 zorder;
struct omap_overlay_info info;
if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
return -ENODEV;
r = kstrtou8(buf, 0, &zorder);
if (r)
return r;
ovl->get_overlay_info(ovl, &info);
info.zorder = zorder;
r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}
return size;
}
struct overlay_attribute {
struct attribute attr;
ssize_t (*show)(struct omap_overlay *, char *);
ssize_t (*store)(struct omap_overlay *, const char *, size_t);
};
#define OVERLAY_ATTR(_name, _mode, _show, _store) \
struct overlay_attribute overlay_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
overlay_manager_show, overlay_manager_store);
static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
overlay_position_show, overlay_position_store);
static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
overlay_output_size_show, overlay_output_size_store);
static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
overlay_enabled_show, overlay_enabled_store);
static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
overlay_global_alpha_show, overlay_global_alpha_store);
static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
overlay_pre_mult_alpha_show,
overlay_pre_mult_alpha_store);
static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
overlay_zorder_show, overlay_zorder_store);
static struct attribute *overlay_sysfs_attrs[] = {
&overlay_attr_name.attr,
&overlay_attr_manager.attr,
&overlay_attr_input_size.attr,
&overlay_attr_screen_width.attr,
&overlay_attr_position.attr,
&overlay_attr_output_size.attr,
&overlay_attr_enabled.attr,
&overlay_attr_global_alpha.attr,
&overlay_attr_pre_mult_alpha.attr,
&overlay_attr_zorder.attr,
NULL
};
static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct omap_overlay *overlay;
struct overlay_attribute *overlay_attr;
overlay = container_of(kobj, struct omap_overlay, kobj);
overlay_attr = container_of(attr, struct overlay_attribute, attr);
if (!overlay_attr->show)
return -ENOENT;
return overlay_attr->show(overlay, buf);
}
static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t size)
{
struct omap_overlay *overlay;
struct overlay_attribute *overlay_attr;
overlay = container_of(kobj, struct omap_overlay, kobj);
overlay_attr = container_of(attr, struct overlay_attribute, attr);
if (!overlay_attr->store)
return -ENOENT;
return overlay_attr->store(overlay, buf, size);
}
static const struct sysfs_ops overlay_sysfs_ops = {
.show = overlay_attr_show,
.store = overlay_attr_store,
};
static struct kobj_type overlay_ktype = {
.sysfs_ops = &overlay_sysfs_ops,
.default_attrs = overlay_sysfs_attrs,
};
int omap_dss_get_num_overlays(void)
{
return num_overlays;
......@@ -512,9 +99,7 @@ void dss_init_overlays(struct platform_device *pdev)
ovl->supported_modes =
dss_feat_get_supported_color_modes(ovl->id);
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
&pdev->dev.kobj, "overlay%d", i);
r = dss_overlay_kobj_init(ovl, pdev);
if (r)
DSSERR("failed to create sysfs file\n");
}
......@@ -595,9 +180,7 @@ void dss_uninit_overlays(struct platform_device *pdev)
for (i = 0; i < num_overlays; ++i) {
struct omap_overlay *ovl = &overlays[i];
kobject_del(&ovl->kobj);
kobject_put(&ovl->kobj);
dss_overlay_kobj_uninit(ovl);
}
kfree(overlays);
......
......@@ -939,7 +939,6 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable);
static int __init rfbi_init_display(struct omap_dss_device *dssdev)
{
rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
return 0;
}
......
......@@ -152,17 +152,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_disable);
void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
sdi.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
omapdss_sdi_display_disable(dssdev);
r = omapdss_sdi_display_enable(dssdev);
if (r)
DSSERR("failed to set new timings\n");
}
}
EXPORT_SYMBOL(omapdss_sdi_set_timings);
......
......@@ -36,7 +36,6 @@
#include <linux/pm_runtime.h>
#include <video/omapdss.h>
#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
......@@ -565,19 +564,6 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
venc.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
int r;
/* turn the venc off and on to get new timings to use */
venc_power_off(dssdev);
r = venc_power_on(dssdev);
if (r)
DSSERR("failed to power on VENC\n");
} else {
dss_mgr_set_timings(dssdev->manager, timings);
}
mutex_unlock(&venc.venc_lock);
}
......
......@@ -1592,6 +1592,20 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
return 0;
}
static void omapfb_clear_fb(struct fb_info *fbi)
{
const struct fb_fillrect rect = {
.dx = 0,
.dy = 0,
.width = fbi->var.xres_virtual,
.height = fbi->var.yres_virtual,
.color = 0,
.rop = ROP_COPY,
};
cfb_fillrect(fbi, &rect);
}
int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
......@@ -1661,6 +1675,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
goto err;
}
omapfb_clear_fb(fbi);
return 0;
err:
omapfb_free_fbmem(fbi);
......@@ -1972,6 +1988,16 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
}
}
for (i = 0; i < fbdev->num_fbs; i++) {
struct fb_info *fbi = fbdev->fbs[i];
struct omapfb_info *ofbi = FB2OFB(fbi);
if (ofbi->region->size == 0)
continue;
omapfb_clear_fb(fbi);
}
/* Enable fb0 */
if (fbdev->num_fbs > 0) {
struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
......
......@@ -34,7 +34,6 @@
#include <asm/setup.h>
#include <plat/vram.h>
#include <plat/dma.h>
#ifdef DEBUG
#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
......@@ -250,59 +249,6 @@ int omap_vram_reserve(unsigned long paddr, size_t size)
}
EXPORT_SYMBOL(omap_vram_reserve);
static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
{
struct completion *compl = data;
complete(compl);
}
static int _omap_vram_clear(u32 paddr, unsigned pages)
{
struct completion compl;
unsigned elem_count;
unsigned frame_count;
int r;
int lch;
init_completion(&compl);
r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
_omap_vram_dma_cb,
&compl, &lch);
if (r) {
pr_err("VRAM: request_dma failed for memory clear\n");
return -EBUSY;
}
elem_count = pages * PAGE_SIZE / 4;
frame_count = 1;
omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
elem_count, frame_count,
OMAP_DMA_SYNC_ELEMENT,
0, 0);
omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
paddr, 0, 0);
omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
omap_start_dma(lch);
if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
omap_stop_dma(lch);
pr_err("VRAM: dma timeout while clearing memory\n");
r = -EIO;
goto err;
}
r = 0;
err:
omap_free_dma(lch);
return r;
}
static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
{
struct vram_region *rm;
......@@ -337,8 +283,6 @@ static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
*paddr = start;
_omap_vram_clear(start, pages);
return 0;
}
......
......@@ -73,6 +73,7 @@ enum omap_plane {
OMAP_DSS_VIDEO1 = 1,
OMAP_DSS_VIDEO2 = 2,
OMAP_DSS_VIDEO3 = 3,
OMAP_DSS_WB = 4,
};
enum omap_channel {
......@@ -605,6 +606,8 @@ struct omap_dss_device {
struct omap_dss_hdmi_data
{
int ct_cp_hpd_gpio;
int ls_oe_gpio;
int hpd_gpio;
};
......@@ -736,6 +739,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
const struct omap_dsi_pin_config *pin_cfg);
int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
unsigned long ddr_clk, unsigned long lp_clk);
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment