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 | ||
871bcdfe | 46 | int sti_vid_commit(struct sti_vid *vid, struct sti_plane *plane) |
cfd8d744 | 47 | { |
871bcdfe VA |
48 | struct drm_display_mode *mode = plane->mode; |
49 | u32 val, ydo, xdo, yds, xds; | |
cfd8d744 BG |
50 | |
51 | /* Unmask */ | |
52 | val = readl(vid->regs + VID_CTL); | |
53 | val &= ~VID_CTL_IGNORE; | |
54 | writel(val, vid->regs + VID_CTL); | |
55 | ||
871bcdfe VA |
56 | ydo = sti_vtg_get_line_number(*mode, plane->dst_y); |
57 | yds = sti_vtg_get_line_number(*mode, plane->dst_y + plane->dst_h - 1); | |
58 | xdo = sti_vtg_get_pixel_number(*mode, plane->dst_x); | |
59 | xds = sti_vtg_get_pixel_number(*mode, plane->dst_x + plane->dst_w - 1); | |
cfd8d744 BG |
60 | |
61 | writel((ydo << 16) | xdo, vid->regs + VID_VPO); | |
62 | writel((yds << 16) | xds, vid->regs + VID_VPS); | |
63 | ||
64 | return 0; | |
65 | } | |
66 | ||
871bcdfe | 67 | int sti_vid_disable(struct sti_vid *vid) |
cfd8d744 BG |
68 | { |
69 | u32 val; | |
70 | ||
71 | /* Mask */ | |
72 | val = readl(vid->regs + VID_CTL); | |
73 | val |= VID_CTL_IGNORE; | |
74 | writel(val, vid->regs + VID_CTL); | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
871bcdfe | 79 | static void sti_vid_init(struct sti_vid *vid) |
cfd8d744 BG |
80 | { |
81 | /* Enable PSI, Mask layer */ | |
82 | writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL); | |
83 | ||
84 | /* Opaque */ | |
85 | writel(VID_ALP_OPAQUE, vid->regs + VID_ALP); | |
86 | ||
87 | /* Color conversion parameters */ | |
88 | writel(VID_MPR0_BT709, vid->regs + VID_MPR0); | |
89 | writel(VID_MPR1_BT709, vid->regs + VID_MPR1); | |
90 | writel(VID_MPR2_BT709, vid->regs + VID_MPR2); | |
91 | writel(VID_MPR3_BT709, vid->regs + VID_MPR3); | |
92 | ||
93 | /* Brightness, contrast, tint, saturation */ | |
94 | writel(VID_BC_DFLT, vid->regs + VID_BC); | |
95 | writel(VID_TINT_DFLT, vid->regs + VID_TINT); | |
96 | writel(VID_CSAT_DFLT, vid->regs + VID_CSAT); | |
97 | } | |
98 | ||
871bcdfe VA |
99 | struct sti_vid *sti_vid_create(struct device *dev, int id, |
100 | void __iomem *baseaddr) | |
cfd8d744 | 101 | { |
871bcdfe | 102 | struct sti_vid *vid; |
cfd8d744 BG |
103 | |
104 | vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL); | |
105 | if (!vid) { | |
106 | DRM_ERROR("Failed to allocate memory for VID\n"); | |
107 | return NULL; | |
108 | } | |
109 | ||
871bcdfe VA |
110 | vid->dev = dev; |
111 | vid->regs = baseaddr; | |
112 | vid->id = id; | |
113 | ||
114 | sti_vid_init(vid); | |
cfd8d744 BG |
115 | |
116 | return vid; | |
117 | } |