blob: ef2faaef593652f2878614f5302e50701b8021b7 [file] [log] [blame]
Thierry Redingd8f4a9e2012-11-15 21:28:22 +00001/*
2 * Copyright (C) 2012 Avionic Design GmbH
Terje Bergstromd43f81c2013-03-22 16:34:09 +02003 * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved.
Thierry Redingd8f4a9e2012-11-15 21:28:22 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
Terje Bergstrom4231c6b2013-03-22 16:34:05 +020010#ifndef HOST1X_DRM_H
11#define HOST1X_DRM_H 1
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000012
Thierry Redinge1e90642013-09-24 13:59:01 +020013#include <uapi/drm/tegra_drm.h>
14#include <linux/host1x.h>
15
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000016#include <drm/drmP.h>
17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_edid.h>
19#include <drm/drm_fb_helper.h>
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000020#include <drm/drm_fixed.h>
21
Thierry Redingc134f012014-06-03 14:48:12 +020022#include "gem.h"
23
Stephen Warrenca480802013-11-06 16:20:54 -070024struct reset_control;
25
Arto Merilainende2ba662013-03-22 16:34:08 +020026struct tegra_fb {
27 struct drm_framebuffer base;
28 struct tegra_bo **planes;
29 unsigned int num_planes;
30};
31
Thierry Reding60c2f702013-10-31 13:28:50 +010032#ifdef CONFIG_DRM_TEGRA_FBDEV
Arto Merilainende2ba662013-03-22 16:34:08 +020033struct tegra_fbdev {
34 struct drm_fb_helper base;
35 struct tegra_fb *fb;
36};
Thierry Reding60c2f702013-10-31 13:28:50 +010037#endif
Arto Merilainende2ba662013-03-22 16:34:08 +020038
Thierry Reding386a2a72013-09-24 13:22:17 +020039struct tegra_drm {
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000040 struct drm_device *drm;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000041
42 struct mutex clients_lock;
43 struct list_head clients;
44
Thierry Reding60c2f702013-10-31 13:28:50 +010045#ifdef CONFIG_DRM_TEGRA_FBDEV
Arto Merilainende2ba662013-03-22 16:34:08 +020046 struct tegra_fbdev *fbdev;
Thierry Reding60c2f702013-10-31 13:28:50 +010047#endif
Thierry Redingd1f3e1e2014-07-11 08:29:14 +020048
49 unsigned int pitch_align;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000050};
51
Thierry Reding53fa7f72013-09-24 15:35:40 +020052struct tegra_drm_client;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000053
Thierry Redingc88c3632013-09-26 16:08:22 +020054struct tegra_drm_context {
Thierry Reding53fa7f72013-09-24 15:35:40 +020055 struct tegra_drm_client *client;
Terje Bergstromd43f81c2013-03-22 16:34:09 +020056 struct host1x_channel *channel;
57 struct list_head list;
58};
59
Thierry Reding53fa7f72013-09-24 15:35:40 +020060struct tegra_drm_client_ops {
61 int (*open_channel)(struct tegra_drm_client *client,
Thierry Redingc88c3632013-09-26 16:08:22 +020062 struct tegra_drm_context *context);
63 void (*close_channel)(struct tegra_drm_context *context);
Thierry Redingc40f0f12013-10-10 11:00:33 +020064 int (*is_addr_reg)(struct device *dev, u32 class, u32 offset);
Thierry Redingc88c3632013-09-26 16:08:22 +020065 int (*submit)(struct tegra_drm_context *context,
Terje Bergstromd43f81c2013-03-22 16:34:09 +020066 struct drm_tegra_submit *args, struct drm_device *drm,
67 struct drm_file *file);
68};
69
Thierry Redingc40f0f12013-10-10 11:00:33 +020070int tegra_drm_submit(struct tegra_drm_context *context,
71 struct drm_tegra_submit *args, struct drm_device *drm,
72 struct drm_file *file);
73
Thierry Reding53fa7f72013-09-24 15:35:40 +020074struct tegra_drm_client {
75 struct host1x_client base;
Thierry Reding776dc382013-10-14 14:43:22 +020076 struct list_head list;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000077
Thierry Reding53fa7f72013-09-24 15:35:40 +020078 const struct tegra_drm_client_ops *ops;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000079};
80
Thierry Reding53fa7f72013-09-24 15:35:40 +020081static inline struct tegra_drm_client *
Thierry Reding776dc382013-10-14 14:43:22 +020082host1x_to_drm_client(struct host1x_client *client)
Thierry Reding53fa7f72013-09-24 15:35:40 +020083{
84 return container_of(client, struct tegra_drm_client, base);
85}
86
Thierry Reding688c59a2014-04-16 09:54:21 +020087int tegra_drm_register_client(struct tegra_drm *tegra,
88 struct tegra_drm_client *client);
89int tegra_drm_unregister_client(struct tegra_drm *tegra,
90 struct tegra_drm_client *client);
Thierry Reding776dc382013-10-14 14:43:22 +020091
Thierry Reding688c59a2014-04-16 09:54:21 +020092int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm);
93int tegra_drm_exit(struct tegra_drm *tegra);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000094
Thierry Reding8620fc62013-12-12 11:03:59 +010095struct tegra_dc_soc_info;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +000096struct tegra_output;
97
98struct tegra_dc {
Thierry Reding776dc382013-10-14 14:43:22 +020099 struct host1x_client client;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000100 struct device *dev;
Thierry Redingd18d3032013-09-26 16:09:19 +0200101 spinlock_t lock;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000102
103 struct drm_crtc base;
Thierry Reding9c012702014-07-07 15:32:53 +0200104 int powergate;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000105 int pipe;
106
107 struct clk *clk;
Stephen Warrenca480802013-11-06 16:20:54 -0700108 struct reset_control *rst;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000109 void __iomem *regs;
110 int irq;
111
112 struct tegra_output *rgb;
113
114 struct list_head list;
115
116 struct drm_info_list *debugfs_files;
117 struct drm_minor *minor;
118 struct dentry *debugfs;
Thierry Reding3c03c462012-11-28 12:00:18 +0100119
120 /* page-flip handling */
121 struct drm_pending_vblank_event *event;
Thierry Reding8620fc62013-12-12 11:03:59 +0100122
123 const struct tegra_dc_soc_info *soc;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000124};
125
Thierry Reding53fa7f72013-09-24 15:35:40 +0200126static inline struct tegra_dc *
Thierry Reding776dc382013-10-14 14:43:22 +0200127host1x_client_to_dc(struct host1x_client *client)
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000128{
129 return container_of(client, struct tegra_dc, client);
130}
131
132static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
133{
Thierry Reding37826512013-11-08 12:30:37 +0100134 return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000135}
136
137static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value,
138 unsigned long reg)
139{
140 writel(value, dc->regs + (reg << 2));
141}
142
143static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
144 unsigned long reg)
145{
146 return readl(dc->regs + (reg << 2));
147}
148
Thierry Redingf34bc782012-11-04 21:47:13 +0100149struct tegra_dc_window {
150 struct {
151 unsigned int x;
152 unsigned int y;
153 unsigned int w;
154 unsigned int h;
155 } src;
156 struct {
157 unsigned int x;
158 unsigned int y;
159 unsigned int w;
160 unsigned int h;
161 } dst;
162 unsigned int bits_per_pixel;
163 unsigned int format;
Thierry Redingf9253902014-01-29 20:31:17 +0100164 unsigned int swap;
Thierry Redingf34bc782012-11-04 21:47:13 +0100165 unsigned int stride[2];
166 unsigned long base[3];
Thierry Redingdb7fbdf2013-10-07 09:47:58 +0200167 bool bottom_up;
Thierry Redingc134f012014-06-03 14:48:12 +0200168
169 struct tegra_bo_tiling tiling;
Thierry Redingf34bc782012-11-04 21:47:13 +0100170};
171
172/* from dc.c */
Thierry Reding688c59a2014-04-16 09:54:21 +0200173void tegra_dc_enable_vblank(struct tegra_dc *dc);
174void tegra_dc_disable_vblank(struct tegra_dc *dc);
175void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
Thierry Redingf34bc782012-11-04 21:47:13 +0100176
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000177struct tegra_output_ops {
178 int (*enable)(struct tegra_output *output);
179 int (*disable)(struct tegra_output *output);
180 int (*setup_clock)(struct tegra_output *output, struct clk *clk,
Thierry Reding91eded92014-03-26 13:32:21 +0100181 unsigned long pclk, unsigned int *div);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000182 int (*check_mode)(struct tegra_output *output,
183 struct drm_display_mode *mode,
184 enum drm_mode_status *status);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100185 enum drm_connector_status (*detect)(struct tegra_output *output);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000186};
187
188enum tegra_output_type {
189 TEGRA_OUTPUT_RGB,
Thierry Redingedec4af2012-11-15 21:28:23 +0000190 TEGRA_OUTPUT_HDMI,
Thierry Redingdec72732013-09-03 08:45:46 +0200191 TEGRA_OUTPUT_DSI,
Thierry Reding6b6b6042013-11-15 16:06:05 +0100192 TEGRA_OUTPUT_EDP,
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000193};
194
195struct tegra_output {
196 struct device_node *of_node;
197 struct device *dev;
198
199 const struct tegra_output_ops *ops;
200 enum tegra_output_type type;
201
Thierry Reding9be7d862013-08-30 15:22:36 +0200202 struct drm_panel *panel;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000203 struct i2c_adapter *ddc;
204 const struct edid *edid;
205 unsigned int hpd_irq;
206 int hpd_gpio;
207
208 struct drm_encoder encoder;
209 struct drm_connector connector;
210};
211
212static inline struct tegra_output *encoder_to_output(struct drm_encoder *e)
213{
214 return container_of(e, struct tegra_output, encoder);
215}
216
217static inline struct tegra_output *connector_to_output(struct drm_connector *c)
218{
219 return container_of(c, struct tegra_output, connector);
220}
221
222static inline int tegra_output_enable(struct tegra_output *output)
223{
224 if (output && output->ops && output->ops->enable)
225 return output->ops->enable(output);
226
227 return output ? -ENOSYS : -EINVAL;
228}
229
230static inline int tegra_output_disable(struct tegra_output *output)
231{
232 if (output && output->ops && output->ops->disable)
233 return output->ops->disable(output);
234
235 return output ? -ENOSYS : -EINVAL;
236}
237
238static inline int tegra_output_setup_clock(struct tegra_output *output,
Thierry Reding91eded92014-03-26 13:32:21 +0100239 struct clk *clk, unsigned long pclk,
240 unsigned int *div)
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000241{
242 if (output && output->ops && output->ops->setup_clock)
Thierry Reding91eded92014-03-26 13:32:21 +0100243 return output->ops->setup_clock(output, clk, pclk, div);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000244
245 return output ? -ENOSYS : -EINVAL;
246}
247
248static inline int tegra_output_check_mode(struct tegra_output *output,
249 struct drm_display_mode *mode,
250 enum drm_mode_status *status)
251{
252 if (output && output->ops && output->ops->check_mode)
253 return output->ops->check_mode(output, mode, status);
254
255 return output ? -ENOSYS : -EINVAL;
256}
257
258/* from rgb.c */
Thierry Reding688c59a2014-04-16 09:54:21 +0200259int tegra_dc_rgb_probe(struct tegra_dc *dc);
260int tegra_dc_rgb_remove(struct tegra_dc *dc);
261int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc);
262int tegra_dc_rgb_exit(struct tegra_dc *dc);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000263
264/* from output.c */
Thierry Reding688c59a2014-04-16 09:54:21 +0200265int tegra_output_probe(struct tegra_output *output);
266int tegra_output_remove(struct tegra_output *output);
267int tegra_output_init(struct drm_device *drm, struct tegra_output *output);
268int tegra_output_exit(struct tegra_output *output);
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000269
Thierry Reding6b6b6042013-11-15 16:06:05 +0100270/* from dpaux.c */
Thierry Reding6b6b6042013-11-15 16:06:05 +0100271struct tegra_dpaux;
272struct drm_dp_link;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100273
274struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np);
275enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux);
276int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output);
277int tegra_dpaux_detach(struct tegra_dpaux *dpaux);
278int tegra_dpaux_enable(struct tegra_dpaux *dpaux);
279int tegra_dpaux_disable(struct tegra_dpaux *dpaux);
280int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding);
281int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
282 u8 pattern);
283
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000284/* from fb.c */
Arto Merilainende2ba662013-03-22 16:34:08 +0200285struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
286 unsigned int index);
Thierry Redingdb7fbdf2013-10-07 09:47:58 +0200287bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
Thierry Redingc134f012014-06-03 14:48:12 +0200288int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
289 struct tegra_bo_tiling *tiling);
Thierry Redinge2215322014-06-27 17:19:25 +0200290int tegra_drm_fb_prepare(struct drm_device *drm);
Thierry Reding1d1e6fe2014-11-06 14:12:08 +0100291void tegra_drm_fb_free(struct drm_device *drm);
Thierry Reding688c59a2014-04-16 09:54:21 +0200292int tegra_drm_fb_init(struct drm_device *drm);
293void tegra_drm_fb_exit(struct drm_device *drm);
Thierry Reding60c2f702013-10-31 13:28:50 +0100294#ifdef CONFIG_DRM_TEGRA_FBDEV
Thierry Reding688c59a2014-04-16 09:54:21 +0200295void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
Thierry Reding60c2f702013-10-31 13:28:50 +0100296#endif
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000297
Thierry Reding776dc382013-10-14 14:43:22 +0200298extern struct platform_driver tegra_dc_driver;
Thierry Redingdec72732013-09-03 08:45:46 +0200299extern struct platform_driver tegra_dsi_driver;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100300extern struct platform_driver tegra_sor_driver;
Thierry Reding776dc382013-10-14 14:43:22 +0200301extern struct platform_driver tegra_hdmi_driver;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100302extern struct platform_driver tegra_dpaux_driver;
Thierry Reding776dc382013-10-14 14:43:22 +0200303extern struct platform_driver tegra_gr2d_driver;
Thierry Reding5f60ed02013-02-28 08:08:01 +0100304extern struct platform_driver tegra_gr3d_driver;
Thierry Redingd8f4a9e2012-11-15 21:28:22 +0000305
Terje Bergstrom4231c6b2013-03-22 16:34:05 +0200306#endif /* HOST1X_DRM_H */