Commit cdeb07d9 authored by luo's avatar luo

[UPDATE]SDK 2.5.0.8.5

parent a7bd4541
......@@ -87,6 +87,7 @@ pack:
cp boot_info/bl2/*.bin ${ACME_IMG_PF_DIR}/; \
cp boot_info/linux/*.bin ${ACME_IMG_PF_DIR}/; \
cp boot_info/fpga/*.bin ${ACME_IMG_PF_DIR}/; \
cp boot_info/sensor/*.bin ${ACME_IMG_PF_DIR}/; \
cp $$(ls boot_info/nor/pt2_nor_v* |sort -rn |head -n 1) ${ACME_IMG_PF_DIR}/; \
cp $$(ls boot_info/nor/evb_nor_v* |sort -rn |head -n 1) ${ACME_IMG_PF_DIR}/; \
if [ ! -f key/rotpk_sha256.bin ]; then ./key_gen.sh 0; fi; \
......
......@@ -15,6 +15,7 @@ dtb-$(CONFIG_ARCH_ACME) += sa6920-i2c.dtbo
#dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-nand-c2.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-evb-v24.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-evb-v15.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-evb-v16.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-pt4.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-pt2s.dtb
dtb-$(CONFIG_ARCH_ACME) += sa6920-ipc-bc6.dtb
......
// SPDX-License-Identifier: GPL-2.0
/*
* Device Tree Source for the SuperACME sa6920 Dual A55 Evaluation board
*
* Copyright (C) 2022 SuperACME Electronics Corp.
*/
/dts-v1/;
#include "sa6920-base.dtsi"
#include "sa6920-cluster.dtsi"
/ {
model = "SuperACME, Product evb-v16 board";
compatible = "SuperACME,sa6920";
};
#include <dt-bindings/gpio/gpio.h>
/ {
aliases {
serial0=&uart3;
serial1=&uart1;
serial2=&uart2;
ethernet0 = &eth0;
};
chosen {
bootargs = "console=ttyS2,115200 mem=64M quiet";
stdout-path = "serial2:115200n8";
};
memory@60000000 {
device_type = "memory";
reg = <0x0 0x60000000 0x0 0x20000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
reserved: linux-firmware@63f00000 {
no-map;
reg = <0x0 0x63f00000 0x0 0x100000>;
};
ramoops@63c00000 {
compatible = "ramoops";
reg = <0 0x63c00000 0 0x100000>;
record-size = <0x4000>;
console-size = <0x4000>;
};
};
};
&rst {
status = "okay";
};
&uart3 {
status = "disabled";
};
&pinctrl{
pinctrl_sdio_pmux: sdio-pmux {
conf_clk {
pins = "PORTF14";
drive-strength = <3>;
};
};
pinctrl_gpioh3_pmux: gpioh3-pmux {
mux {
groups = "gpioh_3_grp";
function = "gpioh_3";
};
conf {
pins = "PORTH3";
bias-pull-up;
};
};
pinctrl_gpioh4_pmux: gpioh4-pmux {
mux {
groups = "gpioh_4_grp";
function = "gpioh_4";
};
conf {
pins = "PORTH4";
bias-pull-up;
};
};
};
&sdhi0{
bus-width = <1>;
max-frequency = <25000000>;
no-sd;
no-mmc;
non-removable;
cap-sdio-irq;
supports-sdio;
keep-power-in-suspend;
pinctrl-0 = <&pinctrl_sdio0_pmux &pinctrl_gpioh3_pmux &pinctrl_gpioh4_pmux>;
status = "ok";
};
&sdhi1 {
bus-width = <4>;
no-sdio;
no-mmc;
disable-wp;
no-1-8-v;
post-power-on-delay-ms = <1>;
//vqmmc-supply = <&reg_ldo3>;
cap-sd-highspeed;
cd-inverted;
cd-gpios = <&portc 0 0>;
pinctrl-0 = <&pinctrl_sdio_pmux &pinctrl_gpioc0_pmux>;
status = "ok";
};
&portd {
sd_power {
gpio-hog;
gpios = <6 GPIO_ACTIVE_HIGH>;
output-high;
};
};
&porta{
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
};
&uart1 {
status = "disabled";
};
&pwm0 {
status = "okay";
};
&pwm1 {
status = "okay";
};
/ {
sa_dvfs-ctrl {
compatible = "acme,sa-dvfs-ctrl";
clocks = <&clock VIN0_MCLK>,<&clock VIN0_SNR_MCLK>,
<&clock VIN0_SNR_MCLK_MUX_OUT>,
<&clock VIN0_SNR_MCLK_PLL1_DIV_OUT>,
<&clock VIN0_SNR_MCLK_XTAL_DIV_OUT>,
<&clock VIN1_MCLK>,<&clock VIN1_SNR_MCLK>,
<&clock VIN1_SNR_MCLK_PRE>,
<&clock VIN1_SNR_PLL1_DIV_OUT>,
<&clock VIN1_SNR_24M_DIV_OUT>,
<&clock JPEG_MCLK>,<&clock VNNE_MCLK>,
<&clock PIXEL_MCLK>,<&clock VENC_CLK>,
<&clock VPU_PLL_SW_OUT>,
<&clock PLL2>,<&clock PLL1>,
<&clock JDEC_CLK>,<&clock NPU_CLK>,
<&clock ISP_ACLK>;
clock-names = "vin0_mclk", "vin0_snr_mclk",
"vin0_snr_mclk_pre","vin0_snr_pll1_div_out",
"vin0_snr_xtal_div_out",
"vin1_mclk", "vin1_snr_mclk",
"vin1_snr_mclk_pre","vin1_snr_pll1_div_out",
"vin1_snr_xtal_div_out",
"jpeg_mclk", "vnne_mclk",
"pixel_mclk","venc_clk",
"vpu_pll_sw_out","pll2","pll1",
"jdec_clk","npu_clk",
"isp_aclk";
};
};
&i2c3ACME {
status = "okay";
};
&i2c2ACME {
clock-frequency = <100000>; /*i2c 100k*/
scl-gpios = <&portf 1 GPIO_ACTIVE_HIGH>;
sda-gpios = <&portf 2 GPIO_ACTIVE_HIGH>;
sa8901_2: codec@3e{
compatible = "microbt,sa8901";
status = "okay";
#sound-dai-cells = <0>;
reg = <0x3e>;
clocks = <&clock I2S0_MCLKOUT>;
clock-names = "mclk";
clock-frequency = <12000000>;
pinctrl-0 = <&pinctrl_i2s0_mclk_pmux>;
pinctrl-1 = <&pinctrl_gpiod11_pmux>;
pinctrl-names = "default","gpio";
mclk-gpios = <&portd 11 GPIO_ACTIVE_HIGH>;
/*spk-ctrl = <0>;*/
spk-ctrl-gpios = <&porte 10 GPIO_ACTIVE_HIGH>;
vad-out-gpios = <&porta 6 GPIO_ACTIVE_LOW>;
ldo-en = <0xff>; /*EN_LDO1P5 bit6:1 EN_LDO1P7 bit5:0*/
};
};
&i2c0PL {
status = "disabled";
};
&sfc {
status = "okay";
flash@0{
compatible = "jedec,spi-nor";
reg = <0x00>;
spi-max-frequency = <48000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader"; /* 0KB -> 320KB */
reg = <0x00000000 0x50000>;
};
partition@1 {
label = "kernel";
reg = <0x50000 0x500000>; /* 320KB -> 5440KB */
};
partition@2 { /* 5440KB -> 15680KB */
label = "sdk";
reg = <0x550000 0xA00000>;
};
partition@3 { /* 15680KB -> 16256KB */
label = "config";
reg = <0xF50000 0x90000>;
};
partition@4 { /* 16256KB -> 16384KB */
label = "config";
reg = <0xFE0000 0x20000>;
};
};
};
};
&spi0 {
status = "disabled";
};
&i2s0_clk {
clock-frequency = <12000000>;
};
&i2s1_clk {
clock-frequency = <8192000>;
};
&i2s1ACME {
status = "disabled";
};
&pdmACME {
pinctrl-0 = <&pinctrl_pdm0_pmux &pinctrl_pdm1_pmux>;
pinctrl-names = "default";
resets = <&clock 0xC 18>;
status = "disabled";
};
&sound_i2s0_codec{
simple-audio-card,bitclock-master = <&i2s0_dailink_master>;
simple-audio-card,frame-master = <&i2s0_dailink_master>;
simple-audio-card,format = "i2s";
simple-audio-card,cpu {
sound-dai = <&i2s0PL>;
};
i2s0_dailink_master:simple-audio-card,codec {
sound-dai = <&sa8901_2>;
clocks = <&i2s0_clk>;
clock-names = "mclk";
};
};
&sound_i2s1_codec{
status = "disable";
};
&sound_pdm{
status = "disabled";
};
/{
rpmsg-i2c{
compatible="i2c-rpbus";
proc-id = "rpmsg_i2c";
status = "okay";
};
sound_0_codec: sound0-codec {
compatible = "acme,sound0-codec";
codec-names = "sa8901";
i2c-device-num = <2>;
clocks = <&clock I2S0_MCLKOUT>;
clock-names = "mclkout";
clock-frequency = <12000000>;
pinctrl-0 = <&pinctrl_i2s0_mclk_pmux>;
pinctrl-1 = <&pinctrl_gpiod11_pmux>;
pinctrl-names = "default","gpio";
mclk-gpios = <&portd 11 GPIO_ACTIVE_HIGH>;
/*spk-ctrl = <0>;*/
vad-out-gpios = <&porta 6 GPIO_ACTIVE_LOW>;
spk-ctrl-gpios = <&porte 10 GPIO_ACTIVE_HIGH>;
/*vad-out-gpios = <&porta 6 GPIO_ACTIVE_LOW>;*/
ldo-en = <0xff>; /*EN_LDO1P5 bit6:1 EN_LDO1P7 bit5:0*/
status = "okay";
};
sound_0_i2s: sound0-i2s {
compatible = "acme,sound0-i2s";
i2s-names = "i2s0";
reg = <0x0 0x48000000 0x0 0x10000>;
dmas = <&dmahost 4 0 1>, <&dmahost 5 1 0>;
dma-names = "rx", "tx";
clocks = <&clock I2S0_PCLK>, <&clock I2S0_MCLK>;
clock-names = "pclk", "mclk";
resets = <&clock 0xC 0xC>;
pinctrl-0 = <&pinctrl_i2s0_pmux>;
pinctrl-names = "default";
status = "okay";
};
};
......@@ -7,6 +7,7 @@ CONFIG_SYSVIPC=y
CONFIG_NO_HZ_IDLE=y
# CONFIG_CONTEXT_TRACKING_FORCE is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
......
......@@ -214,16 +214,16 @@ PNAME(vin1_snr_mclk_pre_p) = { "vin1_snr_xtal_div_out", "vin1_snr_pll1_div_out"
/* shutdown */
PNAME(peri_clk_sw_out_p) = { "xtal24", "pll2" };
PNAME(cpu_pll_sw_out_p) = { "pll3","pll2","pll1" };
PNAME(cpu_pll_sw_out_p) = { "pll3","pll2","pll1","pll2" };
PNAME(cpu_clk_sw_out_p) = { "xtal24","cpu_pll_div_out" };
PNAME(ddr_clk_sw_out_p) = { "xtal24","ddr_pll_div_out" };
PNAME(ddr_pll_sw_out_p) = { "pll3","pll2","pll1" };
PNAME(ddr_pll_sw_out_p) = { "pll3","pll2","pll1","pll2" };
PNAME(bus_clk_sw_out_p) = { "xtal24","bus_pll_div_out" };
PNAME(bus_pll_sw_out_p) = { "pll3","pll2","pll1" };
PNAME(bus_pll_sw_out_p) = { "pll3","pll2","pll1","pll2" };
PNAME(npu_clk_sw_out_p) = { "xtal24","npu_pll_div_out" };
PNAME(npu_pll_sw_out_p) = { "pll3","pll2","pll1" };
PNAME(npu_pll_sw_out_p) = { "pll3","pll2","pll1","pll2" };
PNAME(vpu_clk_sw_out_p) = { "xtal24","vpu_pll_sw_out" };
PNAME(vpu_pll_sw_out_p) = { "pll3","pll2","pll1" };
PNAME(vpu_pll_sw_out_p) = { "pll3","pll2","pll1","pll2" };
PNAME(isp_clk_sw_out_p) = { "xtal24","pll1" };
PNAME(isp_bpclk_sw_out_p) = { "pll3","pll2","pll1" };
......
......@@ -1048,8 +1048,6 @@ static int mmc_sdio_suspend(struct mmc_host *host)
return 0;
}
static int mmc_sdio_resume(struct mmc_host *host)
{
int err = 0;
......@@ -1062,18 +1060,9 @@ static int mmc_sdio_resume(struct mmc_host *host)
* removable card is checked from a detect work later on in the resume
* process.
*/
#if 1
if (!mmc_card_keep_power(host)) {
// if not aich wifi card, power up the card
if(!((host->card->cis.vendor == 0x0296) && (host->card->cis.device == 0x5347))) {
//printk("mmc_sdio_resume: aich wifi card %s vid %x pid %x\n",mmc_hostname(host),host->card->cis.vendor,host->card->cis.device);
if (!((host->card->cis.vendor == 0x0296) && (host->card->cis.device == 0x5347))) {
mmc_power_up(host, host->card->ocr);
#else
//reslove the issue that aich wifi can't be detected after resume
if(!(host->pm_caps & MMC_PM_KEEP_POWER)){
printk("mmc_sdio_resume: pm_caps & MMC_PM_KEEP_POWER\n");
#endif
/*
* Tell runtime PM core we just powered up the card,
* since it still believes the card is powered off.
......@@ -1086,8 +1075,6 @@ static int mmc_sdio_resume(struct mmc_host *host)
pm_runtime_enable(&host->card->dev);
}
err = mmc_sdio_reinit_card(host);
}else{
//printk("mmc_sdio_resume: aich wifi card %s \n",mmc_hostname(host));
}
} else if (mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */
......
......@@ -1961,6 +1961,34 @@ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]);
}
/** 诺存芯片特殊处理!
* spi_nor_sr2_bit2_quad_enable() - set the Quad Enable BIT(1) in the Status
* Register 2.
* @nor: pointer to a 'struct spi_nor'.
*
* Bit 2 of the Status Register 2 is the QE bit for Spansion like QSPI memories.
*
* Return: 0 on success, -errno otherwise.
*/
int spi_nor_sr2_bit2_quad_enable(struct spi_nor *nor)
{
int ret;
if (nor->flags & SNOR_F_NO_READ_CR)
return spi_nor_write_16bit_cr_and_check(nor, SR2_QUAD_EN_BIT2);
ret = spi_nor_read_cr(nor, nor->bouncebuf);
if (ret)
return ret;
if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT2)
return 0;
nor->bouncebuf[0] |= SR2_QUAD_EN_BIT2;
return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]);
}
/**
* spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2.
* @nor: pointer to a 'struct spi_nor'
......
......@@ -408,6 +408,7 @@ int spi_nor_lock_and_prep(struct spi_nor *nor);
void spi_nor_unlock_and_unprep(struct spi_nor *nor);
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit2_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1);
......
......@@ -19,10 +19,25 @@ static void gd25q256_default_init(struct spi_nor *nor)
nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
}
static void nm25Q128evb_default_init(struct spi_nor *nor)
{
/*
* Some manufacturer like GigaDevice may use different
* bit to set QE on different memories, so the MFR can't
* indicate the quad_enable method for this case, we need
* to set it in the default_init fixup hook.
*/
nor->params->quad_enable = spi_nor_sr2_bit2_quad_enable;
}
static struct spi_nor_fixups gd25q256_fixups = {
.default_init = gd25q256_default_init,
};
static struct spi_nor_fixups nm25Q128evb_fixups = {
.default_init = nm25Q128evb_default_init,
};
static const struct flash_info gigadevice_parts[] = {
{ "py25q128la", INFO(0x856518, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
......@@ -67,6 +82,10 @@ static const struct flash_info gigadevice_parts[] = {
SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
.fixups = &gd25q256_fixups },
{ "nm25Q128evb", INFO(0x522118, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |SPI_NOR_SKIP_SFDP)
.fixups = &nm25Q128evb_fixups }
};
const struct spi_nor_manufacturer spi_nor_gigadevice = {
......
......@@ -1200,10 +1200,11 @@ static int sa6920_pinctrl_set_mux(struct pinctrl_dev *pctldev,
/* pinconfig */
#define SA6920_PINCONF_INPUT_ENABLE BIT(0)
#define SA6920_PINCONF_OPEN_DRAIN BIT(1)
#define SA6920_PINCONF_BIAS_PULL_DOWN BIT(2)
#define SA6920_PINCONF_BIAS_PULLUP_DOWN_DISABLE BIT(2)
#define SA6920_PINCONF_PULLUP BIT(3)
#define SA6920_PINCONF_DRIVE_STRENGTH_L BIT(4)
#define SA6920_PINCONF_DRIVE_STRENGTH_H BIT(5)
#define SA6920_PINCONF_DRIVE_STRENGTH_M BIT(5)
#define SA6920_PINCONF_DRIVE_STRENGTH_H BIT(6)
#define SA6920_PINCONF_DRIVE_STRENGTH_SHIFT (4)
#define SA6920_PINCONF_SCHMITT_ENABLE BIT(9)
......@@ -1292,7 +1293,7 @@ static int sa6920_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
arg = 1;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = val & (SA6920_PINCONF_DRIVE_STRENGTH_H | SA6920_PINCONF_DRIVE_STRENGTH_L);
arg = val & (SA6920_PINCONF_DRIVE_STRENGTH_H | SA6920_PINCONF_DRIVE_STRENGTH_M | SA6920_PINCONF_DRIVE_STRENGTH_L);
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if(!(val & SA6920_PINCONF_SCHMITT_ENABLE))
......@@ -1387,14 +1388,19 @@ static int sa6920_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
val |= SA6920_PINCONF_OPEN_DRAIN;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (arg)
val |= SA6920_PINCONF_PULLUP;
else
val |= SA6920_PINCONF_BIAS_PULLUP_DOWN_DISABLE;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
val &= ~SA6920_PINCONF_PULLUP;
val |= SA6920_PINCONF_BIAS_PULLUP_DOWN_DISABLE;
break;
case PIN_CONFIG_BIAS_DISABLE:
val &= ~SA6920_PINCONF_BIAS_PULLUP_DOWN_DISABLE;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
val |= ((arg << SA6920_PINCONF_DRIVE_STRENGTH_SHIFT) &
(SA6920_PINCONF_DRIVE_STRENGTH_L + SA6920_PINCONF_DRIVE_STRENGTH_H)) ;
(SA6920_PINCONF_DRIVE_STRENGTH_L + SA6920_PINCONF_DRIVE_STRENGTH_M + SA6920_PINCONF_DRIVE_STRENGTH_H)) ;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
val |= SA6920_PINCONF_SCHMITT_ENABLE;
......
......@@ -247,7 +247,7 @@ int acme_i2c_async_cmd(uint32_t dev, void *data, uint32_t len, uint32_t delay_ms
return 0;
};
EXPORT_SYMBOL(acme_i2c_async_cmd);
#if 0
static uint8_t read_sa9710_acked = 0;
int acme_sa9710_reg_read(uint8_t reg, uint8_t *val)
{
......@@ -301,7 +301,7 @@ exit:
return ret;
}
EXPORT_SYMBOL(acme_sa9710_reg_read);
#endif
static uint8_t wakeup_source_acked = 0;
int acme_wakeup_source_read(uint32_t code, void* wakeup_data, uint32_t length)
{
......@@ -567,12 +567,13 @@ static int rpmsg_rpc_cb(struct rpmsg_device *rpdev, void *data, int len,
kfifo_in_spinlocked(&rpc_dev.rx_fifo, data, len, &rpc_dev.fifo_lock);
wake_up(&rpc_dev.rpc_ack_waitq);
break;
#endif
case RPMSG_CMD_9710_REG_READ:
kfifo_in_spinlocked(&rpc_dev.rx_fifo, data, len, &rpc_dev.fifo_lock);
read_sa9710_acked = 1;
wake_up(&rpc_dev.rpc_ack_waitq);
break;
#endif
//move wakeup_source_acked after kfifo_in_spinlocked,fix recv date but kfifo_out_spinlocked return 0@2021-09-06 zmh
case RPMSG_CMD_WAKEUP_SRC_READ:
kfifo_in_spinlocked(&rpc_dev.rx_fifo, data, len, &rpc_dev.fifo_lock);
......
......@@ -469,7 +469,7 @@ static void acme_wdt0_timeout(struct acme_wdt *wdt)
wdt->enable[WDT0] = 0;
}
extern int acme_sa9710_reg_read(uint8_t reg, uint8_t *val);
//extern int acme_sa9710_reg_read(uint8_t reg, uint8_t *val);
static int acme_wdt_proc_show(struct seq_file *m, void *v)
{
struct acme_wdt *wdt = acme_a55_wdt;
......@@ -505,12 +505,12 @@ static int acme_wdt_proc_show(struct seq_file *m, void *v)
else if ((reboot_reason & 0x003f0000) == 0x00180000)
seq_printf(m,"last reboot reason: star wdt timeout\n");
else if ((reboot_reason & 0x001f0000) == 0x00000000){
if(0 == acme_sa9710_reg_read(0x5d, &val) && (val & 0x2)){
seq_printf(m,"last reboot reason: extern wdt timeout\n");
}
else{
// if(0 == acme_sa9710_reg_read(0x5d, &val) && (val & 0x2)){
// seq_printf(m,"last reboot reason: extern wdt timeout\n");
// }
//else{
seq_printf(m,"last reboot reason: first boot\n");
}
//}
}
else if ((reboot_reason & 0x000f0000) == 0x000C0000)
seq_printf(m,"last reboot reason: wake up\n");
......
......@@ -296,6 +296,8 @@ int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
tx_fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
//printk(KERN_EMERG "tx_fifo_depth=%d, tx_fifo_count=%d\n", tx_fifo_depth, tx_fifo_count);
if (!tx_fifo_count)
return tx_fifo_depth;
else
......@@ -349,6 +351,7 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
WARN_ONCE(addr + txfsz[ep] > hsotg->fifo_mem,
"insufficient fifo memory");
addr += txfsz[ep];
//printk(KERN_EMERG "[%d]:val=%x, txfsz=%d\n", ep, val, txfsz[ep]);
dwc2_writel(hsotg, val, DPTXFSIZN(ep));
val = dwc2_readl(hsotg, DPTXFSIZN(ep));
......@@ -433,7 +436,9 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_req *hs_req)
{
struct usb_request *req = &hs_req->req;
if (hs_ep->isochronous)
req->dma_mapped = 0;
else
usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->map_dir);
}
......@@ -935,6 +940,13 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
dev_dbg(hsotg->dev, "%s: Filling ep %d, dir %s isoc desc # %d\n",
__func__, hs_ep->index, hs_ep->dir_in ? "in" : "out", index);
if (hs_ep->next_desc) {
hs_ep->desc_list[index - 1].status &= ~DEV_DMA_L;
hs_ep->desc_list[index - 1].status &= ~DEV_DMA_IOC;
if (hs_ep->next_desc >= 15)
hs_ep->desc_list[((hs_ep->next_desc + 1)/8 - 2)*8 + 7].status |= DEV_DMA_IOC;
}
desc->status = 0;
desc->status |= (DEV_DMA_BUFF_STS_HBUSY << DEV_DMA_BUFF_STS_SHIFT);
......@@ -1265,10 +1277,14 @@ static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_ep *hs_ep,
struct usb_request *req)
{
int ret;
int ret = 0;
hs_ep->map_dir = hs_ep->dir_in;
if (hs_ep->isochronous)
req->dma_mapped = 0;
else
ret = usb_gadget_map_request(&hsotg->gadget, req, hs_ep->dir_in);
if (ret)
goto dma_error;
......@@ -2239,7 +2255,7 @@ static void dwc2_gadget_handle_isoc_bna(struct dwc2_hsotg_ep *hs_ep)
if (!hs_ep->dir_in)
dwc2_flush_rx_fifo(hsotg);
dwc2_hsotg_complete_request(hsotg, hs_ep, get_ep_head(hs_ep), 0);
dwc2_hsotg_complete_request(hsotg, hs_ep, get_ep_head(hs_ep), -ENODATA);
hs_ep->target_frame = TARGET_FRAME_INITIAL;
hs_ep->next_desc = 0;
......@@ -3157,7 +3173,7 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__);
if (ints & DXEPINT_BNAINTR) {
dev_dbg(hsotg->dev, "%s: BNA interrupt\n", __func__);
printk("%s: BNA interrupt\n", __func__);
if (hs_ep->isochronous)
dwc2_gadget_handle_isoc_bna(hs_ep);
}
......@@ -4155,6 +4171,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
continue;
val = dwc2_readl(hsotg, DPTXFSIZN(i));
val = (val >> FIFOSIZE_DEPTH_SHIFT) * 4;
//printk(KERN_EMERG "[%d]:fifo_count=%d, val=%d, size=%d\n", i, fifo_count, val, size);
if (val < size)
continue;
/* Search for smallest acceptable fifo */
......
......@@ -311,8 +311,15 @@ static void dwc2_set_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
memset(p->g_tx_fifo_size, 0, sizeof(p->g_tx_fifo_size));
depth_average = dwc2_hsotg_tx_fifo_average_depth(hsotg);
for (i = 1; i <= fifo_count; i++)
for (i = 1; i <= fifo_count; i++) {
p->g_tx_fifo_size[i] = depth_average;
//printk(KERN_EMERG "[%d]:g_tx_fifo_size=%d\n", i, p->g_tx_fifo_size[i]);
}
if (fifo_count >= 6) {
p->g_tx_fifo_size[4] = depth_average*2;
p->g_tx_fifo_size[5] = depth_average;
p->g_tx_fifo_size[6] = 0;
}
}
static void dwc2_set_param_power_down(struct dwc2_hsotg *hsotg)
......@@ -627,6 +634,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
hsotg->params.g_tx_fifo_size[fifo]);
hsotg->params.g_tx_fifo_size[fifo] = dptxfszn;
}
//printk(KERN_EMERG "[%d]:g_tx_fifo_size=%d\n", fifo, hsotg->params.g_tx_fifo_size[fifo]);
}
}
......@@ -760,9 +768,9 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
fifo_count = dwc2_hsotg_tx_fifo_count(hsotg)/2;
for (fifo = 1; fifo <= fifo_count; fifo++) {
hw->g_tx_fifo_size[fifo] = 256;
hw->g_tx_fifo_size[fifo] = 480;
}
hw->g_tx_fifo_size[fifo_count] = 768;
hw->g_tx_fifo_size[fifo_count] = 512;
hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
FIFOSIZE_DEPTH_SHIFT;
......
......@@ -629,6 +629,9 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
max_packet_size = opts->streaming_maxpacket / 3;
}
max_packet_mult = 3;
max_packet_size = 640;
uvc_fs_streaming_ep.wMaxPacketSize =
cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
......
......@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/usb/composite.h>
#include <linux/videodev2.h>
#include <linux/interrupt.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
......@@ -65,7 +66,7 @@ extern unsigned int uvc_gadget_trace_param;
* Driver specific constants
*/
#define UVC_NUM_REQUESTS 4
#define UVC_NUM_REQUESTS 16
#define UVC_MAX_REQUEST_SIZE 64
#define UVC_MAX_EVENTS 4
......@@ -77,8 +78,8 @@ struct uvc_video {
struct uvc_device *uvc;
struct usb_ep *ep;
struct work_struct pump;
//struct work_struct pump;
struct tasklet_struct pump;
/* Frame parameters */
u8 bpp;
u32 fcc;
......
......@@ -169,7 +169,7 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
if (ret < 0)
return ret;
schedule_work(&video->pump);
tasklet_hi_schedule(&video->pump);
return ret;
}
......
......@@ -12,13 +12,14 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/video.h>
//#include <linux/kallsyms.h>
#include <media/v4l2-dev.h>
#include "uvc.h"
#include "uvc_queue.h"
#include "uvc_video.h"
#define SRAM_ADDR 0x20618000 //0x20617FFF
/* --------------------------------------------------------------------------
* Video codecs
*/
......@@ -30,8 +31,10 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
data[0] = 2;
data[1] = UVC_STREAM_EOH | video->fid;
if (buf->bytesused - video->queue.buf_used <= len - 2)
if (buf->bytesused - video->queue.buf_used <= len - 2) {
data[1] |= UVC_STREAM_EOF;
//printk("--%d\n", buf->bytesused);
}
return 2;
}
......@@ -131,8 +134,7 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
if (ret < 0) {
uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n",
ret);
printk(KERN_EMERG "Failed to queue request (%d).\n", ret);
/* Isochronous endpoints can't be halted. */
if (usb_endpoint_xfer_bulk(video->ep->desc))
......@@ -151,17 +153,19 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
switch (req->status) {
case 0:
//if (req->actual != req->length)
// printk(KERN_EMERG "actual=%d\n", req->actual);
break;
case -ESHUTDOWN: /* disconnect from host. */
uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
//printk(KERN_EMERG "VS request cancelled.\n");
uvcg_queue_cancel(queue, 1);
break;
default:
uvcg_info(&video->uvc->func,
"VS request completed with status %d.\n",
req->status);
//uvcg_info(&video->uvc->func,
//printk(KERN_EMERG "VS request completed with status %d.\n",
// req->status);
uvcg_queue_cancel(queue, 0);
}
......@@ -169,7 +173,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
list_add_tail(&req->list, &video->req_free);
spin_unlock_irqrestore(&video->req_lock, flags);
schedule_work(&video->pump);
tasklet_hi_schedule(&video->pump);
}
static int
......@@ -184,7 +188,7 @@ uvc_video_free_requests(struct uvc_video *video)
}
if (video->req_buffer[i]) {
kfree(video->req_buffer[i]);
iounmap(video->req_buffer[i]);
video->req_buffer[i] = NULL;
}
}
......@@ -200,6 +204,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
unsigned int req_size;
unsigned int i;
int ret = -ENOMEM;
phys_addr_t addr;
BUG_ON(video->req_size);
......@@ -208,7 +213,9 @@ uvc_video_alloc_requests(struct uvc_video *video)
* (video->ep->mult);
for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
addr = (phys_addr_t)(SRAM_ADDR + i * 1920);
video->req_buffer[i] = ioremap(addr, req_size);
printk("%s addr=%lx, req_buffer=%lx", __func__, (unsigned long)addr, (unsigned long)video->req_buffer[i]);
if (video->req_buffer[i] == NULL)
goto error;
......@@ -216,6 +223,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
if (video->req[i] == NULL)
goto error;
video->req[i]->dma = addr;
video->req[i]->buf = video->req_buffer[i];
video->req[i]->length = 0;
video->req[i]->complete = uvc_video_complete;
......@@ -243,9 +251,9 @@ error:
* This function fills the available USB requests (listed in req_free) with
* video data from the queued buffers.
*/
static void uvcg_video_pump(struct work_struct *work)
static void uvcg_video_pump(unsigned long data)
{
struct uvc_video *video = container_of(work, struct uvc_video, pump);
struct uvc_video *video = (struct uvc_video *)data;//container_of(work, struct uvc_video, pump);
struct uvc_video_queue *queue = &video->queue;
struct usb_request *req;
struct uvc_buffer *buf;
......@@ -309,7 +317,7 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
}
if (!enable) {
cancel_work_sync(&video->pump);
//tasklet_disable(&video->pump);
uvcg_queue_cancel(&video->queue, 0);
for (i = 0; i < UVC_NUM_REQUESTS; ++i)
......@@ -333,7 +341,7 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
} else
video->encode = uvc_video_encode_isoc;
schedule_work(&video->pump);
tasklet_hi_schedule(&video->pump);
return ret;
}
......@@ -345,7 +353,7 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
{
INIT_LIST_HEAD(&video->req_free);
spin_lock_init(&video->req_lock);
INIT_WORK(&video->pump, uvcg_video_pump);
tasklet_init(&video->pump, uvcg_video_pump, (unsigned long)video);
video->uvc = uvc;
video->fcc = V4L2_PIX_FMT_YUYV;
......
......@@ -135,6 +135,7 @@
/* Status Register 2 bits. */
#define SR2_QUAD_EN_BIT1 BIT(1)
#define SR2_QUAD_EN_BIT2 BIT(2)
#define SR2_QUAD_EN_BIT7 BIT(7)
/* Supported SPI protocols */
......
[boot_info]
name = boot_info
bin_file = bootinfo-BL2-6920E-0P5.bin
store_addr = auto
max_size = 2K
[image1]
name = bl2
bin_file = BL2-6920-E4.bin
store_addr = auto
max_size = 996K
\ No newline at end of file
[boot_info]
name = boot_info
bin_file = bootinfo-BL2-6920E-0P55.bin
store_addr = auto
max_size = 2K
[image1]
name = bl2
bin_file = BL2-6920-E4.bin
store_addr = auto
max_size = 996K
\ No newline at end of file
[boot_info]
name = boot_info
bin_file = bootinfo-BL2-6920E-0P75.bin
store_addr = auto
max_size = 2K
[image1]
name = bl2
bin_file = BL2-6920-E4.bin
store_addr = auto
max_size = 996K
\ No newline at end of file
[boot_info]
name = boot_info
bin_file = bootinfo-6920-linux-aarch32.bin
store_addr = auto
max_size = 24K
[image1]
name = star_app
bin_file = star_app_evb.bin
store_addr = auto
max_size = 256K
[image2]
name = firmware
bin_file = firmware.bin
store_addr = auto
max_size = 256K
[image3]
name = kernel
bin_file = zImage
store_addr = auto
max_size = 16M
[image4]
name = dtb
bin_file = sa6920-ipc-evb.dtb
store_addr = auto
max_size = 48K
\ No newline at end of file
[boot_info]
name = boot_info
bin_file = bootinfo-6920-linux-dvfs-aarch32.bin
store_addr = auto
max_size = 24K
[image1]
name = sensor
bin_file = os04d10_len16652.bin
store_addr = auto
max_size = 24K
[image2]
name = board_info
bin_file = board_evb_v24.bin
store_addr = auto
max_size = 3K
[image3]
name = star_app
bin_file = star_app_evb_v24.bin
store_addr = auto
max_size = 256K
[image4]
name = firmware
bin_file = firmware.bin
store_addr = auto
max_size = 256K
[image5]
name = kernel
bin_file = zImage
store_addr = auto
max_size = 16M
[image6]
name = dtb
bin_file = sa6920-ipc-evb-v24.dtb
store_addr = auto
max_size = 48K
\ No newline at end of file
......@@ -336,10 +336,14 @@ int tm8150b_reg_write(int fd, uint8_t reg, uint8_t val)
#endif
#ifdef ICR_CTRL_GPIO
#if (BOARD_PLATFORM==PLAT_BC22E) || (BOARD_PLATFORM==PLAT_BC6)
#if (BOARD_PLATFORM==PLAT_BC22E)
#define HW_ICR_DAY_GPIO GPIO_PORT_D_PIN_6 //PD6
#define HW_ICR_NIGHT_GPIO GPIO_PORT_D_PIN_5 //PD5
#define HW_PWM1_SWITCH_GPIO GPIO_PORT_A_PIN_0 //PA0
#elif (BOARD_PLATFORM==PLAT_BC6)
#define HW_ICR_DAY_GPIO GPIO_PORT_D_PIN_5 //PD5
#define HW_ICR_NIGHT_GPIO GPIO_PORT_D_PIN_6 //PD6
#define HW_PWM1_SWITCH_GPIO GPIO_PORT_A_PIN_0 //PA0
#else
#define HW_ICR_DAY_GPIO (-1)
#define HW_ICR_NIGHT_GPIO (-1)
......@@ -989,8 +993,15 @@ int isp_led_ctrl(LAMP_TYPE_E type, SA_U16 frq)
/*3. cfg pwm para , bc22e only 1 channel to control 2 fill lights */
chipID = PWM_ID_WL;
#endif
#if (BOARD_PLATFORM==PLAT_BC6)
if(rt_pin_read(GPIO_PORT_D_PIN_1)){
rt_pwm_set(pwm_dev, chipID, 20000, dstFrq*2/5);
}else{
rt_pwm_set(pwm_dev, chipID, 1000000, dstFrq * 20);
}
#else
rt_pwm_set(pwm_dev, chipID, 50000, dstFrq);
#endif
rt_thread_mdelay(1);
if (0 == dstFrq) {
......
......@@ -556,6 +556,11 @@ static void MX_GPIO_Init(void)
rt_thread_delay(50);
rt_pin_write(GPIO_PORT_A_PIN_3, PIN_HIGH);
#endif
#if (BOARD_PLATFORM==PLAT_BC6)
sa_set_padcfs(PADCONF_GPIO_D1,PADC_FS_GPIO_D1); //detect board version
rt_pin_mode(GPIO_PORT_D_PIN_1, PIN_MODE_INPUT);
#endif
}
static void MX_ICACHE_Init(void)
......
# 2.5.0.8.5版本0.0
## 发布日期:2025年04月03日
### 更新内容
1. 修复快启小核不出图问题
# 2.5.0.8.2版本0.0
## 发布日期:2025年03月31日
......
This diff is collapsed.
......@@ -65,6 +65,7 @@ rootfs_copy_file() {
# uvc
cp common/script/uvc-gadget.sh system_temp/scripts/
cp 6920_bsp_release/out_images/lib/modules/5.10.106/kernel/drivers/usb/gadget/function/usb_f_uvc.ko system_temp/lib/modules/usb/
cp 6920_bsp_release/out_images/lib/modules/5.10.106/kernel/drivers/media/common/videobuf2/videobuf2-*.ko system_temp/lib/modules/usb/
cp 6920_bsp_release/out_images/lib/modules/5.10.106/kernel/drivers/media/v4l2-core/videodev.ko system_temp/lib/modules/usb/
fi
......@@ -73,6 +74,7 @@ rootfs_copy_file() {
echo *****ONLY TEST****
cp sdk/lib/libsvp_*.so system_temp/lib/
cp sdk/conf system_temp/ -r
cp common/conf/* system_temp/conf/ -rf
cp sdk/opensource/source/sensor/libsns_os04d10_soc30.so system_temp/lib/libsns_os04d10_soc30.so.$(ls sdk/opensource/lib/libsns_os04d10_soc30.so.* | sed -n 's/.*\.so\.\(.*\)/\1/p' | head -n 1)
cp sdk/opensource/source/sensor/libsns_os04d10_soc30.so system_temp/lib/libsns_os04d10_soc30.so
cp sdk/opensource/source/sensor/libsns_imx681_soc.so system_temp/lib/libsns_imx681_soc.so.$(ls sdk/opensource/lib/libsns_imx681_soc.so.* | sed -n 's/.*\.so\.\(.*\)/\1/p' | head -n 1)
......@@ -123,7 +125,20 @@ check_file_size() {
fi
fi
}
#set -e
make_module() {
local path=$1
local mudule_name=$2
local target_path=$3
cd $1
set -e
make clean
make
set +e
cd -
mv $1/$2 $target_path
}
# Change directory to the 6920_bsp_release directory
cd 6920_bsp_release/ || exit
......@@ -172,6 +187,12 @@ copy_files "$1"
mkdir system_temp/lib/modules -p
mkdir system_temp/usr -p
if [ -d "tools" ]; then
# Get new controller
make_module tools/controller/ controller sdk/bin/
make_module tools/comm/ libtool_comm.so sdk/opensource/lib/
fi
# Copy libraries and scripts
cp system/lib/libcrypto.so* system_temp/lib/
cp system/lib/libstdc++.so.* system_temp/lib/
......
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed.
libispalg.so.2.5.0.8.2
\ No newline at end of file
libispalg.so.2.5.0.8.5
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment