drm/vc4: Add gem_info node via debugfs for vc5
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / vc4 / vc4_drv.h
index 4b550eb..7304d74 100644 (file)
@@ -19,6 +19,7 @@
 #include <drm/drm_modeset_lock.h>
 
 #include "uapi/drm/vc4_drm.h"
+#include "vc4_regs.h"
 
 struct drm_device;
 struct drm_gem_object;
@@ -48,6 +49,8 @@ enum vc4_kernel_bo_type {
  * done. This way, only events related to a specific job will be counted.
  */
 struct vc4_perfmon {
+       struct vc4_dev *dev;
+
        /* Tracks the number of users of the perfmon, when this counter reaches
         * zero the perfmon is destroyed.
         */
@@ -73,14 +76,18 @@ struct vc4_perfmon {
 
 struct vc4_dev {
        struct drm_device base;
+       struct device *dev;
+
+       bool is_vc5;
 
        unsigned int irq;
 
+       bool firmware_kms;
+       struct rpi_firmware *firmware;
+
        struct vc4_hvs *hvs;
        struct vc4_v3d *v3d;
-       struct vc4_dpi *dpi;
-       struct vc4_vec *vec;
-       struct vc4_txp *txp;
+       struct vc4_fkms *fkms;
 
        struct vc4_hang_state *hang_state;
 
@@ -202,9 +209,6 @@ struct vc4_dev {
 
        int power_refcount;
 
-       /* Set to true when the load tracker is supported. */
-       bool load_tracker_available;
-
        /* Set to true when the load tracker is active. */
        bool load_tracker_enabled;
 
@@ -319,12 +323,15 @@ struct vc4_v3d {
 };
 
 struct vc4_hvs {
+       struct vc4_dev *vc4;
        struct platform_device *pdev;
        void __iomem *regs;
        u32 __iomem *dlist;
 
        struct clk *core_clk;
 
+       unsigned long max_core_rate;
+
        /* Memory manager for CRTCs to allocate space in the display
         * list.  Units are dwords.
         */
@@ -337,8 +344,19 @@ struct vc4_hvs {
 
        struct debugfs_regset32 regset;
 
-       /* HVS version 5 flag, therefore requires updated dlist structures */
-       bool hvs5;
+       /*
+        * Even if HDMI0 on the RPi4 can output modes requiring a pixel
+        * rate higher than 297MHz, it needs some adjustments in the
+        * config.txt file to be able to do so and thus won't always be
+        * available.
+        */
+       bool vc5_hdmi_enable_hdmi_20;
+
+       /*
+        * 4096x2160@60 requires a core overclock to work, so register
+        * whether that is sufficient.
+        */
+       bool vc5_hdmi_enable_4096by2160;
 };
 
 struct vc4_plane {
@@ -381,7 +399,7 @@ struct vc4_plane_state {
 
        /* Clipped coordinates of the plane on the display. */
        int crtc_x, crtc_y, crtc_w, crtc_h;
-       /* Clipped area being scanned from in the FB. */
+       /* Clipped area being scanned from in the FB in u16.16 format */
        u32 src_x, src_y;
 
        u32 src_w[2], src_h[2];
@@ -458,6 +476,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
 }
 
 struct vc4_crtc_data {
+       const char *debugfs_name;
+
        /* Bitmask of channels (FIFOs) of the HVS that the output can source from */
        unsigned int hvs_available_channels;
 
@@ -475,10 +495,19 @@ struct vc4_pv_data {
        u8 pixels_per_clock;
 
        enum vc4_encoder_type encoder_types[4];
-       const char *debugfs_name;
+};
 
+struct vc5_gamma_entry {
+       u32 x_c_terms;
+       u32 grad_term;
 };
 
+#define VC5_HVS_SET_GAMMA_ENTRY(x, c, g) (struct vc5_gamma_entry){     \
+       .x_c_terms = VC4_SET_FIELD((x), SCALER5_DSPGAMMA_OFF_X) |       \
+                    VC4_SET_FIELD((c), SCALER5_DSPGAMMA_OFF_C),        \
+       .grad_term = (g)                                                \
+}
+
 struct vc4_crtc {
        struct drm_crtc base;
        struct platform_device *pdev;
@@ -488,9 +517,19 @@ struct vc4_crtc {
        /* Timestamp at start of vblank irq - unaffected by lock delays. */
        ktime_t t_vblank;
 
-       u8 lut_r[256];
-       u8 lut_g[256];
-       u8 lut_b[256];
+       union {
+               struct {  /* VC4 gamma LUT */
+                       u8 lut_r[256];
+                       u8 lut_g[256];
+                       u8 lut_b[256];
+               };
+               struct {  /* VC5 gamma PWL entries */
+                       struct vc5_gamma_entry pwl_r[SCALER5_DSPGAMMA_NUM_POINTS];
+                       struct vc5_gamma_entry pwl_g[SCALER5_DSPGAMMA_NUM_POINTS];
+                       struct vc5_gamma_entry pwl_b[SCALER5_DSPGAMMA_NUM_POINTS];
+                       struct vc5_gamma_entry pwl_a[SCALER5_DSPGAMMA_NUM_POINTS];
+               };
+       };
 
        struct drm_pending_vblank_event *event;
 
@@ -544,6 +583,12 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
        return container_of(data, struct vc4_pv_data, base);
 }
 
+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
+                                            struct drm_crtc_state *state);
+
+struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
+                                        struct drm_crtc_state *state);
+
 struct vc4_crtc_state {
        struct drm_crtc_state base;
        /* Dlist area for this CRTC configuration. */
@@ -551,12 +596,9 @@ struct vc4_crtc_state {
        bool txp_armed;
        unsigned int assigned_channel;
 
-       struct {
-               unsigned int left;
-               unsigned int right;
-               unsigned int top;
-               unsigned int bottom;
-       } margins;
+       struct drm_connector_tv_margins margins;
+
+       unsigned long hvs_load;
 
        /* Transitional state below, only valid during atomic commits */
        bool update_muxing;
@@ -572,12 +614,14 @@ to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
 
 #define V3D_READ(offset) readl(vc4->v3d->regs + offset)
 #define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset)
-#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
-#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
+#define HVS_READ(offset) readl(hvs->regs + offset)
+#define HVS_WRITE(offset, val) writel(val, hvs->regs + offset)
 
 #define VC4_REG32(reg) { .name = #reg, .offset = reg }
 
 struct vc4_exec_info {
+       struct vc4_dev *dev;
+
        /* Sequence number for this bin/render job. */
        uint64_t seqno;
 
@@ -695,16 +739,24 @@ struct vc4_exec_info {
        bool bin_bo_used;
 };
 
+struct drm_vc5_file_private {
+       pid_t pid;
+       pid_t tgid;
+};
+
 /* Per-open file private data. Any driver-specific resource that has to be
  * released when the DRM file is closed should be placed here.
  */
 struct vc4_file {
+       struct vc4_dev *dev;
+
        struct {
                struct idr idr;
                struct mutex lock;
        } perfmon;
 
        bool bin_bo_used;
+       struct drm_vc5_file_private priv;
 };
 
 static inline struct vc4_exec_info *
@@ -812,9 +864,9 @@ struct vc4_validated_shader_info {
 struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
 struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
                             bool from_cache, enum vc4_kernel_bo_type type);
-int vc4_dumb_create(struct drm_file *file_priv,
-                   struct drm_device *dev,
-                   struct drm_mode_create_dumb *args);
+int vc4_bo_dumb_create(struct drm_file *file_priv,
+                      struct drm_device *dev,
+                      struct drm_mode_create_dumb *args);
 int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
@@ -834,6 +886,8 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo);
 void vc4_bo_dec_usecnt(struct vc4_bo *bo);
 void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo);
 void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo);
+int vc4_bo_debugfs_init(struct drm_minor *minor);
+int vc5_bo_debugfs_init(struct drm_minor *minor);
 
 /* vc4_crtc.c */
 extern struct platform_driver vc4_crtc_driver;
@@ -841,7 +895,6 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
 int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
                  const struct drm_crtc_funcs *crtc_funcs,
                  const struct drm_crtc_helper_funcs *crtc_helper_funcs);
-void vc4_crtc_destroy(struct drm_crtc *crtc);
 int vc4_page_flip(struct drm_crtc *crtc,
                  struct drm_framebuffer *fb,
                  struct drm_pending_vblank_event *event,
@@ -852,6 +905,8 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc,
                            struct drm_crtc_state *state);
 void vc4_crtc_reset(struct drm_crtc *crtc);
 void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
+int vc4_crtc_late_register(struct drm_crtc *crtc);
+void vc4_crtc_send_vblank(struct drm_crtc *crtc);
 void vc4_crtc_get_margins(struct drm_crtc_state *state,
                          unsigned int *left, unsigned int *right,
                          unsigned int *top, unsigned int *bottom);
@@ -859,30 +914,33 @@ void vc4_crtc_get_margins(struct drm_crtc_state *state,
 /* vc4_debugfs.c */
 void vc4_debugfs_init(struct drm_minor *minor);
 #ifdef CONFIG_DEBUG_FS
-void vc4_debugfs_add_file(struct drm_device *drm,
-                         const char *filename,
-                         int (*show)(struct seq_file*, void*),
-                         void *data);
-void vc4_debugfs_add_regset32(struct drm_device *drm,
-                             const char *filename,
-                             struct debugfs_regset32 *regset);
+int vc4_debugfs_add_file(struct drm_minor *minor,
+                        const char *filename,
+                        int (*show)(struct seq_file*, void*),
+                        void *data);
+int vc4_debugfs_add_regset32(struct drm_minor *minor,
+                            const char *filename,
+                            struct debugfs_regset32 *regset);
 #else
-static inline void vc4_debugfs_add_file(struct drm_device *drm,
-                                       const char *filename,
-                                       int (*show)(struct seq_file*, void*),
-                                       void *data)
+static inline int vc4_debugfs_add_file(struct drm_minor *minor,
+                                      const char *filename,
+                                      int (*show)(struct seq_file*, void*),
+                                      void *data)
 {
+       return 0;
 }
 
-static inline void vc4_debugfs_add_regset32(struct drm_device *drm,
-                                           const char *filename,
-                                           struct debugfs_regset32 *regset)
+static inline int vc4_debugfs_add_regset32(struct drm_minor *minor,
+                                          const char *filename,
+                                          struct debugfs_regset32 *regset)
 {
+       return 0;
 }
 #endif
 
 /* vc4_drv.c */
 void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
+int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args);
 
 /* vc4_dpi.c */
 extern struct platform_driver vc4_dpi_driver;
@@ -893,6 +951,9 @@ extern struct platform_driver vc4_dsi_driver;
 /* vc4_fence.c */
 extern const struct dma_fence_ops vc4_fence_ops;
 
+/* vc4_firmware_kms.c */
+extern struct platform_driver vc4_firmware_kms_driver;
+
 /* vc4_gem.c */
 int vc4_gem_init(struct drm_device *dev);
 int vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
@@ -931,23 +992,26 @@ void vc4_irq_reset(struct drm_device *dev);
 
 /* vc4_hvs.c */
 extern struct platform_driver vc4_hvs_driver;
-void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
-int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output);
+void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int output);
+int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output);
+u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo);
 int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state);
 void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state);
 void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state);
 void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state);
 void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state);
