Skip to content

Commit 44ab404

Browse files
committed
Merge branch 'for-next' of http://git.agner.ch/git/linux-drm-fsl-dcu into drm-next
As previously discussed, this is my first pull request for the DCU DRM driver along with the change in MAINTAINERS. https://lkml.org/lkml/2016/1/7/26 The pull contains some code cleanup changes (e.g. removing all error handling for the regmap calls) and several fixes. * 'for-next' of http://git.agner.ch/git/linux-drm-fsl-dcu: drm/fsl-dcu: fix register initialization drm/fsl-dcu: use mode flags for hsync/vsync polarity drm/fsl-dcu: fix alpha blending drm/fsl-dcu: mask all interrupts on initialization drm/fsl-dcu: handle initialization errors properly drm/fsl-dcu: avoid memory leak on errors drm/fsl-dcu: remove regmap return value checks drm/fsl-dcu: specify volatile registers drm: fsl-dcu: Fix no fb check bug MAINTAINERS: update for Freescale DCU DRM driver
2 parents 0041ee4 + f76b987 commit 44ab404

File tree

7 files changed

+168
-208
lines changed

7 files changed

+168
-208
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3764,7 +3764,7 @@ F: include/drm/exynos*
37643764
F: include/uapi/drm/exynos*
37653765

37663766
DRM DRIVERS FOR FREESCALE DCU
3767-
M: Jianwei Wang <jianwei.wang.chn@gmail.com>
3767+
M: Stefan Agner <stefan@agner.ch>
37683768
M: Alison Wang <alison.wang@freescale.com>
37693769
L: dri-devel@lists.freedesktop.org
37703770
S: Supported

drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c

Lines changed: 54 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,24 @@ static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
4242
{
4343
struct drm_device *dev = crtc->dev;
4444
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
45-
int ret;
4645

47-
ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
48-
DCU_MODE_DCU_MODE_MASK,
49-
DCU_MODE_DCU_MODE(DCU_MODE_OFF));
50-
if (ret)
51-
dev_err(fsl_dev->dev, "Disable CRTC failed\n");
52-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
53-
DCU_UPDATE_MODE_READREG);
54-
if (ret)
55-
dev_err(fsl_dev->dev, "Enable CRTC failed\n");
46+
regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
47+
DCU_MODE_DCU_MODE_MASK,
48+
DCU_MODE_DCU_MODE(DCU_MODE_OFF));
49+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
50+
DCU_UPDATE_MODE_READREG);
5651
}
5752

5853
static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc)
5954
{
6055
struct drm_device *dev = crtc->dev;
6156
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
62-
int ret;
6357

64-
ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
65-
DCU_MODE_DCU_MODE_MASK,
66-
DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
67-
if (ret)
68-
dev_err(fsl_dev->dev, "Enable CRTC failed\n");
69-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
70-
DCU_UPDATE_MODE_READREG);
71-
if (ret)
72-
dev_err(fsl_dev->dev, "Enable CRTC failed\n");
58+
regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
59+
DCU_MODE_DCU_MODE_MASK,
60+
DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
61+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
62+
DCU_UPDATE_MODE_READREG);
7363
}
7464

7565
static bool fsl_dcu_drm_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -84,9 +74,8 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
8474
struct drm_device *dev = crtc->dev;
8575
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
8676
struct drm_display_mode *mode = &crtc->state->mode;
87-
unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index;
77+
unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index, pol = 0;
8878
unsigned long dcuclk;
89-
int ret;
9079

9180
index = drm_crtc_index(crtc);
9281
dcuclk = clk_get_rate(fsl_dev->clk);
@@ -100,51 +89,36 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
10089
vfp = mode->vsync_start - mode->vdisplay;
10190
vsw = mode->vsync_end - mode->vsync_start;
10291

