sti_vid.c 3.5 KB
Newer Older
B
Benjamin Gaignard 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
/*
 * Copyright (C) STMicroelectronics SA 2014
 * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <drm/drmP.h>

#include "sti_layer.h"
#include "sti_vid.h"
#include "sti_vtg.h"

/* Registers */
#define VID_CTL                 0x00
#define VID_ALP                 0x04
#define VID_CLF                 0x08
#define VID_VPO                 0x0C
#define VID_VPS                 0x10
#define VID_KEY1                0x28
#define VID_KEY2                0x2C
#define VID_MPR0                0x30
#define VID_MPR1                0x34
#define VID_MPR2                0x38
#define VID_MPR3                0x3C
#define VID_MST                 0x68
#define VID_BC                  0x70
#define VID_TINT                0x74
#define VID_CSAT                0x78

/* Registers values */
#define VID_CTL_IGNORE          (BIT(31) | BIT(30))
#define VID_CTL_PSI_ENABLE      (BIT(2) | BIT(1) | BIT(0))
#define VID_ALP_OPAQUE          0x00000080
#define VID_BC_DFLT             0x00008000
#define VID_TINT_DFLT           0x00000000
#define VID_CSAT_DFLT           0x00000080
/* YCbCr to RGB BT709:
 * R = Y+1.5391Cr
 * G = Y-0.4590Cr-0.1826Cb
 * B = Y+1.8125Cb */
#define VID_MPR0_BT709          0x0A800000
#define VID_MPR1_BT709          0x0AC50000
#define VID_MPR2_BT709          0x07150545
#define VID_MPR3_BT709          0x00000AE8

static int sti_vid_prepare_layer(struct sti_layer *vid, bool first_prepare)
{
	u32 val;

	/* Unmask */
	val = readl(vid->regs + VID_CTL);
	val &= ~VID_CTL_IGNORE;
	writel(val, vid->regs + VID_CTL);

	return 0;
}

static int sti_vid_commit_layer(struct sti_layer *vid)
{
	struct drm_display_mode *mode = vid->mode;
	u32 ydo, xdo, yds, xds;

	ydo = sti_vtg_get_line_number(*mode, vid->dst_y);
	yds = sti_vtg_get_line_number(*mode, vid->dst_y + vid->dst_h - 1);
	xdo = sti_vtg_get_pixel_number(*mode, vid->dst_x);
	xds = sti_vtg_get_pixel_number(*mode, vid->dst_x + vid->dst_w - 1);

	writel((ydo << 16) | xdo, vid->regs + VID_VPO);
	writel((yds << 16) | xds, vid->regs + VID_VPS);

	return 0;
}

static int sti_vid_disable_layer(struct sti_layer *vid)
{
	u32 val;

	/* Mask */
	val = readl(vid->regs + VID_CTL);
	val |= VID_CTL_IGNORE;
	writel(val, vid->regs + VID_CTL);

	return 0;
}

static const uint32_t *sti_vid_get_formats(struct sti_layer *layer)
{
	return NULL;
}

static unsigned int sti_vid_get_nb_formats(struct sti_layer *layer)
{
	return 0;
}

static void sti_vid_init(struct sti_layer *vid)
{
	/* Enable PSI, Mask layer */
	writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL);

	/* Opaque */
	writel(VID_ALP_OPAQUE, vid->regs + VID_ALP);

	/* Color conversion parameters */
	writel(VID_MPR0_BT709, vid->regs + VID_MPR0);
	writel(VID_MPR1_BT709, vid->regs + VID_MPR1);
	writel(VID_MPR2_BT709, vid->regs + VID_MPR2);
	writel(VID_MPR3_BT709, vid->regs + VID_MPR3);

	/* Brightness, contrast, tint, saturation */
	writel(VID_BC_DFLT, vid->regs + VID_BC);
	writel(VID_TINT_DFLT, vid->regs + VID_TINT);
	writel(VID_CSAT_DFLT, vid->regs + VID_CSAT);
}

static const struct sti_layer_funcs vid_ops = {
	.get_formats = sti_vid_get_formats,
	.get_nb_formats = sti_vid_get_nb_formats,
	.init = sti_vid_init,
	.prepare = sti_vid_prepare_layer,
	.commit = sti_vid_commit_layer,
	.disable = sti_vid_disable_layer,
};

struct sti_layer *sti_vid_create(struct device *dev)
{
	struct sti_layer *vid;

	vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL);
	if (!vid) {
		DRM_ERROR("Failed to allocate memory for VID\n");
		return NULL;
	}

	vid->ops = &vid_ops;

	return vid;
}