-void vc4_hvs_dump_state(struct drm_device *dev);
-void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel);
-void vc4_hvs_mask_underrun(struct drm_device *dev, int channel);
+void vc4_hvs_dump_state(struct vc4_hvs *hvs);
+void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel);
+void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel);
+int vc4_hvs_debugfs_init(struct drm_minor *minor);
 
 /* vc4_kms.c */
 int vc4_kms_load(struct drm_device *dev);
 
 /* vc4_plane.c */
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
-                                enum drm_plane_type type);
+                                enum drm_plane_type type,
+                                uint32_t possible_crtcs);
 int vc4_plane_create_additional_planes(struct drm_device *dev);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
 u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
@@ -962,6 +1026,7 @@ int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used);
 void vc4_v3d_bin_bo_put(struct vc4_dev *vc4);
 int vc4_v3d_pm_get(struct vc4_dev *vc4);
 void vc4_v3d_pm_put(struct vc4_dev *vc4);
+int vc4_v3d_debugfs_init(struct drm_minor *minor);
 
 /* vc4_validate.c */
 int
@@ -987,6 +1052,8 @@ bool vc4_check_tex_size(struct vc4_exec_info *exec,
 struct vc4_validated_shader_info *
 vc4_validate_shader(struct drm_gem_cma_object *shader_obj);
 
+int vc5_debugfs_gem_info(struct seq_file *m, void *data);
+
 /* vc4_perfmon.c */
 void vc4_perfmon_get(struct vc4_perfmon *perfmon);
 void vc4_perfmon_put(struct vc4_perfmon *perfmon);