Skip to content

Commit 6a4f1c9

Browse files
xuyanAvenger-285714
authored andcommitted
drm/phytium: Fix some Bugs in Phytium Display Engine
modified this files to support Phytium Display Engine more. Signed-off-by: Xu Yan <xuyan1481@phytium.com.cn> Signed-off-by: Yang Xun <yangxun@phytium.com.cn> Signed-off-by: Chen Baozi <chenbaozi@phytium.com.cn> Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
1 parent 0329b2b commit 6a4f1c9

20 files changed

Lines changed: 561 additions & 110 deletions

drivers/gpu/drm/phytium/Kconfig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
config DRM_PHYTIUM
22
tristate "DRM Support for Phytium Graphics Card"
3-
depends on DRM && ARCH_PHYTIUM
3+
depends on DRM
44
select DRM_KMS_HELPER
55
select DRM_DISPLAY_HELPER
66
select DRM_DISPLAY_DP_HELPER
77
select DRM_DISPLAY_HDCP_HELPER
88
help
99
Choose this option if you have a phytium graphics card.
10-
Phytium graphics card include display controller for X100 and E2000 devices.
11-
In addition,the driver also supports the display of E2000S BMC.
1210
This driver provides kernel mode setting and buffer management to userspace.

drivers/gpu/drm/phytium/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ phytium-dc-drm-y := phytium_display_drv.o \
1616

1717
obj-$(CONFIG_DRM_PHYTIUM) += phytium-dc-drm.o
1818
CFLAGS_REMOVE_phytium_crtc.o += -mgeneral-regs-only
19+
ifeq ($(ARCH), x86)
20+
FPU_CFLAGS += -msse -msse2
21+
CFLAGS_phytium_crtc.o += $(FPU_CFLAGS)
22+
endif

drivers/gpu/drm/phytium/pe220x_dc.c

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
#include <drm/drm_atomic_helper.h>
99
#include <drm/drm_atomic.h>
10+
#if defined(__arm__) || defined(__aarch64__)
1011
#include <asm/neon.h>
12+
#endif
1113
#include <linux/delay.h>
1214
#include "phytium_display_drv.h"
1315
#include "pe220x_reg.h"
@@ -56,6 +58,10 @@ static const unsigned int pe220x_primary_formats[] = {
5658
DRM_FORMAT_NV21,
5759
};
5860

