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