Skip to content

Commit bf2ae5d

Browse files
committed
Merge tag 'fbdev-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev updates from Tomi Valkeinen: "Small fixes and improvements to various fbdev drivers" * tag 'fbdev-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (24 commits) omapdss: extend pm notifier to handle hibernation OMAPDSS: Correct video ports description file path in DT binding doc OMAPDSS: disable VT switch fbdev: sh_mobile_lcdc: Fix destruction of uninitialized mutex video: fbdev: sh_mobile_lcdcfb: Fix ROP3 sysfs attribute parsing fbdev: pm3fb: cleanup some confusing indenting hyperv: hyperv_fb: match wait_for_completion_timeout return type video: fbdev: use msecs_to_jiffies for time conversions fbdev: via/via_clock: fix sparse warning video: fbdev: make of_device_id array const fbdev: sm501fb: use memset_io OMAPDSS: workaround for MFLAG + NV12 issue OMAPDSS: Add support for MFLAG OMAPDSS: setup default fifo thresholds OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG OMAPDSS: DISPC: fix div by zero issue in overlay scaling OMAPDSS: DISPC: change sync_pclk_edge default value OMAPDSS: change signal_level & signal_edge enum values OMAPDSS: DISPC: explicit handling for sync and de levels OMAPDSS: DISPC: remove OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES ...
2 parents 14aa024 + 6b75b54 commit bf2ae5d

26 files changed

+193
-50
lines changed

Documentation/devicetree/bindings/video/ti,omap-dss.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Video Ports
2525
-----------
2626

2727
The DSS Core and the encoders have video port outputs. The structure of the
28-
video ports is described in Documentation/devicetree/bindings/video/video-
29-
ports.txt, and the properties for the ports and endpoints for each encoder are
28+
video ports is described in Documentation/devicetree/bindings/graph.txt,
29+
and the properties for the ports and endpoints for each encoder are
3030
described in the SoC's DSS binding documentation.
3131

3232
The video ports are used to describe the connections to external hardware, like

drivers/gpu/drm/omapdrm/omap_connector.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void copy_timings_drm_to_omap(struct omap_video_timings *timings,
102102

103103
timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
104104
timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
105-
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
105+
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
106106
}
107107

108108
static enum drm_connector_status omap_connector_detect(

drivers/video/fbdev/hyperv_fb.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver)
415415
struct fb_info *info = hv_get_drvdata(hdev);
416416
struct hvfb_par *par = info->par;
417417
struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
418-
int t, ret = 0;
418+
int ret = 0;
419+
unsigned long t;
419420

420421
memset(msg, 0, sizeof(struct synthvid_msg));
421422
msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST;
@@ -488,7 +489,8 @@ static int synthvid_send_config(struct hv_device *hdev)
488489
struct fb_info *info = hv_get_drvdata(hdev);
489490
struct hvfb_par *par = info->par;
490491
struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
491-
int t, ret = 0;
492+
int ret = 0;
493+
unsigned long t;
492494

493495
/* Send VRAM location */
494496
memset(msg, 0, sizeof(struct synthvid_msg));

drivers/video/fbdev/imxfb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static struct platform_device_id imxfb_devtype[] = {
183183
};
184184
MODULE_DEVICE_TABLE(platform, imxfb_devtype);
185185

