Commit | Line | Data |
---|---|---|
9bbf86fe BG |
1 | /* |
2 | * Copyright (C) STMicroelectronics SA 2014 | |
3 | * Authors: Benjamin Gaignard <benjamin.gaignard@st.com> | |
4 | * Fabien Dessenne <fabien.dessenne@st.com> | |
5 | * for STMicroelectronics. | |
6 | * License terms: GNU General Public License (GPL), version 2 | |
7 | */ | |
8 | ||
de4b00b0 | 9 | #include <drm/drmP.h> |
871bcdfe | 10 | #include <drm/drm_fb_cma_helper.h> |
29d1dc62 | 11 | #include <drm/drm_gem_cma_helper.h> |
de4b00b0 | 12 | |
9bbf86fe | 13 | #include "sti_compositor.h" |
9e1f05b2 VA |
14 | #include "sti_drv.h" |
15 | #include "sti_plane.h" | |
9bbf86fe | 16 | |
871bcdfe VA |
17 | /* (Background) < GDP0 < GDP1 < HQVDP0 < GDP2 < GDP3 < (ForeGround) */ |
18 | enum sti_plane_desc sti_plane_default_zorder[] = { | |
9bbf86fe | 19 | STI_GDP_0, |
9bbf86fe | 20 | STI_GDP_1, |
871bcdfe | 21 | STI_HQVDP_0, |
9bbf86fe BG |
22 | STI_GDP_2, |
23 | STI_GDP_3, | |
24 | }; | |
25 | ||
871bcdfe | 26 | const char *sti_plane_to_str(struct sti_plane *plane) |
9bbf86fe | 27 | { |
871bcdfe VA |
28 | switch (plane->desc) { |
29 | case STI_GDP_0: | |
30 | return "GDP0"; | |
31 | case STI_GDP_1: | |
32 | return "GDP1"; | |
33 | case STI_GDP_2: | |
34 | return "GDP2"; | |
35 | case STI_GDP_3: | |
36 | return "GDP3"; | |
37 | case STI_HQVDP_0: | |
38 | return "HQVDP0"; | |
39 | case STI_CURSOR: | |
40 | return "CURSOR"; | |
41 | default: | |
42 | return "<UNKNOWN PLANE>"; | |
43 | } | |
44 | } | |
871bcdfe | 45 | |
bf8f9e4a VA |
46 | #define STI_FPS_INTERVAL_MS 3000 |
47 | ||
bf8f9e4a VA |
48 | void sti_plane_update_fps(struct sti_plane *plane, |
49 | bool new_frame, | |
50 | bool new_field) | |
51 | { | |
2c83f581 | 52 | ktime_t now; |
bf8f9e4a VA |
53 | struct sti_fps_info *fps; |
54 | int fpks, fipks, ms_since_last, num_frames, num_fields; | |
55 | ||
2c83f581 | 56 | now = ktime_get(); |
bf8f9e4a VA |
57 | |
58 | /* Compute number of frame updates */ | |
59 | fps = &plane->fps_info; | |
60 | ||
61 | if (new_field) | |
62 | fps->curr_field_counter++; | |
63 | ||
64 | /* do not perform fps calcul if new_frame is false */ | |
65 | if (!new_frame) | |
66 | return; | |
67 | ||
68 | fps->curr_frame_counter++; | |
2c83f581 | 69 | ms_since_last = ktime_to_ms(ktime_sub(now, fps->last_timestamp)); |
bf8f9e4a VA |
70 | num_frames = fps->curr_frame_counter - fps->last_frame_counter; |
71 | ||
72 | if (num_frames <= 0 || ms_since_last < STI_FPS_INTERVAL_MS) | |
73 | return; | |
74 | ||
75 | fps->last_timestamp = now; | |
76 | fps->last_frame_counter = fps->curr_frame_counter; | |
77 | fpks = (num_frames * 1000000) / ms_since_last; | |
78 | snprintf(plane->fps_info.fps_str, FPS_LENGTH, "%-6s @ %d.%.3d fps", | |
79 | sti_plane_to_str(plane), fpks / 1000, fpks % 1000); | |
80 | ||
81 | if (fps->curr_field_counter) { | |
82 | /* Compute number of field updates */ | |
83 | num_fields = fps->curr_field_counter - fps->last_field_counter; | |
84 | fps->last_field_counter = fps->curr_field_counter; | |
85 | fipks = (num_fields * 1000000) / ms_since_last; | |
86 | snprintf(plane->fps_info.fips_str, | |
87 | FPS_LENGTH, " - %d.%.3d field/sec", | |
88 | fipks / 1000, fipks % 1000); | |
89 | } else { | |
90 | plane->fps_info.fips_str[0] = '\0'; | |
91 | } | |
92 | ||
93 | if (fps->output) | |
94 | DRM_INFO("%s%s\n", | |
95 | plane->fps_info.fps_str, | |
96 | plane->fps_info.fips_str); | |
97 | } | |
98 | ||
83af0a48 BG |
99 | int sti_plane_set_property(struct drm_plane *drm_plane, |
100 | struct drm_property *property, | |
101 | uint64_t val) | |
9bbf86fe | 102 | { |
871bcdfe | 103 | struct drm_device *dev = drm_plane->dev; |
9e1f05b2 | 104 | struct sti_private *private = dev->dev_private; |
871bcdfe | 105 | struct sti_plane *plane = to_sti_plane(drm_plane); |
9bbf86fe BG |
106 | |
107 | DRM_DEBUG_DRIVER("\n"); | |
108 | ||
109 | if (property == private->plane_zorder_property) { | |
871bcdfe | 110 | plane->zorder = val; |
9bbf86fe BG |
111 | return 0; |
112 | } | |
113 | ||
114 | return -EINVAL; | |
115 | } | |
116 | ||
9e1f05b2 | 117 | static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane) |
9bbf86fe | 118 | { |
871bcdfe | 119 | struct drm_device *dev = drm_plane->dev; |
9e1f05b2 | 120 | struct sti_private *private = dev->dev_private; |
871bcdfe | 121 | struct sti_plane *plane = to_sti_plane(drm_plane); |
9bbf86fe | 122 | struct drm_property *prop; |
9bbf86fe BG |
123 | |
124 | prop = private->plane_zorder_property; | |
125 | if (!prop) { | |
bf60b29f VA |
126 | prop = drm_property_create_range(dev, 0, "zpos", 1, |
127 | GAM_MIXER_NB_DEPTH_LEVEL); | |
9bbf86fe BG |
128 | if (!prop) |
129 | return; | |
130 | ||
131 | private->plane_zorder_property = prop; | |
132 | } | |
133 | ||
871bcdfe | 134 | drm_object_attach_property(&drm_plane->base, prop, plane->zorder); |
9bbf86fe BG |
135 | } |
136 | ||
29d1dc62 VA |
137 | void sti_plane_init_property(struct sti_plane *plane, |
138 | enum drm_plane_type type) | |
9bbf86fe | 139 | { |
29d1dc62 | 140 | unsigned int i; |
de4b00b0 | 141 | |
871bcdfe VA |
142 | for (i = 0; i < ARRAY_SIZE(sti_plane_default_zorder); i++) |
143 | if (sti_plane_default_zorder[i] == plane->desc) | |
9bbf86fe BG |
144 | break; |
145 | ||
871bcdfe | 146 | plane->zorder = i + 1; |
9bbf86fe BG |
147 | |
148 | if (type == DRM_PLANE_TYPE_OVERLAY) | |
9e1f05b2 | 149 | sti_plane_attach_zorder_property(&plane->drm_plane); |
9bbf86fe | 150 | |
871bcdfe VA |
151 | DRM_DEBUG_DRIVER("drm plane:%d mapped to %s with zorder:%d\n", |
152 | plane->drm_plane.base.id, | |
153 | sti_plane_to_str(plane), plane->zorder); | |
9bbf86fe | 154 | } |