Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) STMicroelectronics SA 2014
0004  * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
0005  *          Fabien Dessenne <fabien.dessenne@st.com>
0006  *          for STMicroelectronics.
0007  */
0008 
0009 #include <linux/types.h>
0010 
0011 #include <drm/drm_blend.h>
0012 #include <drm/drm_fb_cma_helper.h>
0013 #include <drm/drm_fourcc.h>
0014 #include <drm/drm_framebuffer.h>
0015 #include <drm/drm_gem_cma_helper.h>
0016 
0017 #include "sti_compositor.h"
0018 #include "sti_drv.h"
0019 #include "sti_plane.h"
0020 
0021 const char *sti_plane_to_str(struct sti_plane *plane)
0022 {
0023     switch (plane->desc) {
0024     case STI_GDP_0:
0025         return "GDP0";
0026     case STI_GDP_1:
0027         return "GDP1";
0028     case STI_GDP_2:
0029         return "GDP2";
0030     case STI_GDP_3:
0031         return "GDP3";
0032     case STI_HQVDP_0:
0033         return "HQVDP0";
0034     case STI_CURSOR:
0035         return "CURSOR";
0036     default:
0037         return "<UNKNOWN PLANE>";
0038     }
0039 }
0040 
0041 #define STI_FPS_INTERVAL_MS     3000
0042 
0043 void sti_plane_update_fps(struct sti_plane *plane,
0044               bool new_frame,
0045               bool new_field)
0046 {
0047     struct drm_plane_state *state = plane->drm_plane.state;
0048     ktime_t now;
0049     struct sti_fps_info *fps;
0050     int fpks, fipks, ms_since_last, num_frames, num_fields;
0051 
0052     now = ktime_get();
0053 
0054     /* Compute number of frame updates */
0055     fps = &plane->fps_info;
0056 
0057     if (new_field)
0058         fps->curr_field_counter++;
0059 
0060     /* do not perform fps calcul if new_frame is false */
0061     if (!new_frame)
0062         return;
0063 
0064     fps->curr_frame_counter++;
0065     ms_since_last = ktime_to_ms(ktime_sub(now, fps->last_timestamp));
0066     num_frames = fps->curr_frame_counter - fps->last_frame_counter;
0067 
0068     if (num_frames <= 0  || ms_since_last < STI_FPS_INTERVAL_MS)
0069         return;
0070 
0071     fps->last_timestamp = now;
0072     fps->last_frame_counter = fps->curr_frame_counter;
0073 
0074     if (state->fb) {
0075         fpks = (num_frames * 1000000) / ms_since_last;
0076         snprintf(plane->fps_info.fps_str, FPS_LENGTH,
0077              "%-8s %4dx%-4d %.4s @ %3d.%-3.3d fps (%s)",
0078              plane->drm_plane.name,
0079              state->fb->width,
0080              state->fb->height,
0081              (char *)&state->fb->format->format,
0082              fpks / 1000, fpks % 1000,
0083              sti_plane_to_str(plane));
0084     }
0085 
0086     if (fps->curr_field_counter) {
0087         /* Compute number of field updates */
0088         num_fields = fps->curr_field_counter - fps->last_field_counter;
0089         fps->last_field_counter = fps->curr_field_counter;
0090         fipks = (num_fields * 1000000) / ms_since_last;
0091         snprintf(plane->fps_info.fips_str,
0092              FPS_LENGTH, " - %3d.%-3.3d field/sec",
0093              fipks / 1000, fipks % 1000);
0094     } else {
0095         plane->fps_info.fips_str[0] = '\0';
0096     }
0097 
0098     if (fps->output)
0099         DRM_INFO("%s%s\n",
0100              plane->fps_info.fps_str,
0101              plane->fps_info.fips_str);
0102 }
0103 
0104 static int sti_plane_get_default_zpos(enum drm_plane_type type)
0105 {
0106     switch (type) {
0107     case DRM_PLANE_TYPE_PRIMARY:
0108         return 0;
0109     case DRM_PLANE_TYPE_OVERLAY:
0110         return 1;
0111     case DRM_PLANE_TYPE_CURSOR:
0112         return 7;
0113     }
0114     return 0;
0115 }
0116 
0117 static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane,
0118                          enum drm_plane_type type)
0119 {
0120     int zpos = sti_plane_get_default_zpos(type);
0121 
0122     switch (type) {
0123     case DRM_PLANE_TYPE_PRIMARY:
0124     case DRM_PLANE_TYPE_OVERLAY:
0125         drm_plane_create_zpos_property(drm_plane, zpos, 0, 6);
0126         break;
0127     case DRM_PLANE_TYPE_CURSOR:
0128         drm_plane_create_zpos_immutable_property(drm_plane, zpos);
0129         break;
0130     }
0131 }
0132 
0133 void sti_plane_init_property(struct sti_plane *plane,
0134                  enum drm_plane_type type)
0135 {
0136     sti_plane_attach_zorder_property(&plane->drm_plane, type);
0137 
0138     DRM_DEBUG_DRIVER("drm plane:%d mapped to %s\n",
0139              plane->drm_plane.base.id, sti_plane_to_str(plane));
0140 }