Commit | Line | Data |
---|---|---|
cfd8d744 BG |
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 | ||
9e1f05b2 | 9 | #include "sti_plane.h" |
cfd8d744 BG |
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 | ||
29d1dc62 VA |
46 | void sti_vid_commit(struct sti_vid *vid, |
47 | struct drm_plane_state *state) | |
cfd8d744 | 48 | { |
29d1dc62 VA |
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); | |
871bcdfe | 55 | u32 val, ydo, xdo, yds, xds; |
cfd8d744 | 56 | |
29d1dc62 VA |
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 | ||
cfd8d744 BG |
62 | /* Unmask */ |
63 | val = readl(vid->regs + VID_CTL); | |
64 | val &= ~VID_CTL_IGNORE; | |
65 | writel(val, vid->regs + VID_CTL); | |
66 | ||
29d1dc62 VA |
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); | |
cfd8d744 BG |
71 | |
72 | writel((ydo << 16) | xdo, vid->regs + VID_VPO); | |
73 | writel((yds << 16) | xds, vid->regs + VID_VPS); | |
cfd8d744 BG |
74 | } |
75 | ||
29d1dc62 | 76 | void sti_vid_disable(struct sti_vid *vid) |
cfd8d744 BG |
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); | |
cfd8d744 BG |
84 | } |
85 | ||
871bcdfe | 86 | static void sti_vid_init(struct sti_vid *vid) |
cfd8d744 BG |
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 | ||
871bcdfe VA |
106 | struct sti_vid *sti_vid_create(struct device *dev, int id, |
107 | void __iomem *baseaddr) | |
cfd8d744 | 108 | { |
871bcdfe | 109 | struct sti_vid *vid; |
cfd8d744 BG |
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 | ||
871bcdfe VA |
117 | vid->dev = dev; |
118 | vid->regs = baseaddr; | |
119 | vid->id = id; | |
120 | ||
121 | sti_vid_init(vid); | |
cfd8d744 BG |
122 | |
123 | return vid; | |
124 | } |