Merge branch 'for-upstream/malidp-fixes' of git://linux-arm.org/linux-ld into drm-fixes

Fix NV12 writeback and fix vblank reset.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Liviu Dudau <Liviu.Dudau@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180921112354.GR936@e110455-lin.cambridge.arm.com
This commit is contained in:
Dave Airlie 2018-09-27 10:49:44 +10:00
commit 576156bb01
5 changed files with 49 additions and 7 deletions

View File

@ -754,6 +754,7 @@ static int malidp_bind(struct device *dev)
drm->irq_enabled = true; drm->irq_enabled = true;
ret = drm_vblank_init(drm, drm->mode_config.num_crtc); ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
drm_crtc_vblank_reset(&malidp->crtc);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n"); DRM_ERROR("failed to initialise vblank\n");
goto vblank_fail; goto vblank_fail;

View File

@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev, static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
dma_addr_t *addrs, s32 *pitches, dma_addr_t *addrs, s32 *pitches,
int num_planes, u16 w, u16 h, u32 fmt_id) int num_planes, u16 w, u16 h, u32 fmt_id,
const s16 *rgb2yuv_coeffs)
{ {
u32 base = MALIDP500_SE_MEMWRITE_BASE; u32 base = MALIDP500_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h), malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
MALIDP500_SE_MEMWRITE_OUT_SIZE); MALIDP500_SE_MEMWRITE_OUT_SIZE);
if (rgb2yuv_coeffs) {
int i;
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
}
}
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL); malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
return 0; return 0;
@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev, static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
dma_addr_t *addrs, s32 *pitches, dma_addr_t *addrs, s32 *pitches,
int num_planes, u16 w, u16 h, u32 fmt_id) int num_planes, u16 w, u16 h, u32 fmt_id,
const s16 *rgb2yuv_coeffs)
{ {
u32 base = MALIDP550_SE_MEMWRITE_BASE; u32 base = MALIDP550_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN, malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
MALIDP550_SE_CONTROL); MALIDP550_SE_CONTROL);
if (rgb2yuv_coeffs) {
int i;
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
}
}
return 0; return 0;
} }

View File

@ -191,7 +191,8 @@ struct malidp_hw {
* @param fmt_id - internal format ID of output buffer * @param fmt_id - internal format ID of output buffer
*/ */
int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs, int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id); s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
const s16 *rgb2yuv_coeffs);
/* /*
* Disable the writing to memory of the next frame's content. * Disable the writing to memory of the next frame's content.

View File

@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
s32 pitches[2]; s32 pitches[2];
u8 format; u8 format;
u8 n_planes; u8 n_planes;
bool rgb2yuv_initialized;
const s16 *rgb2yuv_coeffs;
}; };
static int malidp_mw_connector_get_modes(struct drm_connector *connector) static int malidp_mw_connector_get_modes(struct drm_connector *connector)
@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector)
static struct drm_connector_state * static struct drm_connector_state *
malidp_mw_connector_duplicate_state(struct drm_connector *connector) malidp_mw_connector_duplicate_state(struct drm_connector *connector)
{ {
struct malidp_mw_connector_state *mw_state; struct malidp_mw_connector_state *mw_state, *mw_current_state;
if (WARN_ON(!connector->state)) if (WARN_ON(!connector->state))
return NULL; return NULL;
@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
if (!mw_state) if (!mw_state)
return NULL; return NULL;
/* No need to preserve any of our driver-local data */ mw_current_state = to_mw_state(connector->state);
mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs;
mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized;
__drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base); __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
return &mw_state->base; return &mw_state->base;
@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
47, 157, 16,
-26, -87, 112,
112, -102, -10,
16, 128, 128
};
static int static int
malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state, struct drm_crtc_state *crtc_state,
@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
} }
mw_state->n_planes = n_planes; mw_state->n_planes = n_planes;
if (fb->format->is_yuv)
mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
return 0; return 0;
} }
@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
drm_writeback_queue_job(mw_conn, conn_state->writeback_job); drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
conn_state->writeback_job = NULL; conn_state->writeback_job = NULL;
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs, hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
mw_state->pitches, mw_state->n_planes, mw_state->pitches, mw_state->n_planes,
fb->width, fb->height, mw_state->format); fb->width, fb->height, mw_state->format,
!mw_state->rgb2yuv_initialized ?
mw_state->rgb2yuv_coeffs : NULL);
mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs;
} else { } else {
DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n"); DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
hwdev->hw->disable_memwrite(hwdev); hwdev->hw->disable_memwrite(hwdev);

View File

@ -205,6 +205,7 @@
#define MALIDP500_SE_BASE 0x00c00 #define MALIDP500_SE_BASE 0x00c00
#define MALIDP500_SE_CONTROL 0x00c0c #define MALIDP500_SE_CONTROL 0x00c0c
#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c #define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
#define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74
#define MALIDP500_SE_MEMWRITE_BASE 0x00e00 #define MALIDP500_SE_MEMWRITE_BASE 0x00e00
#define MALIDP500_DC_IRQ_BASE 0x00f00 #define MALIDP500_DC_IRQ_BASE 0x00f00
#define MALIDP500_CONFIG_VALID 0x00f00 #define MALIDP500_CONFIG_VALID 0x00f00
@ -238,6 +239,7 @@
#define MALIDP550_SE_CONTROL 0x08010 #define MALIDP550_SE_CONTROL 0x08010
#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7) #define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030 #define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
#define MALIDP550_SE_RGB_YUV_COEFFS 0x08078
#define MALIDP550_SE_MEMWRITE_BASE 0x08100 #define MALIDP550_SE_MEMWRITE_BASE 0x08100
#define MALIDP550_DC_BASE 0x0c000 #define MALIDP550_DC_BASE 0x0c000
#define MALIDP550_DC_CONTROL 0x0c010 #define MALIDP550_DC_CONTROL 0x0c010