2013-12-01 04:12:10 +07:00
|
|
|
/*
|
2018-06-28 02:26:09 +07:00
|
|
|
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
2013-12-01 04:12:10 +07: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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __MSM_KMS_H__
|
|
|
|
#define __MSM_KMS_H__
|
|
|
|
|
|
|
|
#include <linux/clk.h>
|
|
|
|
#include <linux/regulator/consumer.h>
|
|
|
|
|
|
|
|
#include "msm_drv.h"
|
|
|
|
|
2014-12-08 22:48:57 +07:00
|
|
|
#define MAX_PLANE 4
|
|
|
|
|
2013-12-01 04:12:10 +07:00
|
|
|
/* As there are different display controller blocks depending on the
|
|
|
|
* snapdragon version, the kms support is split out and the appropriate
|
|
|
|
* implementation is loaded at runtime. The kms module is responsible
|
|
|
|
* for constructing the appropriate planes/crtcs/encoders/connectors.
|
|
|
|
*/
|
|
|
|
struct msm_kms_funcs {
|
|
|
|
/* hw initialization: */
|
|
|
|
int (*hw_init)(struct msm_kms *kms);
|
|
|
|
/* irq handling: */
|
|
|
|
void (*irq_preinstall)(struct msm_kms *kms);
|
|
|
|
int (*irq_postinstall)(struct msm_kms *kms);
|
|
|
|
void (*irq_uninstall)(struct msm_kms *kms);
|
|
|
|
irqreturn_t (*irq)(struct msm_kms *kms);
|
|
|
|
int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
|
|
|
|
void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
|
2015-01-31 05:04:45 +07:00
|
|
|
/* modeset, bracketing atomic_commit(): */
|
|
|
|
void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
|
2018-06-28 00:49:23 +07:00
|
|
|
void (*commit)(struct msm_kms *kms, struct drm_atomic_state *state);
|
2015-01-31 05:04:45 +07:00
|
|
|
void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
|
2015-04-29 06:35:37 +07:00
|
|
|
/* functions to wait for atomic commit completed on each CRTC */
|
|
|
|
void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
|
|
|
|
struct drm_crtc *crtc);
|
2018-02-14 00:42:44 +07:00
|
|
|
/* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
|
|
|
|
const struct msm_format *(*get_format)(struct msm_kms *kms,
|
|
|
|
const uint32_t format,
|
|
|
|
const uint64_t modifiers);
|
2018-06-28 02:26:09 +07:00
|
|
|
/* do format checking on format modified through fb_cmd2 modifiers */
|
|
|
|
int (*check_modified_format)(const struct msm_kms *kms,
|
|
|
|
const struct msm_format *msm_fmt,
|
|
|
|
const struct drm_mode_fb_cmd2 *cmd,
|
|
|
|
struct drm_gem_object **bos);
|
2013-12-01 04:12:10 +07:00
|
|
|
/* misc: */
|
|
|
|
long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
|
|
|
|
struct drm_encoder *encoder);
|
2015-03-27 06:25:15 +07:00
|
|
|
int (*set_split_display)(struct msm_kms *kms,
|
|
|
|
struct drm_encoder *encoder,
|
|
|
|
struct drm_encoder *slave_encoder,
|
|
|
|
bool is_cmd_mode);
|
2016-12-05 16:54:53 +07:00
|
|
|
void (*set_encoder_mode)(struct msm_kms *kms,
|
|
|
|
struct drm_encoder *encoder,
|
|
|
|
bool cmd_mode);
|
2013-12-01 04:12:10 +07:00
|
|
|
/* cleanup: */
|
|
|
|
void (*destroy)(struct msm_kms *kms);
|
2016-10-27 01:06:55 +07:00
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
|
|
/* debugfs: */
|
|
|
|
int (*debugfs_init)(struct msm_kms *kms, struct drm_minor *minor);
|
|
|
|
#endif
|
2013-12-01 04:12:10 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct msm_kms {
|
|
|
|
const struct msm_kms_funcs *funcs;
|
2016-05-18 16:36:03 +07:00
|
|
|
|
|
|
|
/* irq number to be passed on to drm_irq_install */
|
|
|
|
int irq;
|
2017-06-13 21:22:37 +07:00
|
|
|
|
|
|
|
/* mapper-id used to request GEM buffer mapped for scanout: */
|
|
|
|
struct msm_gem_address_space *aspace;
|
2013-12-01 04:12:10 +07:00
|
|
|
};
|
|
|
|
|
2013-12-01 05:24:22 +07:00
|
|
|
static inline void msm_kms_init(struct msm_kms *kms,
|
|
|
|
const struct msm_kms_funcs *funcs)
|
|
|
|
{
|
|
|
|
kms->funcs = funcs;
|
|
|
|
}
|
|
|
|
|
2013-12-01 04:12:10 +07:00
|
|
|
struct msm_kms *mdp4_kms_init(struct drm_device *dev);
|
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-12-01 05:51:47 +07:00
|
|
|
struct msm_kms *mdp5_kms_init(struct drm_device *dev);
|
2018-06-28 02:26:09 +07:00
|
|
|
struct msm_kms *dpu_kms_init(struct drm_device *dev);
|
2018-06-22 03:06:10 +07:00
|
|
|
|
|
|
|
struct msm_mdss_funcs {
|
|
|
|
int (*enable)(struct msm_mdss *mdss);
|
|
|
|
int (*disable)(struct msm_mdss *mdss);
|
|
|
|
void (*destroy)(struct drm_device *dev);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct msm_mdss {
|
|
|
|
struct drm_device *dev;
|
|
|
|
const struct msm_mdss_funcs *funcs;
|
|
|
|
};
|
|
|
|
|
|
|
|
int mdp5_mdss_init(struct drm_device *dev);
|
2018-06-28 02:26:09 +07:00
|
|
|
int dpu_mdss_init(struct drm_device *dev);
|
2013-12-01 04:12:10 +07:00
|
|
|
|
|
|
|
#endif /* __MSM_KMS_H__ */
|