1 /* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. 4 * 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 10 #ifndef HOST1X_DRM_H 11 #define HOST1X_DRM_H 1 12 13 #include <uapi/drm/tegra_drm.h> 14 #include <linux/host1x.h> 15 16 #include <drm/drmP.h> 17 #include <drm/drm_crtc_helper.h> 18 #include <drm/drm_edid.h> 19 #include <drm/drm_fb_helper.h> 20 #include <drm/drm_fixed.h> 21 22 struct reset_control; 23 24 struct tegra_fb { 25 struct drm_framebuffer base; 26 struct tegra_bo **planes; 27 unsigned int num_planes; 28 }; 29 30 struct tegra_fbdev { 31 struct drm_fb_helper base; 32 struct tegra_fb *fb; 33 }; 34 35 struct tegra_drm { 36 struct drm_device *drm; 37 38 struct mutex clients_lock; 39 struct list_head clients; 40 41 struct tegra_fbdev *fbdev; 42 }; 43 44 struct tegra_drm_client; 45 46 struct tegra_drm_context { 47 struct tegra_drm_client *client; 48 struct host1x_channel *channel; 49 struct list_head list; 50 }; 51 52 struct tegra_drm_client_ops { 53 int (*open_channel)(struct tegra_drm_client *client, 54 struct tegra_drm_context *context); 55 void (*close_channel)(struct tegra_drm_context *context); 56 int (*is_addr_reg)(struct device *dev, u32 class, u32 offset); 57 int (*submit)(struct tegra_drm_context *context, 58 struct drm_tegra_submit *args, struct drm_device *drm, 59 struct drm_file *file); 60 }; 61 62 int tegra_drm_submit(struct tegra_drm_context *context, 63 struct drm_tegra_submit *args, struct drm_device *drm, 64 struct drm_file *file); 65 66 struct tegra_drm_client { 67 struct host1x_client base; 68 struct list_head list; 69 70 const struct tegra_drm_client_ops *ops; 71 }; 72 73 static inline struct tegra_drm_client * 74 host1x_to_drm_client(struct host1x_client *client) 75 { 76 return container_of(client, struct tegra_drm_client, base); 77 } 78 79 extern int tegra_drm_register_client(struct tegra_drm *tegra, 80 struct tegra_drm_client *client); 81 extern int tegra_drm_unregister_client(struct tegra_drm *tegra, 82 struct tegra_drm_client *client); 83 84 extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); 85 extern int tegra_drm_exit(struct tegra_drm *tegra); 86 87 struct tegra_output; 88 89 struct tegra_dc { 90 struct host1x_client client; 91 struct device *dev; 92 spinlock_t lock; 93 94 struct drm_crtc base; 95 int pipe; 96 97 struct clk *clk; 98 struct reset_control *rst; 99 void __iomem *regs; 100 int irq; 101 102 struct tegra_output *rgb; 103 104 struct list_head list; 105 106 struct drm_info_list *debugfs_files; 107 struct drm_minor *minor; 108 struct dentry *debugfs; 109 110 /* page-flip handling */ 111 struct drm_pending_vblank_event *event; 112 }; 113 114 static inline struct tegra_dc * 115 host1x_client_to_dc(struct host1x_client *client) 116 { 117 return container_of(client, struct tegra_dc, client); 118 } 119 120 static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) 121 { 122 return crtc ? container_of(crtc, struct tegra_dc, base) : NULL; 123 } 124 125 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value, 126 unsigned long reg) 127 { 128 writel(value, dc->regs + (reg << 2)); 129 } 130 131 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc, 132 unsigned long reg) 133 { 134 return readl(dc->regs + (reg << 2)); 135 } 136 137 struct tegra_dc_window { 138 struct { 139 unsigned int x; 140 unsigned int y; 141 unsigned int w; 142 unsigned int h; 143 } src; 144 struct { 145 unsigned int x; 146 unsigned int y; 147 unsigned int w; 148 unsigned int h; 149 } dst; 150 unsigned int bits_per_pixel; 151 unsigned int format; 152 unsigned int stride[2]; 153 unsigned long base[3]; 154 bool bottom_up; 155 bool tiled; 156 }; 157 158 /* from dc.c */ 159 extern unsigned int tegra_dc_format(uint32_t format); 160 extern int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, 161 const struct tegra_dc_window *window); 162 extern void tegra_dc_enable_vblank(struct tegra_dc *dc); 163 extern void tegra_dc_disable_vblank(struct tegra_dc *dc); 164 extern void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, 165 struct drm_file *file); 166 167 struct tegra_output_ops { 168 int (*enable)(struct tegra_output *output); 169 int (*disable)(struct tegra_output *output); 170 int (*setup_clock)(struct tegra_output *output, struct clk *clk, 171 unsigned long pclk); 172 int (*check_mode)(struct tegra_output *output, 173 struct drm_display_mode *mode, 174 enum drm_mode_status *status); 175 }; 176 177 enum tegra_output_type { 178 TEGRA_OUTPUT_RGB, 179 TEGRA_OUTPUT_HDMI, 180 }; 181 182 struct tegra_output { 183 struct device_node *of_node; 184 struct device *dev; 185 186 const struct tegra_output_ops *ops; 187 enum tegra_output_type type; 188 189 struct drm_panel *panel; 190 struct i2c_adapter *ddc; 191 const struct edid *edid; 192 unsigned int hpd_irq; 193 int hpd_gpio; 194 195 struct drm_encoder encoder; 196 struct drm_connector connector; 197 }; 198 199 static inline struct tegra_output *encoder_to_output(struct drm_encoder *e) 200 { 201 return container_of(e, struct tegra_output, encoder); 202 } 203 204 static inline struct tegra_output *connector_to_output(struct drm_connector *c) 205 { 206 return container_of(c, struct tegra_output, connector); 207 } 208 209 static inline int tegra_output_enable(struct tegra_output *output) 210 { 211 if (output && output->ops && output->ops->enable) 212 return output->ops->enable(output); 213 214 return output ? -ENOSYS : -EINVAL; 215 } 216 217 static inline int tegra_output_disable(struct tegra_output *output) 218 { 219 if (output && output->ops && output->ops->disable) 220 return output->ops->disable(output); 221 222 return output ? -ENOSYS : -EINVAL; 223 } 224 225 static inline int tegra_output_setup_clock(struct tegra_output *output, 226 struct clk *clk, unsigned long pclk) 227 { 228 if (output && output->ops && output->ops->setup_clock) 229 return output->ops->setup_clock(output, clk, pclk); 230 231 return output ? -ENOSYS : -EINVAL; 232 } 233 234 static inline int tegra_output_check_mode(struct tegra_output *output, 235 struct drm_display_mode *mode, 236 enum drm_mode_status *status) 237 { 238 if (output && output->ops && output->ops->check_mode) 239 return output->ops->check_mode(output, mode, status); 240 241 return output ? -ENOSYS : -EINVAL; 242 } 243 244 /* from bus.c */ 245 int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device); 246 void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device); 247 248 /* from rgb.c */ 249 extern int tegra_dc_rgb_probe(struct tegra_dc *dc); 250 extern int tegra_dc_rgb_remove(struct tegra_dc *dc); 251 extern int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc); 252 extern int tegra_dc_rgb_exit(struct tegra_dc *dc); 253 254 /* from output.c */ 255 extern int tegra_output_probe(struct tegra_output *output); 256 extern int tegra_output_remove(struct tegra_output *output); 257 extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output); 258 extern int tegra_output_exit(struct tegra_output *output); 259 260 /* from fb.c */ 261 struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer, 262 unsigned int index); 263 bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer); 264 bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer); 265 extern int tegra_drm_fb_init(struct drm_device *drm); 266 extern void tegra_drm_fb_exit(struct drm_device *drm); 267 extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev); 268 269 extern struct platform_driver tegra_dc_driver; 270 extern struct platform_driver tegra_hdmi_driver; 271 extern struct platform_driver tegra_gr2d_driver; 272 extern struct platform_driver tegra_gr3d_driver; 273 274 #endif /* HOST1X_DRM_H */ 275