103-
ret = regmap_write(fsl_dev->regmap, DCU_HSYN_PARA,
104-
DCU_HSYN_PARA_BP(hbp) |
105-
DCU_HSYN_PARA_PW(hsw) |
106-
DCU_HSYN_PARA_FP(hfp));
107-
if (ret)
108-
goto set_failed;
109-
ret = regmap_write(fsl_dev->regmap, DCU_VSYN_PARA,
110-
DCU_VSYN_PARA_BP(vbp) |
111-
DCU_VSYN_PARA_PW(vsw) |
112-
DCU_VSYN_PARA_FP(vfp));
113-
if (ret)
114-
goto set_failed;
115-
ret = regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
116-
DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
117-
DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
118-
if (ret)
119-
goto set_failed;
120-
ret = regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
121-
if (ret)
122-
goto set_failed;
123-
ret = regmap_write(fsl_dev->regmap, DCU_SYN_POL,
124-
DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW);
125-
if (ret)
126-
goto set_failed;
127-
ret = regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
128-
DCU_BGND_G(0) | DCU_BGND_B(0));
129-
if (ret)
130-
goto set_failed;
131-
ret = regmap_write(fsl_dev->regmap, DCU_DCU_MODE,
132-
DCU_MODE_BLEND_ITER(1) | DCU_MODE_RASTER_EN);
133-
if (ret)
134-
goto set_failed;
135-
ret = regmap_write(fsl_dev->regmap, DCU_THRESHOLD,
136-
DCU_THRESHOLD_LS_BF_VS(BF_VS_VAL) |
137-
DCU_THRESHOLD_OUT_BUF_HIGH(BUF_MAX_VAL) |
138-
DCU_THRESHOLD_OUT_BUF_LOW(BUF_MIN_VAL));
139-
if (ret)
140-
goto set_failed;
141-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
142-
DCU_UPDATE_MODE_READREG);
143-
if (ret)
144-
goto set_failed;
92+
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
93+
pol |= DCU_SYN_POL_INV_HS_LOW;
94+
95+
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
96+
pol |= DCU_SYN_POL_INV_VS_LOW;
97+
98+
regmap_write(fsl_dev->regmap, DCU_HSYN_PARA,
99+
DCU_HSYN_PARA_BP(hbp) |
100+
DCU_HSYN_PARA_PW(hsw) |
101+
DCU_HSYN_PARA_FP(hfp));
102+
regmap_write(fsl_dev->regmap, DCU_VSYN_PARA,
103+
DCU_VSYN_PARA_BP(vbp) |
104+
DCU_VSYN_PARA_PW(vsw) |
105+
DCU_VSYN_PARA_FP(vfp));
106+
regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
107+
DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
108+
DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
109+
regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
110+
regmap_write(fsl_dev->regmap, DCU_SYN_POL, pol);
111+
regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
112+
DCU_BGND_G(0) | DCU_BGND_B(0));
113+
regmap_write(fsl_dev->regmap, DCU_DCU_MODE,
114+
DCU_MODE_BLEND_ITER(1) | DCU_MODE_RASTER_EN);
115+
regmap_write(fsl_dev->regmap, DCU_THRESHOLD,
116+
DCU_THRESHOLD_LS_BF_VS(BF_VS_VAL) |
117+
DCU_THRESHOLD_OUT_BUF_HIGH(BUF_MAX_VAL) |
118+
DCU_THRESHOLD_OUT_BUF_LOW(BUF_MIN_VAL));
119+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
120+
DCU_UPDATE_MODE_READREG);
145121
return;
146-
set_failed:
147-
dev_err(dev->dev, "set DCU register failed\n");
148122
}
149123

150124
static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
@@ -174,37 +148,31 @@ int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
174148
int ret;
175149

176150
primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
151+
if (!primary)
152+
return -ENOMEM;
153+
177154
ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
178155
&fsl_dcu_drm_crtc_funcs, NULL);
179-
if (ret < 0)
156+
if (ret) {
157+
primary->funcs->destroy(primary);
180158
return ret;
159+
}
181160

182161
drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs);
183162

184163
if (!strcmp(fsl_dev->soc->name, "ls1021a"))
185164
reg_num = LS1021A_LAYER_REG_NUM;
186165
else
187166
reg_num = VF610_LAYER_REG_NUM;
188-
for (i = 0; i <= fsl_dev->soc->total_layer; i++) {
189-
for (j = 0; j < reg_num; j++) {
190-
ret = regmap_write(fsl_dev->regmap,
191-
DCU_CTRLDESCLN(i, j), 0);
192-
if (ret)
193-
goto init_failed;
194-
}
167+
for (i = 0; i < fsl_dev->soc->total_layer; i++) {
168+
for (j = 1; j <= reg_num; j++)
169+
regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(i, j), 0);
195170
}
196-
ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
197-
DCU_MODE_DCU_MODE_MASK,
198-
DCU_MODE_DCU_MODE(DCU_MODE_OFF));
199-
if (ret)
200-
goto init_failed;
201-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
202-
DCU_UPDATE_MODE_READREG);
203-
if (ret)
204-
goto init_failed;
171+
regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
172+
DCU_MODE_DCU_MODE_MASK,
173+
DCU_MODE_DCU_MODE(DCU_MODE_OFF));
174+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
175+
DCU_UPDATE_MODE_READREG);
205176

206177
return 0;
207-
init_failed:
208-
dev_err(fsl_dev->dev, "init DCU register failed\n");
209-
return ret;
210178
}

drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,36 @@
2828
#include "fsl_dcu_drm_crtc.h"
2929
#include "fsl_dcu_drm_drv.h"
3030

31+
static bool fsl_dcu_drm_is_volatile_reg(struct device *dev, unsigned int reg)
32+
{
33+
if (reg == DCU_INT_STATUS || reg == DCU_UPDATE_MODE)
34+
return true;
35+
36+
return false;
37+
}
38+
3139
static const struct regmap_config fsl_dcu_regmap_config = {
3240
.reg_bits = 32,
3341
.reg_stride = 4,
3442
.val_bits = 32,
3543
.cache_type = REGCACHE_RBTREE,
44+
45+
.volatile_reg = fsl_dcu_drm_is_volatile_reg,
3646
};
3747

