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_layer.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 46static int sti_vid_prepare_layer(struct sti_layer *vid, bool first_prepare) 47{ 48 u32 val; 49 50 /* Unmask */ 51 val = readl(vid->regs + VID_CTL); 52 val &= ~VID_CTL_IGNORE; 53 writel(val, vid->regs + VID_CTL); 54 55 return 0; 56} 57 58static int sti_vid_commit_layer(struct sti_layer *vid) 59{ 60 struct drm_display_mode *mode = vid->mode; 61 u32 ydo, xdo, yds, xds; 62 63 ydo = sti_vtg_get_line_number(*mode, vid->dst_y); 64 yds = sti_vtg_get_line_number(*mode, vid->dst_y + vid->dst_h - 1); 65 xdo = sti_vtg_get_pixel_number(*mode, vid->dst_x); 66 xds = sti_vtg_get_pixel_number(*mode, vid->dst_x + vid->dst_w - 1); 67 68 writel((ydo << 16) | xdo, vid->regs + VID_VPO); 69 writel((yds << 16) | xds, vid->regs + VID_VPS); 70 71 return 0; 72} 73 74static int sti_vid_disable_layer(struct sti_layer *vid) 75{ 76 u32 val; 77 78 /* Mask */ 79 val = readl(vid->regs + VID_CTL); 80 val |= VID_CTL_IGNORE; 81 writel(val, vid->regs + VID_CTL); 82 83 return 0; 84} 85 86static const uint32_t *sti_vid_get_formats(struct sti_layer *layer) 87{ 88 return NULL; 89} 90 91static unsigned int sti_vid_get_nb_formats(struct sti_layer *layer) 92{ 93 return 0; 94} 95 96static void sti_vid_init(struct sti_layer *vid) 97{ 98 /* Enable PSI, Mask layer */ 99 writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL); 100 101 /* Opaque */ 102 writel(VID_ALP_OPAQUE, vid->regs + VID_ALP); 103 104 /* Color conversion parameters */ 105 writel(VID_MPR0_BT709, vid->regs + VID_MPR0); 106 writel(VID_MPR1_BT709, vid->regs + VID_MPR1); 107 writel(VID_MPR2_BT709, vid->regs + VID_MPR2); 108 writel(VID_MPR3_BT709, vid->regs + VID_MPR3); 109 110 /* Brightness, contrast, tint, saturation */ 111 writel(VID_BC_DFLT, vid->regs + VID_BC); 112 writel(VID_TINT_DFLT, vid->regs + VID_TINT); 113 writel(VID_CSAT_DFLT, vid->regs + VID_CSAT); 114} 115 116static const struct sti_layer_funcs vid_ops = { 117 .get_formats = sti_vid_get_formats, 118 .get_nb_formats = sti_vid_get_nb_formats, 119 .init = sti_vid_init, 120 .prepare = sti_vid_prepare_layer, 121 .commit = sti_vid_commit_layer, 122 .disable = sti_vid_disable_layer, 123}; 124 125struct sti_layer *sti_vid_create(struct device *dev) 126{ 127 struct sti_layer *vid; 128 129 vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL); 130 if (!vid) { 131 DRM_ERROR("Failed to allocate memory for VID\n"); 132 return NULL; 133 } 134 135 vid->ops = &vid_ops; 136 137 return vid; 138} 139