Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Original author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Ben Collins <bcollins@ubuntu.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Additional work by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * John Brooks <john.brooks@bluecherry.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/font.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "solo6x10.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define VI_PROG_HSIZE			(1280 - 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define VI_PROG_VSIZE			(1024 - 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define IRQ_LEVEL			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static void solo_capture_config(struct solo_dev *solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned long height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned long width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	solo_reg_write(solo_dev, SOLO_CAP_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		       SOLO_CAP_MAX_PAGE((SOLO_CAP_EXT_SIZE(solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 					  - SOLO_CAP_PAGE_SIZE) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		       | SOLO_CAP_BASE_ADDR(SOLO_CAP_EXT_ADDR(solo_dev) >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	/* XXX: Undocumented bits at b17 and b24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (solo_dev->type == SOLO_DEV_6110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		/* NOTE: Ref driver has (62 << 24) here as well, but it causes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		 * wacked out frame timing on 4-port 6110. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		solo_reg_write(solo_dev, SOLO_CAP_BTW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 			       (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			       SOLO_CAP_MAX_BANDWIDTH(36));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		solo_reg_write(solo_dev, SOLO_CAP_BTW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			       (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			       SOLO_CAP_MAX_BANDWIDTH(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	/* Set scale 1, 9 dimension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	width = solo_dev->video_hsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	height = solo_dev->video_vsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	solo_reg_write(solo_dev, SOLO_DIM_SCALE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	/* Set scale 2, 10 dimension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	width = solo_dev->video_hsize / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	height = solo_dev->video_vsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	solo_reg_write(solo_dev, SOLO_DIM_SCALE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	/* Set scale 3, 11 dimension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	width = solo_dev->video_hsize / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	height = solo_dev->video_vsize / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	solo_reg_write(solo_dev, SOLO_DIM_SCALE3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/* Set scale 4, 12 dimension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	width = solo_dev->video_hsize / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	height = solo_dev->video_vsize / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	solo_reg_write(solo_dev, SOLO_DIM_SCALE4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/* Set scale 5, 13 dimension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	width = solo_dev->video_hsize / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	height = solo_dev->video_vsize / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	solo_reg_write(solo_dev, SOLO_DIM_SCALE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/* Progressive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	width = VI_PROG_HSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	height = VI_PROG_VSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	solo_reg_write(solo_dev, SOLO_DIM_PROG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		       SOLO_DIM_H_MB_NUM(width / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		       SOLO_DIM_V_MB_NUM_FRAME(height / 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* Clear OSD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, SOLO_EOSD_EXT_ADDR >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	solo_reg_write(solo_dev, SOLO_VE_OSD_CLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		       0xF0 << 16 | 0x80 << 8 | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (solo_dev->type == SOLO_DEV_6010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		solo_reg_write(solo_dev, SOLO_VE_OSD_OPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			       SOLO_VE_OSD_H_SHADOW | SOLO_VE_OSD_V_SHADOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, SOLO_VE_OSD_V_DOUBLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			       | SOLO_VE_OSD_H_SHADOW | SOLO_VE_OSD_V_SHADOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* Clear OSG buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	buf = kzalloc(SOLO_EOSD_EXT_SIZE(solo_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	for (i = 0; i < solo_dev->nr_chans; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		solo_p2m_dma(solo_dev, 1, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			     SOLO_EOSD_EXT_ADDR +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			     (SOLO_EOSD_EXT_SIZE(solo_dev) * i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			     SOLO_EOSD_EXT_SIZE(solo_dev), 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define SOLO_OSD_WRITE_SIZE (16 * OSD_TEXT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Should be called with enable_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int solo_osd_print(struct solo_enc_dev *solo_enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct solo_dev *solo_dev = solo_enc->solo_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	u8 *str = solo_enc->osd_text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	u8 *buf = solo_enc->osd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	const struct font_desc *vga = find_font("VGA8x16");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	const u8 *vga_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (WARN_ON_ONCE(!vga))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (!*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		/* Disable OSD on this channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		reg &= ~(1 << solo_enc->ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	memset(buf, 0, SOLO_OSD_WRITE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	vga_data = (const u8 *)vga->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	for (i = 0; *str; i++, str++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		for (j = 0; j < 16; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			buf[(j << 1) | (i & 1) | ((i & ~1) << 4)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			    bitrev8(vga_data[(*str << 4) | j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	solo_p2m_dma(solo_dev, 1, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		     SOLO_EOSD_EXT_ADDR_CHAN(solo_dev, solo_enc->ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		     SOLO_OSD_WRITE_SIZE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	/* Enable OSD on this channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	reg |= (1 << solo_enc->ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * Set channel Quality Profile (0-3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) void solo_s_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		    unsigned int qp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	unsigned int idx, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if ((ch > 31) || (qp > 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (solo_dev->type == SOLO_DEV_6010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (ch < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		reg = SOLO_VE_JPEG_QP_CH_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		ch -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		reg = SOLO_VE_JPEG_QP_CH_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	ch *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	spin_lock_irqsave(&solo_dev->jpeg_qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	solo_dev->jpeg_qp[idx] &= ~(3 << ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	solo_dev->jpeg_qp[idx] |= (qp & 3) << ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	solo_reg_write(solo_dev, reg, solo_dev->jpeg_qp[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	spin_unlock_irqrestore(&solo_dev->jpeg_qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int solo_g_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (solo_dev->type == SOLO_DEV_6010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (WARN_ON_ONCE(ch > 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if (ch < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		ch -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ch *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return (solo_dev->jpeg_qp[idx] >> ch) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define SOLO_QP_INIT 0xaaaaaaaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void solo_jpeg_config(struct solo_dev *solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (solo_dev->type == SOLO_DEV_6010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			       (2 << 24) | (2 << 16) | (2 << 8) | 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			       (4 << 24) | (3 << 16) | (2 << 8) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	spin_lock_init(&solo_dev->jpeg_qp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	/* Initialize Quality Profile for all channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	solo_dev->jpeg_qp[0] = solo_dev->jpeg_qp[1] = SOLO_QP_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, SOLO_QP_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, SOLO_QP_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		(SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (solo_dev->type == SOLO_DEV_6110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			       (0 << 16) | (30 << 8) | 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static void solo_mp4e_config(struct solo_dev *solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	solo_reg_write(solo_dev, SOLO_VE_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		       SOLO_VE_INTR_CTRL(IRQ_LEVEL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		       SOLO_VE_BLOCK_SIZE(SOLO_MP4E_EXT_SIZE(solo_dev) >> 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		       SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	cfg = SOLO_VE_BYTE_ALIGN(2) | SOLO_VE_INSERT_INDEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		| SOLO_VE_MOTION_MODE(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (solo_dev->type != SOLO_DEV_6010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		cfg |= SOLO_VE_MPEG_SIZE_H(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			(SOLO_MP4E_EXT_SIZE(solo_dev) >> 24) & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		cfg |= SOLO_VE_JPEG_SIZE_H(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			(SOLO_JPEG_EXT_SIZE(solo_dev) >> 24) & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	solo_reg_write(solo_dev, SOLO_VE_CFG1, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	solo_reg_write(solo_dev, SOLO_VE_VMRK_INIT_KEY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	solo_reg_write(solo_dev, SOLO_VE_WMRK_STRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (solo_dev->type == SOLO_DEV_6110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		solo_reg_write(solo_dev, SOLO_VE_WMRK_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	solo_reg_write(solo_dev, SOLO_VE_ATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		       SOLO_VE_LITTLE_ENDIAN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		       SOLO_COMP_ATTR_FCODE(1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		       SOLO_COMP_TIME_INC(0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		       SOLO_COMP_TIME_WIDTH(15) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		       SOLO_DCT_INTERVAL(solo_dev->type == SOLO_DEV_6010 ? 9 : 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	for (i = 0; i < solo_dev->nr_chans; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			       (SOLO_EREF_EXT_ADDR(solo_dev) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			       (i * SOLO_EREF_EXT_SIZE)) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE_E(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			       (SOLO_EREF_EXT_ADDR(solo_dev) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			       ((i + 16) * SOLO_EREF_EXT_SIZE)) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (solo_dev->type == SOLO_DEV_6110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		solo_reg_write(solo_dev, SOLO_VE_COMPT_MOT, 0x00040008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		for (i = 0; i < solo_dev->nr_chans; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			solo_reg_write(solo_dev, SOLO_VE_CH_MOT(i), 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int solo_enc_init(struct solo_dev *solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	solo_capture_config(solo_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	solo_mp4e_config(solo_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	solo_jpeg_config(solo_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	for (i = 0; i < solo_dev->nr_chans; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) void solo_enc_exit(struct solo_dev *solo_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	for (i = 0; i < solo_dev->nr_chans; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }