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 | ||
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 | ||
46 | static 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 | ||
58 | static 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 | ||
74 | static 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 | ||
86 | static const uint32_t *sti_vid_get_formats(struct sti_layer *layer) | |
87 | { | |
88 | return NULL; | |
89 | } | |
90 | ||
91 | static unsigned int sti_vid_get_nb_formats(struct sti_layer *layer) | |
92 | { | |
93 | return 0; | |
94 | } | |
95 | ||
96 | static 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 | ||
116 | static 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 | ||
125 | struct 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 | } |