[go: nahoru, domu]

1/*
2 * Copyright (C) 2013 Red Hat
3 * Author: Rob Clark <robdclark@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __MDP5_KMS_H__
19#define __MDP5_KMS_H__
20
21#include "msm_drv.h"
22#include "msm_kms.h"
23#include "mdp/mdp_kms.h"
24/* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */
25#define MDP5_MAX_BASES		8
26struct mdp5_sub_block {
27	int	count;
28	uint32_t base[MDP5_MAX_BASES];
29};
30struct mdp5_config {
31	char  *name;
32	struct mdp5_sub_block ctl;
33	struct mdp5_sub_block pipe_vig;
34	struct mdp5_sub_block pipe_rgb;
35	struct mdp5_sub_block pipe_dma;
36	struct mdp5_sub_block lm;
37	struct mdp5_sub_block dspp;
38	struct mdp5_sub_block ad;
39	struct mdp5_sub_block intf;
40};
41extern const struct mdp5_config *mdp5_cfg;
42#include "mdp5.xml.h"
43#include "mdp5_smp.h"
44
45struct mdp5_kms {
46	struct mdp_kms base;
47
48	struct drm_device *dev;
49
50	int rev;
51	const struct mdp5_config *hw_cfg;
52
53	/* mapper-id used to request GEM buffer mapped for scanout: */
54	int id;
55	struct msm_mmu *mmu;
56
57	/* for tracking smp allocation amongst pipes: */
58	mdp5_smp_state_t smp_state;
59	struct mdp5_client_smp_state smp_client_state[CID_MAX];
60	int smp_blk_cnt;
61
62	/* io/register spaces: */
63	void __iomem *mmio, *vbif;
64
65	struct regulator *vdd;
66
67	struct clk *axi_clk;
68	struct clk *ahb_clk;
69	struct clk *src_clk;
70	struct clk *core_clk;
71	struct clk *lut_clk;
72	struct clk *vsync_clk;
73
74	struct hdmi *hdmi;
75
76	struct mdp_irq error_handler;
77};
78#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
79
80/* platform config data (ie. from DT, or pdata) */
81struct mdp5_platform_config {
82	struct iommu_domain *iommu;
83	uint32_t max_clk;
84	int smp_blk_cnt;
85};
86
87static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
88{
89	msm_writel(data, mdp5_kms->mmio + reg);
90}
91
92static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
93{
94	return msm_readl(mdp5_kms->mmio + reg);
95}
96
97static inline const char *pipe2name(enum mdp5_pipe pipe)
98{
99	static const char *names[] = {
100#define NAME(n) [SSPP_ ## n] = #n
101		NAME(VIG0), NAME(VIG1), NAME(VIG2),
102		NAME(RGB0), NAME(RGB1), NAME(RGB2),
103		NAME(DMA0), NAME(DMA1),
104		NAME(VIG3), NAME(RGB3),
105#undef NAME
106	};
107	return names[pipe];
108}
109
110static inline uint32_t pipe2flush(enum mdp5_pipe pipe)
111{
112	switch (pipe) {
113	case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0;
114	case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1;
115	case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2;
116	case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0;
117	case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1;
118	case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2;
119	case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0;
120	case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
121	case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
122	case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
123	default:        return 0;
124	}
125}
126
127static inline int pipe2nclients(enum mdp5_pipe pipe)
128{
129	switch (pipe) {
130	case SSPP_RGB0:
131	case SSPP_RGB1:
132	case SSPP_RGB2:
133	case SSPP_RGB3:
134		return 1;
135	default:
136		return 3;
137	}
138}
139
140static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane)
141{
142	WARN_ON(plane >= pipe2nclients(pipe));
143	switch (pipe) {
144	case SSPP_VIG0: return CID_VIG0_Y + plane;
145	case SSPP_VIG1: return CID_VIG1_Y + plane;
146	case SSPP_VIG2: return CID_VIG2_Y + plane;
147	case SSPP_RGB0: return CID_RGB0;
148	case SSPP_RGB1: return CID_RGB1;
149	case SSPP_RGB2: return CID_RGB2;
150	case SSPP_DMA0: return CID_DMA0_Y + plane;
151	case SSPP_DMA1: return CID_DMA1_Y + plane;
152	case SSPP_VIG3: return CID_VIG3_Y + plane;
153	case SSPP_RGB3: return CID_RGB3;
154	default:        return CID_UNUSED;
155	}
156}
157
158static inline uint32_t mixer2flush(int lm)
159{
160	switch (lm) {
161	case 0:  return MDP5_CTL_FLUSH_LM0;
162	case 1:  return MDP5_CTL_FLUSH_LM1;
163	case 2:  return MDP5_CTL_FLUSH_LM2;
164	default: return 0;
165	}
166}
167
168static inline uint32_t intf2err(int intf)
169{
170	switch (intf) {
171	case 0:  return MDP5_IRQ_INTF0_UNDER_RUN;
172	case 1:  return MDP5_IRQ_INTF1_UNDER_RUN;
173	case 2:  return MDP5_IRQ_INTF2_UNDER_RUN;
174	case 3:  return MDP5_IRQ_INTF3_UNDER_RUN;
175	default: return 0;
176	}
177}
178
179static inline uint32_t intf2vblank(int intf)
180{
181	switch (intf) {
182	case 0:  return MDP5_IRQ_INTF0_VSYNC;
183	case 1:  return MDP5_IRQ_INTF1_VSYNC;
184	case 2:  return MDP5_IRQ_INTF2_VSYNC;
185	case 3:  return MDP5_IRQ_INTF3_VSYNC;
186	default: return 0;
187	}
188}
189
190int mdp5_disable(struct mdp5_kms *mdp5_kms);
191int mdp5_enable(struct mdp5_kms *mdp5_kms);
192
193void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask);
194void mdp5_irq_preinstall(struct msm_kms *kms);
195int mdp5_irq_postinstall(struct msm_kms *kms);
196void mdp5_irq_uninstall(struct msm_kms *kms);
197irqreturn_t mdp5_irq(struct msm_kms *kms);
198int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
199void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
200
201static inline
202uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats,
203		uint32_t max_formats)
204{
205	/* TODO when we have YUV, we need to filter supported formats
206	 * based on pipe id..
207	 */
208	return mdp_get_formats(pixel_formats, max_formats);
209}
210
211void mdp5_plane_install_properties(struct drm_plane *plane,
212		struct drm_mode_object *obj);
213void mdp5_plane_set_scanout(struct drm_plane *plane,
214		struct drm_framebuffer *fb);
215int mdp5_plane_mode_set(struct drm_plane *plane,
216		struct drm_crtc *crtc, struct drm_framebuffer *fb,
217		int crtc_x, int crtc_y,
218		unsigned int crtc_w, unsigned int crtc_h,
219		uint32_t src_x, uint32_t src_y,
220		uint32_t src_w, uint32_t src_h);
221void mdp5_plane_complete_flip(struct drm_plane *plane);
222enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
223struct drm_plane *mdp5_plane_init(struct drm_device *dev,
224		enum mdp5_pipe pipe, bool private_plane);
225
226uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
227
228void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
229void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf,
230		enum mdp5_intf intf_id);
231void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
232void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
233struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
234		struct drm_plane *plane, int id);
235
236struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf,
237		enum mdp5_intf intf_id);
238
239#endif /* __MDP5_KMS_H__ */
240