61+
static const unsigned int pe220x_bmc_primary_formats[] = {
62+
DRM_FORMAT_XRGB8888,
63+
};
64+
5965
static uint64_t pe220x_primary_formats_modifiers[] = {
6066
DRM_FORMAT_MOD_LINEAR,
6167
DRM_FORMAT_MOD_INVALID
@@ -109,49 +115,76 @@ void pe220x_dc_hw_reset(struct drm_crtc *crtc)
109115
int config = 0;
110116
int phys_pipe = phytium_crtc->phys_pipe;
111117

112-
/* disable pixel clock for bmc mode */
113-
if (phys_pipe == 0)
114-
pe220x_dc_hw_disable(crtc);
115-
116118
config = phytium_readl_reg(priv, 0, PE220X_DC_CLOCK_CONTROL);
117-
config &= (~(DC0_CORE_RESET | DC1_CORE_RESET | AXI_RESET | AHB_RESET));
118119

119-
if (phys_pipe == 0) {
120-
phytium_writel_reg(priv, config | DC0_CORE_RESET,
121-
0, PE220X_DC_CLOCK_CONTROL);
122-
udelay(20);
123-
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET,
124-
0, PE220X_DC_CLOCK_CONTROL);
125-
udelay(20);
126-
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET | AHB_RESET,
127-
0, PE220X_DC_CLOCK_CONTROL);
128-
udelay(20);
129-
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET,
130-
0, PE220X_DC_CLOCK_CONTROL);
131-
udelay(20);
132-
phytium_writel_reg(priv, config | DC0_CORE_RESET,
133-
0, PE220X_DC_CLOCK_CONTROL);
134-
udelay(20);
135-
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
136-
udelay(20);
120+
if (priv->info.bmc_mode) {
121+
pe220x_dc_hw_disable(crtc);
122+
config &= (~(DC0_CORE_RESET | DC1_CORE_RESET | AHB_RESET));
123+
if (phys_pipe == 0) {
124+
phytium_writel_reg(priv, config | DC0_CORE_RESET,
125+
0, PE220X_DC_CLOCK_CONTROL);
126+
udelay(20);
127+
phytium_writel_reg(priv, config | DC0_CORE_RESET | AHB_RESET,
128+
0, PE220X_DC_CLOCK_CONTROL);
129+
udelay(20);
130+
phytium_writel_reg(priv, config | DC0_CORE_RESET,
131+
0, PE220X_DC_CLOCK_CONTROL);
132+
udelay(20);
133+
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
134+
udelay(20);
135+
} else {
136+
phytium_writel_reg(priv, config | DC1_CORE_RESET,
137+
0, PE220X_DC_CLOCK_CONTROL);
138+
udelay(20);
139+
phytium_writel_reg(priv, config | DC1_CORE_RESET | AHB_RESET,
140+
0, PE220X_DC_CLOCK_CONTROL);
141+
udelay(20);
142+
phytium_writel_reg(priv, config | DC1_CORE_RESET,
143+
0, PE220X_DC_CLOCK_CONTROL);
144+
udelay(20);
145+
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
146+
udelay(20);
147+
}
148+
137149
} else {
138-
phytium_writel_reg(priv, config | DC1_CORE_RESET,
139-
0, PE220X_DC_CLOCK_CONTROL);
140-
udelay(20);
141-
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET,
142-
0, PE220X_DC_CLOCK_CONTROL);
143-
udelay(20);
144-
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET | AHB_RESET,
145-
0, PE220X_DC_CLOCK_CONTROL);
146-
udelay(20);
147-
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET,
148-
0, PE220X_DC_CLOCK_CONTROL);
149-
udelay(20);
150-
phytium_writel_reg(priv, config | DC1_CORE_RESET,
151-
0, PE220X_DC_CLOCK_CONTROL);
152-
udelay(20);
153-
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
154-
udelay(20);
150+
config &= (~(DC0_CORE_RESET | DC1_CORE_RESET | AXI_RESET | AHB_RESET));
151+
if (phys_pipe == 0) {
152+
phytium_writel_reg(priv, config | DC0_CORE_RESET,
153+
0, PE220X_DC_CLOCK_CONTROL);
154+
udelay(20);
155+
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET,
156+
0, PE220X_DC_CLOCK_CONTROL);
157+
udelay(20);
158+
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET | AHB_RESET,
159+
0, PE220X_DC_CLOCK_CONTROL);
160+
udelay(20);
161+
phytium_writel_reg(priv, config | DC0_CORE_RESET | AXI_RESET,
162+
0, PE220X_DC_CLOCK_CONTROL);
163+
udelay(20);
164+
phytium_writel_reg(priv, config | DC0_CORE_RESET,
165+
0, PE220X_DC_CLOCK_CONTROL);
166+
udelay(20);
167+
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
168+
udelay(20);
169+
} else {
170+
phytium_writel_reg(priv, config | DC1_CORE_RESET,
171+
0, PE220X_DC_CLOCK_CONTROL);
172+
udelay(20);
173+
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET,
174+
0, PE220X_DC_CLOCK_CONTROL);
175+
udelay(20);
176+
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET | AHB_RESET,
177+
0, PE220X_DC_CLOCK_CONTROL);
178+
udelay(20);
179+
phytium_writel_reg(priv, config | DC1_CORE_RESET | AXI_RESET,
180+
0, PE220X_DC_CLOCK_CONTROL);
181+
udelay(20);
182+
phytium_writel_reg(priv, config | DC1_CORE_RESET,
183+
0, PE220X_DC_CLOCK_CONTROL);
184+
udelay(20);
185+
phytium_writel_reg(priv, config, 0, PE220X_DC_CLOCK_CONTROL);
186+
udelay(20);
187+
}
155188
}
156189
}
157190

@@ -216,6 +249,15 @@ void pe220x_dc_hw_plane_get_primary_format(const uint64_t **format_modifiers,
216249
*format_count = ARRAY_SIZE(pe220x_primary_formats);
217250
}
218251

252+
void pe220x_dc_bmc_hw_plane_get_primary_format(const uint64_t **format_modifiers,
253+
const uint32_t **formats,
254+
uint32_t *format_count)
255+
{
256+
*format_modifiers = pe220x_primary_formats_modifiers;
257+
*formats = pe220x_bmc_primary_formats;
258+
*format_count = ARRAY_SIZE(pe220x_bmc_primary_formats);
259+
}
260+
219261
void pe220x_dc_hw_plane_get_cursor_format(const uint64_t **format_modifiers,
220262
const uint32_t **formats,
221263
uint32_t *format_count)

