root/drivers/gpu/drm/sti/sti_vid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vid_dbg_ctl
  2. vid_dbg_vpo
  3. vid_dbg_vps
  4. vid_dbg_mst
  5. vid_dbg_show
  6. vid_debugfs_init
  7. sti_vid_commit
  8. sti_vid_disable
  9. sti_vid_init
  10. sti_vid_create

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) STMicroelectronics SA 2014
   4  * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
   5  */
   6 #include <linux/seq_file.h>
   7 
   8 #include <drm/drm_debugfs.h>
   9 #include <drm/drm_file.h>
  10 #include <drm/drm_print.h>
  11 
  12 #include "sti_plane.h"
  13 #include "sti_vid.h"
  14 #include "sti_vtg.h"
  15 
  16 /* Registers */
  17 #define VID_CTL                 0x00
  18 #define VID_ALP                 0x04
  19 #define VID_CLF                 0x08
  20 #define VID_VPO                 0x0C
  21 #define VID_VPS                 0x10
  22 #define VID_KEY1                0x28
  23 #define VID_KEY2                0x2C
  24 #define VID_MPR0                0x30
  25 #define VID_MPR1                0x34
  26 #define VID_MPR2                0x38
  27 #define VID_MPR3                0x3C
  28 #define VID_MST                 0x68
  29 #define VID_BC                  0x70
  30 #define VID_TINT                0x74
  31 #define VID_CSAT                0x78
  32 
  33 /* Registers values */
  34 #define VID_CTL_IGNORE          (BIT(31) | BIT(30))
  35 #define VID_CTL_PSI_ENABLE      (BIT(2) | BIT(1) | BIT(0))
  36 #define VID_ALP_OPAQUE          0x00000080
  37 #define VID_BC_DFLT             0x00008000
  38 #define VID_TINT_DFLT           0x00000000
  39 #define VID_CSAT_DFLT           0x00000080
  40 /* YCbCr to RGB BT709:
  41  * R = Y+1.5391Cr
  42  * G = Y-0.4590Cr-0.1826Cb
  43  * B = Y+1.8125Cb */
  44 #define VID_MPR0_BT709          0x0A800000
  45 #define VID_MPR1_BT709          0x0AC50000
  46 #define VID_MPR2_BT709          0x07150545
  47 #define VID_MPR3_BT709          0x00000AE8
  48 /* YCbCr to RGB BT709:
  49  * R = Y+1.3711Cr
  50  * G = Y-0.6992Cr-0.3359Cb
  51  * B = Y+1.7344Cb
  52  */
  53 #define VID_MPR0_BT601          0x0A800000
  54 #define VID_MPR1_BT601          0x0AAF0000
  55 #define VID_MPR2_BT601          0x094E0754
  56 #define VID_MPR3_BT601          0x00000ADD
  57 
  58 #define VID_MIN_HD_HEIGHT       720
  59 
  60 #define DBGFS_DUMP(reg) seq_printf(s, "\n  %-25s 0x%08X", #reg, \
  61                                    readl(vid->regs + reg))
  62 
  63 static void vid_dbg_ctl(struct seq_file *s, int val)
  64 {
  65         val = val >> 30;
  66         seq_putc(s, '\t');
  67 
  68         if (!(val & 1))
  69                 seq_puts(s, "NOT ");
  70         seq_puts(s, "ignored on main mixer - ");
  71 
  72         if (!(val & 2))
  73                 seq_puts(s, "NOT ");
  74         seq_puts(s, "ignored on aux mixer");
  75 }
  76 
  77 static void vid_dbg_vpo(struct seq_file *s, int val)
  78 {
  79         seq_printf(s, "\txdo:%4d\tydo:%4d", val & 0x0FFF, (val >> 16) & 0x0FFF);
  80 }
  81 
  82 static void vid_dbg_vps(struct seq_file *s, int val)
  83 {
  84         seq_printf(s, "\txds:%4d\tyds:%4d", val & 0x0FFF, (val >> 16) & 0x0FFF);
  85 }
  86 
  87 static void vid_dbg_mst(struct seq_file *s, int val)
  88 {
  89         if (val & 1)
  90                 seq_puts(s, "\tBUFFER UNDERFLOW!");
  91 }
  92 
  93 static int vid_dbg_show(struct seq_file *s, void *arg)
  94 {
  95         struct drm_info_node *node = s->private;
  96         struct sti_vid *vid = (struct sti_vid *)node->info_ent->data;
  97 
  98         seq_printf(s, "VID: (vaddr= 0x%p)", vid->regs);
  99 
 100         DBGFS_DUMP(VID_CTL);
 101         vid_dbg_ctl(s, readl(vid->regs + VID_CTL));
 102         DBGFS_DUMP(VID_ALP);
 103         DBGFS_DUMP(VID_CLF);
 104         DBGFS_DUMP(VID_VPO);
 105         vid_dbg_vpo(s, readl(vid->regs + VID_VPO));
 106         DBGFS_DUMP(VID_VPS);
 107         vid_dbg_vps(s, readl(vid->regs + VID_VPS));
 108         DBGFS_DUMP(VID_KEY1);
 109         DBGFS_DUMP(VID_KEY2);
 110         DBGFS_DUMP(VID_MPR0);
 111         DBGFS_DUMP(VID_MPR1);
 112         DBGFS_DUMP(VID_MPR2);
 113         DBGFS_DUMP(VID_MPR3);
 114         DBGFS_DUMP(VID_MST);
 115         vid_dbg_mst(s, readl(vid->regs + VID_MST));
 116         DBGFS_DUMP(VID_BC);
 117         DBGFS_DUMP(VID_TINT);
 118         DBGFS_DUMP(VID_CSAT);
 119         seq_putc(s, '\n');
 120         return 0;
 121 }
 122 
 123 static struct drm_info_list vid_debugfs_files[] = {
 124         { "vid", vid_dbg_show, 0, NULL },
 125 };
 126 
 127 int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor)
 128 {
 129         unsigned int i;
 130 
 131         for (i = 0; i < ARRAY_SIZE(vid_debugfs_files); i++)
 132                 vid_debugfs_files[i].data = vid;
 133 
 134         return drm_debugfs_create_files(vid_debugfs_files,
 135                                         ARRAY_SIZE(vid_debugfs_files),
 136                                         minor->debugfs_root, minor);
 137 }
 138 
 139 void sti_vid_commit(struct sti_vid *vid,
 140                     struct drm_plane_state *state)
 141 {
 142         struct drm_crtc *crtc = state->crtc;
 143         struct drm_display_mode *mode = &crtc->mode;
 144         int dst_x = state->crtc_x;
 145         int dst_y = state->crtc_y;
 146         int dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
 147         int dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
 148         int src_h = state->src_h >> 16;
 149         u32 val, ydo, xdo, yds, xds;
 150 
 151         /* Input / output size
 152          * Align to upper even value */
 153         dst_w = ALIGN(dst_w, 2);
 154         dst_h = ALIGN(dst_h, 2);
 155 
 156         /* Unmask */
 157         val = readl(vid->regs + VID_CTL);
 158         val &= ~VID_CTL_IGNORE;
 159         writel(val, vid->regs + VID_CTL);
 160 
 161         ydo = sti_vtg_get_line_number(*mode, dst_y);
 162         yds = sti_vtg_get_line_number(*mode, dst_y + dst_h - 1);
 163         xdo = sti_vtg_get_pixel_number(*mode, dst_x);
 164         xds = sti_vtg_get_pixel_number(*mode, dst_x + dst_w - 1);
 165 
 166         writel((ydo << 16) | xdo, vid->regs + VID_VPO);
 167         writel((yds << 16) | xds, vid->regs + VID_VPS);
 168 
 169         /* Color conversion parameters */
 170         if (src_h >= VID_MIN_HD_HEIGHT) {
 171                 writel(VID_MPR0_BT709, vid->regs + VID_MPR0);
 172                 writel(VID_MPR1_BT709, vid->regs + VID_MPR1);
 173                 writel(VID_MPR2_BT709, vid->regs + VID_MPR2);
 174                 writel(VID_MPR3_BT709, vid->regs + VID_MPR3);
 175         } else {
 176                 writel(VID_MPR0_BT601, vid->regs + VID_MPR0);
 177                 writel(VID_MPR1_BT601, vid->regs + VID_MPR1);
 178                 writel(VID_MPR2_BT601, vid->regs + VID_MPR2);
 179                 writel(VID_MPR3_BT601, vid->regs + VID_MPR3);
 180         }
 181 }
 182 
 183 void sti_vid_disable(struct sti_vid *vid)
 184 {
 185         u32 val;
 186 
 187         /* Mask */
 188         val = readl(vid->regs + VID_CTL);
 189         val |= VID_CTL_IGNORE;
 190         writel(val, vid->regs + VID_CTL);
 191 }
 192 
 193 static void sti_vid_init(struct sti_vid *vid)
 194 {
 195         /* Enable PSI, Mask layer */
 196         writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL);
 197 
 198         /* Opaque */
 199         writel(VID_ALP_OPAQUE, vid->regs + VID_ALP);
 200 
 201         /* Brightness, contrast, tint, saturation */
 202         writel(VID_BC_DFLT, vid->regs + VID_BC);
 203         writel(VID_TINT_DFLT, vid->regs + VID_TINT);
 204         writel(VID_CSAT_DFLT, vid->regs + VID_CSAT);
 205 }
 206 
 207 struct sti_vid *sti_vid_create(struct device *dev, struct drm_device *drm_dev,
 208                                int id, void __iomem *baseaddr)
 209 {
 210         struct sti_vid *vid;
 211 
 212         vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL);
 213         if (!vid) {
 214                 DRM_ERROR("Failed to allocate memory for VID\n");
 215                 return NULL;
 216         }
 217 
 218         vid->dev = dev;
 219         vid->regs = baseaddr;
 220         vid->id = id;
 221 
 222         sti_vid_init(vid);
 223 
 224         return vid;
 225 }

/* [<][>][^][v][top][bottom][index][help] */