Merge omapdss topic branch for fbdev 4.1

This commit is contained in:
Tomi Valkeinen 2015-04-20 12:09:31 +03:00
commit 6b75b54c84
19 changed files with 172 additions and 32 deletions

View file

@ -37,7 +37,7 @@ static const struct omap_video_timings dvic_default_timings = {
.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
};
struct panel_drv_data {

View file

@ -114,12 +114,21 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static void tfp410_fix_timings(struct omap_video_timings *timings)
{
timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
}
static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
tfp410_fix_timings(timings);
ddata->timings = *timings;
dssdev->panel.timings = *timings;
@ -140,6 +149,8 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
tfp410_fix_timings(timings);
return in->ops.dpi->check_timings(in, timings);
}

View file

@ -37,7 +37,7 @@ static struct omap_video_timings lb035q02_timings = {
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
};
struct panel_drv_data {

View file

@ -54,7 +54,7 @@ static const struct omap_video_timings sharp_ls_timings = {
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
};
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

View file

@ -108,7 +108,7 @@ static const struct omap_video_timings acx565akm_panel_timings = {
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
};
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

View file

@ -58,7 +58,7 @@ static struct omap_video_timings td028ttec1_panel_timings = {
.data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
};
#define JBT_COMMAND 0x000

View file

@ -91,7 +91,7 @@ static const struct omap_video_timings tpo_td043_timings = {
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
.data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
};
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

View file

@ -179,10 +179,14 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
switch (v) {
case PM_SUSPEND_PREPARE:
case PM_HIBERNATION_PREPARE:
case PM_RESTORE_PREPARE:
DSSDBG("suspending displays\n");
return dss_suspend_all_devices();
case PM_POST_SUSPEND:
case PM_POST_HIBERNATION:
case PM_POST_RESTORE:
DSSDBG("resuming displays\n");
return dss_resume_all_devices();

View file

@ -123,6 +123,9 @@ static struct {
struct regmap *syscon_pol;
u32 syscon_pol_offset;
/* DISPC_CONTROL & DISPC_CONFIG lock*/
spinlock_t control_lock;
} dispc;
enum omap_color_component {
@ -261,7 +264,16 @@ static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
static void mgr_fld_write(enum omap_channel channel,
enum mgr_reg_fields regfld, int val) {
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
const bool need_lock = rfld.reg == DISPC_CONTROL || rfld.reg == DISPC_CONFIG;
unsigned long flags;
if (need_lock)
spin_lock_irqsave(&dispc.control_lock, flags);
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
if (need_lock)
spin_unlock_irqrestore(&dispc.control_lock, flags);
}
#define SR(reg) \
@ -1126,6 +1138,7 @@ static void dispc_init_fifos(void)
int fifo;
u8 start, end;
u32 unit;
int i;
unit = dss_feat_get_buffer_size_unit();
@ -1165,6 +1178,20 @@ static void dispc_init_fifos(void)
dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
}
/*
* Setup default fifo thresholds.
*/
for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
u32 low, high;
const bool use_fifomerge = false;
const bool manual_update = false;
dispc_ovl_compute_fifo_thresholds(i, &low, &high,
use_fifomerge, manual_update);
dispc_ovl_set_fifo_threshold(i, low, high);
}
}
static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
@ -1278,6 +1305,63 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
}
EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable)
{
int bit;
if (plane == OMAP_DSS_GFX)
bit = 14;
else
bit = 23;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
}
static void dispc_ovl_set_mflag_threshold(enum omap_plane plane,
int low, int high)
{
dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane),
FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0));
}
static void dispc_init_mflag(void)
{
int i;
/*
* HACK: NV12 color format and MFLAG seem to have problems working
* together: using two displays, and having an NV12 overlay on one of
* the displays will cause underflows/synclosts when MFLAG_CTRL=2.
* Changing MFLAG thresholds and PRELOAD to certain values seem to
* remove the errors, but there doesn't seem to be a clear logic on
* which values work and which not.
*
* As a work-around, set force MFLAG to always on.
*/
dispc_write_reg(DISPC_GLOBAL_MFLAG_ATTRIBUTE,
(1 << 0) | /* MFLAG_CTRL = force always on */
(0 << 2)); /* MFLAG_START = disable */
for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
u32 size = dispc_ovl_get_fifo_size(i);
u32 unit = dss_feat_get_buffer_size_unit();
u32 low, high;
dispc_ovl_set_mflag(i, true);
/*
* Simulation team suggests below thesholds:
* HT = fifosize * 5 / 8;
* LT = fifosize * 4 / 8;
*/
low = size * 4 / 8 / unit;
high = size * 5 / 8 / unit;
dispc_ovl_set_mflag_threshold(i, low, high);
}
}
static void dispc_ovl_set_fir(enum omap_plane plane,
int hinc, int vinc,
enum omap_color_component color_comp)
@ -2322,6 +2406,11 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
if (width == out_width && height == out_height)
return 0;
if (pclk == 0 || mgr_timings->pixelclock == 0) {
DSSERR("cannot calculate scaling settings: pclk is zero\n");
return -EINVAL;
}
if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
return -EINVAL;
@ -2441,7 +2530,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
unsigned long pclk = dispc_plane_pclk_rate(plane);
unsigned long lclk = dispc_plane_lclk_rate(plane);
if (paddr == 0)
if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER)
return -EINVAL;
out_width = out_width == 0 ? width : out_width;
@ -2915,7 +3004,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
{
u32 timing_h, timing_v, l;
bool onoff, rf, ipc;
bool onoff, rf, ipc, vs, hs, de;
timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
@ -2927,6 +3016,39 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
switch (vsync_level) {
case OMAPDSS_SIG_ACTIVE_LOW:
vs = true;
break;
case OMAPDSS_SIG_ACTIVE_HIGH:
vs = false;
break;
default:
BUG();
}
switch (hsync_level) {
case OMAPDSS_SIG_ACTIVE_LOW:
hs = true;
break;
case OMAPDSS_SIG_ACTIVE_HIGH:
hs = false;
break;
default:
BUG();
}
switch (de_level) {
case OMAPDSS_SIG_ACTIVE_LOW:
de = true;
break;
case OMAPDSS_SIG_ACTIVE_HIGH:
de = false;
break;
default:
BUG();
}
switch (data_pclk_edge) {
case OMAPDSS_DRIVE_SIG_RISING_EDGE:
ipc = false;
@ -2934,22 +3056,18 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
ipc = true;
break;
case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
default:
BUG();
}
/* always use the 'rf' setting */
onoff = true;
switch (sync_pclk_edge) {
case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
onoff = false;
rf = false;
break;
case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
onoff = true;
rf = false;
break;
case OMAPDSS_DRIVE_SIG_RISING_EDGE:
onoff = true;
rf = true;
break;
default:
@ -2958,10 +3076,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
l = FLD_VAL(onoff, 17, 17) |
FLD_VAL(rf, 16, 16) |
FLD_VAL(de_level, 15, 15) |
FLD_VAL(de, 15, 15) |
FLD_VAL(ipc, 14, 14) |
FLD_VAL(hsync_level, 13, 13) |
FLD_VAL(vsync_level, 12, 12);
FLD_VAL(hs, 13, 13) |
FLD_VAL(vs, 12, 12);
dispc_write_reg(DISPC_POL_FREQ(channel), l);
@ -3569,6 +3687,9 @@ static void _omap_dispc_initial_config(void)
if (dispc.feat->mstandby_workaround)
REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
if (dss_has_feature(FEAT_MFLAG))
dispc_init_mflag();
}
static const struct dispc_features omap24xx_dispc_feats __initconst = {
@ -3770,6 +3891,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
dispc.pdev = pdev;
spin_lock_init(&dispc.control_lock);
r = dispc_init_features(dispc.pdev);
if (r)
return r;

View file

@ -295,7 +295,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
OMAPDSS_DRIVE_SIG_RISING_EDGE :
OMAPDSS_DRIVE_SIG_FALLING_EDGE;
ovt->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
ovt->sync_pclk_edge = ovt->data_pclk_edge;
}
EXPORT_SYMBOL(videomode_to_omap_video_timings);

View file

@ -4137,7 +4137,7 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
dss_mgr_set_timings(mgr, &dsi->timings);

View file

@ -38,6 +38,7 @@
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <video/omapdss.h>
@ -1138,6 +1139,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
dss_debugfs_create_file("dss", dss_dump_regs);
pm_set_vt_switch(0);
return 0;
err_pll_init:

View file

@ -440,7 +440,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
static const struct dss_param_range am43xx_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
};

View file

@ -55,7 +55,7 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
const unsigned ss_scl_low = 4700; /* ns */
const unsigned fs_scl_high = 600; /* ns */
const unsigned fs_scl_low = 1300; /* ns */
const unsigned sda_hold = 300; /* ns */
const unsigned sda_hold = 1000; /* ns */
const unsigned sfr_div = 10;
unsigned long long sfr;
unsigned v;

View file

@ -869,7 +869,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
dss_mgr_set_timings(mgr, &rfbi.timings);
}

View file

@ -2073,7 +2073,7 @@ static int omapfb_mode_to_timings(const char *mode_str,
} else {
timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
}
timings->pixelclock = PICOS2KHZ(var->pixclock) * 1000;
@ -2223,7 +2223,7 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
} else {
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
t->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
}
t->x_res = m->xres;