1 /* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012 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 TEGRA_DRM_H 11 #define TEGRA_DRM_H 1 12 13 #include <drm/drmP.h> 14 #include <drm/drm_crtc_helper.h> 15 #include <drm/drm_edid.h> 16 #include <drm/drm_fb_helper.h> 17 #include <drm/drm_gem_cma_helper.h> 18 #include <drm/drm_fb_cma_helper.h> 19 #include <drm/drm_fixed.h> 20 21 struct host1x { 22 struct drm_device *drm; 23 struct device *dev; 24 void __iomem *regs; 25 struct clk *clk; 26 int syncpt; 27 int irq; 28 29 struct mutex drm_clients_lock; 30 struct list_head drm_clients; 31 struct list_head drm_active; 32 33 struct mutex clients_lock; 34 struct list_head clients; 35 36 struct drm_fbdev_cma *fbdev; 37 }; 38 39 struct host1x_client; 40 41 struct host1x_client_ops { 42 int (*drm_init)(struct host1x_client *client, struct drm_device *drm); 43 int (*drm_exit)(struct host1x_client *client); 44 }; 45 46 struct host1x_client { 47 struct host1x *host1x; 48 struct device *dev; 49 50 const struct host1x_client_ops *ops; 51 52 struct list_head list; 53 }; 54 55 extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm); 56 extern int host1x_drm_exit(struct host1x *host1x); 57 58 extern int host1x_register_client(struct host1x *host1x, 59 struct host1x_client *client); 60 extern int host1x_unregister_client(struct host1x *host1x, 61 struct host1x_client *client); 62 63 struct tegra_output; 64 65 struct tegra_dc { 66 struct host1x_client client; 67 spinlock_t lock; 68 69 struct host1x *host1x; 70 struct device *dev; 71 72 struct drm_crtc base; 73 int pipe; 74 75 struct clk *clk; 76 77 void __iomem *regs; 78 int irq; 79 80 struct tegra_output *rgb; 81 82 struct list_head list; 83 84 struct drm_info_list *debugfs_files; 85 struct drm_minor *minor; 86 struct dentry *debugfs; 87 88 /* page-flip handling */ 89 struct drm_pending_vblank_event *event; 90 }; 91 92 static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client) 93 { 94 return container_of(client, struct tegra_dc, client); 95 } 96 97 static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) 98 { 99 return container_of(crtc, struct tegra_dc, base); 100 } 101 102 static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value, 103 unsigned long reg) 104 { 105 writel(value, dc->regs + (reg << 2)); 106 } 107 108 static inline unsigned long tegra_dc_readl(struct tegra_dc *dc, 109 unsigned long reg) 110 { 111 return readl(dc->regs + (reg << 2)); 112 } 113 114 struct tegra_dc_window { 115 struct { 116 unsigned int x; 117 unsigned int y; 118 unsigned int w; 119 unsigned int h; 120 } src; 121 struct { 122 unsigned int x; 123 unsigned int y; 124 unsigned int w; 125 unsigned int h; 126 } dst; 127 unsigned int bits_per_pixel; 128 unsigned int format; 129 unsigned int stride[2]; 130 unsigned long base[3]; 131 }; 132 133 /* from dc.c */ 134 extern unsigned int tegra_dc_format(uint32_t format); 135 extern int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, 136 const struct tegra_dc_window *window); 137 extern void tegra_dc_enable_vblank(struct tegra_dc *dc); 138 extern void tegra_dc_disable_vblank(struct tegra_dc *dc); 139 extern void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, 140 struct drm_file *file); 141 142 struct tegra_output_ops { 143 int (*enable)(struct tegra_output *output); 144 int (*disable)(struct tegra_output *output); 145 int (*setup_clock)(struct tegra_output *output, struct clk *clk, 146 unsigned long pclk); 147 int (*check_mode)(struct tegra_output *output, 148 struct drm_display_mode *mode, 149 enum drm_mode_status *status); 150 }; 151 152 enum tegra_output_type { 153 TEGRA_OUTPUT_RGB, 154 TEGRA_OUTPUT_HDMI, 155 }; 156 157 struct tegra_output { 158 struct device_node *of_node; 159 struct device *dev; 160 161 const struct tegra_output_ops *ops; 162 enum tegra_output_type type; 163 164 struct i2c_adapter *ddc; 165 const struct edid *edid; 166 unsigned int hpd_irq; 167 int hpd_gpio; 168 169 struct drm_encoder encoder; 170 struct drm_connector connector; 171 }; 172 173 static inline struct tegra_output *encoder_to_output(struct drm_encoder *e) 174 { 175 return container_of(e, struct tegra_output, encoder); 176 } 177 178 static inline struct tegra_output *connector_to_output(struct drm_connector *c) 179 { 180 return container_of(c, struct tegra_output, connector); 181 } 182 183 static inline int tegra_output_enable(struct tegra_output *output) 184 { 185 if (output && output->ops && output->ops->enable) 186 return output->ops->enable(output); 187 188 return output ? -ENOSYS : -EINVAL; 189 } 190 191 static inline int tegra_output_disable(struct tegra_output *output) 192 { 193 if (output && output->ops && output->ops->disable) 194 return output->ops->disable(output); 195 196 return output ? -ENOSYS : -EINVAL; 197 } 198 199 static inline int tegra_output_setup_clock(struct tegra_output *output, 200 struct clk *clk, unsigned long pclk) 201 { 202 if (output && output->ops && output->ops->setup_clock) 203 return output->ops->setup_clock(output, clk, pclk); 204 205 return output ? -ENOSYS : -EINVAL; 206 } 207 208 static inline int tegra_output_check_mode(struct tegra_output *output, 209 struct drm_display_mode *mode, 210 enum drm_mode_status *status) 211 { 212 if (output && output->ops && output->ops->check_mode) 213 return output->ops->check_mode(output, mode, status); 214 215 return output ? -ENOSYS : -EINVAL; 216 } 217 218 /* from rgb.c */ 219 extern int tegra_dc_rgb_probe(struct tegra_dc *dc); 220 extern int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc); 221 extern int tegra_dc_rgb_exit(struct tegra_dc *dc); 222 223 /* from output.c */ 224 extern int tegra_output_parse_dt(struct tegra_output *output); 225 extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output); 226 extern int tegra_output_exit(struct tegra_output *output); 227 228 /* from fb.c */ 229 extern int tegra_drm_fb_init(struct drm_device *drm); 230 extern void tegra_drm_fb_exit(struct drm_device *drm); 231 232 extern struct platform_driver tegra_host1x_driver; 233 extern struct platform_driver tegra_hdmi_driver; 234 extern struct platform_driver tegra_dc_driver; 235 extern struct drm_driver tegra_drm_driver; 236 237 #endif /* TEGRA_DRM_H */ 238