15acd3514SThierry Reding /* 25acd3514SThierry Reding * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. 35acd3514SThierry Reding * 45acd3514SThierry Reding * This program is free software; you can redistribute it and/or modify 55acd3514SThierry Reding * it under the terms of the GNU General Public License version 2 as 65acd3514SThierry Reding * published by the Free Software Foundation. 75acd3514SThierry Reding */ 85acd3514SThierry Reding 95acd3514SThierry Reding #include <drm/drm_atomic.h> 105acd3514SThierry Reding #include <drm/drm_atomic_helper.h> 115acd3514SThierry Reding #include <drm/drm_plane_helper.h> 125acd3514SThierry Reding 135acd3514SThierry Reding #include "dc.h" 145acd3514SThierry Reding #include "plane.h" 155acd3514SThierry Reding 165acd3514SThierry Reding static void tegra_plane_destroy(struct drm_plane *plane) 175acd3514SThierry Reding { 185acd3514SThierry Reding struct tegra_plane *p = to_tegra_plane(plane); 195acd3514SThierry Reding 205acd3514SThierry Reding drm_plane_cleanup(plane); 215acd3514SThierry Reding kfree(p); 225acd3514SThierry Reding } 235acd3514SThierry Reding 245acd3514SThierry Reding static void tegra_plane_reset(struct drm_plane *plane) 255acd3514SThierry Reding { 265acd3514SThierry Reding struct tegra_plane_state *state; 275acd3514SThierry Reding 285acd3514SThierry Reding if (plane->state) 295acd3514SThierry Reding __drm_atomic_helper_plane_destroy_state(plane->state); 305acd3514SThierry Reding 315acd3514SThierry Reding kfree(plane->state); 325acd3514SThierry Reding plane->state = NULL; 335acd3514SThierry Reding 345acd3514SThierry Reding state = kzalloc(sizeof(*state), GFP_KERNEL); 355acd3514SThierry Reding if (state) { 365acd3514SThierry Reding plane->state = &state->base; 375acd3514SThierry Reding plane->state->plane = plane; 385acd3514SThierry Reding } 395acd3514SThierry Reding } 405acd3514SThierry Reding 415acd3514SThierry Reding static struct drm_plane_state * 425acd3514SThierry Reding tegra_plane_atomic_duplicate_state(struct drm_plane *plane) 435acd3514SThierry Reding { 445acd3514SThierry Reding struct tegra_plane_state *state = to_tegra_plane_state(plane->state); 455acd3514SThierry Reding struct tegra_plane_state *copy; 465acd3514SThierry Reding 475acd3514SThierry Reding copy = kmalloc(sizeof(*copy), GFP_KERNEL); 485acd3514SThierry Reding if (!copy) 495acd3514SThierry Reding return NULL; 505acd3514SThierry Reding 515acd3514SThierry Reding __drm_atomic_helper_plane_duplicate_state(plane, ©->base); 525acd3514SThierry Reding copy->tiling = state->tiling; 535acd3514SThierry Reding copy->format = state->format; 545acd3514SThierry Reding copy->swap = state->swap; 555acd3514SThierry Reding 565acd3514SThierry Reding return ©->base; 575acd3514SThierry Reding } 585acd3514SThierry Reding 595acd3514SThierry Reding static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 605acd3514SThierry Reding struct drm_plane_state *state) 615acd3514SThierry Reding { 625acd3514SThierry Reding __drm_atomic_helper_plane_destroy_state(state); 635acd3514SThierry Reding kfree(state); 645acd3514SThierry Reding } 655acd3514SThierry Reding 665acd3514SThierry Reding const struct drm_plane_funcs tegra_plane_funcs = { 675acd3514SThierry Reding .update_plane = drm_atomic_helper_update_plane, 685acd3514SThierry Reding .disable_plane = drm_atomic_helper_disable_plane, 695acd3514SThierry Reding .destroy = tegra_plane_destroy, 705acd3514SThierry Reding .reset = tegra_plane_reset, 715acd3514SThierry Reding .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, 725acd3514SThierry Reding .atomic_destroy_state = tegra_plane_atomic_destroy_state, 735acd3514SThierry Reding }; 745acd3514SThierry Reding 755acd3514SThierry Reding int tegra_plane_state_add(struct tegra_plane *plane, 765acd3514SThierry Reding struct drm_plane_state *state) 775acd3514SThierry Reding { 785acd3514SThierry Reding struct drm_crtc_state *crtc_state; 795acd3514SThierry Reding struct tegra_dc_state *tegra; 805acd3514SThierry Reding struct drm_rect clip; 815acd3514SThierry Reding int err; 825acd3514SThierry Reding 835acd3514SThierry Reding /* Propagate errors from allocation or locking failures. */ 845acd3514SThierry Reding crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); 855acd3514SThierry Reding if (IS_ERR(crtc_state)) 865acd3514SThierry Reding return PTR_ERR(crtc_state); 875acd3514SThierry Reding 885acd3514SThierry Reding clip.x1 = 0; 895acd3514SThierry Reding clip.y1 = 0; 905acd3514SThierry Reding clip.x2 = crtc_state->mode.hdisplay; 915acd3514SThierry Reding clip.y2 = crtc_state->mode.vdisplay; 925acd3514SThierry Reding 935acd3514SThierry Reding /* Check plane state for visibility and calculate clipping bounds */ 945acd3514SThierry Reding err = drm_atomic_helper_check_plane_state(state, crtc_state, &clip, 955acd3514SThierry Reding 0, INT_MAX, true, true); 965acd3514SThierry Reding if (err < 0) 975acd3514SThierry Reding return err; 985acd3514SThierry Reding 995acd3514SThierry Reding tegra = to_dc_state(crtc_state); 1005acd3514SThierry Reding 1015acd3514SThierry Reding tegra->planes |= WIN_A_ACT_REQ << plane->index; 1025acd3514SThierry Reding 1035acd3514SThierry Reding return 0; 1045acd3514SThierry Reding } 1055acd3514SThierry Reding 1065acd3514SThierry Reding int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) 1075acd3514SThierry Reding { 1085acd3514SThierry Reding /* assume no swapping of fetched data */ 1095acd3514SThierry Reding if (swap) 1105acd3514SThierry Reding *swap = BYTE_SWAP_NOSWAP; 1115acd3514SThierry Reding 1125acd3514SThierry Reding switch (fourcc) { 113*511c7023SThierry Reding case DRM_FORMAT_ARGB4444: 114*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_B4G4R4A4; 1157772fdaeSThierry Reding break; 1167772fdaeSThierry Reding 117*511c7023SThierry Reding case DRM_FORMAT_ARGB1555: 118*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_B5G5R5A1; 1195acd3514SThierry Reding break; 1205acd3514SThierry Reding 121*511c7023SThierry Reding case DRM_FORMAT_RGB565: 122*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_B5G6R5; 123*511c7023SThierry Reding break; 124*511c7023SThierry Reding 125*511c7023SThierry Reding case DRM_FORMAT_RGBA5551: 126*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_A1B5G5R5; 1277772fdaeSThierry Reding break; 1287772fdaeSThierry Reding 1297772fdaeSThierry Reding case DRM_FORMAT_ARGB8888: 1305acd3514SThierry Reding *format = WIN_COLOR_DEPTH_B8G8R8A8; 1315acd3514SThierry Reding break; 1325acd3514SThierry Reding 133*511c7023SThierry Reding case DRM_FORMAT_ABGR8888: 134*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R8G8B8A8; 135*511c7023SThierry Reding break; 136*511c7023SThierry Reding 137*511c7023SThierry Reding case DRM_FORMAT_ABGR4444: 138*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R4G4B4A4; 139*511c7023SThierry Reding break; 140*511c7023SThierry Reding 141*511c7023SThierry Reding case DRM_FORMAT_ABGR1555: 142*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R5G5B5A; 143*511c7023SThierry Reding break; 144*511c7023SThierry Reding 145*511c7023SThierry Reding case DRM_FORMAT_BGRA5551: 146*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_AR5G5B5; 147*511c7023SThierry Reding break; 148*511c7023SThierry Reding 149*511c7023SThierry Reding case DRM_FORMAT_XRGB1555: 150*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_B5G5R5X1; 151*511c7023SThierry Reding break; 152*511c7023SThierry Reding 153*511c7023SThierry Reding case DRM_FORMAT_RGBX5551: 154*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_X1B5G5R5; 155*511c7023SThierry Reding break; 156*511c7023SThierry Reding 157*511c7023SThierry Reding case DRM_FORMAT_XBGR1555: 158*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R5G5B5X1; 159*511c7023SThierry Reding break; 160*511c7023SThierry Reding 161*511c7023SThierry Reding case DRM_FORMAT_BGRX5551: 162*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_X1R5G5B5; 163*511c7023SThierry Reding break; 164*511c7023SThierry Reding 165*511c7023SThierry Reding case DRM_FORMAT_BGR565: 166*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R5G6B5; 167*511c7023SThierry Reding break; 168*511c7023SThierry Reding 169*511c7023SThierry Reding case DRM_FORMAT_BGRA8888: 170*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_A8R8G8B8; 171*511c7023SThierry Reding break; 172*511c7023SThierry Reding 173*511c7023SThierry Reding case DRM_FORMAT_RGBA8888: 174*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_A8B8G8R8; 175*511c7023SThierry Reding break; 176*511c7023SThierry Reding 177*511c7023SThierry Reding case DRM_FORMAT_XRGB8888: 178*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_B8G8R8X8; 179*511c7023SThierry Reding break; 180*511c7023SThierry Reding 181*511c7023SThierry Reding case DRM_FORMAT_XBGR8888: 182*511c7023SThierry Reding *format = WIN_COLOR_DEPTH_R8G8B8X8; 1835acd3514SThierry Reding break; 1845acd3514SThierry Reding 1855acd3514SThierry Reding case DRM_FORMAT_UYVY: 1865acd3514SThierry Reding *format = WIN_COLOR_DEPTH_YCbCr422; 1875acd3514SThierry Reding break; 1885acd3514SThierry Reding 1895acd3514SThierry Reding case DRM_FORMAT_YUYV: 1905acd3514SThierry Reding if (!swap) 1915acd3514SThierry Reding return -EINVAL; 1925acd3514SThierry Reding 1935acd3514SThierry Reding *format = WIN_COLOR_DEPTH_YCbCr422; 1945acd3514SThierry Reding *swap = BYTE_SWAP_SWAP2; 1955acd3514SThierry Reding break; 1965acd3514SThierry Reding 1975acd3514SThierry Reding case DRM_FORMAT_YUV420: 1985acd3514SThierry Reding *format = WIN_COLOR_DEPTH_YCbCr420P; 1995acd3514SThierry Reding break; 2005acd3514SThierry Reding 2015acd3514SThierry Reding case DRM_FORMAT_YUV422: 2025acd3514SThierry Reding *format = WIN_COLOR_DEPTH_YCbCr422P; 2035acd3514SThierry Reding break; 2045acd3514SThierry Reding 2055acd3514SThierry Reding default: 2065acd3514SThierry Reding return -EINVAL; 2075acd3514SThierry Reding } 2085acd3514SThierry Reding 2095acd3514SThierry Reding return 0; 2105acd3514SThierry Reding } 2115acd3514SThierry Reding 2125acd3514SThierry Reding bool tegra_plane_format_is_yuv(unsigned int format, bool *planar) 2135acd3514SThierry Reding { 2145acd3514SThierry Reding switch (format) { 2155acd3514SThierry Reding case WIN_COLOR_DEPTH_YCbCr422: 2165acd3514SThierry Reding case WIN_COLOR_DEPTH_YUV422: 2175acd3514SThierry Reding if (planar) 2185acd3514SThierry Reding *planar = false; 2195acd3514SThierry Reding 2205acd3514SThierry Reding return true; 2215acd3514SThierry Reding 2225acd3514SThierry Reding case WIN_COLOR_DEPTH_YCbCr420P: 2235acd3514SThierry Reding case WIN_COLOR_DEPTH_YUV420P: 2245acd3514SThierry Reding case WIN_COLOR_DEPTH_YCbCr422P: 2255acd3514SThierry Reding case WIN_COLOR_DEPTH_YUV422P: 2265acd3514SThierry Reding case WIN_COLOR_DEPTH_YCbCr422R: 2275acd3514SThierry Reding case WIN_COLOR_DEPTH_YUV422R: 2285acd3514SThierry Reding case WIN_COLOR_DEPTH_YCbCr422RA: 2295acd3514SThierry Reding case WIN_COLOR_DEPTH_YUV422RA: 2305acd3514SThierry Reding if (planar) 2315acd3514SThierry Reding *planar = true; 2325acd3514SThierry Reding 2335acd3514SThierry Reding return true; 2345acd3514SThierry Reding } 2355acd3514SThierry Reding 2365acd3514SThierry Reding if (planar) 2375acd3514SThierry Reding *planar = false; 2385acd3514SThierry Reding 2395acd3514SThierry Reding return false; 2405acd3514SThierry Reding } 241