1 /* 2 * Copyright (C) STMicroelectronics SA 2014 3 * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. 4 * License terms: GNU General Public License (GPL), version 2 5 */ 6 7 #include <drm/drmP.h> 8 9 #include "sti_plane.h" 10 #include "sti_vid.h" 11 #include "sti_vtg.h" 12 13 /* Registers */ 14 #define VID_CTL 0x00 15 #define VID_ALP 0x04 16 #define VID_CLF 0x08 17 #define VID_VPO 0x0C 18 #define VID_VPS 0x10 19 #define VID_KEY1 0x28 20 #define VID_KEY2 0x2C 21 #define VID_MPR0 0x30 22 #define VID_MPR1 0x34 23 #define VID_MPR2 0x38 24 #define VID_MPR3 0x3C 25 #define VID_MST 0x68 26 #define VID_BC 0x70 27 #define VID_TINT 0x74 28 #define VID_CSAT 0x78 29 30 /* Registers values */ 31 #define VID_CTL_IGNORE (BIT(31) | BIT(30)) 32 #define VID_CTL_PSI_ENABLE (BIT(2) | BIT(1) | BIT(0)) 33 #define VID_ALP_OPAQUE 0x00000080 34 #define VID_BC_DFLT 0x00008000 35 #define VID_TINT_DFLT 0x00000000 36 #define VID_CSAT_DFLT 0x00000080 37 /* YCbCr to RGB BT709: 38 * R = Y+1.5391Cr 39 * G = Y-0.4590Cr-0.1826Cb 40 * B = Y+1.8125Cb */ 41 #define VID_MPR0_BT709 0x0A800000 42 #define VID_MPR1_BT709 0x0AC50000 43 #define VID_MPR2_BT709 0x07150545 44 #define VID_MPR3_BT709 0x00000AE8 45 46 void sti_vid_commit(struct sti_vid *vid, 47 struct drm_plane_state *state) 48 { 49 struct drm_crtc *crtc = state->crtc; 50 struct drm_display_mode *mode = &crtc->mode; 51 int dst_x = state->crtc_x; 52 int dst_y = state->crtc_y; 53 int dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x); 54 int dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y); 55 u32 val, ydo, xdo, yds, xds; 56 57 /* Input / output size 58 * Align to upper even value */ 59 dst_w = ALIGN(dst_w, 2); 60 dst_h = ALIGN(dst_h, 2); 61 62 /* Unmask */ 63 val = readl(vid->regs + VID_CTL); 64 val &= ~VID_CTL_IGNORE; 65 writel(val, vid->regs + VID_CTL); 66 67 ydo = sti_vtg_get_line_number(*mode, dst_y); 68 yds = sti_vtg_get_line_number(*mode, dst_y + dst_h - 1); 69 xdo = sti_vtg_get_pixel_number(*mode, dst_x); 70 xds = sti_vtg_get_pixel_number(*mode, dst_x + dst_w - 1); 71 72 writel((ydo << 16) | xdo, vid->regs + VID_VPO); 73 writel((yds << 16) | xds, vid->regs + VID_VPS); 74 } 75 76 void sti_vid_disable(struct sti_vid *vid) 77 { 78 u32 val; 79 80 /* Mask */ 81 val = readl(vid->regs + VID_CTL); 82 val |= VID_CTL_IGNORE; 83 writel(val, vid->regs + VID_CTL); 84 } 85 86 static void sti_vid_init(struct sti_vid *vid) 87 { 88 /* Enable PSI, Mask layer */ 89 writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL); 90 91 /* Opaque */ 92 writel(VID_ALP_OPAQUE, vid->regs + VID_ALP); 93 94 /* Color conversion parameters */ 95 writel(VID_MPR0_BT709, vid->regs + VID_MPR0); 96 writel(VID_MPR1_BT709, vid->regs + VID_MPR1); 97 writel(VID_MPR2_BT709, vid->regs + VID_MPR2); 98 writel(VID_MPR3_BT709, vid->regs + VID_MPR3); 99 100 /* Brightness, contrast, tint, saturation */ 101 writel(VID_BC_DFLT, vid->regs + VID_BC); 102 writel(VID_TINT_DFLT, vid->regs + VID_TINT); 103 writel(VID_CSAT_DFLT, vid->regs + VID_CSAT); 104 } 105 106 struct sti_vid *sti_vid_create(struct device *dev, int id, 107 void __iomem *baseaddr) 108 { 109 struct sti_vid *vid; 110 111 vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL); 112 if (!vid) { 113 DRM_ERROR("Failed to allocate memory for VID\n"); 114 return NULL; 115 } 116 117 vid->dev = dev; 118 vid->regs = baseaddr; 119 vid->id = id; 120 121 sti_vid_init(vid); 122 123 return vid; 124 } 125