drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
/*
|
2015-04-28 23:35:38 +00:00
|
|
|
* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
* Copyright (C) 2013 Red Hat
|
|
|
|
* Author: Rob Clark <robdclark@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
|
|
* the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mdp5_kms.h"
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
#include <linux/sort.h>
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
#include <drm/drm_mode.h>
|
|
|
|
#include "drm_crtc.h"
|
|
|
|
#include "drm_crtc_helper.h"
|
|
|
|
#include "drm_flip_work.h"
|
|
|
|
|
2015-01-13 22:18:04 +00:00
|
|
|
#define CURSOR_WIDTH 64
|
|
|
|
#define CURSOR_HEIGHT 64
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
struct mdp5_crtc {
|
|
|
|
struct drm_crtc base;
|
|
|
|
int id;
|
|
|
|
bool enabled;
|
|
|
|
|
2014-11-18 17:49:49 +00:00
|
|
|
/* layer mixer used for this CRTC (+ its lock): */
|
|
|
|
#define GET_LM_ID(crtc_id) ((crtc_id == 3) ? 5 : crtc_id)
|
|
|
|
int lm;
|
|
|
|
spinlock_t lm_lock; /* protect REG_MDP5_LM_* registers */
|
|
|
|
|
|
|
|
/* CTL used for this CRTC: */
|
2014-11-18 19:28:43 +00:00
|
|
|
struct mdp5_ctl *ctl;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
/* if there is a pending flip, these will be non-null: */
|
|
|
|
struct drm_pending_vblank_event *event;
|
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
/* Bits have been flushed at the last commit,
|
|
|
|
* used to decide if a vsync has happened since last commit.
|
|
|
|
*/
|
|
|
|
u32 flushed_mask;
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
#define PENDING_CURSOR 0x1
|
|
|
|
#define PENDING_FLIP 0x2
|
|
|
|
atomic_t pending;
|
|
|
|
|
2015-01-13 22:18:04 +00:00
|
|
|
/* for unref'ing cursor bo's after scanout completes: */
|
|
|
|
struct drm_flip_work unref_cursor_work;
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
struct mdp_irq vblank;
|
|
|
|
struct mdp_irq err;
|
2015-04-28 23:35:38 +00:00
|
|
|
struct mdp_irq pp_done;
|
|
|
|
|
|
|
|
struct completion pp_completion;
|
|
|
|
|
|
|
|
bool cmd_mode;
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
struct {
|
|
|
|
/* protect REG_MDP5_LM_CURSOR* registers and cursor scanout_bo*/
|
|
|
|
spinlock_t lock;
|
|
|
|
|
|
|
|
/* current cursor being scanned out: */
|
|
|
|
struct drm_gem_object *scanout_bo;
|
2015-02-24 19:47:57 +00:00
|
|
|
uint32_t width, height;
|
|
|
|
uint32_t x, y;
|
2015-01-13 22:18:04 +00:00
|
|
|
} cursor;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
};
|
|
|
|
#define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base)
|
|
|
|
|
|
|
|
static struct mdp5_kms *get_kms(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct msm_drm_private *priv = crtc->dev->dev_private;
|
|
|
|
return to_mdp5_kms(to_mdp_kms(priv->kms));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void request_pending(struct drm_crtc *crtc, uint32_t pending)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
|
|
|
|
atomic_or(pending, &mdp5_crtc->pending);
|
|
|
|
mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank);
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:35:38 +00:00
|
|
|
static void request_pp_done_pending(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
reinit_completion(&mdp5_crtc->pp_completion);
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
static u32 crtc_flush(struct drm_crtc *crtc, u32 flush_mask)
|
2014-11-18 17:49:49 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: flush=%08x", crtc->name, flush_mask);
|
2015-04-28 23:35:37 +00:00
|
|
|
return mdp5_ctl_commit(mdp5_crtc->ctl, flush_mask);
|
2014-11-18 17:49:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* flush updates, to make sure hw is updated to new scanout fb,
|
|
|
|
* so that we can safely queue unref to current fb (ie. next
|
|
|
|
* vblank we know hw is done w/ previous scanout_fb).
|
|
|
|
*/
|
2015-04-28 23:35:37 +00:00
|
|
|
static u32 crtc_flush_all(struct drm_crtc *crtc)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
2014-11-12 16:37:12 +00:00
|
|
|
struct drm_plane *plane;
|
2014-11-18 17:49:49 +00:00
|
|
|
uint32_t flush_mask = 0;
|
|
|
|
|
2015-02-20 21:30:56 +00:00
|
|
|
/* this should not happen: */
|
|
|
|
if (WARN_ON(!mdp5_crtc->ctl))
|
2015-04-28 23:35:37 +00:00
|
|
|
return 0;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-26 01:29:47 +00:00
|
|
|
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
2014-11-18 17:49:49 +00:00
|
|
|
flush_mask |= mdp5_plane_get_flush(plane);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
2015-03-13 19:49:33 +00:00
|
|
|
|
|
|
|
flush_mask |= mdp_ctl_flush_mask_lm(mdp5_crtc->lm);
|
2014-11-12 16:37:12 +00:00
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
return crtc_flush(crtc, flush_mask);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if file!=NULL, this is preclose potential cancel-flip path */
|
|
|
|
static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct drm_pending_vblank_event *event;
|
2014-11-12 16:37:12 +00:00
|
|
|
unsigned long flags;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
event = mdp5_crtc->event;
|
|
|
|
if (event) {
|
|
|
|
/* if regular vblank case (!file) or if cancel-flip from
|
|
|
|
* preclose on file that requested flip, then send the
|
|
|
|
* event:
|
|
|
|
*/
|
|
|
|
if (!file || (event->base.file_priv == file)) {
|
|
|
|
mdp5_crtc->event = NULL;
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: send event: %p", crtc->name, event);
|
2016-04-14 17:48:16 +00:00
|
|
|
drm_crtc_send_vblank_event(crtc, event);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
2015-02-20 21:30:56 +00:00
|
|
|
if (mdp5_crtc->ctl && !crtc->state->enable) {
|
2015-05-15 00:21:37 +00:00
|
|
|
/* set STAGE_UNUSED for all layers */
|
2015-06-26 20:03:25 +00:00
|
|
|
mdp5_ctl_blend(mdp5_crtc->ctl, NULL, 0, 0);
|
2015-02-20 21:30:56 +00:00
|
|
|
mdp5_crtc->ctl = NULL;
|
|
|
|
}
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-13 22:18:04 +00:00
|
|
|
static void unref_cursor_worker(struct drm_flip_work *work, void *val)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc =
|
|
|
|
container_of(work, struct mdp5_crtc, unref_cursor_work);
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
|
|
|
|
|
|
|
|
msm_gem_put_iova(val, mdp5_kms->id);
|
|
|
|
drm_gem_object_unreference_unlocked(val);
|
|
|
|
}
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
static void mdp5_crtc_destroy(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
|
|
|
|
drm_crtc_cleanup(crtc);
|
2015-01-13 22:18:04 +00:00
|
|
|
drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
kfree(mdp5_crtc);
|
|
|
|
}
|
|
|
|
|
2014-11-18 17:49:49 +00:00
|
|
|
/*
|
|
|
|
* blend_setup() - blend all the planes of a CRTC
|
|
|
|
*
|
2015-06-25 21:37:42 +00:00
|
|
|
* If no base layer is available, border will be enabled as the base layer.
|
|
|
|
* Otherwise all layers will be blended based on their stage calculated
|
|
|
|
* in mdp5_crtc_atomic_check.
|
2014-11-18 17:49:49 +00:00
|
|
|
*/
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
static void blend_setup(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
2014-11-18 17:49:49 +00:00
|
|
|
struct drm_plane *plane;
|
|
|
|
const struct mdp5_cfg_hw *hw_cfg;
|
2015-06-25 21:37:42 +00:00
|
|
|
struct mdp5_plane_state *pstate, *pstates[STAGE_MAX + 1] = {NULL};
|
|
|
|
const struct mdp_format *format;
|
|
|
|
uint32_t lm = mdp5_crtc->lm;
|
|
|
|
uint32_t blend_op, fg_alpha, bg_alpha, ctl_blend_flags = 0;
|
2014-11-18 17:49:49 +00:00
|
|
|
unsigned long flags;
|
2015-06-25 21:37:42 +00:00
|
|
|
uint8_t stage[STAGE_MAX + 1];
|
|
|
|
int i, plane_cnt = 0;
|
|
|
|
#define blender(stage) ((stage) - STAGE0)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-18 19:28:43 +00:00
|
|
|
hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-18 17:49:49 +00:00
|
|
|
spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
|
|
|
|
|
|
|
|
/* ctl could be released already when we are shutting down: */
|
|
|
|
if (!mdp5_crtc->ctl)
|
|
|
|
goto out;
|
|
|
|
|
2015-06-25 21:37:42 +00:00
|
|
|
/* Collect all plane information */
|
2014-11-26 01:29:47 +00:00
|
|
|
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
2015-06-25 21:37:42 +00:00
|
|
|
pstate = to_mdp5_plane_state(plane->state);
|
|
|
|
pstates[pstate->stage] = pstate;
|
|
|
|
stage[pstate->stage] = mdp5_plane_pipe(plane);
|
|
|
|
plane_cnt++;
|
|
|
|
}
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2016-10-13 16:43:17 +00:00
|
|
|
if (!pstates[STAGE_BASE]) {
|
2015-06-25 21:37:42 +00:00
|
|
|
ctl_blend_flags |= MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT;
|
|
|
|
DBG("Border Color is enabled");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The reset for blending */
|
|
|
|
for (i = STAGE0; i <= STAGE_MAX; i++) {
|
|
|
|
if (!pstates[i])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
format = to_mdp_format(
|
|
|
|
msm_framebuffer_format(pstates[i]->base.fb));
|
|
|
|
plane = pstates[i]->base.plane;
|
|
|
|
blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST);
|
|
|
|
fg_alpha = pstates[i]->alpha;
|
|
|
|
bg_alpha = 0xFF - pstates[i]->alpha;
|
|
|
|
DBG("Stage %d fg_alpha %x bg_alpha %x", i, fg_alpha, bg_alpha);
|
|
|
|
|
|
|
|
if (format->alpha_enable && pstates[i]->premultiplied) {
|
|
|
|
blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
|
|
|
|
if (fg_alpha != 0xff) {
|
|
|
|
bg_alpha = fg_alpha;
|
|
|
|
blend_op |=
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_MOD_ALPHA |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_INV_MOD_ALPHA;
|
|
|
|
} else {
|
|
|
|
blend_op |= MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA;
|
|
|
|
}
|
|
|
|
} else if (format->alpha_enable) {
|
|
|
|
blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_PIXEL) |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
|
|
|
|
if (fg_alpha != 0xff) {
|
|
|
|
bg_alpha = fg_alpha;
|
|
|
|
blend_op |=
|
|
|
|
MDP5_LM_BLEND_OP_MODE_FG_MOD_ALPHA |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_FG_INV_MOD_ALPHA |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_MOD_ALPHA |
|
|
|
|
MDP5_LM_BLEND_OP_MODE_BG_INV_MOD_ALPHA;
|
|
|
|
} else {
|
|
|
|
blend_op |= MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA;
|
|
|
|
}
|
|
|
|
}
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2015-06-25 21:37:42 +00:00
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_OP_MODE(lm,
|
|
|
|
blender(i)), blend_op);
|
2014-11-18 17:49:49 +00:00
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_FG_ALPHA(lm,
|
2015-06-25 21:37:42 +00:00
|
|
|
blender(i)), fg_alpha);
|
2014-11-18 17:49:49 +00:00
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(lm,
|
2015-06-25 21:37:42 +00:00
|
|
|
blender(i)), bg_alpha);
|
2014-11-18 17:49:49 +00:00
|
|
|
}
|
|
|
|
|
2015-06-26 20:03:25 +00:00
|
|
|
mdp5_ctl_blend(mdp5_crtc->ctl, stage, plane_cnt, ctl_blend_flags);
|
2014-11-18 17:49:49 +00:00
|
|
|
|
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
2014-11-18 17:49:49 +00:00
|
|
|
unsigned long flags;
|
2014-11-19 17:31:03 +00:00
|
|
|
struct drm_display_mode *mode;
|
|
|
|
|
|
|
|
if (WARN_ON(!crtc->state))
|
|
|
|
return;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
mode = &crtc->state->adjusted_mode;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
|
2016-10-31 20:05:22 +00:00
|
|
|
crtc->name, mode->base.id, mode->name,
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
mode->vrefresh, mode->clock,
|
|
|
|
mode->hdisplay, mode->hsync_start,
|
|
|
|
mode->hsync_end, mode->htotal,
|
|
|
|
mode->vdisplay, mode->vsync_start,
|
|
|
|
mode->vsync_end, mode->vtotal,
|
|
|
|
mode->type, mode->flags);
|
|
|
|
|
2014-11-18 17:49:49 +00:00
|
|
|
spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(mdp5_crtc->lm),
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) |
|
|
|
|
MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay));
|
2014-11-18 17:49:49 +00:00
|
|
|
spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-30 22:04:45 +00:00
|
|
|
static void mdp5_crtc_disable(struct drm_crtc *crtc)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
2015-01-30 22:04:45 +00:00
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s", crtc->name);
|
2015-01-30 22:04:45 +00:00
|
|
|
|
|
|
|
if (WARN_ON(!mdp5_crtc->enabled))
|
|
|
|
return;
|
|
|
|
|
2015-04-28 23:35:38 +00:00
|
|
|
if (mdp5_crtc->cmd_mode)
|
|
|
|
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done);
|
|
|
|
|
2015-01-30 22:04:45 +00:00
|
|
|
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
|
|
|
|
mdp5_disable(mdp5_kms);
|
|
|
|
|
|
|
|
mdp5_crtc->enabled = false;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-30 22:04:45 +00:00
|
|
|
static void mdp5_crtc_enable(struct drm_crtc *crtc)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
2014-11-19 17:31:03 +00:00
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
2015-01-30 22:04:45 +00:00
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s", crtc->name);
|
2015-01-30 22:04:45 +00:00
|
|
|
|
|
|
|
if (WARN_ON(mdp5_crtc->enabled))
|
|
|
|
return;
|
|
|
|
|
|
|
|
mdp5_enable(mdp5_kms);
|
|
|
|
mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
|
|
|
|
|
2015-04-28 23:35:38 +00:00
|
|
|
if (mdp5_crtc->cmd_mode)
|
|
|
|
mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done);
|
|
|
|
|
2015-01-30 22:04:45 +00:00
|
|
|
mdp5_crtc->enabled = true;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
struct plane_state {
|
|
|
|
struct drm_plane *plane;
|
|
|
|
struct mdp5_plane_state *state;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pstate_cmp(const void *a, const void *b)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
2014-11-19 17:31:03 +00:00
|
|
|
struct plane_state *pa = (struct plane_state *)a;
|
|
|
|
struct plane_state *pb = (struct plane_state *)b;
|
|
|
|
return pa->state->zpos - pb->state->zpos;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2016-10-13 16:43:17 +00:00
|
|
|
/* is there a helper for this? */
|
|
|
|
static bool is_fullscreen(struct drm_crtc_state *cstate,
|
|
|
|
struct drm_plane_state *pstate)
|
|
|
|
{
|
|
|
|
return (pstate->crtc_x <= 0) && (pstate->crtc_y <= 0) &&
|
|
|
|
((pstate->crtc_x + pstate->crtc_w) >= cstate->mode.hdisplay) &&
|
|
|
|
((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay);
|
|
|
|
}
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|
|
|
struct drm_crtc_state *state)
|
2014-11-18 17:49:49 +00:00
|
|
|
{
|
2014-11-19 17:31:03 +00:00
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
|
|
|
struct drm_plane *plane;
|
|
|
|
struct drm_device *dev = crtc->dev;
|
2015-06-25 21:37:42 +00:00
|
|
|
struct plane_state pstates[STAGE_MAX + 1];
|
|
|
|
const struct mdp5_cfg_hw *hw_cfg;
|
2016-06-02 14:21:44 +00:00
|
|
|
const struct drm_plane_state *pstate;
|
2016-10-13 16:43:17 +00:00
|
|
|
int cnt = 0, base = 0, i;
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: check", crtc->name);
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2016-06-02 14:21:44 +00:00
|
|
|
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
|
2014-11-19 17:31:03 +00:00
|
|
|
pstates[cnt].plane = plane;
|
|
|
|
pstates[cnt].state = to_mdp5_plane_state(pstate);
|
|
|
|
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
|
2015-06-25 21:37:42 +00:00
|
|
|
/* assign a stage based on sorted zpos property */
|
2014-11-19 17:31:03 +00:00
|
|
|
sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
|
|
|
|
|
2016-10-13 16:43:17 +00:00
|
|
|
/* if the bottom-most layer is not fullscreen, we need to use
|
|
|
|
* it for solid-color:
|
|
|
|
*/
|
|
|
|
if ((cnt > 0) && !is_fullscreen(state, &pstates[0].state->base))
|
|
|
|
base++;
|
|
|
|
|
|
|
|
/* verify that there are not too many planes attached to crtc
|
|
|
|
* and that we don't have conflicting mixer stages:
|
|
|
|
*/
|
|
|
|
hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
|
|
|
|
|
|
|
|
if ((cnt + base) >= hw_cfg->lm.nb_stages) {
|
2016-10-31 20:05:22 +00:00
|
|
|
dev_err(dev->dev, "too many planes! cnt=%d, base=%d\n", cnt, base);
|
2016-10-13 16:43:17 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
for (i = 0; i < cnt; i++) {
|
2016-10-13 16:43:17 +00:00
|
|
|
pstates[i].state->stage = STAGE_BASE + i + base;
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: assign pipe %s on stage=%d", crtc->name,
|
2016-11-01 15:56:54 +00:00
|
|
|
pstates[i].plane->name,
|
2014-11-19 17:31:03 +00:00
|
|
|
pstates[i].state->stage);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2014-11-18 17:49:49 +00:00
|
|
|
}
|
|
|
|
|
2015-07-21 11:28:58 +00:00
|
|
|
static void mdp5_crtc_atomic_begin(struct drm_crtc *crtc,
|
|
|
|
struct drm_crtc_state *old_crtc_state)
|
2014-11-19 17:31:03 +00:00
|
|
|
{
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: begin", crtc->name);
|
2014-11-19 17:31:03 +00:00
|
|
|
}
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2015-07-21 11:28:58 +00:00
|
|
|
static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
|
|
|
|
struct drm_crtc_state *old_crtc_state)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
unsigned long flags;
|
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: event: %p", crtc->name, crtc->state->event);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
WARN_ON(mdp5_crtc->event);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
2014-11-19 17:31:03 +00:00
|
|
|
mdp5_crtc->event = crtc->state->event;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
2015-02-20 21:30:56 +00:00
|
|
|
/*
|
|
|
|
* If no CTL has been allocated in mdp5_crtc_atomic_check(),
|
|
|
|
* it means we are trying to flush a CRTC whose state is disabled:
|
|
|
|
* nothing else needs to be done.
|
|
|
|
*/
|
|
|
|
if (unlikely(!mdp5_crtc->ctl))
|
|
|
|
return;
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
blend_setup(crtc);
|
2015-04-28 23:35:37 +00:00
|
|
|
|
2015-04-28 23:35:38 +00:00
|
|
|
/* PP_DONE irq is only used by command mode for now.
|
|
|
|
* It is better to request pending before FLUSH and START trigger
|
|
|
|
* to make sure no pp_done irq missed.
|
|
|
|
* This is safe because no pp_done will happen before SW trigger
|
|
|
|
* in command mode.
|
|
|
|
*/
|
|
|
|
if (mdp5_crtc->cmd_mode)
|
|
|
|
request_pp_done_pending(crtc);
|
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
mdp5_crtc->flushed_mask = crtc_flush_all(crtc);
|
|
|
|
|
2014-11-19 17:31:03 +00:00
|
|
|
request_pending(crtc, PENDING_FLIP);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2015-02-24 19:47:57 +00:00
|
|
|
static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
uint32_t xres = crtc->mode.hdisplay;
|
|
|
|
uint32_t yres = crtc->mode.vdisplay;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cursor Region Of Interest (ROI) is a plane read from cursor
|
|
|
|
* buffer to render. The ROI region is determined by the visibility of
|
|
|
|
* the cursor point. In the default Cursor image the cursor point will
|
|
|
|
* be at the top left of the cursor image, unless it is specified
|
|
|
|
* otherwise using hotspot feature.
|
|
|
|
*
|
|
|
|
* If the cursor point reaches the right (xres - x < cursor.width) or
|
|
|
|
* bottom (yres - y < cursor.height) boundary of the screen, then ROI
|
|
|
|
* width and ROI height need to be evaluated to crop the cursor image
|
|
|
|
* accordingly.
|
|
|
|
* (xres-x) will be new cursor width when x > (xres - cursor.width)
|
|
|
|
* (yres-y) will be new cursor height when y > (yres - cursor.height)
|
|
|
|
*/
|
|
|
|
*roi_w = min(mdp5_crtc->cursor.width, xres -
|
|
|
|
mdp5_crtc->cursor.x);
|
|
|
|
*roi_h = min(mdp5_crtc->cursor.height, yres -
|
|
|
|
mdp5_crtc->cursor.y);
|
|
|
|
}
|
|
|
|
|
2015-01-13 22:18:04 +00:00
|
|
|
static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
|
|
|
struct drm_file *file, uint32_t handle,
|
|
|
|
uint32_t width, uint32_t height)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
2015-03-13 19:49:33 +00:00
|
|
|
struct drm_gem_object *cursor_bo, *old_bo = NULL;
|
2016-11-11 17:06:46 +00:00
|
|
|
uint32_t blendcfg, stride;
|
|
|
|
uint64_t cursor_addr;
|
2016-06-08 23:32:10 +00:00
|
|
|
int ret, lm;
|
2015-01-13 22:18:04 +00:00
|
|
|
enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
|
|
|
|
uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
|
2015-02-24 19:47:57 +00:00
|
|
|
uint32_t roi_w, roi_h;
|
2015-03-13 19:49:33 +00:00
|
|
|
bool cursor_enable = true;
|
2015-01-13 22:18:04 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
|
|
|
|
dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL == mdp5_crtc->ctl)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (!handle) {
|
|
|
|
DBG("Cursor off");
|
2015-03-13 19:49:33 +00:00
|
|
|
cursor_enable = false;
|
|
|
|
goto set_cursor;
|
2015-01-13 22:18:04 +00:00
|
|
|
}
|
|
|
|
|
2016-05-09 10:04:54 +00:00
|
|
|
cursor_bo = drm_gem_object_lookup(file, handle);
|
2015-01-13 22:18:04 +00:00
|
|
|
if (!cursor_bo)
|
|
|
|
return -ENOENT;
|
|
|
|
|
|
|
|
ret = msm_gem_get_iova(cursor_bo, mdp5_kms->id, &cursor_addr);
|
|
|
|
if (ret)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
lm = mdp5_crtc->lm;
|
2016-06-08 23:32:10 +00:00
|
|
|
stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
|
|
|
|
old_bo = mdp5_crtc->cursor.scanout_bo;
|
|
|
|
|
2015-02-24 19:47:57 +00:00
|
|
|
mdp5_crtc->cursor.scanout_bo = cursor_bo;
|
|
|
|
mdp5_crtc->cursor.width = width;
|
|
|
|
mdp5_crtc->cursor.height = height;
|
|
|
|
|
|
|
|
get_roi(crtc, &roi_w, &roi_h);
|
|
|
|
|
2015-01-13 22:18:04 +00:00
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
|
|
|
|
MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm),
|
|
|
|
MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) |
|
|
|
|
MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width));
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
|
2015-02-24 19:47:57 +00:00
|
|
|
MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) |
|
|
|
|
MDP5_LM_CURSOR_SIZE_ROI_W(roi_w));
|
2015-01-13 22:18:04 +00:00
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr);
|
|
|
|
|
|
|
|
blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN;
|
|
|
|
blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha);
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
|
|
|
|
|
2015-03-13 19:49:33 +00:00
|
|
|
set_cursor:
|
|
|
|
ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, 0, cursor_enable);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(dev->dev, "failed to %sable cursor: %d\n",
|
|
|
|
cursor_enable ? "en" : "dis", ret);
|
2015-01-13 22:18:04 +00:00
|
|
|
goto end;
|
2015-03-13 19:49:33 +00:00
|
|
|
}
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
crtc_flush(crtc, flush_mask);
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (old_bo) {
|
|
|
|
drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
|
|
|
|
/* enable vblank to complete cursor work: */
|
|
|
|
request_pending(crtc, PENDING_CURSOR);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
|
|
|
{
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
|
|
|
|
uint32_t roi_w;
|
|
|
|
uint32_t roi_h;
|
|
|
|
unsigned long flags;
|
|
|
|
|
2015-02-20 21:30:56 +00:00
|
|
|
/* In case the CRTC is disabled, just drop the cursor update */
|
|
|
|
if (unlikely(!crtc->state->enable))
|
|
|
|
return 0;
|
|
|
|
|
2015-02-24 19:47:57 +00:00
|
|
|
mdp5_crtc->cursor.x = x = max(x, 0);
|
|
|
|
mdp5_crtc->cursor.y = y = max(y, 0);
|
2015-01-13 22:18:04 +00:00
|
|
|
|
2015-02-24 19:47:57 +00:00
|
|
|
get_roi(crtc, &roi_w, &roi_h);
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm),
|
|
|
|
MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) |
|
|
|
|
MDP5_LM_CURSOR_SIZE_ROI_W(roi_w));
|
|
|
|
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(mdp5_crtc->lm),
|
|
|
|
MDP5_LM_CURSOR_START_XY_Y_START(y) |
|
|
|
|
MDP5_LM_CURSOR_START_XY_X_START(x));
|
|
|
|
spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
|
|
|
|
|
|
|
|
crtc_flush(crtc, flush_mask);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
static const struct drm_crtc_funcs mdp5_crtc_funcs = {
|
2014-11-19 17:31:03 +00:00
|
|
|
.set_config = drm_atomic_helper_set_config,
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
.destroy = mdp5_crtc_destroy,
|
2014-11-19 17:31:03 +00:00
|
|
|
.page_flip = drm_atomic_helper_page_flip,
|
2016-02-25 05:49:42 +00:00
|
|
|
.set_property = drm_atomic_helper_crtc_set_property,
|
2014-11-19 17:31:03 +00:00
|
|
|
.reset = drm_atomic_helper_crtc_reset,
|
|
|
|
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
|
|
|
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
2015-01-13 22:18:04 +00:00
|
|
|
.cursor_set = mdp5_crtc_cursor_set,
|
|
|
|
.cursor_move = mdp5_crtc_cursor_move,
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
|
2014-11-19 17:31:03 +00:00
|
|
|
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
|
2015-02-20 17:40:58 +00:00
|
|
|
.disable = mdp5_crtc_disable,
|
|
|
|
.enable = mdp5_crtc_enable,
|
2014-11-19 17:31:03 +00:00
|
|
|
.atomic_check = mdp5_crtc_atomic_check,
|
|
|
|
.atomic_begin = mdp5_crtc_atomic_begin,
|
|
|
|
.atomic_flush = mdp5_crtc_atomic_flush,
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank);
|
|
|
|
struct drm_crtc *crtc = &mdp5_crtc->base;
|
2015-01-13 22:18:04 +00:00
|
|
|
struct msm_drm_private *priv = crtc->dev->dev_private;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
unsigned pending;
|
|
|
|
|
|
|
|
mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank);
|
|
|
|
|
|
|
|
pending = atomic_xchg(&mdp5_crtc->pending, 0);
|
|
|
|
|
|
|
|
if (pending & PENDING_FLIP) {
|
|
|
|
complete_flip(crtc, NULL);
|
|
|
|
}
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
if (pending & PENDING_CURSOR)
|
|
|
|
drm_flip_work_commit(&mdp5_crtc->unref_cursor_work, priv->wq);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, err);
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2016-10-31 20:05:22 +00:00
|
|
|
DBG("%s: error: %08x", mdp5_crtc->base.name, irqstatus);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 23:35:38 +00:00
|
|
|
static void mdp5_crtc_pp_done_irq(struct mdp_irq *irq, uint32_t irqstatus)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc,
|
|
|
|
pp_done);
|
|
|
|
|
|
|
|
complete(&mdp5_crtc->pp_completion);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion,
|
|
|
|
msecs_to_jiffies(50));
|
|
|
|
if (ret == 0)
|
|
|
|
dev_warn(dev->dev, "pp done time out, lm=%d\n", mdp5_crtc->lm);
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
static void mdp5_crtc_wait_for_flush_done(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Should not call this function if crtc is disabled. */
|
|
|
|
if (!mdp5_crtc->ctl)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ret = drm_crtc_vblank_get(crtc);
|
|
|
|
if (ret)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ret = wait_event_timeout(dev->vblank[drm_crtc_index(crtc)].queue,
|
|
|
|
((mdp5_ctl_get_commit_status(mdp5_crtc->ctl) &
|
|
|
|
mdp5_crtc->flushed_mask) == 0),
|
|
|
|
msecs_to_jiffies(50));
|
|
|
|
if (ret <= 0)
|
|
|
|
dev_warn(dev->dev, "vblank time out, crtc=%d\n", mdp5_crtc->id);
|
|
|
|
|
|
|
|
mdp5_crtc->flushed_mask = 0;
|
|
|
|
|
|
|
|
drm_crtc_vblank_put(crtc);
|
|
|
|
}
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
return mdp5_crtc->vblank.irqmask;
|
|
|
|
}
|
|
|
|
|
2015-06-26 20:03:25 +00:00
|
|
|
void mdp5_crtc_set_pipeline(struct drm_crtc *crtc,
|
|
|
|
struct mdp5_interface *intf, struct mdp5_ctl *ctl)
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
2015-03-13 19:49:32 +00:00
|
|
|
int lm = mdp5_crtc_get_lm(crtc);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
/* now that we know what irq's we want: */
|
2015-03-13 19:49:32 +00:00
|
|
|
mdp5_crtc->err.irqmask = intf2err(intf->num);
|
2015-04-28 23:35:38 +00:00
|
|
|
mdp5_crtc->vblank.irqmask = intf2vblank(lm, intf);
|
|
|
|
|
|
|
|
if ((intf->type == INTF_DSI) &&
|
|
|
|
(intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) {
|
|
|
|
mdp5_crtc->pp_done.irqmask = lm2ppdone(lm);
|
|
|
|
mdp5_crtc->pp_done.irq = mdp5_crtc_pp_done_irq;
|
|
|
|
mdp5_crtc->cmd_mode = true;
|
|
|
|
} else {
|
|
|
|
mdp5_crtc->pp_done.irqmask = 0;
|
|
|
|
mdp5_crtc->pp_done.irq = NULL;
|
|
|
|
mdp5_crtc->cmd_mode = false;
|
|
|
|
}
|
2015-04-28 23:35:37 +00:00
|
|
|
|
2014-12-02 16:50:06 +00:00
|
|
|
mdp_irq_update(&mdp5_kms->base);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2015-06-26 20:03:25 +00:00
|
|
|
mdp5_crtc->ctl = ctl;
|
|
|
|
mdp5_ctl_set_pipeline(ctl, intf, lm);
|
2014-11-18 17:49:49 +00:00
|
|
|
}
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
2014-11-18 17:49:49 +00:00
|
|
|
int mdp5_crtc_get_lm(struct drm_crtc *crtc)
|
|
|
|
{
|
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
2015-03-13 19:49:33 +00:00
|
|
|
return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm;
|
|
|
|
}
|
2014-11-18 17:49:49 +00:00
|
|
|
|
2015-04-28 23:35:37 +00:00
|
|
|
void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc)
|
|
|
|
{
|
2015-04-28 23:35:38 +00:00
|
|
|
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
|
|
|
|
|
|
|
if (mdp5_crtc->cmd_mode)
|
|
|
|
mdp5_crtc_wait_for_pp_done(crtc);
|
|
|
|
else
|
|
|
|
mdp5_crtc_wait_for_flush_done(crtc);
|
2015-04-28 23:35:37 +00:00
|
|
|
}
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
/* initialize crtc */
|
|
|
|
struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
|
|
|
struct drm_plane *plane, int id)
|
|
|
|
{
|
|
|
|
struct drm_crtc *crtc = NULL;
|
|
|
|
struct mdp5_crtc *mdp5_crtc;
|
|
|
|
|
|
|
|
mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL);
|
2014-11-14 18:30:30 +00:00
|
|
|
if (!mdp5_crtc)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
crtc = &mdp5_crtc->base;
|
|
|
|
|
|
|
|
mdp5_crtc->id = id;
|
2014-11-18 17:49:49 +00:00
|
|
|
mdp5_crtc->lm = GET_LM_ID(id);
|
|
|
|
|
|
|
|
spin_lock_init(&mdp5_crtc->lm_lock);
|
2015-01-13 22:18:04 +00:00
|
|
|
spin_lock_init(&mdp5_crtc->cursor.lock);
|
2015-04-28 23:35:38 +00:00
|
|
|
init_completion(&mdp5_crtc->pp_completion);
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
|
|
|
|
mdp5_crtc->err.irq = mdp5_crtc_err_irq;
|
|
|
|
|
drm: Pass 'name' to drm_crtc_init_with_planes()
Done with coccinelle for the most part. However, it thinks '...' is
part of the semantic patch, so I put an 'int DOTDOTDOT' placeholder
in its place and got rid of it with sed afterwards.
I didn't convert drm_crtc_init() since passing the varargs through
would mean either cpp macros or va_list, and I figured we don't
care about these legacy functions enough to warrant the extra pain.
@@
identifier dev, crtc, primary, cursor, funcs;
@@
int drm_crtc_init_with_planes(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_plane *primary, struct drm_plane *cursor,
const struct drm_crtc_funcs *funcs
+ ,const char *name, int DOTDOTDOT
)
{ ... }
@@
identifier dev, crtc, primary, cursor, funcs;
@@
int drm_crtc_init_with_planes(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_plane *primary, struct drm_plane *cursor,
const struct drm_crtc_funcs *funcs
+ ,const char *name, int DOTDOTDOT
);
@@
expression E1, E2, E3, E4, E5;
@@
drm_crtc_init_with_planes(E1, E2, E3, E4, E5
+ ,NULL
)
v2: Split crtc and plane changes apart
Pass NULL for no-name instead of ""
Leave drm_crtc_init() alone
v3: Add ', or NULL...' to @name kernel doc (Jani)
Annotate the function with __printf() attribute (Jani)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1449670771-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-12-09 14:19:31 +00:00
|
|
|
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs,
|
|
|
|
NULL);
|
2015-01-13 22:18:04 +00:00
|
|
|
|
|
|
|
drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
|
|
|
|
"unref cursor", unref_cursor_worker);
|
|
|
|
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs);
|
2014-11-12 16:37:12 +00:00
|
|
|
plane->crtc = crtc;
|
drm/msm: add mdp5/apq8x74
Add support for the new MDP5 display controller block. The mapping
between parts of the display controller and KMS is:
plane -> PIPE{RGBn,VIGn} \
crtc -> LM (layer mixer) |-> MDP "device"
encoder -> INTF /
connector -> HDMI/DSI/eDP/etc --> other device(s)
Unlike MDP4, it appears we can get by with a single encoder, rather
than needing a different implementation for DTV, DSI, etc. (Ie. the
register interface is same, just different bases.)
Also unlike MDP4, all the IRQs for other blocks (HDMI, DSI, etc) are
routed through MDP.
And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
which blocks need to be allocated to the active pipes based on fetch
stride.
Signed-off-by: Rob Clark <robdclark@gmail.com>
2013-11-30 22:51:47 +00:00
|
|
|
|
|
|
|
return crtc;
|
|
|
|
}
|