162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com> 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Original author: 662306a36Sopenharmony_ci * Ben Collins <bcollins@ubuntu.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Additional work by: 962306a36Sopenharmony_ci * John Brooks <john.brooks@bluecherry.net> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/videodev2.h> 1562306a36Sopenharmony_ci#include <media/v4l2-ioctl.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "solo6x10.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define SOLO_VCLK_DELAY 3 2062306a36Sopenharmony_ci#define SOLO_PROGRESSIVE_VSIZE 1024 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define SOLO_MOT_THRESH_W 64 2362306a36Sopenharmony_ci#define SOLO_MOT_THRESH_H 64 2462306a36Sopenharmony_ci#define SOLO_MOT_THRESH_SIZE 8192 2562306a36Sopenharmony_ci#define SOLO_MOT_THRESH_REAL (SOLO_MOT_THRESH_W * SOLO_MOT_THRESH_H) 2662306a36Sopenharmony_ci#define SOLO_MOT_FLAG_SIZE 1024 2762306a36Sopenharmony_ci#define SOLO_MOT_FLAG_AREA (SOLO_MOT_FLAG_SIZE * 16) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic void solo_vin_config(struct solo_dev *solo_dev) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci solo_dev->vin_hstart = 8; 3262306a36Sopenharmony_ci solo_dev->vin_vstart = 2; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_SYS_VCLK, 3562306a36Sopenharmony_ci SOLO_VCLK_SELECT(2) | 3662306a36Sopenharmony_ci SOLO_VCLK_VIN1415_DELAY(SOLO_VCLK_DELAY) | 3762306a36Sopenharmony_ci SOLO_VCLK_VIN1213_DELAY(SOLO_VCLK_DELAY) | 3862306a36Sopenharmony_ci SOLO_VCLK_VIN1011_DELAY(SOLO_VCLK_DELAY) | 3962306a36Sopenharmony_ci SOLO_VCLK_VIN0809_DELAY(SOLO_VCLK_DELAY) | 4062306a36Sopenharmony_ci SOLO_VCLK_VIN0607_DELAY(SOLO_VCLK_DELAY) | 4162306a36Sopenharmony_ci SOLO_VCLK_VIN0405_DELAY(SOLO_VCLK_DELAY) | 4262306a36Sopenharmony_ci SOLO_VCLK_VIN0203_DELAY(SOLO_VCLK_DELAY) | 4362306a36Sopenharmony_ci SOLO_VCLK_VIN0001_DELAY(SOLO_VCLK_DELAY)); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_ACT_I_P, 4662306a36Sopenharmony_ci SOLO_VI_H_START(solo_dev->vin_hstart) | 4762306a36Sopenharmony_ci SOLO_VI_V_START(solo_dev->vin_vstart) | 4862306a36Sopenharmony_ci SOLO_VI_V_STOP(solo_dev->vin_vstart + 4962306a36Sopenharmony_ci solo_dev->video_vsize)); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_ACT_I_S, 5262306a36Sopenharmony_ci SOLO_VI_H_START(solo_dev->vout_hstart) | 5362306a36Sopenharmony_ci SOLO_VI_V_START(solo_dev->vout_vstart) | 5462306a36Sopenharmony_ci SOLO_VI_V_STOP(solo_dev->vout_vstart + 5562306a36Sopenharmony_ci solo_dev->video_vsize)); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_ACT_P, 5862306a36Sopenharmony_ci SOLO_VI_H_START(0) | 5962306a36Sopenharmony_ci SOLO_VI_V_START(1) | 6062306a36Sopenharmony_ci SOLO_VI_V_STOP(SOLO_PROGRESSIVE_VSIZE)); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_CH_FORMAT, 6362306a36Sopenharmony_ci SOLO_VI_FD_SEL_MASK(0) | SOLO_VI_PROG_MASK(0)); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci /* On 6110, initialize mozaic darkness strength */ 6662306a36Sopenharmony_ci if (solo_dev->type == SOLO_DEV_6010) 6762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_FMT_CFG, 0); 6862306a36Sopenharmony_ci else 6962306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_FMT_CFG, 16 << 22); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PAGE_SW, 2); 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { 7462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, 7562306a36Sopenharmony_ci SOLO_VI_PB_USER_MODE); 7662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, 7762306a36Sopenharmony_ci SOLO_VI_PB_HSIZE(858) | SOLO_VI_PB_VSIZE(246)); 7862306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, 7962306a36Sopenharmony_ci SOLO_VI_PB_VSTART(4) | 8062306a36Sopenharmony_ci SOLO_VI_PB_VSTOP(4 + 240)); 8162306a36Sopenharmony_ci } else { 8262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, 8362306a36Sopenharmony_ci SOLO_VI_PB_USER_MODE | SOLO_VI_PB_PAL); 8462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, 8562306a36Sopenharmony_ci SOLO_VI_PB_HSIZE(864) | SOLO_VI_PB_VSIZE(294)); 8662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, 8762306a36Sopenharmony_ci SOLO_VI_PB_VSTART(4) | 8862306a36Sopenharmony_ci SOLO_VI_PB_VSTOP(4 + 288)); 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_PB_ACT_H, SOLO_VI_PB_HSTART(16) | 9162306a36Sopenharmony_ci SOLO_VI_PB_HSTOP(16 + 720)); 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic void solo_vout_config_cursor(struct solo_dev *dev) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci int i; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci /* Load (blank) cursor bitmap mask (2bpp) */ 9962306a36Sopenharmony_ci for (i = 0; i < 20; i++) 10062306a36Sopenharmony_ci solo_reg_write(dev, SOLO_VO_CURSOR_MASK(i), 0); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci solo_reg_write(dev, SOLO_VO_CURSOR_POS, 0); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci solo_reg_write(dev, SOLO_VO_CURSOR_CLR, 10562306a36Sopenharmony_ci (0x80 << 24) | (0x80 << 16) | (0x10 << 8) | 0x80); 10662306a36Sopenharmony_ci solo_reg_write(dev, SOLO_VO_CURSOR_CLR2, (0xe0 << 8) | 0x80); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic void solo_vout_config(struct solo_dev *solo_dev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci solo_dev->vout_hstart = 6; 11262306a36Sopenharmony_ci solo_dev->vout_vstart = 8; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_FMT_ENC, 11562306a36Sopenharmony_ci solo_dev->video_type | 11662306a36Sopenharmony_ci SOLO_VO_USER_COLOR_SET_NAV | 11762306a36Sopenharmony_ci SOLO_VO_USER_COLOR_SET_NAH | 11862306a36Sopenharmony_ci SOLO_VO_NA_COLOR_Y(0) | 11962306a36Sopenharmony_ci SOLO_VO_NA_COLOR_CB(0) | 12062306a36Sopenharmony_ci SOLO_VO_NA_COLOR_CR(0)); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_ACT_H, 12362306a36Sopenharmony_ci SOLO_VO_H_START(solo_dev->vout_hstart) | 12462306a36Sopenharmony_ci SOLO_VO_H_STOP(solo_dev->vout_hstart + 12562306a36Sopenharmony_ci solo_dev->video_hsize)); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_ACT_V, 12862306a36Sopenharmony_ci SOLO_VO_V_START(solo_dev->vout_vstart) | 12962306a36Sopenharmony_ci SOLO_VO_V_STOP(solo_dev->vout_vstart + 13062306a36Sopenharmony_ci solo_dev->video_vsize)); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RANGE_HV, 13362306a36Sopenharmony_ci SOLO_VO_H_LEN(solo_dev->video_hsize) | 13462306a36Sopenharmony_ci SOLO_VO_V_LEN(solo_dev->video_vsize)); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /* Border & background colors */ 13762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_COLOR, 13862306a36Sopenharmony_ci (0xa0 << 24) | (0x88 << 16) | (0xa0 << 8) | 0x88); 13962306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_COLOR, 14062306a36Sopenharmony_ci (0x10 << 24) | (0x8f << 16) | (0x10 << 8) | 0x8f); 14162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BKG_COLOR, 14262306a36Sopenharmony_ci (16 << 24) | (128 << 16) | (16 << 8) | 128); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_WIN_SW, 0); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0); 14962306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_FREEZE_CTRL, 0); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, SOLO_VO_DISP_ON | 15262306a36Sopenharmony_ci SOLO_VO_DISP_ERASE_COUNT(8) | 15362306a36Sopenharmony_ci SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR)); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci solo_vout_config_cursor(solo_dev); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* Enable channels we support */ 15962306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_CH_ENA, 16062306a36Sopenharmony_ci (1 << solo_dev->nr_chans) - 1); 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic int solo_dma_vin_region(struct solo_dev *solo_dev, u32 off, 16462306a36Sopenharmony_ci u16 val, int reg_size) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci __le16 *buf; 16762306a36Sopenharmony_ci const int n = 64, size = n * sizeof(*buf); 16862306a36Sopenharmony_ci int i, ret = 0; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci buf = kmalloc(size, GFP_KERNEL); 17162306a36Sopenharmony_ci if (!buf) 17262306a36Sopenharmony_ci return -ENOMEM; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci for (i = 0; i < n; i++) 17562306a36Sopenharmony_ci buf[i] = cpu_to_le16(val); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci for (i = 0; i < reg_size; i += size) { 17862306a36Sopenharmony_ci ret = solo_p2m_dma(solo_dev, 1, buf, 17962306a36Sopenharmony_ci SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, 18062306a36Sopenharmony_ci size, 0, 0); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci if (ret) 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci kfree(buf); 18762306a36Sopenharmony_ci return ret; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciint solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci if (ch > solo_dev->nr_chans) 19362306a36Sopenharmony_ci return -EINVAL; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci return solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + 19662306a36Sopenharmony_ci (ch * SOLO_MOT_THRESH_SIZE * 2), 19762306a36Sopenharmony_ci val, SOLO_MOT_THRESH_SIZE); 19862306a36Sopenharmony_ci} 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ciint solo_set_motion_block(struct solo_dev *solo_dev, u8 ch, 20162306a36Sopenharmony_ci const u16 *thresholds) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci const unsigned size = sizeof(u16) * 64; 20462306a36Sopenharmony_ci u32 off = SOLO_MOT_FLAG_AREA + ch * SOLO_MOT_THRESH_SIZE * 2; 20562306a36Sopenharmony_ci __le16 *buf; 20662306a36Sopenharmony_ci int x, y; 20762306a36Sopenharmony_ci int ret = 0; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 21062306a36Sopenharmony_ci if (buf == NULL) 21162306a36Sopenharmony_ci return -ENOMEM; 21262306a36Sopenharmony_ci for (y = 0; y < SOLO_MOTION_SZ; y++) { 21362306a36Sopenharmony_ci for (x = 0; x < SOLO_MOTION_SZ; x++) 21462306a36Sopenharmony_ci buf[x] = cpu_to_le16(thresholds[y * SOLO_MOTION_SZ + x]); 21562306a36Sopenharmony_ci ret |= solo_p2m_dma(solo_dev, 1, buf, 21662306a36Sopenharmony_ci SOLO_MOTION_EXT_ADDR(solo_dev) + off + y * size, 21762306a36Sopenharmony_ci size, 0, 0); 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci kfree(buf); 22062306a36Sopenharmony_ci return ret; 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* First 8k is motion flag (512 bytes * 16). Following that is an 8k+8k 22462306a36Sopenharmony_ci * threshold and working table for each channel. At least that's what the 22562306a36Sopenharmony_ci * spec says. However, this code (taken from rdk) has some mystery 8k 22662306a36Sopenharmony_ci * block right after the flag area, before the first thresh table. */ 22762306a36Sopenharmony_cistatic void solo_motion_config(struct solo_dev *solo_dev) 22862306a36Sopenharmony_ci{ 22962306a36Sopenharmony_ci int i; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci for (i = 0; i < solo_dev->nr_chans; i++) { 23262306a36Sopenharmony_ci /* Clear motion flag area */ 23362306a36Sopenharmony_ci solo_dma_vin_region(solo_dev, i * SOLO_MOT_FLAG_SIZE, 0x0000, 23462306a36Sopenharmony_ci SOLO_MOT_FLAG_SIZE); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci /* Clear working cache table */ 23762306a36Sopenharmony_ci solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + 23862306a36Sopenharmony_ci (i * SOLO_MOT_THRESH_SIZE * 2) + 23962306a36Sopenharmony_ci SOLO_MOT_THRESH_SIZE, 0x0000, 24062306a36Sopenharmony_ci SOLO_MOT_THRESH_SIZE); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci /* Set default threshold table */ 24362306a36Sopenharmony_ci solo_set_motion_threshold(solo_dev, i, SOLO_DEF_MOT_THRESH); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* Default motion settings */ 24762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) | 24862306a36Sopenharmony_ci (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); 24962306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL, 25062306a36Sopenharmony_ci SOLO_VI_MOTION_FRAME_COUNT(3) | 25162306a36Sopenharmony_ci SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16) 25262306a36Sopenharmony_ci /* | SOLO_VI_MOTION_INTR_START_STOP */ 25362306a36Sopenharmony_ci | SOLO_VI_MOTION_SAMPLE_COUNT(10)); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); 25662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ciint solo_disp_init(struct solo_dev *solo_dev) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci int i; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci solo_dev->video_hsize = 704; 26462306a36Sopenharmony_ci if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { 26562306a36Sopenharmony_ci solo_dev->video_vsize = 240; 26662306a36Sopenharmony_ci solo_dev->fps = 30; 26762306a36Sopenharmony_ci } else { 26862306a36Sopenharmony_ci solo_dev->video_vsize = 288; 26962306a36Sopenharmony_ci solo_dev->fps = 25; 27062306a36Sopenharmony_ci } 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci solo_vin_config(solo_dev); 27362306a36Sopenharmony_ci solo_motion_config(solo_dev); 27462306a36Sopenharmony_ci solo_vout_config(solo_dev); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci for (i = 0; i < solo_dev->nr_chans; i++) 27762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 1); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return 0; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_civoid solo_disp_exit(struct solo_dev *solo_dev) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci int i; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, 0); 28762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0); 28862306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_FREEZE_CTRL, 0); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci for (i = 0; i < solo_dev->nr_chans; i++) { 29162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(i), 0); 29262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(i), 0); 29362306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 0); 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* Set default border */ 29762306a36Sopenharmony_ci for (i = 0; i < 5; i++) 29862306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_X(i), 0); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci for (i = 0; i < 5; i++) 30162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_Y(i), 0); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_MASK, 0); 30462306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_MASK, 0); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0); 30762306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0); 30862306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0); 31162306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0); 31262306a36Sopenharmony_ci solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0); 31362306a36Sopenharmony_ci} 314