186-
static struct of_device_id imxfb_of_dev_id[] = {
186+
static const struct of_device_id imxfb_of_dev_id[] = {
187187
{
188188
.compatible = "fsl,imx1-fb",
189189
.data = &imxfb_devtype[IMX1_FB],

drivers/video/fbdev/omap2/displays-new/connector-dvi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static const struct omap_video_timings dvic_default_timings = {
3737
.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
3838
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
3939
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
40-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
40+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
4141
};
4242

4343
struct panel_drv_data {

drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,21 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
114114
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
115115
}
116116

117+
static void tfp410_fix_timings(struct omap_video_timings *timings)
118+
{
119+
timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
120+
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
121+
timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
122+
}
123+
117124
static void tfp410_set_timings(struct omap_dss_device *dssdev,
118125
struct omap_video_timings *timings)
119126
{
120127
struct panel_drv_data *ddata = to_panel_data(dssdev);
121128
struct omap_dss_device *in = ddata->in;
122129

130+
tfp410_fix_timings(timings);
131+
123132
ddata->timings = *timings;
124133
dssdev->panel.timings = *timings;
125134

@@ -140,6 +149,8 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
140149
struct panel_drv_data *ddata = to_panel_data(dssdev);
141150
struct omap_dss_device *in = ddata->in;
142151

152+
tfp410_fix_timings(timings);
153+
143154
return in->ops.dpi->check_timings(in, timings);
144155
}
145156

drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static struct omap_video_timings lb035q02_timings = {
3737
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
3838
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
3939
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
40-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
40+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
4141
};
4242

4343
struct panel_drv_data {

drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static const struct omap_video_timings sharp_ls_timings = {
5454
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
5555
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
5656
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
57-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
57+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
5858
};
5959

6060
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static const struct omap_video_timings acx565akm_panel_timings = {
108108

109109
.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
110110
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
111-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
111+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
112112
};
113113

114114
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static struct omap_video_timings td028ttec1_panel_timings = {
5858

5959
.data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
6060
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
61-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
61+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
6262
};
6363

6464
#define JBT_COMMAND 0x000

drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static const struct omap_video_timings tpo_td043_timings = {
9191
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
9292
.data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
9393
.de_level = OMAPDSS_SIG_ACTIVE_HIGH,
94-
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
94+
.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
9595
};
9696

9797
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)

drivers/video/fbdev/omap2/dss/core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,14 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
179179

180180
switch (v) {
181181
case PM_SUSPEND_PREPARE:
182+
case PM_HIBERNATION_PREPARE:
183+
case PM_RESTORE_PREPARE:
182184
DSSDBG("suspending displays\n");
183185
return dss_suspend_all_devices();
184186

185187
case PM_POST_SUSPEND:
188+
case PM_POST_HIBERNATION:
189+
case PM_POST_RESTORE:
186190
DSSDBG("resuming displays\n");
187191
return dss_resume_all_devices();
188192

drivers/video/fbdev/omap2/dss/dispc.c

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ static struct {
123123

124124
struct regmap *syscon_pol;
125125
u32 syscon_pol_offset;
126+
127+
/* DISPC_CONTROL & DISPC_CONFIG lock*/
128+
spinlock_t control_lock;
126129
} dispc;
127130

128131
enum omap_color_component {
@@ -261,7 +264,16 @@ static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
261264
static void mgr_fld_write(enum omap_channel channel,
262265
enum mgr_reg_fields regfld, int val) {
263266
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
267+
const bool need_lock = rfld.reg == DISPC_CONTROL || rfld.reg == DISPC_CONFIG;
268+
unsigned long flags;
269+
270+
if (need_lock)
271+
spin_lock_irqsave(&dispc.control_lock, flags);
272+
264273
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
274+
275+
if (need_lock)
276+
spin_unlock_irqrestore(&dispc.control_lock, flags);
265277
}
266278

267279
#define SR(reg) \
@@ -1126,6 +1138,7 @@ static void dispc_init_fifos(void)
11261138
int fifo;
11271139
u8 start, end;
11281140
u32 unit;
1141+
int i;
11291142

11301143
unit = dss_feat_get_buffer_size_unit();
11311144

@@ -1165,6 +1178,20 @@ static void dispc_init_fifos(void)
11651178
dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
11661179
dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
11671180
}
1181+
1182+
/*
1183+
* Setup default fifo thresholds.
1184+
*/
1185+
for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
1186+
u32 low, high;
1187+
const bool use_fifomerge = false;
1188+
const bool manual_update = false;
1189+
1190+
dispc_ovl_compute_fifo_thresholds(i, &low, &high,
1191+
use_fifomerge, manual_update);
1192+
1193+
dispc_ovl_set_fifo_threshold(i, low, high);
1194+
}
11681195
}
11691196

11701197
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,
12781305
}
12791306
EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
12801307

1308+
static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable)
1309+
{
1310+
int bit;
1311+
1312+
if (plane == OMAP_DSS_GFX)
1313+
bit = 14;
1314+
else
1315+
bit = 23;
1316+
1317+
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
1318+
}
1319+
1320+
static void dispc_ovl_set_mflag_threshold(enum omap_plane plane,
1321+
int low, int high)
1322+
{
1323+
dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane),
1324+
FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0));
1325+
}
1326+
1327+
static void dispc_init_mflag(void)
1328+
{
1329+
int i;
1330+
1331+
/*
1332+
* HACK: NV12 color format and MFLAG seem to have problems working
1333+
* together: using two displays, and having an NV12 overlay on one of
1334+
* the displays will cause underflows/synclosts when MFLAG_CTRL=2.
1335+
* Changing MFLAG thresholds and PRELOAD to certain values seem to
1336+
* remove the errors, but there doesn't seem to be a clear logic on
1337+
* which values work and which not.
1338+
*
1339+
* As a work-around, set force MFLAG to always on.
1340+
*/
1341+
dispc_write_reg(DISPC_GLOBAL_MFLAG_ATTRIBUTE,
1342+
(1 << 0) | /* MFLAG_CTRL = force always on */
1343+
(0 << 2)); /* MFLAG_START = disable */
1344+
1345+
for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
1346+
u32 size = dispc_ovl_get_fifo_size(i);
1347+
u32 unit = dss_feat_get_buffer_size_unit();
1348+
u32 low, high;
1349+
1350+
dispc_ovl_set_mflag(i, true);
1351+
1352+
/*
1353+
* Simulation team suggests below thesholds:
1354+
* HT = fifosize * 5 / 8;
1355+
* LT = fifosize * 4 / 8;
1356+
*/
1357+
1358+
low = size * 4 / 8 / unit;
1359+
high = size * 5 / 8 / unit;
1360+
1361+
dispc_ovl_set_mflag_threshold(i, low, high);
1362+
}
1363+
}
1364+
12811365
static void dispc_ovl_set_fir(enum omap_plane plane,
12821366
int hinc, int vinc,
12831367
enum omap_color_component color_comp)
@@ -2322,6 +2406,11 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
23222406
if (width == out_width && height == out_height)
23232407
return 0;
23242408

