cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fsl_dcu_drm_plane.c (6296B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2015 Freescale Semiconductor, Inc.
      4 *
      5 * Freescale DCU drm device driver
      6 */
      7
      8#include <linux/regmap.h>
      9
     10#include <drm/drm_atomic.h>
     11#include <drm/drm_atomic_helper.h>
     12#include <drm/drm_crtc.h>
     13#include <drm/drm_fb_cma_helper.h>
     14#include <drm/drm_fourcc.h>
     15#include <drm/drm_gem_cma_helper.h>
     16#include <drm/drm_plane_helper.h>
     17#include <drm/drm_probe_helper.h>
     18
     19#include "fsl_dcu_drm_drv.h"
     20#include "fsl_dcu_drm_plane.h"
     21
     22static int fsl_dcu_drm_plane_index(struct drm_plane *plane)
     23{
     24	struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
     25	unsigned int total_layer = fsl_dev->soc->total_layer;
     26	unsigned int index;
     27
     28	index = drm_plane_index(plane);
     29	if (index < total_layer)
     30		return total_layer - index - 1;
     31
     32	dev_err(fsl_dev->dev, "No more layer left\n");
     33	return -EINVAL;
     34}
     35
     36static int fsl_dcu_drm_plane_atomic_check(struct drm_plane *plane,
     37					  struct drm_atomic_state *state)
     38{
     39	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
     40										 plane);
     41	struct drm_framebuffer *fb = new_plane_state->fb;
     42
     43	if (!new_plane_state->fb || !new_plane_state->crtc)
     44		return 0;
     45
     46	switch (fb->format->format) {
     47	case DRM_FORMAT_RGB565:
     48	case DRM_FORMAT_RGB888:
     49	case DRM_FORMAT_XRGB8888:
     50	case DRM_FORMAT_ARGB8888:
     51	case DRM_FORMAT_XRGB4444:
     52	case DRM_FORMAT_ARGB4444:
     53	case DRM_FORMAT_XRGB1555:
     54	case DRM_FORMAT_ARGB1555:
     55	case DRM_FORMAT_YUV422:
     56		return 0;
     57	default:
     58		return -EINVAL;
     59	}
     60}
     61
     62static void fsl_dcu_drm_plane_atomic_disable(struct drm_plane *plane,
     63					     struct drm_atomic_state *state)
     64{
     65	struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
     66	unsigned int value;
     67	int index;
     68
     69	index = fsl_dcu_drm_plane_index(plane);
     70	if (index < 0)
     71		return;
     72
     73	regmap_read(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4), &value);
     74	value &= ~DCU_LAYER_EN;
     75	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4), value);
     76}
     77
     78static void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane,
     79					    struct drm_atomic_state *state)
     80
     81{
     82	struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
     83	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
     84									   plane);
     85	struct drm_framebuffer *fb = plane->state->fb;
     86	struct drm_gem_cma_object *gem;
     87	unsigned int alpha = DCU_LAYER_AB_NONE, bpp;
     88	int index;
     89
     90	if (!fb)
     91		return;
     92
     93	index = fsl_dcu_drm_plane_index(plane);
     94	if (index < 0)
     95		return;
     96
     97	gem = drm_fb_cma_get_gem_obj(fb, 0);
     98
     99	switch (fb->format->format) {
    100	case DRM_FORMAT_RGB565:
    101		bpp = FSL_DCU_RGB565;
    102		break;
    103	case DRM_FORMAT_RGB888:
    104		bpp = FSL_DCU_RGB888;
    105		break;
    106	case DRM_FORMAT_ARGB8888:
    107		alpha = DCU_LAYER_AB_WHOLE_FRAME;
    108		fallthrough;
    109	case DRM_FORMAT_XRGB8888:
    110		bpp = FSL_DCU_ARGB8888;
    111		break;
    112	case DRM_FORMAT_ARGB4444:
    113		alpha = DCU_LAYER_AB_WHOLE_FRAME;
    114		fallthrough;
    115	case DRM_FORMAT_XRGB4444:
    116		bpp = FSL_DCU_ARGB4444;
    117		break;
    118	case DRM_FORMAT_ARGB1555:
    119		alpha = DCU_LAYER_AB_WHOLE_FRAME;
    120		fallthrough;
    121	case DRM_FORMAT_XRGB1555:
    122		bpp = FSL_DCU_ARGB1555;
    123		break;
    124	case DRM_FORMAT_YUV422:
    125		bpp = FSL_DCU_YUV422;
    126		break;
    127	default:
    128		return;
    129	}
    130
    131	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 1),
    132		     DCU_LAYER_HEIGHT(new_state->crtc_h) |
    133		     DCU_LAYER_WIDTH(new_state->crtc_w));
    134	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 2),
    135		     DCU_LAYER_POSY(new_state->crtc_y) |
    136		     DCU_LAYER_POSX(new_state->crtc_x));
    137	regmap_write(fsl_dev->regmap,
    138		     DCU_CTRLDESCLN(index, 3), gem->paddr);
    139	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4),
    140		     DCU_LAYER_EN |
    141		     DCU_LAYER_TRANS(0xff) |
    142		     DCU_LAYER_BPP(bpp) |
    143		     alpha);
    144	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 5),
    145		     DCU_LAYER_CKMAX_R(0xFF) |
    146		     DCU_LAYER_CKMAX_G(0xFF) |
    147		     DCU_LAYER_CKMAX_B(0xFF));
    148	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 6),
    149		     DCU_LAYER_CKMIN_R(0) |
    150		     DCU_LAYER_CKMIN_G(0) |
    151		     DCU_LAYER_CKMIN_B(0));
    152	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 7), 0);
    153	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 8),
    154		     DCU_LAYER_FG_FCOLOR(0));
    155	regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 9),
    156		     DCU_LAYER_BG_BCOLOR(0));
    157
    158	if (!strcmp(fsl_dev->soc->name, "ls1021a")) {
    159		regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 10),
    160			     DCU_LAYER_POST_SKIP(0) |
    161			     DCU_LAYER_PRE_SKIP(0));
    162	}
    163
    164	return;
    165}
    166
    167static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = {
    168	.atomic_check = fsl_dcu_drm_plane_atomic_check,
    169	.atomic_disable = fsl_dcu_drm_plane_atomic_disable,
    170	.atomic_update = fsl_dcu_drm_plane_atomic_update,
    171};
    172
    173static void fsl_dcu_drm_plane_destroy(struct drm_plane *plane)
    174{
    175	drm_plane_cleanup(plane);
    176	kfree(plane);
    177}
    178
    179static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = {
    180	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
    181	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
    182	.destroy = fsl_dcu_drm_plane_destroy,
    183	.disable_plane = drm_atomic_helper_disable_plane,
    184	.reset = drm_atomic_helper_plane_reset,
    185	.update_plane = drm_atomic_helper_update_plane,
    186};
    187
    188static const u32 fsl_dcu_drm_plane_formats[] = {
    189	DRM_FORMAT_RGB565,
    190	DRM_FORMAT_RGB888,
    191	DRM_FORMAT_XRGB8888,
    192	DRM_FORMAT_ARGB8888,
    193	DRM_FORMAT_XRGB4444,
    194	DRM_FORMAT_ARGB4444,
    195	DRM_FORMAT_XRGB1555,
    196	DRM_FORMAT_ARGB1555,
    197	DRM_FORMAT_YUV422,
    198};
    199
    200void fsl_dcu_drm_init_planes(struct drm_device *dev)
    201{
    202	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
    203	int i, j;
    204
    205	for (i = 0; i < fsl_dev->soc->total_layer; i++) {
    206		for (j = 1; j <= fsl_dev->soc->layer_regs; j++)
    207			regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(i, j), 0);
    208	}
    209}
    210
    211struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
    212{
    213	struct drm_plane *primary;
    214	int ret;
    215
    216	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
    217	if (!primary) {
    218		DRM_DEBUG_KMS("Failed to allocate primary plane\n");
    219		return NULL;
    220	}
    221
    222	/* possible_crtc's will be filled in later by crtc_init */
    223	ret = drm_universal_plane_init(dev, primary, 0,
    224				       &fsl_dcu_drm_plane_funcs,
    225				       fsl_dcu_drm_plane_formats,
    226				       ARRAY_SIZE(fsl_dcu_drm_plane_formats),
    227				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
    228	if (ret) {
    229		kfree(primary);
    230		primary = NULL;
    231	}
    232	drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
    233
    234	return primary;
    235}