Commit 4ae9f874 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2022-09-30' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v6.1:

Core Changes:
- Add dma_resv_assert_held to vmap/vunmap calls.
- Add kunit tests for some format conversion calls.
- Don't rewrite link config when setting phy test pattern in
  DP link training.

Driver Changes:
- Assorted small fixes in bridge/lt8192b, qxl, virtio-gpu, ast.
- Fix corrupted image output in lt8912b.
- Fix driver unbind in meson.
- Add INX, BOE, AUO, Multi-Inno Technology panels to panel-edp.
- Synchronize access to GEM bo's in simpledrm, ssd130x.
- Use dev_err_probe in panel-edp and panel-simple.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/afbd505a-3799-c73b-8008-ef6e156ad7e1@linux.intel.com
parents 7860d720 c9b48b91
...@@ -234,6 +234,8 @@ properties: ...@@ -234,6 +234,8 @@ properties:
- mitsubishi,aa070mc01-ca1 - mitsubishi,aa070mc01-ca1
# Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module # Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module
- multi-inno,mi0700s4t-6 - multi-inno,mi0700s4t-6
# Multi-Inno Technology Co.,Ltd MI0800FT-9 8" 800x600 TFT Resistive Touch Module
- multi-inno,mi0800ft-9
# Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod. # Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod.
- multi-inno,mi1010ait-1cp - multi-inno,mi1010ait-1cp
# NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel # NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "ast_drv.h" #include "ast_drv.h"
int ast_modeset = -1; static int ast_modeset = -1;
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, ast_modeset, int, 0400); module_param_named(modeset, ast_modeset, int, 0400);
......
...@@ -165,30 +165,38 @@ static int lt8912_write_rxlogicres_config(struct lt8912 *lt) ...@@ -165,30 +165,38 @@ static int lt8912_write_rxlogicres_config(struct lt8912 *lt)
return ret; return ret;
}; };
/* enable LVDS output with some hardcoded configuration, not required for the HDMI output */
static int lt8912_write_lvds_config(struct lt8912 *lt) static int lt8912_write_lvds_config(struct lt8912 *lt)
{ {
const struct reg_sequence seq[] = { const struct reg_sequence seq[] = {
// lvds power up
{0x44, 0x30}, {0x44, 0x30},
{0x51, 0x05}, {0x51, 0x05},
{0x50, 0x24},
{0x51, 0x2d}, // core pll bypass
{0x52, 0x04}, {0x50, 0x24}, // cp=50uA
{0x69, 0x0e}, {0x51, 0x2d}, // Pix_clk as reference, second order passive LPF PLL
{0x52, 0x04}, // loopdiv=0, use second-order PLL
{0x69, 0x0e}, // CP_PRESET_DIV_RATIO
{0x69, 0x8e}, {0x69, 0x8e},
{0x6a, 0x00}, {0x6a, 0x00},
{0x6c, 0xb8}, {0x6c, 0xb8}, // RGD_CP_SOFT_K_EN,RGD_CP_SOFT_K[13:8]
{0x6b, 0x51}, {0x6b, 0x51},
{0x04, 0xfb},
{0x04, 0xfb}, // core pll reset
{0x04, 0xff}, {0x04, 0xff},
{0x7f, 0x00},
{0xa8, 0x13}, // scaler bypass
{0x02, 0xf7}, {0x7f, 0x00}, // disable scaler
{0xa8, 0x13}, // 0x13: JEIDA, 0x33: VESA
{0x02, 0xf7}, // lvds pll reset
{0x02, 0xff}, {0x02, 0xff},
{0x03, 0xcf}, {0x03, 0xcf},
{0x03, 0xff}, {0x03, 0xff},
}; };
return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq)); return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
}; };
static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b) static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
...@@ -268,7 +276,7 @@ static int lt8912_video_setup(struct lt8912 *lt) ...@@ -268,7 +276,7 @@ static int lt8912_video_setup(struct lt8912 *lt)
u32 hactive, h_total, hpw, hfp, hbp; u32 hactive, h_total, hpw, hfp, hbp;
u32 vactive, v_total, vpw, vfp, vbp; u32 vactive, v_total, vpw, vfp, vbp;
u8 settle = 0x08; u8 settle = 0x08;
int ret; int ret, hsync_activehigh, vsync_activehigh;
if (!lt) if (!lt)
return -EINVAL; return -EINVAL;
...@@ -278,12 +286,14 @@ static int lt8912_video_setup(struct lt8912 *lt) ...@@ -278,12 +286,14 @@ static int lt8912_video_setup(struct lt8912 *lt)
hpw = lt->mode.hsync_len; hpw = lt->mode.hsync_len;
hbp = lt->mode.hback_porch; hbp = lt->mode.hback_porch;
h_total = hactive + hfp + hpw + hbp; h_total = hactive + hfp + hpw + hbp;
hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH;
vactive = lt->mode.vactive; vactive = lt->mode.vactive;
vfp = lt->mode.vfront_porch; vfp = lt->mode.vfront_porch;
vpw = lt->mode.vsync_len; vpw = lt->mode.vsync_len;
vbp = lt->mode.vback_porch; vbp = lt->mode.vback_porch;
v_total = vactive + vfp + vpw + vbp; v_total = vactive + vfp + vpw + vbp;
vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH;
if (vactive <= 600) if (vactive <= 600)
settle = 0x04; settle = 0x04;
...@@ -317,6 +327,13 @@ static int lt8912_video_setup(struct lt8912 *lt) ...@@ -317,6 +327,13 @@ static int lt8912_video_setup(struct lt8912 *lt)
ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff); ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8); ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);
ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0),
vsync_activehigh ? BIT(0) : 0);
ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
hsync_activehigh ? BIT(1) : 0);
ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0),
lt->connector.display_info.is_hdmi ? BIT(0) : 0);
return ret; return ret;
} }
......
...@@ -2670,17 +2670,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, ...@@ -2670,17 +2670,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
struct drm_dp_phy_test_params *data, u8 dp_rev) struct drm_dp_phy_test_params *data, u8 dp_rev)
{ {
int err, i; int err, i;
u8 link_config[2];
u8 test_pattern; u8 test_pattern;
link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate);
link_config[1] = data->num_lanes;
if (data->enhanced_frame_cap)
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2);
if (err < 0)
return err;
test_pattern = data->phy_pattern; test_pattern = data->phy_pattern;
if (dp_rev < 0x12) { if (dp_rev < 0x12) {
test_pattern = (test_pattern << 2) & test_pattern = (test_pattern << 2) &
......
...@@ -553,6 +553,7 @@ void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *d ...@@ -553,6 +553,7 @@ void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *d
drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
drm_fb_xrgb8888_to_xrgb2101010_line); drm_fb_xrgb8888_to_xrgb2101010_line);
} }
EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010);
static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels) static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels)
{ {
......
...@@ -87,13 +87,13 @@ int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y, ...@@ -87,13 +87,13 @@ int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y,
src_x > fb_width - src_w || src_x > fb_width - src_w ||
src_h > fb_height || src_h > fb_height ||
src_y > fb_height - src_h) { src_y > fb_height - src_h) {
DRM_DEBUG_KMS("Invalid source coordinates " drm_dbg_kms(fb->dev, "Invalid source coordinates "
"%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n", "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
src_w >> 16, ((src_w & 0xffff) * 15625) >> 10, src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
src_h >> 16, ((src_h & 0xffff) * 15625) >> 10, src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
src_x >> 16, ((src_x & 0xffff) * 15625) >> 10, src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
src_y >> 16, ((src_y & 0xffff) * 15625) >> 10, src_y >> 16, ((src_y & 0xffff) * 15625) >> 10,
fb->width, fb->height); fb->width, fb->height);
return -ENOSPC; return -ENOSPC;
} }
...@@ -125,7 +125,7 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, ...@@ -125,7 +125,7 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
r.pixel_format = drm_driver_legacy_fb_format(dev, or->bpp, or->depth); r.pixel_format = drm_driver_legacy_fb_format(dev, or->bpp, or->depth);
if (r.pixel_format == DRM_FORMAT_INVALID) { if (r.pixel_format == DRM_FORMAT_INVALID) {
DRM_DEBUG("bad {bpp:%d, depth:%d}\n", or->bpp, or->depth); drm_dbg_kms(dev, "bad {bpp:%d, depth:%d}\n", or->bpp, or->depth);
return -EINVAL; return -EINVAL;
} }
...@@ -177,18 +177,18 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -177,18 +177,18 @@ static int framebuffer_check(struct drm_device *dev,
/* check if the format is supported at all */ /* check if the format is supported at all */
if (!__drm_format_info(r->pixel_format)) { if (!__drm_format_info(r->pixel_format)) {
DRM_DEBUG_KMS("bad framebuffer format %p4cc\n", drm_dbg_kms(dev, "bad framebuffer format %p4cc\n",
&r->pixel_format); &r->pixel_format);
return -EINVAL; return -EINVAL;
} }
if (r->width == 0) { if (r->width == 0) {
DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); drm_dbg_kms(dev, "bad framebuffer width %u\n", r->width);
return -EINVAL; return -EINVAL;
} }
if (r->height == 0) { if (r->height == 0) {
DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); drm_dbg_kms(dev, "bad framebuffer height %u\n", r->height);
return -EINVAL; return -EINVAL;
} }
...@@ -202,12 +202,12 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -202,12 +202,12 @@ static int framebuffer_check(struct drm_device *dev,
u64 min_pitch = drm_format_info_min_pitch(info, i, width); u64 min_pitch = drm_format_info_min_pitch(info, i, width);
if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) { if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i); drm_dbg_kms(dev, "Format requires non-linear modifier for plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
if (!r->handles[i]) { if (!r->handles[i]) {
DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); drm_dbg_kms(dev, "no buffer object handle for plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
...@@ -218,20 +218,20 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -218,20 +218,20 @@ static int framebuffer_check(struct drm_device *dev,
return -ERANGE; return -ERANGE;
if (block_size && r->pitches[i] < min_pitch) { if (block_size && r->pitches[i] < min_pitch) {
DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); drm_dbg_kms(dev, "bad pitch %u for plane %d\n", r->pitches[i], i);
return -EINVAL; return -EINVAL;
} }
if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) { if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n", drm_dbg_kms(dev, "bad fb modifier %llu for plane %d\n",
r->modifier[i], i); r->modifier[i], i);
return -EINVAL; return -EINVAL;
} }
if (r->flags & DRM_MODE_FB_MODIFIERS && if (r->flags & DRM_MODE_FB_MODIFIERS &&
r->modifier[i] != r->modifier[0]) { r->modifier[i] != r->modifier[0]) {
DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n", drm_dbg_kms(dev, "bad fb modifier %llu for plane %d\n",
r->modifier[i], i); r->modifier[i], i);
return -EINVAL; return -EINVAL;
} }
...@@ -244,7 +244,7 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -244,7 +244,7 @@ static int framebuffer_check(struct drm_device *dev,
if (r->pixel_format != DRM_FORMAT_NV12 || if (r->pixel_format != DRM_FORMAT_NV12 ||
width % 128 || height % 32 || width % 128 || height % 32 ||
r->pitches[i] % 128) { r->pitches[i] % 128) {
DRM_DEBUG_KMS("bad modifier data for plane %d\n", i); drm_dbg_kms(dev, "bad modifier data for plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
break; break;
...@@ -256,7 +256,7 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -256,7 +256,7 @@ static int framebuffer_check(struct drm_device *dev,
for (i = info->num_planes; i < 4; i++) { for (i = info->num_planes; i < 4; i++) {
if (r->modifier[i]) { if (r->modifier[i]) {
DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i); drm_dbg_kms(dev, "non-zero modifier for unused plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
...@@ -265,17 +265,17 @@ static int framebuffer_check(struct drm_device *dev, ...@@ -265,17 +265,17 @@ static int framebuffer_check(struct drm_device *dev,
continue; continue;
if (r->handles[i]) { if (r->handles[i]) {
DRM_DEBUG_KMS("buffer object handle for unused plane %d\n", i); drm_dbg_kms(dev, "buffer object handle for unused plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
if (r->pitches[i]) { if (r->pitches[i]) {
DRM_DEBUG_KMS("non-zero pitch for unused plane %d\n", i); drm_dbg_kms(dev, "non-zero pitch for unused plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
if (r->offsets[i]) { if (r->offsets[i]) {
DRM_DEBUG_KMS("non-zero offset for unused plane %d\n", i); drm_dbg_kms(dev, "non-zero offset for unused plane %d\n", i);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -293,24 +293,24 @@ drm_internal_framebuffer_create(struct drm_device *dev, ...@@ -293,24 +293,24 @@ drm_internal_framebuffer_create(struct drm_device *dev,
int ret; int ret;
if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) { if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); drm_dbg_kms(dev, "bad framebuffer flags 0x%08x\n", r->flags);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if ((config->min_width > r->width) || (r->width > config->max_width)) { if ((config->min_width > r->width) || (r->width > config->max_width)) {
DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n", drm_dbg_kms(dev, "bad framebuffer width %d, should be >= %d && <= %d\n",
r->width, config->min_width, config->max_width); r->width, config->min_width, config->max_width);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if ((config->min_height > r->height) || (r->height > config->max_height)) { if ((config->min_height > r->height) || (r->height > config->max_height)) {
DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n", drm_dbg_kms(dev, "bad framebuffer height %d, should be >= %d && <= %d\n",
r->height, config->min_height, config->max_height); r->height, config->min_height, config->max_height);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (r->flags & DRM_MODE_FB_MODIFIERS && if (r->flags & DRM_MODE_FB_MODIFIERS &&
dev->mode_config.fb_modifiers_not_supported) { dev->mode_config.fb_modifiers_not_supported) {
DRM_DEBUG_KMS("driver does not support fb modifiers\n"); drm_dbg_kms(dev, "driver does not support fb modifiers\n");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
...@@ -320,7 +320,7 @@ drm_internal_framebuffer_create(struct drm_device *dev, ...@@ -320,7 +320,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) { if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n"); drm_dbg_kms(dev, "could not create framebuffer\n");
return fb; return fb;
} }
...@@ -356,7 +356,7 @@ int drm_mode_addfb2(struct drm_device *dev, ...@@ -356,7 +356,7 @@ int drm_mode_addfb2(struct drm_device *dev,
if (IS_ERR(fb)) if (IS_ERR(fb))
return PTR_ERR(fb); return PTR_ERR(fb);
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); drm_dbg_kms(dev, "[FB:%d]\n", fb->base.id);
r->fb_id = fb->base.id; r->fb_id = fb->base.id;
/* Transfer ownership to the filp for reaping on close */ /* Transfer ownership to the filp for reaping on close */
...@@ -384,7 +384,7 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev, ...@@ -384,7 +384,7 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev,
* then. So block it to make userspace fallback to * then. So block it to make userspace fallback to
* ADDFB. * ADDFB.
*/ */
DRM_DEBUG_KMS("addfb2 broken on bigendian"); drm_dbg_kms(dev, "addfb2 broken on bigendian");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
#endif #endif
......
...@@ -388,10 +388,14 @@ static void meson_drv_unbind(struct device *dev) ...@@ -388,10 +388,14 @@ static void meson_drv_unbind(struct device *dev)
drm_dev_unregister(drm); drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm); drm_kms_helper_poll_fini(drm);
drm_atomic_helper_shutdown(drm); drm_atomic_helper_shutdown(drm);
component_unbind_all(dev, drm);
free_irq(priv->vsync_irq, drm); free_irq(priv->vsync_irq, drm);
drm_dev_put(drm); drm_dev_put(drm);
meson_encoder_hdmi_remove(priv);
meson_encoder_cvbs_remove(priv);
component_unbind_all(dev, drm);
if (priv->afbcd.ops) if (priv->afbcd.ops)
priv->afbcd.ops->exit(priv); priv->afbcd.ops->exit(priv);
} }
...@@ -493,6 +497,13 @@ static int meson_drv_probe(struct platform_device *pdev) ...@@ -493,6 +497,13 @@ static int meson_drv_probe(struct platform_device *pdev)
return 0; return 0;
}; };
static int meson_drv_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &meson_drv_master_ops);
return 0;
}
static struct meson_drm_match_data meson_drm_gxbb_data = { static struct meson_drm_match_data meson_drm_gxbb_data = {
.compat = VPU_COMPATIBLE_GXBB, .compat = VPU_COMPATIBLE_GXBB,
}; };
...@@ -530,6 +541,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = { ...@@ -530,6 +541,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
static struct platform_driver meson_drm_platform_driver = { static struct platform_driver meson_drm_platform_driver = {
.probe = meson_drv_probe, .probe = meson_drv_probe,
.remove = meson_drv_remove,
.shutdown = meson_drv_shutdown, .shutdown = meson_drv_shutdown,
.driver = { .driver = {
.name = "meson-drm", .name = "meson-drm",
......
...@@ -25,6 +25,12 @@ enum vpu_compatible { ...@@ -25,6 +25,12 @@ enum vpu_compatible {
VPU_COMPATIBLE_G12A = 3, VPU_COMPATIBLE_G12A = 3,
}; };
enum {
MESON_ENC_CVBS = 0,
MESON_ENC_HDMI,
MESON_ENC_LAST,
};
struct meson_drm_match_data { struct meson_drm_match_data {
enum vpu_compatible compat; enum vpu_compatible compat;
struct meson_afbcd_ops *afbcd_ops; struct meson_afbcd_ops *afbcd_ops;
...@@ -51,6 +57,7 @@ struct meson_drm { ...@@ -51,6 +57,7 @@ struct meson_drm {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_plane *primary_plane; struct drm_plane *primary_plane;
struct drm_plane *overlay_plane; struct drm_plane *overlay_plane;
void *encoders[MESON_ENC_LAST];
const struct meson_drm_soc_limits *limits; const struct meson_drm_soc_limits *limits;
......
...@@ -281,5 +281,18 @@ int meson_encoder_cvbs_init(struct meson_drm *priv) ...@@ -281,5 +281,18 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
} }
drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder); drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
return 0; return 0;
} }
void meson_encoder_cvbs_remove(struct meson_drm *priv)
{
struct meson_encoder_cvbs *meson_encoder_cvbs;
if (priv->encoders[MESON_ENC_CVBS]) {
meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
drm_bridge_remove(&meson_encoder_cvbs->bridge);
drm_bridge_remove(meson_encoder_cvbs->next_bridge);
}
}
...@@ -25,5 +25,6 @@ struct meson_cvbs_mode { ...@@ -25,5 +25,6 @@ struct meson_cvbs_mode {
extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT]; extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
int meson_encoder_cvbs_init(struct meson_drm *priv); int meson_encoder_cvbs_init(struct meson_drm *priv);
void meson_encoder_cvbs_remove(struct meson_drm *priv);
#endif /* __MESON_VENC_CVBS_H */ #endif /* __MESON_VENC_CVBS_H */
...@@ -452,6 +452,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) ...@@ -452,6 +452,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
meson_encoder_hdmi->cec_notifier = notifier; meson_encoder_hdmi->cec_notifier = notifier;
} }
priv->encoders[MESON_ENC_HDMI] = meson_encoder_hdmi;
dev_dbg(priv->dev, "HDMI encoder initialized\n"); dev_dbg(priv->dev, "HDMI encoder initialized\n");
return 0; return 0;
...@@ -460,3 +462,14 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) ...@@ -460,3 +462,14 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
of_node_put(remote); of_node_put(remote);
return ret; return ret;
} }
void meson_encoder_hdmi_remove(struct meson_drm *priv)
{
struct meson_encoder_hdmi *meson_encoder_hdmi;
if (priv->encoders[MESON_ENC_HDMI]) {
meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
drm_bridge_remove(&meson_encoder_hdmi->bridge);
drm_bridge_remove(meson_encoder_hdmi->next_bridge);
}
}
...@@ -8,5 +8,6 @@ ...@@ -8,5 +8,6 @@
#define __MESON_ENCODER_HDMI_H #define __MESON_ENCODER_HDMI_H
int meson_encoder_hdmi_init(struct meson_drm *priv); int meson_encoder_hdmi_init(struct meson_drm *priv);
void meson_encoder_hdmi_remove(struct meson_drm *priv);
#endif /* __MESON_ENCODER_HDMI_H */ #endif /* __MESON_ENCODER_HDMI_H */
...@@ -403,17 +403,10 @@ static int panel_edp_unprepare(struct drm_panel *panel) ...@@ -403,17 +403,10 @@ static int panel_edp_unprepare(struct drm_panel *panel)
static int panel_edp_get_hpd_gpio(struct device *dev, struct panel_edp *p) static int panel_edp_get_hpd_gpio(struct device *dev, struct panel_edp *p)
{ {
int err;
p->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); p->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
if (IS_ERR(p->hpd_gpio)) { if (IS_ERR(p->hpd_gpio))
err = PTR_ERR(p->hpd_gpio); return dev_err_probe(dev, PTR_ERR(p->hpd_gpio),
"failed to get 'hpd' GPIO\n");
if (err != -EPROBE_DEFER)
dev_err(dev, "failed to get 'hpd' GPIO: %d\n", err);
return err;
}
return 0; return 0;
} }
...@@ -832,12 +825,9 @@ static int panel_edp_probe(struct device *dev, const struct panel_desc *desc, ...@@ -832,12 +825,9 @@ static int panel_edp_probe(struct device *dev, const struct panel_desc *desc,
panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (IS_ERR(panel->enable_gpio)) { if (IS_ERR(panel->enable_gpio))
err = PTR_ERR(panel->enable_gpio); return dev_err_probe(dev, PTR_ERR(panel->enable_gpio),
if (err != -EPROBE_DEFER) "failed to request GPIO\n");
dev_err(dev, "failed to request GPIO: %d\n", err);
return err;
}
err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation); err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
if (err) { if (err) {
...@@ -1878,6 +1868,7 @@ static const struct panel_delay delay_200_500_e200 = { ...@@ -1878,6 +1868,7 @@ static const struct panel_delay delay_200_500_e200 = {
static const struct edp_panel_entry edp_panels[] = { static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"),
...@@ -1885,10 +1876,15 @@ static const struct edp_panel_entry edp_panels[] = { ...@@ -1885,10 +1876,15 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x094b, &delay_200_500_e50, "NT116WHM-N21"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x09dd, &delay_200_500_e50, "NT116WHM-N21"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ac5, &delay_200_500_e50, "NV116WHM-N4C"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, &innolux_n116bca_ea1.delay, "N116BCA-EA1"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, &innolux_n116bca_ea1.delay, "N116BCA-EA1"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x1152, &delay_200_500_e80_d50, "N116BCN-EA1"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x1154, &delay_200_500_e80_d50, "N116BCA-EA2"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1"),
EDP_PANEL_ENTRY('I', 'V', 'O', 0x057d, &delay_200_500_e200, "R140NWF5 RH"), EDP_PANEL_ENTRY('I', 'V', 'O', 0x057d, &delay_200_500_e200, "R140NWF5 RH"),
......
...@@ -575,12 +575,9 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) ...@@ -575,12 +575,9 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (IS_ERR(panel->enable_gpio)) { if (IS_ERR(panel->enable_gpio))
err = PTR_ERR(panel->enable_gpio); return dev_err_probe(dev, PTR_ERR(panel->enable_gpio),
if (err != -EPROBE_DEFER) "failed to request GPIO\n");
dev_err(dev, "failed to request GPIO: %d\n", err);
return err;
}
err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation); err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
if (err) { if (err) {
...@@ -2701,6 +2698,36 @@ static const struct panel_desc multi_inno_mi0700s4t_6 = { ...@@ -2701,6 +2698,36 @@ static const struct panel_desc multi_inno_mi0700s4t_6 = {
.connector_type = DRM_MODE_CONNECTOR_DPI, .connector_type = DRM_MODE_CONNECTOR_DPI,
}; };
static const struct display_timing multi_inno_mi0800ft_9_timing = {
.pixelclock = { 32000000, 40000000, 50000000 },
.hactive = { 800, 800, 800 },
.hfront_porch = { 16, 210, 354 },
.hback_porch = { 6, 26, 45 },
.hsync_len = { 1, 20, 40 },
.vactive = { 600, 600, 600 },
.vfront_porch = { 1, 12, 77 },
.vback_porch = { 3, 13, 22 },
.vsync_len = { 1, 10, 20 },
.flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
DISPLAY_FLAGS_SYNC_POSEDGE,
};
static const struct panel_desc multi_inno_mi0800ft_9 = {
.timings = &multi_inno_mi0800ft_9_timing,
.num_timings = 1,
.bpc = 8,
.size = {
.width = 162,
.height = 122,
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_DE_HIGH |
DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
static const struct display_timing multi_inno_mi1010ait_1cp_timing = { static const struct display_timing multi_inno_mi1010ait_1cp_timing = {
.pixelclock = { 68900000, 70000000, 73400000 }, .pixelclock = { 68900000, 70000000, 73400000 },
.hactive = { 1280, 1280, 1280 }, .hactive = { 1280, 1280, 1280 },
...@@ -4132,6 +4159,9 @@ static const struct of_device_id platform_of_match[] = { ...@@ -4132,6 +4159,9 @@ static const struct of_device_id platform_of_match[] = {
}, { }, {
.compatible = "multi-inno,mi0700s4t-6", .compatible = "multi-inno,mi0700s4t-6",
.data = &multi_inno_mi0700s4t_6, .data = &multi_inno_mi0700s4t_6,
}, {
.compatible = "multi-inno,mi0800ft-9",
.data = &multi_inno_mi0800ft_9,
}, { }, {
.compatible = "multi-inno,mi1010ait-1cp", .compatible = "multi-inno,mi1010ait-1cp",
.data = &multi_inno_mi1010ait_1cp, .data = &multi_inno_mi1010ait_1cp,
......
...@@ -53,17 +53,11 @@ void qxl_ring_free(struct qxl_ring *ring) ...@@ -53,17 +53,11 @@ void qxl_ring_free(struct qxl_ring *ring)
kfree(ring); kfree(ring);
} }
void qxl_ring_init_hdr(struct qxl_ring *ring)
{
ring->ring->header.notify_on_prod = ring->n_elements;
}
struct qxl_ring * struct qxl_ring *
qxl_ring_create(struct qxl_ring_header *header, qxl_ring_create(struct qxl_ring_header *header,
int element_size, int element_size,
int n_elements, int n_elements,
int prod_notify, int prod_notify,
bool set_prod_notify,
wait_queue_head_t *push_event) wait_queue_head_t *push_event)
{ {
struct qxl_ring *ring; struct qxl_ring *ring;
...@@ -77,8 +71,6 @@ qxl_ring_create(struct qxl_ring_header *header, ...@@ -77,8 +71,6 @@ qxl_ring_create(struct qxl_ring_header *header,
ring->n_elements = n_elements; ring->n_elements = n_elements;
ring->prod_notify = prod_notify; ring->prod_notify = prod_notify;
ring->push_event = push_event; ring->push_event = push_event;
if (set_prod_notify)
qxl_ring_init_hdr(ring);
spin_lock_init(&ring->lock); spin_lock_init(&ring->lock);
return ring; return ring;
} }
......
...@@ -277,10 +277,8 @@ struct qxl_ring *qxl_ring_create(struct qxl_ring_header *header, ...@@ -277,10 +277,8 @@ struct qxl_ring *qxl_ring_create(struct qxl_ring_header *header,
int element_size, int element_size,
int n_elements, int n_elements,
int prod_notify, int prod_notify,
bool set_prod_notify,
wait_queue_head_t *push_event); wait_queue_head_t *push_event);
void qxl_ring_free(struct qxl_ring *ring); void qxl_ring_free(struct qxl_ring *ring);
void qxl_ring_init_hdr(struct qxl_ring *ring);
int qxl_check_idle(struct qxl_ring *ring); int qxl_check_idle(struct qxl_ring *ring);
static inline uint64_t static inline uint64_t
......
...@@ -194,7 +194,6 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -194,7 +194,6 @@ int qxl_device_init(struct qxl_device *qdev,
sizeof(struct qxl_command), sizeof(struct qxl_command),
QXL_COMMAND_RING_SIZE, QXL_COMMAND_RING_SIZE,
qdev->io_base + QXL_IO_NOTIFY_CMD, qdev->io_base + QXL_IO_NOTIFY_CMD,
false,
&qdev->display_event); &qdev->display_event);
if (!qdev->command_ring) { if (!qdev->command_ring) {
DRM_ERROR("Unable to create command ring\n"); DRM_ERROR("Unable to create command ring\n");
...@@ -207,7 +206,6 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -207,7 +206,6 @@ int qxl_device_init(struct qxl_device *qdev,
sizeof(struct qxl_command), sizeof(struct qxl_command),
QXL_CURSOR_RING_SIZE, QXL_CURSOR_RING_SIZE,
qdev->io_base + QXL_IO_NOTIFY_CURSOR, qdev->io_base + QXL_IO_NOTIFY_CURSOR,
false,
&qdev->cursor_event); &qdev->cursor_event);
if (!qdev->cursor_ring) { if (!qdev->cursor_ring) {
...@@ -219,7 +217,7 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -219,7 +217,7 @@ int qxl_device_init(struct qxl_device *qdev,
qdev->release_ring = qxl_ring_create( qdev->release_ring = qxl_ring_create(
&(qdev->ram_header->release_ring_hdr), &(qdev->ram_header->release_ring_hdr),
sizeof(uint64_t), sizeof(uint64_t),
QXL_RELEASE_RING_SIZE, 0, true, QXL_RELEASE_RING_SIZE, 0,
NULL); NULL);
if (!qdev->release_ring) { if (!qdev->release_ring) {
......
...@@ -555,21 +555,28 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m ...@@ -555,21 +555,28 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
if (ret)
goto out_free;
iosys_map_set_vaddr(&dst, buf); iosys_map_set_vaddr(&dst, buf);
drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect); drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect);
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
ssd130x_update_rect(ssd130x, buf, rect); ssd130x_update_rect(ssd130x, buf, rect);
out_free:
kfree(buf); kfree(buf);
return ret; return ret;
} }
static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane, static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *old_state) struct drm_atomic_state *state)
{ {
struct drm_plane_state *plane_state = plane->state; struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane); struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_device *drm = plane->dev; struct drm_device *drm = plane->dev;
struct drm_rect src_clip, dst_clip; struct drm_rect src_clip, dst_clip;
...@@ -591,7 +598,7 @@ static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -591,7 +598,7 @@ static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane,
} }
static void ssd130x_primary_plane_helper_atomic_disable(struct drm_plane *plane, static void ssd130x_primary_plane_helper_atomic_disable(struct drm_plane *plane,
struct drm_atomic_state *old_state) struct drm_atomic_state *state)
{ {
struct drm_device *drm = plane->dev; struct drm_device *drm = plane->dev;
struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
#define TEST_BUF_SIZE 50 #define TEST_BUF_SIZE 50
struct convert_to_gray8_result {
unsigned int dst_pitch;
const u8 expected[TEST_BUF_SIZE];
};
struct convert_to_rgb332_result { struct convert_to_rgb332_result {
unsigned int dst_pitch; unsigned int dst_pitch;
const u8 expected[TEST_BUF_SIZE]; const u8 expected[TEST_BUF_SIZE];
...@@ -27,13 +32,26 @@ struct convert_to_rgb565_result { ...@@ -27,13 +32,26 @@ struct convert_to_rgb565_result {
const u16 expected_swab[TEST_BUF_SIZE]; const u16 expected_swab[TEST_BUF_SIZE];
}; };
struct convert_to_rgb888_result {
unsigned int dst_pitch;
const u8 expected[TEST_BUF_SIZE];
};
struct convert_to_xrgb2101010_result {
unsigned int dst_pitch;
const u32 expected[TEST_BUF_SIZE];
};
struct convert_xrgb8888_case { struct convert_xrgb8888_case {
const char *name; const char *name;
unsigned int pitch; unsigned int pitch;
struct drm_rect clip; struct drm_rect clip;
const u32 xrgb8888[TEST_BUF_SIZE]; const u32 xrgb8888[TEST_BUF_SIZE];
struct convert_to_gray8_result gray8_result;
struct convert_to_rgb332_result rgb332_result; struct convert_to_rgb332_result rgb332_result;
struct convert_to_rgb565_result rgb565_result; struct convert_to_rgb565_result rgb565_result;
struct convert_to_rgb888_result rgb888_result;
struct convert_to_xrgb2101010_result xrgb2101010_result;
}; };
static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
...@@ -42,6 +60,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -42,6 +60,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
.pitch = 1 * 4, .pitch = 1 * 4,
.clip = DRM_RECT_INIT(0, 0, 1, 1), .clip = DRM_RECT_INIT(0, 0, 1, 1),
.xrgb8888 = { 0x01FF0000 }, .xrgb8888 = { 0x01FF0000 },
.gray8_result = {
.dst_pitch = 0,
.expected = { 0x4C },
},
.rgb332_result = { .rgb332_result = {
.dst_pitch = 0, .dst_pitch = 0,
.expected = { 0xE0 }, .expected = { 0xE0 },
...@@ -51,6 +73,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -51,6 +73,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
.expected = { 0xF800 }, .expected = { 0xF800 },
.expected_swab = { 0x00F8 }, .expected_swab = { 0x00F8 },
}, },
.rgb888_result = {
.dst_pitch = 0,
.expected = { 0x00, 0x00, 0xFF },
},
.xrgb2101010_result = {
.dst_pitch = 0,
.expected = { 0x3FF00000 },
},
}, },
{ {
.name = "single_pixel_clip_rectangle", .name = "single_pixel_clip_rectangle",
...@@ -60,6 +90,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -60,6 +90,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x10FF0000, 0x00000000, 0x10FF0000,
}, },
.gray8_result = {
.dst_pitch = 0,
.expected = { 0x4C },
},
.rgb332_result = { .rgb332_result = {
.dst_pitch = 0, .dst_pitch = 0,
.expected = { 0xE0 }, .expected = { 0xE0 },
...@@ -69,6 +103,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -69,6 +103,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
.expected = { 0xF800 }, .expected = { 0xF800 },
.expected_swab = { 0x00F8 }, .expected_swab = { 0x00F8 },
}, },
.rgb888_result = {
.dst_pitch = 0,
.expected = { 0x00, 0x00, 0xFF },
},
.xrgb2101010_result = {
.dst_pitch = 0,
.expected = { 0x3FF00000 },
},
}, },
{ {
/* Well known colors: White, black, red, green, blue, magenta, /* Well known colors: White, black, red, green, blue, magenta,
...@@ -85,6 +127,15 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -85,6 +127,15 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000, 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000, 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
}, },
.gray8_result = {
.dst_pitch = 0,
.expected = {
0xFF, 0x00,
0x4C, 0x99,
0x19, 0x66,
0xE5, 0xB2,
},
},
.rgb332_result = { .rgb332_result = {
.dst_pitch = 0, .dst_pitch = 0,
.expected = { .expected = {
...@@ -109,6 +160,24 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -109,6 +160,24 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
0xE0FF, 0xFF07, 0xE0FF, 0xFF07,
}, },
}, },
.rgb888_result = {
.dst_pitch = 0,
.expected = {
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
},
},
.xrgb2101010_result = {
.dst_pitch = 0,
.expected = {
0x3FFFFFFF, 0x00000000,
0x3FF00000, 0x000FFC00,
0x000003FF, 0x3FF003FF,
0x3FFFFC00, 0x000FFFFF,
},
},
}, },
{ {
/* Randomly picked colors. Full buffer within the clip area. */ /* Randomly picked colors. Full buffer within the clip area. */
...@@ -120,6 +189,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -120,6 +189,14 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
0xD16C7073, 0xA20E449C, 0xB2114D05, 0xD16C7073, 0xA20E449C, 0xB2114D05,
0xC2A80303, 0xD26C7073, 0xA30E449C, 0xC2A80303, 0xD26C7073, 0xA30E449C,
}, },
.gray8_result = {
.dst_pitch = 5,
.expected = {
0x3C, 0x33, 0x34, 0x00, 0x00,
0x6F, 0x3C, 0x33, 0x00, 0x00,
0x34, 0x6F, 0x3C, 0x00, 0x00,
},
},
.rgb332_result = { .rgb332_result = {
.dst_pitch = 5, .dst_pitch = 5,
.expected = { .expected = {
...@@ -141,6 +218,25 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { ...@@ -141,6 +218,25 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000, 0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000,
}, },
}, },
.rgb888_result = {
.dst_pitch = 15,
.expected = {
0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0x03, 0xA8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x03, 0xA8, 0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
.xrgb2101010_result = {
.dst_pitch = 20,
.expected = {
0x03844672, 0x0444D414, 0x2A20300C, 0x00000000, 0x00000000,
0x1B1705CD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
0x2A20300C, 0x1B1705CD, 0x03844672, 0x00000000, 0x00000000,
},
},
}, },
}; };
...@@ -192,6 +288,36 @@ static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t, ...@@ -192,6 +288,36 @@ static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases, KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
convert_xrgb8888_case_desc); convert_xrgb8888_case_desc);
static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
{
const struct convert_xrgb8888_case *params = test->param_value;
const struct convert_to_gray8_result *result = &params->gray8_result;
size_t dst_size;
__u8 *buf = NULL;
__u32 *xrgb8888 = NULL;
struct iosys_map dst, src;
struct drm_framebuffer fb = {
.format = drm_format_info(DRM_FORMAT_XRGB8888),
.pitches = { params->pitch, 0, 0 },
};
dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
&params->clip);
KUNIT_ASSERT_GT(test, dst_size, 0);
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
iosys_map_set_vaddr(&dst, buf);
xrgb8888 = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
iosys_map_set_vaddr(&src, xrgb8888);
drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, &params->clip);
KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
}
static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test) static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
{ {
const struct convert_xrgb8888_case *params = test->param_value; const struct convert_xrgb8888_case *params = test->param_value;
...@@ -255,9 +381,73 @@ static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test) ...@@ -255,9 +381,73 @@ static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected_swab, dst_size), 0); KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected_swab, dst_size), 0);
} }
static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
{
const struct convert_xrgb8888_case *params = test->param_value;
const struct convert_to_rgb888_result *result = &params->rgb888_result;
size_t dst_size;
__u8 *buf = NULL;
__u32 *xrgb8888 = NULL;
struct iosys_map dst, src;
struct drm_framebuffer fb = {
.format = drm_format_info(DRM_FORMAT_XRGB8888),
.pitches = { params->pitch, 0, 0 },
};
dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
&params->clip);
KUNIT_ASSERT_GT(test, dst_size, 0);
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
iosys_map_set_vaddr(&dst, buf);
xrgb8888 = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
iosys_map_set_vaddr(&src, xrgb8888);
drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
}
static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
{
const struct convert_xrgb8888_case *params = test->param_value;
const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
size_t dst_size;
__u32 *buf = NULL;
__u32 *xrgb8888 = NULL;
struct iosys_map dst, src;
struct drm_framebuffer fb = {
.format = drm_format_info(DRM_FORMAT_XRGB8888),
.pitches = { params->pitch, 0, 0 },
};
dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
result->dst_pitch, &params->clip);
KUNIT_ASSERT_GT(test, dst_size, 0);
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
iosys_map_set_vaddr(&dst, buf);
xrgb8888 = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
iosys_map_set_vaddr(&src, xrgb8888);
drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
buf = le32buf_to_cpu(test, buf, TEST_BUF_SIZE);
KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
}
static struct kunit_case drm_format_helper_test_cases[] = { static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
{} {}
}; };
......
...@@ -470,40 +470,45 @@ static const uint64_t simpledrm_primary_plane_format_modifiers[] = { ...@@ -470,40 +470,45 @@ static const uint64_t simpledrm_primary_plane_format_modifiers[] = {
}; };
static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane, static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *old_state) struct drm_atomic_state *state)
{ {
struct drm_plane_state *plane_state = plane->state; struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane); struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
struct drm_device *dev = plane->dev; struct drm_device *dev = plane->dev;
struct simpledrm_device *sdev = simpledrm_device_of_dev(dev); struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base); struct drm_atomic_helper_damage_iter iter;
struct drm_rect src_clip, dst_clip; struct drm_rect damage;
int idx; int ret, idx;
if (!fb) ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
if (ret)
return; return;
if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip)) if (!drm_dev_enter(dev, &idx))
return; goto out_drm_gem_fb_end_cpu_access;
dst_clip = plane_state->dst; drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
if (!drm_rect_intersect(&dst_clip, &src_clip)) drm_atomic_for_each_plane_damage(&iter, &damage) {
return; struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base);
struct drm_rect dst_clip = plane_state->dst;
if (!drm_dev_enter(dev, &idx)) if (!drm_rect_intersect(&dst_clip, &damage))
return; continue;
iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip)); iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip));
drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb, drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb,
&src_clip); &damage);
}
drm_dev_exit(idx); drm_dev_exit(idx);
out_drm_gem_fb_end_cpu_access:
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
} }
static void simpledrm_primary_plane_helper_atomic_disable(struct drm_plane *plane, static void simpledrm_primary_plane_helper_atomic_disable(struct drm_plane *plane,
struct drm_atomic_state *old_state) struct drm_atomic_state *state)
{ {
struct drm_device *dev = plane->dev; struct drm_device *dev = plane->dev;
struct simpledrm_device *sdev = simpledrm_device_of_dev(dev); struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
...@@ -687,8 +692,11 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, ...@@ -687,8 +692,11 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
drm_err(dev, "no simplefb configuration found\n"); drm_err(dev, "no simplefb configuration found\n");
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
if (!stride) if (!stride) {
stride = DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8); stride = drm_format_info_min_pitch(format, 0, width);
if (drm_WARN_ON(dev, !stride))
return ERR_PTR(-EINVAL);
}
sdev->mode = simpledrm_mode(width, height); sdev->mode = simpledrm_mode(width, height);
sdev->format = format; sdev->format = format;
......
...@@ -402,6 +402,8 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map) ...@@ -402,6 +402,8 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map)
struct ttm_resource *mem = bo->resource; struct ttm_resource *mem = bo->resource;
int ret; int ret;
dma_resv_assert_held(bo->base.resv);
ret = ttm_mem_io_reserve(bo->bdev, mem); ret = ttm_mem_io_reserve(bo->bdev, mem);
if (ret) if (ret)
return ret; return ret;
...@@ -460,6 +462,8 @@ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map) ...@@ -460,6 +462,8 @@ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map)
{ {
struct ttm_resource *mem = bo->resource; struct ttm_resource *mem = bo->resource;
dma_resv_assert_held(bo->base.resv);
if (iosys_map_is_null(map)) if (iosys_map_is_null(map))
return; return;
......
...@@ -47,7 +47,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev, ...@@ -47,7 +47,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev,
struct virtio_gpu_fence_event *e = NULL; struct virtio_gpu_fence_event *e = NULL;
int ret; int ret;
if (!(vfpriv->ring_idx_mask & (1 << ring_idx))) if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx)))
return 0; return 0;
e = kzalloc(sizeof(*e), GFP_KERNEL); e = kzalloc(sizeof(*e), GFP_KERNEL);
......
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