2409+
if (pclk == 0 || mgr_timings->pixelclock == 0) {
2410+
DSSERR("cannot calculate scaling settings: pclk is zero\n");
2411+
return -EINVAL;
2412+
}
2413+
23252414
if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
23262415
return -EINVAL;
23272416

@@ -2441,7 +2530,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
24412530
unsigned long pclk = dispc_plane_pclk_rate(plane);
24422531
unsigned long lclk = dispc_plane_lclk_rate(plane);
24432532

2444-
if (paddr == 0)
2533+
if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER)
24452534
return -EINVAL;
24462535

24472536
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,
29153004

29163005
{
29173006
u32 timing_h, timing_v, l;
2918-
bool onoff, rf, ipc;
3007+
bool onoff, rf, ipc, vs, hs, de;
29193008

29203009
timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
29213010
FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
@@ -2927,29 +3016,58 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
29273016
dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
29283017
dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
29293018

3019+
switch (vsync_level) {
3020+
case OMAPDSS_SIG_ACTIVE_LOW:
3021+
vs = true;
3022+
break;
3023+
case OMAPDSS_SIG_ACTIVE_HIGH:
3024+
vs = false;
3025+
break;
3026+
default:
3027+
BUG();
3028+
}
3029+
3030+
switch (hsync_level) {
3031+
case OMAPDSS_SIG_ACTIVE_LOW:
3032+
hs = true;
3033+
break;
3034+
case OMAPDSS_SIG_ACTIVE_HIGH:
3035+
hs = false;
3036+
break;
3037+
default:
3038+
BUG();
3039+
}
3040+
3041+
switch (de_level) {
3042+
case OMAPDSS_SIG_ACTIVE_LOW:
3043+
de = true;
3044+
break;
3045+
case OMAPDSS_SIG_ACTIVE_HIGH:
3046+
de = false;
3047+
break;
3048+
default:
3049+
BUG();
3050+
}
3051+
29303052
switch (data_pclk_edge) {
29313053
case OMAPDSS_DRIVE_SIG_RISING_EDGE:
29323054
ipc = false;
29333055
break;
29343056
case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
29353057
ipc = true;
29363058
break;
2937-
case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
29383059
default:
29393060
BUG();
29403061
}
29413062

3063+
/* always use the 'rf' setting */
3064+
onoff = true;
3065+
29423066
switch (sync_pclk_edge) {
2943-
case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
2944-
onoff = false;
2945-
rf = false;
2946-
break;
29473067
case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
2948-
onoff = true;
29493068
rf = false;
29503069
break;
29513070
case OMAPDSS_DRIVE_SIG_RISING_EDGE:
2952-
onoff = true;
29533071
rf = true;
29543072
break;
29553073
default:
@@ -2958,10 +3076,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
29583076

29593077
l = FLD_VAL(onoff, 17, 17) |
29603078
FLD_VAL(rf, 16, 16) |
2961-
FLD_VAL(de_level, 15, 15) |
3079+
FLD_VAL(de, 15, 15) |
29623080
FLD_VAL(ipc, 14, 14) |
2963-
FLD_VAL(hsync_level, 13, 13) |
2964-
FLD_VAL(vsync_level, 12, 12);
3081+
FLD_VAL(hs, 13, 13) |
3082+
FLD_VAL(vs, 12, 12);
29653083

29663084
dispc_write_reg(DISPC_POL_FREQ(channel), l);
29673085

@@ -3569,6 +3687,9 @@ static void _omap_dispc_initial_config(void)
35693687

35703688
if (dispc.feat->mstandby_workaround)
35713689
REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
3690+
3691+
if (dss_has_feature(FEAT_MFLAG))
3692+
dispc_init_mflag();
35723693
}
35733694

35743695
static const struct dispc_features omap24xx_dispc_feats __initconst = {
@@ -3770,6 +3891,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
37703891

37713892
dispc.pdev = pdev;
37723893

3894+
spin_lock_init(&dispc.control_lock);
3895+
37733896
r = dispc_init_features(dispc.pdev);
37743897
if (r)
37753898
return r;

0 commit comments

Comments
 (0)