VIDeo plug are one of the compositor input sub-devices. VID are dedicated to video inputs like YUV plans. Like GDP, VID are part of Compositor hardware block and use sti_layer structure to provide an abstraction for Compositor calls. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Reviewed-by: Rob Clark <robdclark@gmail.com>
		
			
				
	
	
		
			138 lines
		
	
	
	
		
			3.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * 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;
 | 
						|
}
 |