drivers/gpu/drm/phytium/pe220x_dc.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
#define __PE220X_DC_H__
1010

1111
#define PE220X_DC_PIX_CLOCK_MAX (594000)
12-
#define PE220X_DC_HDISPLAY_MAX 3840
13-
#define PE220X_DC_VDISPLAY_MAX 2160
12+
#define PE220X_DC_HDISPLAY_MAX 1920
13+
#define PE220X_DC_VDISPLAY_MAX 1080
1414
#define PE220X_DC_ADDRESS_MASK 0x7f
1515

1616
extern void pe220x_dc_hw_vram_init(struct phytium_display_private *priv,
@@ -22,6 +22,9 @@ extern int pe220x_dc_hw_fb_format_check(const struct drm_mode_fb_cmd2 *mode_cmd,
2222
extern void pe220x_dc_hw_plane_get_primary_format(const uint64_t **format_modifiers,
2323
const uint32_t **formats,
2424
uint32_t *format_count);
25+
extern void pe220x_dc_bmc_hw_plane_get_primary_format(const uint64_t **format_modifiers,
26+
const uint32_t **formats,
27+
uint32_t *format_count);
2528
extern void pe220x_dc_hw_plane_get_cursor_format(const uint64_t **format_modifiers,
2629
const uint32_t **formats,
2730
uint32_t *format_count);

drivers/gpu/drm/phytium/pe220x_dp.c

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* Copyright (C) 2021-2023, Phytium Technology Co., Ltd.
66
*/
77

8+
#include <linux/pwm.h>
9+
#include <linux/gpio.h>
10+
#include <linux/gpio/consumer.h>
811
#include "phytium_display_drv.h"
912
#include "pe220x_reg.h"
1013
#include "phytium_dp.h"
@@ -379,13 +382,9 @@ static void pe220x_dp_hw_poweron_panel(struct phytium_dp_device *phytium_dp)
379382
{
380383
struct drm_device *dev = phytium_dp->dev;
381384
struct phytium_display_private *priv = dev->dev_private;
382-
int port = phytium_dp->port;
383385
int ret = 0;
384386

385-
phytium_writel_reg(priv, FLAG_REQUEST | CMD_BACKLIGHT | PANEL_POWER_ENABLE,
386-
0, PE220X_DC_CMD_REGISTER(port));
387-
ret = phytium_wait_cmd_done(priv, PE220X_DC_CMD_REGISTER(port),
388-
FLAG_REQUEST, FLAG_REPLY);
387+
gpiod_set_value(priv->edp_power_en, 1);
389388
if (ret < 0)
390389
DRM_ERROR("%s: failed to poweron panel\n", __func__);
391390
}
@@ -394,13 +393,9 @@ static void pe220x_dp_hw_poweroff_panel(struct phytium_dp_device *phytium_dp)
394393
{
395394
struct drm_device *dev = phytium_dp->dev;
396395
struct phytium_display_private *priv = dev->dev_private;
397-
int port = phytium_dp->port;
398396
int ret = 0;
399397

400-
phytium_writel_reg(priv, FLAG_REQUEST | CMD_BACKLIGHT | PANEL_POWER_DISABLE,
401-
0, PE220X_DC_CMD_REGISTER(port));
402-
ret = phytium_wait_cmd_done(priv, PE220X_DC_CMD_REGISTER(port),
403-
FLAG_REQUEST, FLAG_REPLY);
398+
gpiod_set_value(priv->edp_power_en, 0);
404399
if (ret < 0)
405400
DRM_ERROR("%s: failed to poweroff panel\n", __func__);
406401
}
@@ -409,12 +404,14 @@ static void pe220x_dp_hw_enable_backlight(struct phytium_dp_device *phytium_dp)
409404
{
410405
struct drm_device *dev = phytium_dp->dev;
411406
struct phytium_display_private *priv = dev->dev_private;
412-
int port = phytium_dp->port, ret = 0;
407+
struct pwm_state state;
408+
int ret = 0;
413409

414-
phytium_writel_reg(priv, FLAG_REQUEST | CMD_BACKLIGHT | BACKLIGHT_ENABLE,
415-
0, PE220X_DC_CMD_REGISTER(port));
416-
ret = phytium_wait_cmd_done(priv, PE220X_DC_CMD_REGISTER(port),
417-
FLAG_REQUEST, FLAG_REPLY);
410+
pwm_get_state(phytium_dp->pwm, &state);
411+
state.enabled = true;
412+
pwm_set_relative_duty_cycle(&state, 50, 100);
413+
ret = pwm_apply_might_sleep(phytium_dp->pwm, &state);
414+
gpiod_set_value(priv->edp_bl_en, 1);
418415
if (ret < 0)
419416
DRM_ERROR("%s: failed to enable backlight\n", __func__);
420417
}
@@ -423,45 +420,41 @@ static void pe220x_dp_hw_disable_backlight(struct phytium_dp_device *phytium_dp)
423420
{
424421
struct drm_device *dev = phytium_dp->dev;
425422
struct phytium_display_private *priv = dev->dev_private;
426-
int port = phytium_dp->port;
427423
int ret = 0;
428424

429-
phytium_writel_reg(priv, FLAG_REQUEST | CMD_BACKLIGHT | BACKLIGHT_DISABLE,
430-
0, PE220X_DC_CMD_REGISTER(port));
431-
ret = phytium_wait_cmd_done(priv, PE220X_DC_CMD_REGISTER(port),
432-
FLAG_REQUEST, FLAG_REPLY);
425+
gpiod_set_value(priv->edp_bl_en, 0);
433426
if (ret < 0)
434-
DRM_ERROR("%s: failed to disable backlight\n", __func__);
427+
DRM_ERROR("%s: failed to disable backlight, ret = %d\n", __func__, ret);
435428
}
436429

437430
static uint32_t pe220x_dp_hw_get_backlight(struct phytium_dp_device *phytium_dp)
438431
{
439-
struct drm_device *dev = phytium_dp->dev;
440-
struct phytium_display_private *priv = dev->dev_private;
441-
int config;
442-
uint32_t group_offset = priv->address_transform_base;
432+
struct pwm_state state;
433+
uint32_t level;
443434

444-
config = phytium_readl_reg(priv, group_offset, PE220X_DC_ADDRESS_TRANSFORM_BACKLIGHT_VALUE);
445-
return ((config >> BACKLIGHT_VALUE_SHIFT) & BACKLIGHT_VALUE_MASK);
435+
pwm_get_state(phytium_dp->pwm, &state);
436+
level = pwm_get_relative_duty_cycle(&state, 100);
437+
return level;
446438
}
447439

448440
static int pe220x_dp_hw_set_backlight(struct phytium_dp_device *phytium_dp, uint32_t level)
449441
{
450-
struct drm_device *dev = phytium_dp->dev;
451-
struct phytium_display_private *priv = dev->dev_private;
452-
int port = phytium_dp->port;
453-
int config = 0;
442+
struct pwm_state state;
454443
int ret = 0;
455444

456445
if (level > PE220X_DP_BACKLIGHT_MAX) {
457446
ret = -EINVAL;
458447
goto out;
459448
}
449+
pwm_get_state(phytium_dp->pwm, &state);
450+
state.enabled = true;
451+
state.period = phytium_dp->pwm->args.period;
452+
if (state.period == 0)
453+
DRM_ERROR("%s: set pwm period to 0\n", __func__);
454+
455+
pwm_set_relative_duty_cycle(&state, level, 100);
460456

461-
config = FLAG_REQUEST | CMD_BACKLIGHT | ((level & BACKLIGHT_MASK) << BACKLIGHT_SHIFT);
462-
phytium_writel_reg(priv, config, 0, PE220X_DC_CMD_REGISTER(port));
463-
ret = phytium_wait_cmd_done(priv, PE220X_DC_CMD_REGISTER(port),
464-
FLAG_REQUEST, FLAG_REPLY);
457+
ret = pwm_apply_might_sleep(phytium_dp->pwm, &state);
465458
if (ret < 0)
466459
DRM_ERROR("%s: failed to set backlight\n", __func__);
467460
out:

drivers/gpu/drm/phytium/pe220x_dp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#ifndef __PE220X_DP_H__
99
#define __PE220X_DP_H__
1010

11-
#define PE220X_DP_BACKLIGHT_MAX 100
11+
#define PE220X_DP_BACKLIGHT_MAX 99
12+
#define PE220X_DP_BACKLIGHT_MIN 2
1213

1314
void pe220x_dp_func_register(struct phytium_dp_device *phytium_dp);
1415
#endif /* __PE220X_DP_H__ */

0 commit comments

Comments
 (0)