brintos

brintos / linux-shallow public Read only

0
0
Text · 4.4 KiB · 0df8186 Raw
175 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2019 NXP.4 */5 6#include <linux/device.h>7#include <linux/slab.h>8 9#include "dcss-dev.h"10 11#define DCSS_SS_SYS_CTRL			0x0012#define   RUN_EN				BIT(0)13#define DCSS_SS_DISPLAY				0x1014#define   LRC_X_POS				015#define   LRC_X_MASK				GENMASK(12, 0)16#define   LRC_Y_POS				1617#define   LRC_Y_MASK				GENMASK(28, 16)18#define DCSS_SS_HSYNC				0x2019#define DCSS_SS_VSYNC				0x3020#define   SYNC_START_POS			021#define   SYNC_START_MASK			GENMASK(12, 0)22#define   SYNC_END_POS				1623#define   SYNC_END_MASK				GENMASK(28, 16)24#define   SYNC_POL				BIT(31)25#define DCSS_SS_DE_ULC				0x4026#define   ULC_X_POS				027#define   ULC_X_MASK				GENMASK(12, 0)28#define   ULC_Y_POS				1629#define   ULC_Y_MASK				GENMASK(28, 16)30#define   ULC_POL				BIT(31)31#define DCSS_SS_DE_LRC				0x5032#define DCSS_SS_MODE				0x6033#define   PIPE_MODE_POS				034#define   PIPE_MODE_MASK			GENMASK(1, 0)35#define DCSS_SS_COEFF				0x7036#define   HORIZ_A_POS				037#define   HORIZ_A_MASK				GENMASK(3, 0)38#define   HORIZ_B_POS				439#define   HORIZ_B_MASK				GENMASK(7, 4)40#define   HORIZ_C_POS				841#define   HORIZ_C_MASK				GENMASK(11, 8)42#define   HORIZ_H_NORM_POS			1243#define   HORIZ_H_NORM_MASK			GENMASK(14, 12)44#define   VERT_A_POS				1645#define   VERT_A_MASK				GENMASK(19, 16)46#define   VERT_B_POS				2047#define   VERT_B_MASK				GENMASK(23, 20)48#define   VERT_C_POS				2449#define   VERT_C_MASK				GENMASK(27, 24)50#define   VERT_H_NORM_POS			2851#define   VERT_H_NORM_MASK			GENMASK(30, 28)52#define DCSS_SS_CLIP_CB				0x8053#define DCSS_SS_CLIP_CR				0x9054#define   CLIP_MIN_POS				055#define   CLIP_MIN_MASK				GENMASK(9, 0)56#define   CLIP_MAX_POS				057#define   CLIP_MAX_MASK				GENMASK(23, 16)58#define DCSS_SS_INTER_MODE			0xA059#define   INT_EN				BIT(0)60#define   VSYNC_SHIFT				BIT(1)61 62struct dcss_ss {63	struct device *dev;64	void __iomem *base_reg;65	u32 base_ofs;66 67	struct dcss_ctxld *ctxld;68	u32 ctx_id;69 70	bool in_use;71};72 73static void dcss_ss_write(struct dcss_ss *ss, u32 val, u32 ofs)74{75	if (!ss->in_use)76		dcss_writel(val, ss->base_reg + ofs);77 78	dcss_ctxld_write(ss->ctxld, ss->ctx_id, val,79			 ss->base_ofs + ofs);80}81 82int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base)83{84	struct dcss_ss *ss;85 86	ss = devm_kzalloc(dcss->dev, sizeof(*ss), GFP_KERNEL);87	if (!ss)88		return -ENOMEM;89 90	dcss->ss = ss;91	ss->dev = dcss->dev;92	ss->ctxld = dcss->ctxld;93 94	ss->base_reg = devm_ioremap(ss->dev, ss_base, SZ_4K);95	if (!ss->base_reg) {96		dev_err(ss->dev, "ss: unable to remap ss base\n");97		return -ENOMEM;98	}99 100	ss->base_ofs = ss_base;101	ss->ctx_id = CTX_SB_HP;102 103	return 0;104}105 106void dcss_ss_exit(struct dcss_ss *ss)107{108	/* stop SS */109	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);110}111 112void dcss_ss_subsam_set(struct dcss_ss *ss)113{114	dcss_ss_write(ss, 0x41614161, DCSS_SS_COEFF);115	dcss_ss_write(ss, 0, DCSS_SS_MODE);116	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CB);117	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CR);118}119 120void dcss_ss_sync_set(struct dcss_ss *ss, struct videomode *vm,121		      bool phsync, bool pvsync)122{123	u16 lrc_x, lrc_y;124	u16 hsync_start, hsync_end;125	u16 vsync_start, vsync_end;126	u16 de_ulc_x, de_ulc_y;127	u16 de_lrc_x, de_lrc_y;128 129	lrc_x = vm->hfront_porch + vm->hback_porch + vm->hsync_len +130		vm->hactive - 1;131	lrc_y = vm->vfront_porch + vm->vback_porch + vm->vsync_len +132		vm->vactive - 1;133 134	dcss_ss_write(ss, (lrc_y << LRC_Y_POS) | lrc_x, DCSS_SS_DISPLAY);135 136	hsync_start = vm->hfront_porch + vm->hback_porch + vm->hsync_len +137		      vm->hactive - 1;138	hsync_end = vm->hsync_len - 1;139 140	dcss_ss_write(ss, (phsync ? SYNC_POL : 0) |141		      ((u32)hsync_end << SYNC_END_POS) | hsync_start,142		      DCSS_SS_HSYNC);143 144	vsync_start = vm->vfront_porch - 1;145	vsync_end = vm->vfront_porch + vm->vsync_len - 1;146 147	dcss_ss_write(ss, (pvsync ? SYNC_POL : 0) |148		      ((u32)vsync_end << SYNC_END_POS) | vsync_start,149		      DCSS_SS_VSYNC);150 151	de_ulc_x = vm->hsync_len + vm->hback_porch - 1;152	de_ulc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch;153 154	dcss_ss_write(ss, SYNC_POL | ((u32)de_ulc_y << ULC_Y_POS) | de_ulc_x,155		      DCSS_SS_DE_ULC);156 157	de_lrc_x = vm->hsync_len + vm->hback_porch + vm->hactive - 1;158	de_lrc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch +159		   vm->vactive - 1;160 161	dcss_ss_write(ss, (de_lrc_y << LRC_Y_POS) | de_lrc_x, DCSS_SS_DE_LRC);162}163 164void dcss_ss_enable(struct dcss_ss *ss)165{166	dcss_ss_write(ss, RUN_EN, DCSS_SS_SYS_CTRL);167	ss->in_use = true;168}169 170void dcss_ss_shutoff(struct dcss_ss *ss)171{172	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);173	ss->in_use = false;174}175