3848
static int fsl_dcu_drm_irq_init(struct drm_device *dev)
3949
{
4050
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
41-
unsigned int value;
4251
int ret;
4352

4453
ret = drm_irq_install(dev, fsl_dev->irq);
4554
if (ret < 0)
4655
dev_err(dev->dev, "failed to install IRQ handler\n");
4756

48-
ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0);
49-
if (ret)
50-
dev_err(dev->dev, "set DCU_INT_STATUS failed\n");
51-
ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
52-
if (ret)
53-
dev_err(dev->dev, "read DCU_INT_MASK failed\n");
54-
value &= DCU_INT_MASK_VBLANK;
55-
ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
56-
if (ret)
57-
dev_err(dev->dev, "set DCU_INT_MASK failed\n");
58-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
59-
DCU_UPDATE_MODE_READREG);
60-
if (ret)
61-
dev_err(dev->dev, "set DCU_UPDATE_MODE failed\n");
57+
regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0);
58+
regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0);
59+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
60+
DCU_UPDATE_MODE_READREG);
6261

6362
return ret;
6463
}
@@ -120,18 +119,17 @@ static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
120119
int ret;
121120

122121
ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
123-
if (ret)
124-
dev_err(dev->dev, "set DCU_INT_STATUS failed\n");
122+
if (ret) {
123+
dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
124+
return IRQ_NONE;
125+
}
126+
125127
if (int_status & DCU_INT_STATUS_VBLANK)
126128
drm_handle_vblank(dev, 0);
127129

128-
ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0xffffffff);
129-
if (ret)
130-
dev_err(dev->dev, "set DCU_INT_STATUS failed\n");
131-
ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
132-
DCU_UPDATE_MODE_READREG);
133-
if (ret)
134-
dev_err(dev->dev, "set DCU_UPDATE_MODE failed\n");
130+
regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
131+
regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
132+
DCU_UPDATE_MODE_READREG);
135133

136134
return IRQ_HANDLED;
137135
}
@@ -140,15 +138,11 @@ static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, unsigned int pipe)
140138
{
141139
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
142140
unsigned int value;
143-
int ret;
144141

145-
ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
146-
if (ret)
147-
dev_err(dev->dev, "read DCU_INT_MASK failed\n");
142+
regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
148143
value &= ~DCU_INT_MASK_VBLANK;
149-
ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
150-
if (ret)
151-
dev_err(dev->dev, "set DCU_INT_MASK failed\n");
144+
regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
145+
152146
return 0;
153147
}
154148

@@ -157,15 +151,10 @@ static void fsl_dcu_drm_disable_vblank(struct drm_device *dev,
157151
{
158152
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
159153
unsigned int value;
160-
int ret;
161154

162-
ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
163-
if (ret)
164-
dev_err(dev->dev, "read DCU_INT_MASK failed\n");
155+
regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
165156
value |= DCU_INT_MASK_VBLANK;
166-
ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
167-
if (ret)
168-
dev_err(dev->dev, "set DCU_INT_MASK failed\n");
157+
regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
169158
}
170159

171160
static const struct file_operations fsl_dcu_drm_fops = {

drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@
133133
#define DCU_LAYER_RLE_EN BIT(15)
134134
#define DCU_LAYER_LUOFFS(x) ((x) << 4)
135135
#define DCU_LAYER_BB_ON BIT(2)
136-
#define DCU_LAYER_AB(x) (x)
136+
#define DCU_LAYER_AB_NONE 0
137+
#define DCU_LAYER_AB_CHROMA_KEYING 1
138+
#define DCU_LAYER_AB_WHOLE_FRAME 2
137139

138140
#define DCU_LAYER_CKMAX_R(x) ((x) << 16)
139141
#define DCU_LAYER_CKMAX_G(x) ((x) << 8)

drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ static const struct drm_mode_config_funcs fsl_dcu_drm_mode_config_funcs = {
2525

2626
int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
2727
{
28+
int ret;
29+
2830
drm_mode_config_init(fsl_dev->drm);
2931

3032
fsl_dev->drm->mode_config.min_width = 0;
@@ -33,11 +35,25 @@ int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
3335
fsl_dev->drm->mode_config.max_height = 2047;
3436
fsl_dev->drm->mode_config.funcs = &fsl_dcu_drm_mode_config_funcs;
3537

36-
drm_kms_helper_poll_init(fsl_dev->drm);
37-
fsl_dcu_drm_crtc_create(fsl_dev);
38-
fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc);
39-
fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder);
38+
ret = fsl_dcu_drm_crtc_create(fsl_dev);
39+
if (ret)
40+
return ret;
41+
42+
ret = fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc);
43+
if (ret)
44+
goto fail_encoder;
45+
46+
ret = fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder);
47+
if (ret)
48+
goto fail_connector;
49+
4050
drm_mode_config_reset(fsl_dev->drm);
51+
drm_kms_helper_poll_init(fsl_dev->drm);
4152

4253
return 0;
54+
fail_encoder:
55+
fsl_dev->crtc.funcs->destroy(&fsl_dev->crtc);
56+
fail_connector:
57+
fsl_dev->encoder.funcs->destroy(&fsl_dev->encoder);
58+
return ret;
4359
}

0 commit comments

Comments
 (0)