mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
Merge commit '8bbe906daa75d355607df9b586a5beb7adf3bf45'
* commit '8bbe906daa75d355607df9b586a5beb7adf3bf45': (31 commits) mfd: display-serdes: power off remote serdes while shutdown ARM: dts: rockchip: rv1106g-evb2-v12-wakeup add rtt for vicap node arm64: dts: rockchip: rk3588s: add winusb reboot mode. dt-bindings: soc: rockchip: add reboot mode winusb. MALI: bifrost: Fix a null pointer exception when event tracing is enabled arm64: dts: rockchip: rk3588-vehicle-evb-v22: Use location name for camera regulators media: i2c: maxim4c: Fix unbalanced disable of PoC regulator usb: host: ohci-platform: enable async suspend for rk3588 arm64: dts: rockchip: rk3588s: Add compatible for ohci arm64: dts: rockchip: rk3588-linux: set rcu_expedited/rcu_nocbs arm64: dts: rockchip: rk3588-android: set rcu_expedited/rcu_nocbs arm64: rockchip_linux_defconfig: enable configs needed for RCU perf/power optimizations arm64: rockchip_defconfig: enable configs needed for RCU perf/power optimizations ARM: dts: rockchip: rv1106g-evb2-v12-wakeup add rtt for isp node arm64: dts: rockchip: rk3562-evb1-cam: add dw9714 supply control media: rockchip: isp: fix resume hold by lut error media: rockchip: isp: suspend resume with rtt media: rockchip: isp: pm add call sensor s_power arm64: dts: rockchip: update rk3568-evb1-ddr4-v10-dual-lvds relevant files ARM: dts: rockchip: add rv1106g-4k dts ... Change-Id: I7cafbe314407a130b7ec94675b83b87d82079468
This commit is contained in:
@@ -1134,6 +1134,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
|
||||
rv1106g-evb1-rgb-display-v11.dtb \
|
||||
rv1106g-evb1-v10.dtb \
|
||||
rv1106g-evb1-v11.dtb \
|
||||
rv1106g-evb1-v11-4k.dtb \
|
||||
rv1106g-evb1-v11-cvr.dtb \
|
||||
rv1106g-evb1-v11-cvr-dual-cam.dtb \
|
||||
rv1106g-evb1-v11-spi-nand-cvr.dtb \
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
csi_dphy_input6: endpoint@6 {
|
||||
reg = <6>;
|
||||
remote-endpoint = <&imx415_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
port {
|
||||
imx415_out: endpoint {
|
||||
remote-endpoint = <&csi_dphy_input6>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
17
arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts
Normal file
17
arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "rv1106g-evb1-v11.dts"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RV1106G EVB1 V11 Board For RV1106G3 4K Unite";
|
||||
compatible = "rockchip,rv1106g-evb1-v11-4k", "rockchip,rv1106";
|
||||
};
|
||||
|
||||
&rkisp {
|
||||
rockchip,unite-en;
|
||||
};
|
||||
@@ -223,7 +223,8 @@
|
||||
|
||||
&rkcif_mipi_lvds {
|
||||
status = "okay";
|
||||
//memory-region-thunderboot = <&rkisp_thunderboot>;
|
||||
memory-region-thunderboot = <&rkisp_thunderboot>;
|
||||
rtt-suspend;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mipi_pins>;
|
||||
@@ -253,6 +254,9 @@
|
||||
&rkisp_vir0 {
|
||||
status = "okay";
|
||||
|
||||
memory-region-thunderboot = <&rkisp_thunderboot>;
|
||||
rtt-suspend;
|
||||
|
||||
port@0 {
|
||||
isp_in: endpoint {
|
||||
remote-endpoint = <&mipi_lvds_sditf>;
|
||||
|
||||
@@ -37,6 +37,7 @@ CONFIG_SPI=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_VIDEO_GC2053=m
|
||||
CONFIG_VIDEO_IMX415=m
|
||||
CONFIG_VIDEO_OS04A10=m
|
||||
CONFIG_VIDEO_SC3336=m
|
||||
CONFIG_VIDEO_SC4336=m
|
||||
|
||||
@@ -59,6 +59,7 @@ static struct rv1106_sleep_ddr_data ddr_data;
|
||||
|
||||
static void __iomem *pmucru_base;
|
||||
static void __iomem *cru_base;
|
||||
static void __iomem *pvtpllcru_base;
|
||||
static void __iomem *pericru_base;
|
||||
static void __iomem *vicru_base;
|
||||
static void __iomem *npucru_base;
|
||||
@@ -105,6 +106,10 @@ static struct reg_region vd_core_reg_rgns[] = {
|
||||
{ REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
|
||||
{ REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)},
|
||||
|
||||
/* pvtpll_cru */
|
||||
{ REG_REGION(0x00, 0x24, 4, &pvtpllcru_base, WMSK_VAL)},
|
||||
{ REG_REGION(0x30, 0x54, 4, &pvtpllcru_base, WMSK_VAL)},
|
||||
|
||||
/* core_sgrf */
|
||||
{ REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
|
||||
{ REG_REGION(0x000, 0x000, 4, &coresgrf_base, 0)},
|
||||
@@ -1165,6 +1170,7 @@ static int __init rv1106_suspend_init(struct device_node *np)
|
||||
|
||||
pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
|
||||
cru_base = dev_reg_base + RV1106_CRU_OFFSET;
|
||||
pvtpllcru_base = dev_reg_base + RV1106_PVTPLLCRU_OFFSET;
|
||||
pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
|
||||
vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
|
||||
npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#define RV1106_PMUCRU_OFFSET 0x3a0000
|
||||
#define RV1106_CRU_OFFSET 0x3b0000
|
||||
#define RV1106_PVTPLLCRU_OFFSET 0x3b1000
|
||||
#define RV1106_PERICRU_OFFSET 0x3b2000
|
||||
#define RV1106_VICRU_OFFSET 0x3b4000
|
||||
#define RV1106_NPUCRU_OFFSET 0x3b6000
|
||||
|
||||
@@ -155,6 +155,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-camera.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-lvds.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-lvds-linux.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-amp.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-spi-nor.dtb
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
compatible = "dongwoon,dw9714";
|
||||
status = "okay";
|
||||
reg = <0x0c>;
|
||||
avdd-supply = <&vcc2v8_dvp>;
|
||||
rockchip,vcm-start-current = <10>;
|
||||
rockchip,vcm-rated-current = <85>;
|
||||
rockchip,vcm-step-mode = <5>;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/display/rockchip_vop.h>
|
||||
#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi"
|
||||
#include "rk3568-linux.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RK3568 EVB1 V10 Board with Dual LVDS";
|
||||
compatible = "rockchip,rk3568-evb1-ddr4-v10-dual-lvds", "rockchip,rk3568";
|
||||
};
|
||||
|
||||
&vp0 {
|
||||
cursor-win-id = <ROCKCHIP_VOP2_CLUSTER0>;
|
||||
};
|
||||
|
||||
&vp1 {
|
||||
cursor-win-id = <ROCKCHIP_VOP2_CLUSTER1>;
|
||||
};
|
||||
@@ -5,165 +5,10 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
#include "rk3568-evb1-ddr4-v10.dtsi"
|
||||
#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi"
|
||||
#include "rk3568-android.dtsi"
|
||||
|
||||
/ {
|
||||
panel {
|
||||
compatible = "simple-panel";
|
||||
backlight = <&backlight>;
|
||||
power-supply = <&vcc3v3_lcd0_n>;
|
||||
enable-delay-ms = <20>;
|
||||
prepare-delay-ms = <20>;
|
||||
unprepare-delay-ms = <20>;
|
||||
disable-delay-ms = <20>;
|
||||
bus-format = <MEDIA_BUS_FMT_RGB666_1X7X3_SPWG>;
|
||||
width-mm = <217>;
|
||||
height-mm = <136>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
|
||||
timing0: timing0 {
|
||||
clock-frequency = <134000000>;
|
||||
hactive = <1600>;
|
||||
vactive = <1280>;
|
||||
hback-porch = <60>;
|
||||
hfront-porch = <60>;
|
||||
vback-porch = <4>;
|
||||
vfront-porch = <2>;
|
||||
hsync-len = <8>;
|
||||
vsync-len = <2>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/**
|
||||
* Panel <----> LVDS0
|
||||
* Panel <----> LVDS1
|
||||
*/
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dual-lvds-left-pixels;
|
||||
panel_in_lvds0: endpoint {
|
||||
remote-endpoint = <&lvds0_out_panel>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dual-lvds-right-pixels;
|
||||
panel_in_lvds1: endpoint {
|
||||
remote-endpoint = <&lvds1_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&backlight1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds {
|
||||
status = "okay";
|
||||
dual-channel;
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds0_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds1_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&lvds1_in_vp2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable hdmi */
|
||||
&hdmi_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable video phy */
|
||||
&video_phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video_phy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* disable other encoder output */
|
||||
&dsi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&edp_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&rgb_in_vp2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
&vcc3v3_lcd0_n {
|
||||
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
&vcc3v3_lcd1_n {
|
||||
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
model = "Rockchip RK3568 EVB1 V10 Board with Dual LVDS";
|
||||
compatible = "rockchip,rk3568-evb1-ddr4-v10-dual-lvds", "rockchip,rk3568";
|
||||
};
|
||||
|
||||
161
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dtsi
Normal file
161
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dtsi
Normal file
@@ -0,0 +1,161 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include "rk3568-evb1-ddr4-v10.dtsi"
|
||||
|
||||
/ {
|
||||
panel {
|
||||
compatible = "simple-panel";
|
||||
backlight = <&backlight>;
|
||||
power-supply = <&vcc3v3_lcd0_n>;
|
||||
enable-delay-ms = <20>;
|
||||
prepare-delay-ms = <20>;
|
||||
unprepare-delay-ms = <20>;
|
||||
disable-delay-ms = <20>;
|
||||
bus-format = <MEDIA_BUS_FMT_RGB666_1X7X3_SPWG>;
|
||||
width-mm = <217>;
|
||||
height-mm = <136>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
|
||||
timing0: timing0 {
|
||||
clock-frequency = <134000000>;
|
||||
hactive = <1600>;
|
||||
vactive = <1280>;
|
||||
hback-porch = <60>;
|
||||
hfront-porch = <60>;
|
||||
vback-porch = <4>;
|
||||
vfront-porch = <2>;
|
||||
hsync-len = <8>;
|
||||
vsync-len = <2>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/**
|
||||
* Panel <----> LVDS0
|
||||
* Panel <----> LVDS1
|
||||
*/
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dual-lvds-left-pixels;
|
||||
panel_in_lvds0: endpoint {
|
||||
remote-endpoint = <&lvds0_out_panel>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dual-lvds-right-pixels;
|
||||
panel_in_lvds1: endpoint {
|
||||
remote-endpoint = <&lvds1_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&backlight1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&edp_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&hdmi_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds {
|
||||
status = "okay";
|
||||
dual-channel;
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds0_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds1_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&lvds1_in_vp2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&rgb_in_vp2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&video_phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video_phy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vcc3v3_lcd0_n {
|
||||
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
&vcc3v3_lcd1_n {
|
||||
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/ {
|
||||
chosen: chosen {
|
||||
bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0";
|
||||
bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 rcupdate.rcu_expedited=1 rcu_nocbs=all";
|
||||
};
|
||||
|
||||
cspmu: cspmu@fd10c000 {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
};
|
||||
|
||||
chosen: chosen {
|
||||
bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait";
|
||||
bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait rcupdate.rcu_expedited=1 rcu_nocbs=all";
|
||||
};
|
||||
|
||||
cspmu: cspmu@fd10c000 {
|
||||
|
||||
@@ -149,11 +149,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
camera1_vcc12v_buck: camera1_vcc12v-buck {
|
||||
dcphy0_vcc12v_buck: dcphy0_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera1_vcc12v_buck";
|
||||
regulator-name = "dcphy0_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
@@ -167,11 +166,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
camera2_vcc12v_buck: camera2_vcc12v-buck {
|
||||
dcphy1_vcc12v_buck: dcphy1_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera2_vcc12v_buck";
|
||||
regulator-name = "dcphy1_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
@@ -185,11 +183,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
camera3_vcc12v_buck: camera3_vcc12v-buck {
|
||||
dphy0_vcc12v_buck: dphy0_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera3_vcc12v_buck";
|
||||
regulator-name = "dphy0_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
@@ -203,11 +200,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
camera4_vcc12v_buck: camera4_vcc12v-buck {
|
||||
dphy3_vcc12v_buck: dphy3_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera4_vcc12v_buck";
|
||||
regulator-name = "dphy3_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
@@ -348,7 +344,7 @@
|
||||
};
|
||||
|
||||
&max96712_dphy3_poc {
|
||||
vin-supply = <&camera1_vcc12v_buck>;
|
||||
vin-supply = <&dphy3_vcc12v_buck>;
|
||||
};
|
||||
|
||||
&avdd1v8_ddr_pll_s0 {
|
||||
@@ -373,12 +369,12 @@
|
||||
};
|
||||
|
||||
&i2c2_bu18tl82 {
|
||||
//route-enable;
|
||||
use-delay-work;
|
||||
route-enable;
|
||||
//use-delay-work;
|
||||
};
|
||||
|
||||
&i2c2_bu18rl82 {
|
||||
use-delay-work;
|
||||
//use-delay-work;
|
||||
vpower-supply = <&lcd1_vcc12v_buck>;
|
||||
};
|
||||
|
||||
@@ -389,11 +385,11 @@
|
||||
};
|
||||
|
||||
&i2c4_bu18tl82 {
|
||||
use-delay-work;
|
||||
//use-delay-work;
|
||||
};
|
||||
|
||||
&i2c4_bu18rl82 {
|
||||
use-delay-work;
|
||||
//use-delay-work;
|
||||
vpower-supply = <&lcd5_vcc12v_buck>;
|
||||
};
|
||||
|
||||
@@ -435,11 +431,11 @@
|
||||
};
|
||||
|
||||
&i2c5_bu18tl82 {
|
||||
use-delay-work;
|
||||
//use-delay-work;
|
||||
};
|
||||
|
||||
&i2c5_bu18rl82 {
|
||||
use-delay-work;
|
||||
//use-delay-work;
|
||||
vpower-supply = <&lcd3_vcc12v_buck>;
|
||||
};
|
||||
|
||||
@@ -450,8 +446,8 @@
|
||||
};
|
||||
|
||||
&i2c6_bu18tl82 {
|
||||
//route-enable;
|
||||
use-delay-work;
|
||||
route-enable;
|
||||
//use-delay-work;
|
||||
};
|
||||
|
||||
&i2c6_bu18rl82 {
|
||||
@@ -565,11 +561,11 @@
|
||||
};
|
||||
|
||||
&route_dsi0 {
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&route_dsi1 {
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&u2phy1_otg {
|
||||
|
||||
@@ -2651,7 +2651,7 @@
|
||||
};
|
||||
|
||||
usb_host0_ohci: usb@fc840000 {
|
||||
compatible = "generic-ohci";
|
||||
compatible = "rockchip,rk3588-ohci", "generic-ohci";
|
||||
reg = <0x0 0xfc840000 0x0 0x40000>;
|
||||
interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>, <&aclk_usb>;
|
||||
@@ -2676,7 +2676,7 @@
|
||||
};
|
||||
|
||||
usb_host1_ohci: usb@fc8c0000 {
|
||||
compatible = "generic-ohci";
|
||||
compatible = "rockchip,rk3588-ohci", "generic-ohci";
|
||||
reg = <0x0 0xfc8c0000 0x0 0x40000>;
|
||||
interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>, <&aclk_usb>;
|
||||
@@ -2760,6 +2760,8 @@
|
||||
mode-panic = <BOOT_PANIC>;
|
||||
mode-watchdog = <BOOT_WATCHDOG>;
|
||||
mode-quiescent = <BOOT_QUIESCENT>;
|
||||
/* add a mode to capture the ramdump through usb */
|
||||
mode-winusb = <BOOT_WINUSB>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_PSI=y
|
||||
CONFIG_RCU_EXPERT=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_RCU_BOOST=y
|
||||
CONFIG_RCU_NOCB_CPU=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_IKHEADERS=m
|
||||
|
||||
@@ -4,6 +4,9 @@ CONFIG_SYSVIPC=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_RCU_EXPERT=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_RCU_NOCB_CPU=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=18
|
||||
|
||||
@@ -1604,6 +1604,10 @@ static int kbasep_kcpu_fence_signal_init(struct kbase_kcpu_command_queue *kcpu_q
|
||||
if (!kcpu_fence)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Set reference to KCPU metadata and increment refcount */
|
||||
kcpu_fence->metadata = kcpu_queue->metadata;
|
||||
WARN_ON(!kbase_refcount_inc_not_zero(&kcpu_fence->metadata->refcount));
|
||||
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
fence_out = (struct fence *)kcpu_fence;
|
||||
#else
|
||||
@@ -1625,10 +1629,6 @@ static int kbasep_kcpu_fence_signal_init(struct kbase_kcpu_command_queue *kcpu_q
|
||||
dma_fence_get(fence_out);
|
||||
#endif
|
||||
|
||||
/* Set reference to KCPU metadata and increment refcount */
|
||||
kcpu_fence->metadata = kcpu_queue->metadata;
|
||||
WARN_ON(!kbase_refcount_inc_not_zero(&kcpu_fence->metadata->refcount));
|
||||
|
||||
/* create a sync_file fd representing the fence */
|
||||
*sync_file = sync_file_create(fence_out);
|
||||
if (!(*sync_file)) {
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
* V2.03.00
|
||||
* 1. remote device add the maxim4c prefix to driver name.
|
||||
*
|
||||
* V2.04.02
|
||||
* V2.04.03
|
||||
* 1. Add regulator supplier dependencies.
|
||||
* 2. Add config ssc-ratio property
|
||||
* 3. Add debugfs entry to change MIPI timing
|
||||
* 4. Use PM runtime autosuspend feature
|
||||
* 5. Fix unbalanced disabling for PoC regulator
|
||||
*
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
@@ -63,7 +65,7 @@
|
||||
|
||||
#include "maxim4c_api.h"
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(2, 0x04, 0x02)
|
||||
#define DRIVER_VERSION KERNEL_VERSION(2, 0x04, 0x03)
|
||||
|
||||
#define MAXIM4C_XVCLK_FREQ 25000000
|
||||
|
||||
@@ -681,6 +683,14 @@ static int maxim4c_probe(struct i2c_client *client,
|
||||
if (ret)
|
||||
goto err_destroy_mutex;
|
||||
|
||||
ret = maxim4c_remote_device_power_on(maxim4c);
|
||||
if (ret)
|
||||
dev_warn(dev, "Power on PoC regulator failed\n");
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = maxim4c_check_local_chipid(maxim4c);
|
||||
if (ret)
|
||||
goto err_power_off;
|
||||
@@ -704,9 +714,10 @@ static int maxim4c_probe(struct i2c_client *client,
|
||||
goto err_power_off;
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_idle(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 1000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
#endif /* MAXIM4C_TEST_PATTERN */
|
||||
@@ -731,9 +742,10 @@ static int maxim4c_probe(struct i2c_client *client,
|
||||
maxim4c_lock_irq_init(maxim4c);
|
||||
maxim4c_lock_state_work_init(maxim4c);
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_idle(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 1000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -742,6 +754,9 @@ err_dbgfs_deinit:
|
||||
err_subdev_deinit:
|
||||
maxim4c_v4l2_subdev_deinit(maxim4c);
|
||||
err_power_off:
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
maxim4c_remote_device_power_off(maxim4c);
|
||||
maxim4c_local_device_power_off(maxim4c);
|
||||
err_destroy_mutex:
|
||||
mutex_destroy(&maxim4c->mutex);
|
||||
|
||||
@@ -589,21 +589,20 @@ static int maxim4c_s_stream(struct v4l2_subdev *sd, int on)
|
||||
goto unlock_and_return;
|
||||
|
||||
if (on) {
|
||||
ret = pm_runtime_get_sync(&client->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
if (ret < 0)
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
ret = __maxim4c_start_stream(maxim4c);
|
||||
if (ret) {
|
||||
v4l2_err(sd, "start stream failed while write regs\n");
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put_sync(&client->dev);
|
||||
goto unlock_and_return;
|
||||
}
|
||||
} else {
|
||||
__maxim4c_stop_stream(maxim4c);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
}
|
||||
|
||||
maxim4c->streaming = on;
|
||||
|
||||
@@ -2046,11 +2046,11 @@ static int sc200ai_probe(struct i2c_client *client,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
|
||||
sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc200ai->reset_gpio))
|
||||
dev_warn(dev, "Failed to get reset-gpios\n");
|
||||
|
||||
sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
|
||||
sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc200ai->pwdn_gpio))
|
||||
dev_warn(dev, "Failed to get pwdn-gpios\n");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* V0.0X01.0X01 first version
|
||||
*/
|
||||
|
||||
//#define DEBUG
|
||||
// #define DEBUG
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -192,10 +192,10 @@ static const struct regval sc2336_linear_10_1920x1080_30fps_regs[] = {
|
||||
{0x3301, 0x09},
|
||||
{0x3302, 0xff},
|
||||
{0x3303, 0x10},
|
||||
{0x3306, 0x60},
|
||||
{0x3306, 0x68},
|
||||
{0x3307, 0x02},
|
||||
{0x330a, 0x01},
|
||||
{0x330b, 0x10},
|
||||
{0x330b, 0x18},
|
||||
{0x330c, 0x16},
|
||||
{0x330d, 0xff},
|
||||
{0x3318, 0x02},
|
||||
@@ -219,8 +219,8 @@ static const struct regval sc2336_linear_10_1920x1080_30fps_regs[] = {
|
||||
{0x33b1, 0x80},
|
||||
{0x33b2, 0x68},
|
||||
{0x33b3, 0x42},
|
||||
{0x33f9, 0x70},
|
||||
{0x33fb, 0xd0},
|
||||
{0x33f9, 0x78},
|
||||
{0x33fb, 0xe0},
|
||||
{0x33fc, 0x0f},
|
||||
{0x33fd, 0x1f},
|
||||
{0x349f, 0x03},
|
||||
@@ -229,9 +229,9 @@ static const struct regval sc2336_linear_10_1920x1080_30fps_regs[] = {
|
||||
{0x34a8, 0x42},
|
||||
{0x34a9, 0x06},
|
||||
{0x34aa, 0x01},
|
||||
{0x34ab, 0x23},
|
||||
{0x34ab, 0x28},
|
||||
{0x34ac, 0x01},
|
||||
{0x34ad, 0x84},
|
||||
{0x34ad, 0x90},
|
||||
{0x3630, 0xf4},
|
||||
{0x3633, 0x22},
|
||||
{0x3639, 0xf4},
|
||||
@@ -242,9 +242,9 @@ static const struct regval sc2336_linear_10_1920x1080_30fps_regs[] = {
|
||||
{0x3676, 0xed},
|
||||
{0x367c, 0x09},
|
||||
{0x367d, 0x0f},
|
||||
{0x3690, 0x33},
|
||||
{0x3691, 0x33},
|
||||
{0x3692, 0x43},
|
||||
{0x3690, 0x22},
|
||||
{0x3691, 0x22},
|
||||
{0x3692, 0x22},
|
||||
{0x3698, 0x89},
|
||||
{0x3699, 0x96},
|
||||
{0x369a, 0xd0},
|
||||
@@ -452,15 +452,15 @@ static int sc2336_set_gain_reg(struct sc2336 *sc2336, u32 gain)
|
||||
coarse_dgain = 0x00;
|
||||
fine_dgain = gain_factor * 128 / 1000;
|
||||
} else if (gain_factor < 1000 * 4) { /*2x ~ 4x gain*/
|
||||
coarse_again = 0x01;
|
||||
coarse_again = 0x08;
|
||||
coarse_dgain = 0x00;
|
||||
fine_dgain = gain_factor * 128 / 1000 / 2;
|
||||
} else if (gain_factor < 1000 * 8) { /*4x ~ 8x gain*/
|
||||
coarse_again = 0x03;
|
||||
coarse_again = 0x09;
|
||||
coarse_dgain = 0x00;
|
||||
fine_dgain = gain_factor * 128 / 1000 / 4;
|
||||
} else if (gain_factor < 1000 * 16) { /*8x ~ 16x gain*/
|
||||
coarse_again = 0x07;
|
||||
coarse_again = 0x0b;
|
||||
coarse_dgain = 0x00;
|
||||
fine_dgain = gain_factor * 128 / 1000 / 8;
|
||||
} else if (gain_factor < 1000 * 32) { /*16x ~ 32x gain*/
|
||||
@@ -481,6 +481,7 @@ static int sc2336_set_gain_reg(struct sc2336 *sc2336, u32 gain)
|
||||
coarse_dgain = 0x03;
|
||||
fine_dgain = 0x80;
|
||||
}
|
||||
fine_dgain = fine_dgain / 4 * 4;
|
||||
dev_dbg(&sc2336->client->dev,
|
||||
"total_gain: 0x%x, d_gain: 0x%x, d_fine_gain: 0x%x, c_gain: 0x%x\n",
|
||||
gain, coarse_dgain, fine_dgain, coarse_again);
|
||||
@@ -1148,7 +1149,7 @@ static int sc2336_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_VBLANK:
|
||||
/* Update max exposure while meeting expected vblanking */
|
||||
max = sc2336->cur_mode->height + ctrl->val - 8;
|
||||
max = sc2336->cur_mode->height + ctrl->val - 6;
|
||||
__v4l2_ctrl_modify_range(sc2336->exposure,
|
||||
sc2336->exposure->minimum, max,
|
||||
sc2336->exposure->step,
|
||||
@@ -1271,7 +1272,7 @@ static int sc2336_initialize_controls(struct sc2336 *sc2336)
|
||||
V4L2_CID_VBLANK, vblank_def,
|
||||
SC2336_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
exposure_max = mode->vts_def - 8;
|
||||
exposure_max = mode->vts_def - 6;
|
||||
sc2336->exposure = v4l2_ctrl_new_std(handler, &sc2336_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, SC2336_EXPOSURE_MIN,
|
||||
exposure_max, SC2336_EXPOSURE_STEP,
|
||||
|
||||
@@ -1225,6 +1225,15 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state)
|
||||
struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_buf;
|
||||
u64 ns = 0;
|
||||
|
||||
if (stream->skip_frame) {
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
|
||||
if (stream->skip_frame)
|
||||
stream->skip_frame--;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Dequeue a filled buffer */
|
||||
for (i = 0; i < isp_fmt->mplanes; i++) {
|
||||
u32 payload_size =
|
||||
@@ -1287,6 +1296,7 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state)
|
||||
stream->curr_buf = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
if (!interlaced ||
|
||||
(stream->curr_buf == stream->next_buf &&
|
||||
stream->u.sp.field == RKISP_FIELD_ODD)) {
|
||||
@@ -1505,7 +1515,7 @@ static int rkisp_start(struct rkisp_stream *stream)
|
||||
if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP)
|
||||
hdr_config_dmatx(dev);
|
||||
stream->streaming = true;
|
||||
|
||||
stream->skip_frame = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -977,6 +977,15 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state)
|
||||
struct vb2_buffer *vb2_buf = &buf->vb.vb2_buf;
|
||||
u64 ns = 0;
|
||||
|
||||
if (stream->skip_frame) {
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
list_add_tail(&buf->queue, &stream->buf_queue);
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
|
||||
if (stream->skip_frame)
|
||||
stream->skip_frame--;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Dequeue a filled buffer */
|
||||
for (i = 0; i < isp_fmt->mplanes; i++) {
|
||||
u32 payload_size = stream->out_fmt.plane_fmt[i].sizeimage;
|
||||
@@ -1097,7 +1106,7 @@ static int rkisp_start(struct rkisp_stream *stream)
|
||||
|
||||
stream->ops->enable_mi(stream);
|
||||
stream->streaming = true;
|
||||
|
||||
stream->skip_frame = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "isp_external.h"
|
||||
#include "regs.h"
|
||||
|
||||
static void get_remote_mipi_sensor(struct rkisp_device *dev,
|
||||
void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev,
|
||||
struct v4l2_subdev **sensor_sd, u32 function)
|
||||
{
|
||||
struct media_graph graph;
|
||||
@@ -191,7 +191,7 @@ static int csi_config(struct rkisp_csi_device *csi)
|
||||
emd_vc = 0xFF;
|
||||
emd_dt = 0;
|
||||
dev->hdr.sensor = NULL;
|
||||
get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
|
||||
rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
|
||||
if (mipi_sensor) {
|
||||
ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler,
|
||||
CIFISP_CID_EMB_VC);
|
||||
@@ -527,7 +527,7 @@ int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
get_remote_mipi_sensor(dev, &sd, type);
|
||||
rkisp_get_remote_mipi_sensor(dev, &sd, type);
|
||||
if (!sd) {
|
||||
v4l2_err(&dev->v4l2_dev, "%s don't find subdev\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -558,7 +558,7 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
|
||||
memset(&mode, 0, sizeof(mode));
|
||||
mode.name = dev->name;
|
||||
|
||||
get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
|
||||
rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
|
||||
if (!mipi_sensor)
|
||||
return -EINVAL;
|
||||
dev->hdr.op_mode = HDR_NORMAL;
|
||||
|
||||
@@ -80,4 +80,6 @@ void rkisp_unregister_csi_subdev(struct rkisp_device *dev);
|
||||
int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg);
|
||||
int rkisp_csi_config_patch(struct rkisp_device *dev);
|
||||
void rkisp_csi_sof(struct rkisp_device *dev, u8 id);
|
||||
void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev,
|
||||
struct v4l2_subdev **sensor_sd, u32 function);
|
||||
#endif
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "regs.h"
|
||||
#include "rkisp.h"
|
||||
#include "version.h"
|
||||
#include "csi.h"
|
||||
|
||||
#define RKISP_VERNO_LEN 10
|
||||
|
||||
@@ -813,6 +814,15 @@ static int rkisp_get_reserved_mem(struct rkisp_device *isp_dev)
|
||||
DMA_BIDIRECTIONAL);
|
||||
ret = dma_mapping_error(dev, isp_dev->resmem_addr);
|
||||
isp_dev->is_thunderboot = true;
|
||||
isp_dev->is_rtt_suspend = false;
|
||||
isp_dev->is_rtt_first = true;
|
||||
if (device_property_read_bool(dev, "rtt-suspend")) {
|
||||
isp_dev->is_rtt_suspend = true;
|
||||
if (!isp_dev->hw_dev->is_thunderboot) {
|
||||
isp_dev->is_thunderboot = false;
|
||||
isp_dev->is_rtt_first = false;
|
||||
}
|
||||
}
|
||||
dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa);
|
||||
return ret;
|
||||
}
|
||||
@@ -1004,9 +1014,159 @@ static int __init rkisp_clr_unready_dev(void)
|
||||
late_initcall_sync(rkisp_clr_unready_dev);
|
||||
#endif
|
||||
|
||||
static int rkisp_pm_prepare(struct device *dev)
|
||||
{
|
||||
struct rkisp_device *isp_dev = dev_get_drvdata(dev);
|
||||
struct rkisp_hw_dev *hw = isp_dev->hw_dev;
|
||||
struct rkisp_pipeline *p = &isp_dev->pipe;
|
||||
unsigned long lock_flags = 0;
|
||||
int i, on = 0, time = 100;
|
||||
|
||||
if (isp_dev->isp_state & ISP_STOP) {
|
||||
if (pm_runtime_active(dev) &&
|
||||
rkisp_link_sensor(isp_dev->isp_inp)) {
|
||||
struct v4l2_subdev *mipi_sensor = NULL;
|
||||
|
||||
rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
|
||||
if (mipi_sensor)
|
||||
v4l2_subdev_call(mipi_sensor, core, s_power, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
isp_dev->suspend_sync = false;
|
||||
isp_dev->is_suspend = true;
|
||||
if (rkisp_link_sensor(isp_dev->isp_inp)) {
|
||||
for (i = p->num_subdevs - 1; i >= 0; i--)
|
||||
v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
|
||||
} else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) {
|
||||
v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_QUICK_STREAM, &on);
|
||||
}
|
||||
if (IS_HDR_RDBK(isp_dev->rd_mode)) {
|
||||
spin_lock_irqsave(&hw->rdbk_lock, lock_flags);
|
||||
if (!hw->is_idle && hw->cur_dev_id == isp_dev->dev_id)
|
||||
isp_dev->suspend_sync = true;
|
||||
spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags);
|
||||
} else {
|
||||
/* wait one frame for online */
|
||||
isp_dev->suspend_sync = true;
|
||||
if (hw->isp_size[isp_dev->dev_id].fps)
|
||||
time = 1000 / hw->isp_size[isp_dev->dev_id].fps;
|
||||
}
|
||||
|
||||
if (isp_dev->suspend_sync) {
|
||||
wait_for_completion_timeout(&isp_dev->pm_cmpl, msecs_to_jiffies(time));
|
||||
isp_dev->suspend_sync = false;
|
||||
}
|
||||
|
||||
if (rkisp_link_sensor(isp_dev->isp_inp)) {
|
||||
for (i = p->num_subdevs - 1; i >= 0; i--)
|
||||
v4l2_subdev_call(p->subdevs[i], core, s_power, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rkisp_pm_complete(struct device *dev)
|
||||
{
|
||||
struct rkisp_device *isp_dev = dev_get_drvdata(dev);
|
||||
struct rkisp_hw_dev *hw = isp_dev->hw_dev;
|
||||
struct rkisp_pipeline *p = &isp_dev->pipe;
|
||||
struct rkisp_stream *stream;
|
||||
int i, on = 1, rd_mode = isp_dev->rd_mode;
|
||||
|
||||
if (isp_dev->isp_state & ISP_STOP) {
|
||||
if (pm_runtime_active(dev) &&
|
||||
rkisp_link_sensor(isp_dev->isp_inp)) {
|
||||
struct v4l2_subdev *mipi_sensor = NULL;
|
||||
|
||||
rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
|
||||
if (mipi_sensor)
|
||||
v4l2_subdev_call(mipi_sensor, core, s_power, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isp_dev->is_rtt_suspend) {
|
||||
rkisp_save_tb_info(isp_dev);
|
||||
v4l2_info(&isp_dev->v4l2_dev,
|
||||
"tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d mode:%d\n",
|
||||
isp_dev->tb_head.enable, isp_dev->tb_head.complete,
|
||||
isp_dev->tb_head.frm_total, isp_dev->tb_head.width,
|
||||
isp_dev->tb_head.height, isp_dev->tb_head.camera_num,
|
||||
isp_dev->tb_head.camera_index, isp_dev->tb_head.rtt_mode);
|
||||
isp_dev->is_first_double = false;
|
||||
switch (isp_dev->tb_head.rtt_mode) {
|
||||
case RKISP_RTT_MODE_ONE_FRAME:
|
||||
isp_dev->is_first_double = true;
|
||||
/* switch to readback mode */
|
||||
switch (rd_mode) {
|
||||
case HDR_LINEX3_DDR:
|
||||
isp_dev->rd_mode = HDR_RDBK_FRAME3;
|
||||
break;
|
||||
case HDR_LINEX2_DDR:
|
||||
isp_dev->rd_mode = HDR_RDBK_FRAME2;
|
||||
break;
|
||||
default:
|
||||
isp_dev->rd_mode = HDR_RDBK_FRAME1;
|
||||
}
|
||||
break;
|
||||
case RKISP_RTT_MODE_MULTI_FRAME:
|
||||
default:
|
||||
if (isp_dev->tb_head.rtt_mode != RKISP_RTT_MODE_MULTI_FRAME)
|
||||
v4l2_warn(&isp_dev->v4l2_dev,
|
||||
"invalid rtt mode:%d, change to mode:%d\n",
|
||||
isp_dev->tb_head.rtt_mode, RKISP_RTT_MODE_MULTI_FRAME);
|
||||
if (!hw->is_single)
|
||||
break;
|
||||
/* switch to online mode for single sensor */
|
||||
switch (rd_mode) {
|
||||
case HDR_RDBK_FRAME3:
|
||||
isp_dev->rd_mode = HDR_LINEX3_DDR;
|
||||
break;
|
||||
case HDR_RDBK_FRAME2:
|
||||
isp_dev->rd_mode = HDR_LINEX2_DDR;
|
||||
break;
|
||||
default:
|
||||
isp_dev->rd_mode = HDR_NORMAL;
|
||||
}
|
||||
}
|
||||
isp_dev->hdr.op_mode = isp_dev->rd_mode;
|
||||
if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) {
|
||||
rkisp_unite_write(isp_dev, CSI2RX_CTRL0,
|
||||
SW_IBUF_OP_MODE(isp_dev->rd_mode), true);
|
||||
if (IS_HDR_RDBK(isp_dev->rd_mode))
|
||||
rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0,
|
||||
SW_MPIP_DROP_FRM_DIS, true);
|
||||
else
|
||||
rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG,
|
||||
SW_MPIP_DROP_FRM_DIS, true);
|
||||
}
|
||||
}
|
||||
|
||||
isp_dev->is_suspend = false;
|
||||
isp_dev->isp_state = ISP_START | ISP_FRAME_END;
|
||||
for (i = 0; i < RKISP_MAX_STREAM; i++) {
|
||||
stream = &isp_dev->cap_dev.stream[i];
|
||||
if (i == RKISP_STREAM_VIR || !stream->streaming)
|
||||
continue;
|
||||
stream->skip_frame = 1;
|
||||
}
|
||||
if (hw->cur_dev_id == isp_dev->dev_id)
|
||||
rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL);
|
||||
|
||||
if (rkisp_link_sensor(isp_dev->isp_inp)) {
|
||||
for (i = 0; i < p->num_subdevs; i++)
|
||||
v4l2_subdev_call(p->subdevs[i], core, s_power, 1);
|
||||
for (i = 0; i < p->num_subdevs; i++)
|
||||
v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
|
||||
} else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) {
|
||||
v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_QUICK_STREAM, &on);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rkisp_plat_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
pm_runtime_force_resume)
|
||||
.prepare = rkisp_pm_prepare,
|
||||
.complete = rkisp_pm_complete,
|
||||
SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
|
||||
@@ -235,6 +235,10 @@ struct rkisp_device {
|
||||
size_t resmem_size;
|
||||
struct rkisp_thunderboot_resmem_head tb_head;
|
||||
bool is_thunderboot;
|
||||
/* first frame for rtt */
|
||||
bool is_rtt_first;
|
||||
/* suspend/resume with rtt */
|
||||
bool is_rtt_suspend;
|
||||
struct rkisp_tb_stream_info tb_stream_info;
|
||||
unsigned int tb_addr_idx;
|
||||
|
||||
@@ -246,6 +250,8 @@ struct rkisp_device {
|
||||
struct rkisp_ispp_buf *cur_fbcgain;
|
||||
struct rkisp_buffer *cur_spbuf;
|
||||
|
||||
struct completion pm_cmpl;
|
||||
|
||||
struct work_struct rdbk_work;
|
||||
struct kfifo rdbk_kfifo;
|
||||
spinlock_t rdbk_lock;
|
||||
@@ -269,6 +275,8 @@ struct rkisp_device {
|
||||
bool is_first_double;
|
||||
bool is_probe_end;
|
||||
bool is_frame_double;
|
||||
bool is_suspend;
|
||||
bool suspend_sync;
|
||||
|
||||
struct rkisp_vicap_input vicap_in;
|
||||
|
||||
@@ -304,4 +312,8 @@ rkisp_unite_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask,
|
||||
rkisp_next_clear_bits(dev, reg, mask, is_direct);
|
||||
}
|
||||
|
||||
static inline bool rkisp_link_sensor(u32 isp_inp)
|
||||
{
|
||||
return isp_inp & (INP_CSI | INP_DVP | INP_LVDS);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
* rkisp_hw
|
||||
*/
|
||||
|
||||
struct backup_reg {
|
||||
const u32 base;
|
||||
const u32 shd;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct isp_irqs_data {
|
||||
const char *name;
|
||||
irqreturn_t (*irq_hdl)(int irq, void *ctx);
|
||||
@@ -302,6 +308,192 @@ int rkisp_register_irq(struct rkisp_hw_dev *hw_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rkisp_hw_reg_save(struct rkisp_hw_dev *dev)
|
||||
{
|
||||
void *buf = dev->sw_reg;
|
||||
|
||||
memcpy_fromio(buf, dev->base_addr, RKISP_ISP_SW_REG_SIZE);
|
||||
if (dev->unite == ISP_UNITE_TWO) {
|
||||
buf += RKISP_ISP_SW_REG_SIZE;
|
||||
memcpy_fromio(buf, dev->base_next_addr, RKISP_ISP_SW_REG_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev)
|
||||
{
|
||||
struct rkisp_device *isp = dev->isp[dev->cur_dev_id];
|
||||
void __iomem *base = dev->base_addr;
|
||||
void *reg_buf = dev->sw_reg;
|
||||
u32 val, *reg, *reg1, i, j;
|
||||
u32 self_upd_reg[] = {
|
||||
ISP21_BAY3D_BASE, ISP21_DRC_BASE, ISP3X_BAY3D_CTRL,
|
||||
ISP_DHAZ_CTRL, ISP3X_3DLUT_BASE, ISP_RAWAE_LITE_BASE,
|
||||
RAWAE_BIG1_BASE, RAWAE_BIG2_BASE, RAWAE_BIG3_BASE,
|
||||
ISP_RAWHIST_LITE_BASE, ISP_RAWHIST_BIG1_BASE,
|
||||
ISP_RAWHIST_BIG2_BASE, ISP_RAWHIST_BIG3_BASE,
|
||||
ISP_RAWAF_BASE, ISP_RAWAWB_BASE, ISP_LDCH_BASE,
|
||||
ISP3X_CAC_BASE,
|
||||
};
|
||||
struct backup_reg backup[] = {
|
||||
{
|
||||
.base = MI_MP_WR_Y_BASE,
|
||||
.shd = MI_MP_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_MP_WR_CB_BASE,
|
||||
.shd = MI_MP_WR_CB_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_MP_WR_CR_BASE,
|
||||
.shd = MI_MP_WR_CR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_Y_BASE,
|
||||
.shd = MI_SP_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_CB_BASE,
|
||||
.shd = MI_SP_WR_CB_BASE_AD_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_CR_BASE,
|
||||
.shd = MI_SP_WR_CR_BASE_AD_SHD,
|
||||
}, {
|
||||
.base = ISP3X_MI_BP_WR_Y_BASE,
|
||||
.shd = ISP3X_MI_BP_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = ISP3X_MI_BP_WR_CB_BASE,
|
||||
.shd = ISP3X_MI_BP_WR_CB_BASE_SHD,
|
||||
}, {
|
||||
.base = ISP32_MI_MPDS_WR_Y_BASE,
|
||||
.shd = ISP32_MI_MPDS_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = ISP32_MI_MPDS_WR_CB_BASE,
|
||||
.shd = ISP32_MI_MPDS_WR_CB_BASE_SHD,
|
||||
}, {
|
||||
.base = ISP32_MI_BPDS_WR_Y_BASE,
|
||||
.shd = ISP32_MI_BPDS_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = ISP32_MI_BPDS_WR_CB_BASE,
|
||||
.shd = ISP32_MI_BPDS_WR_CB_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW0_WR_BASE,
|
||||
.shd = MI_RAW0_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW1_WR_BASE,
|
||||
.shd = MI_RAW1_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW2_WR_BASE,
|
||||
.shd = MI_RAW2_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW3_WR_BASE,
|
||||
.shd = MI_RAW3_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW0_RD_BASE,
|
||||
.shd = MI_RAW0_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW1_RD_BASE,
|
||||
.shd = MI_RAW1_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW2_RD_BASE,
|
||||
.shd = MI_RAW2_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_GAIN_WR_BASE,
|
||||
.shd = MI_GAIN_WR_BASE_SHD,
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i <= !!dev->unite; i++) {
|
||||
if (dev->unite != ISP_UNITE_TWO && i)
|
||||
break;
|
||||
|
||||
if (i) {
|
||||
reg_buf += RKISP_ISP_SW_REG_SIZE;
|
||||
base = dev->base_next_addr;
|
||||
}
|
||||
|
||||
/* process special reg */
|
||||
for (j = 0; j < ARRAY_SIZE(self_upd_reg); j++) {
|
||||
reg = reg_buf + self_upd_reg[j];
|
||||
*reg &= ~ISP21_SELF_FORCE_UPD;
|
||||
if (self_upd_reg[j] == ISP3X_3DLUT_BASE && *reg & ISP_3DLUT_EN) {
|
||||
reg = reg_buf + ISP3X_3DLUT_UPDATE;
|
||||
*reg = 1;
|
||||
}
|
||||
}
|
||||
reg = reg_buf + ISP_CTRL;
|
||||
*reg &= ~(CIF_ISP_CTRL_ISP_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_INFORM_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_CFG_UPD);
|
||||
reg = reg_buf + MI_WR_INIT;
|
||||
*reg = 0;
|
||||
reg = reg_buf + CSI2RX_CTRL0;
|
||||
*reg &= ~SW_CSI2RX_EN;
|
||||
for (j = 0; j < RKISP_ISP_SW_REG_SIZE; j += 4) {
|
||||
/* skip table RAM */
|
||||
if ((j > ISP3X_LSC_CTRL && j < ISP3X_LSC_XGRAD_01) ||
|
||||
(j > ISP32_CAC_OFFSET && j < ISP3X_CAC_RO_CNT) ||
|
||||
(j > ISP3X_3DLUT_UPDATE && j < ISP3X_GAIN_BASE) ||
|
||||
(j == 0x4840 || j == 0x4a80 || j == 0x4b40 || j == 0x5660))
|
||||
continue;
|
||||
/* skip mmu range */
|
||||
if (dev->isp_ver < ISP_V30 &&
|
||||
j > ISP21_MI_BAY3D_RD_BASE_SHD && j < CSI2RX_CTRL0)
|
||||
continue;
|
||||
/* reg value of read diff to write */
|
||||
if (j == ISP_MPFBC_CTRL ||
|
||||
j == ISP32_ISP_AWB1_GAIN_G || j == ISP32_ISP_AWB1_GAIN_RB)
|
||||
reg = isp->sw_base_addr + j;
|
||||
else
|
||||
reg = reg_buf + j;
|
||||
writel(*reg, base + j);
|
||||
}
|
||||
|
||||
/* config shd_reg to base_reg */
|
||||
for (j = 0; j < ARRAY_SIZE(backup); j++) {
|
||||
reg = reg_buf + backup[j].base;
|
||||
reg1 = reg_buf + backup[j].shd;
|
||||
backup[j].val = *reg;
|
||||
writel(*reg1, base + backup[j].base);
|
||||
}
|
||||
|
||||
/* update module */
|
||||
reg = reg_buf + DUAL_CROP_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL);
|
||||
reg = reg_buf + SELF_RESIZE_CTRL;
|
||||
if (*reg & 0xf) {
|
||||
if (dev->isp_ver == ISP_V32_L)
|
||||
writel(*reg | ISP32_SCALE_FORCE_UPD, base + ISP32_SELF_SCALE_UPDATE);
|
||||
else
|
||||
writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL);
|
||||
}
|
||||
reg = reg_buf + MAIN_RESIZE_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL);
|
||||
reg = reg_buf + ISP32_BP_RESIZE_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + ISP32_BP_RESIZE_CTRL);
|
||||
|
||||
/* update mi and isp, base_reg will update to shd_reg */
|
||||
writel(CIF_MI_INIT_SOFT_UPD, base + MI_WR_INIT);
|
||||
|
||||
/* config base_reg */
|
||||
for (j = 0; j < ARRAY_SIZE(backup); j++)
|
||||
writel(backup[j].val, base + backup[j].base);
|
||||
/* base_reg = shd_reg, write is base but read is shd */
|
||||
val = rkisp_read_reg_cache(isp, ISP_MPFBC_HEAD_PTR);
|
||||
writel(val, base + ISP_MPFBC_HEAD_PTR);
|
||||
val = rkisp_read_reg_cache(isp, MI_SWS_3A_WR_BASE);
|
||||
writel(val, base + MI_SWS_3A_WR_BASE);
|
||||
}
|
||||
|
||||
rkisp_params_cfgsram(&isp->params_vdev, false);
|
||||
|
||||
reg = reg_buf + ISP_CTRL;
|
||||
*reg |= CIF_ISP_CTRL_ISP_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_CFG_UPD |
|
||||
CIF_ISP_CTRL_ISP_INFORM_ENABLE;
|
||||
writel(*reg, dev->base_addr + ISP_CTRL);
|
||||
if (dev->unite == ISP_UNITE_TWO)
|
||||
writel(*reg, dev->base_next_addr + ISP_CTRL);
|
||||
}
|
||||
|
||||
static const char * const rk3562_isp_clks[] = {
|
||||
"clk_isp_core",
|
||||
"aclk_isp",
|
||||
@@ -733,7 +925,6 @@ static void disable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
static int enable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
{
|
||||
int i, ret = -EINVAL;
|
||||
unsigned long rate;
|
||||
|
||||
for (i = 0; i < dev->num_clks; i++) {
|
||||
if (!IS_ERR(dev->clks[i])) {
|
||||
@@ -743,12 +934,6 @@ static int enable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev->is_assigned_clk) {
|
||||
rate = dev->clk_rate_tbl[0].clk_rate * 1000000UL;
|
||||
rkisp_set_clk_rate(dev->clks[0], rate);
|
||||
if (dev->unite == ISP_UNITE_TWO)
|
||||
rkisp_set_clk_rate(dev->clks[5], rate);
|
||||
}
|
||||
rkisp_soft_reset(dev, false);
|
||||
isp_config_clk(dev, true);
|
||||
return 0;
|
||||
@@ -805,19 +990,24 @@ static int rkisp_hw_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rkisp_hw_dev *hw_dev;
|
||||
struct resource *res;
|
||||
int i, ret;
|
||||
int i, ret, mult = 1;
|
||||
bool is_mem_reserved = true;
|
||||
u32 clk_rate = 0;
|
||||
|
||||
match = of_match_node(rkisp_hw_of_match, node);
|
||||
if (IS_ERR(match))
|
||||
return PTR_ERR(match);
|
||||
match_data = match->data;
|
||||
|
||||
hw_dev = devm_kzalloc(dev, sizeof(*hw_dev), GFP_KERNEL);
|
||||
if (!hw_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
match_data = match->data;
|
||||
if (match_data->unite)
|
||||
mult = 2;
|
||||
hw_dev->sw_reg = devm_kzalloc(dev, RKISP_ISP_SW_REG_SIZE * mult, GFP_KERNEL);
|
||||
if (!hw_dev->sw_reg)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(dev, hw_dev);
|
||||
hw_dev->dev = dev;
|
||||
hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
|
||||
@@ -995,11 +1185,23 @@ static void rkisp_hw_shutdown(struct platform_device *pdev)
|
||||
static int __maybe_unused rkisp_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
hw_dev->dev_link_num = 0;
|
||||
hw_dev->is_single = true;
|
||||
hw_dev->is_multi_overflow = false;
|
||||
hw_dev->is_frm_buf = false;
|
||||
hw_dev->is_idle = true;
|
||||
if (dev->power.runtime_status) {
|
||||
hw_dev->dev_link_num = 0;
|
||||
hw_dev->is_single = true;
|
||||
hw_dev->is_multi_overflow = false;
|
||||
hw_dev->is_frm_buf = false;
|
||||
} else {
|
||||
/* system suspend */
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
if (hw_dev->isp_size[i].is_on) {
|
||||
rkisp_hw_reg_save(hw_dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
disable_sys_clk(hw_dev);
|
||||
return pinctrl_pm_select_sleep_state(dev);
|
||||
}
|
||||
@@ -1062,28 +1264,45 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
return ret;
|
||||
|
||||
enable_sys_clk(hw_dev);
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
isp = hw_dev->isp[i];
|
||||
if (!isp || !isp->sw_base_addr)
|
||||
continue;
|
||||
buf = isp->sw_base_addr;
|
||||
memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
if (hw_dev->unite) {
|
||||
buf += RKISP_ISP_SW_MAX_SIZE;
|
||||
base = hw_dev->base_next_addr;
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
if (dev->power.runtime_status) {
|
||||
if (!hw_dev->is_assigned_clk) {
|
||||
unsigned long rate = hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL;
|
||||
|
||||
rkisp_set_clk_rate(hw_dev->clks[0], rate);
|
||||
if (hw_dev->unite == ISP_UNITE_TWO)
|
||||
rkisp_set_clk_rate(hw_dev->clks[5], rate);
|
||||
}
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
isp = hw_dev->isp[i];
|
||||
if (!isp || !isp->sw_base_addr)
|
||||
continue;
|
||||
buf = isp->sw_base_addr;
|
||||
memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
if (hw_dev->unite) {
|
||||
buf += RKISP_ISP_SW_MAX_SIZE;
|
||||
base = hw_dev->base_next_addr;
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
}
|
||||
default_sw_reg_flag(hw_dev->isp[i]);
|
||||
}
|
||||
rkisp_hw_enum_isp_size(hw_dev);
|
||||
hw_dev->monitor.is_en = rkisp_monitor;
|
||||
} else {
|
||||
/* system resume */
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
if (hw_dev->isp_size[i].is_on) {
|
||||
rkisp_hw_reg_restore(hw_dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default_sw_reg_flag(hw_dev->isp[i]);
|
||||
}
|
||||
rkisp_hw_enum_isp_size(hw_dev);
|
||||
hw_dev->monitor.is_en = rkisp_monitor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rkisp_hw_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(rkisp_runtime_suspend,
|
||||
rkisp_runtime_resume, NULL)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
|
||||
SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver rkisp_hw_drv = {
|
||||
|
||||
@@ -29,7 +29,6 @@ struct rkisp_monitor {
|
||||
struct rkisp_hw_dev *dev;
|
||||
struct work_struct work;
|
||||
struct completion cmpl;
|
||||
int (*reset_handle)(struct rkisp_device *dev);
|
||||
u32 state;
|
||||
u8 retry;
|
||||
bool is_en;
|
||||
@@ -53,6 +52,7 @@ struct rkisp_hw_dev {
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
struct regmap *grf;
|
||||
void *sw_reg;
|
||||
void __iomem *base_addr;
|
||||
void __iomem *base_next_addr;
|
||||
struct clk *clks[RKISP_MAX_BUS_CLK];
|
||||
@@ -110,4 +110,6 @@ struct rkisp_hw_dev {
|
||||
int rkisp_register_irq(struct rkisp_hw_dev *dev);
|
||||
void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure);
|
||||
void rkisp_hw_enum_isp_size(struct rkisp_hw_dev *hw_dev);
|
||||
void rkisp_hw_reg_save(struct rkisp_hw_dev *dev);
|
||||
void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev);
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#define RKISP_VICAP_CMD_RX_BUFFER_FREE \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkisp_rx_buf)
|
||||
|
||||
#define RKISP_VICAP_CMD_QUICK_STREAM \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 3, int)
|
||||
|
||||
#define RKISP_VICAP_BUF_CNT 3
|
||||
#define RKISP_VICAP_BUF_CNT_MAX 8
|
||||
#define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT_MAX * 3)
|
||||
|
||||
@@ -185,6 +185,28 @@ static void rkisp_params_vb2_buf_queue(struct vb2_buffer *vb)
|
||||
spin_lock_irqsave(¶ms_vdev->config_lock, flags);
|
||||
list_add_tail(¶ms_buf->queue, ¶ms_vdev->params);
|
||||
spin_unlock_irqrestore(¶ms_vdev->config_lock, flags);
|
||||
|
||||
if (params_vdev->dev->is_first_double) {
|
||||
struct isp32_isp_params_cfg *params = params_buf->vaddr[0];
|
||||
struct rkisp_buffer *buf;
|
||||
|
||||
if (!(params->module_cfg_update & ISP32_MODULE_RTT_FST))
|
||||
return;
|
||||
spin_lock_irqsave(¶ms_vdev->config_lock, flags);
|
||||
while (!list_empty(¶ms_vdev->params)) {
|
||||
buf = list_first_entry(¶ms_vdev->params,
|
||||
struct rkisp_buffer, queue);
|
||||
if (buf == params_buf)
|
||||
break;
|
||||
list_del(&buf->queue);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
}
|
||||
spin_unlock_irqrestore(¶ms_vdev->config_lock, flags);
|
||||
dev_info(params_vdev->dev->dev,
|
||||
"first params:%d for rtt resume\n", params->frame_id);
|
||||
params_vdev->dev->is_first_double = false;
|
||||
rkisp_trigger_read_back(params_vdev->dev, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
|
||||
@@ -368,15 +390,16 @@ void rkisp_params_cfg(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id)
|
||||
params_vdev->ops->param_cfg(params_vdev, frame_id, RKISP_PARAMS_IMD);
|
||||
}
|
||||
|
||||
void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev)
|
||||
void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev, bool is_check)
|
||||
{
|
||||
if (params_vdev->dev->procfs.mode & RKISP_PROCFS_FIL_SW)
|
||||
return;
|
||||
|
||||
/* multi device to switch sram config */
|
||||
if (params_vdev->dev->hw_dev->is_single)
|
||||
return;
|
||||
if (is_check) {
|
||||
if (params_vdev->dev->procfs.mode & RKISP_PROCFS_FIL_SW)
|
||||
return;
|
||||
|
||||
/* multi device to switch sram config */
|
||||
if (params_vdev->dev->hw_dev->is_single)
|
||||
return;
|
||||
}
|
||||
if (params_vdev->ops->param_cfgsram)
|
||||
params_vdev->ops->param_cfgsram(params_vdev);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ void rkisp_params_isr(struct rkisp_isp_params_vdev *params_vdev, u32 isp_mis);
|
||||
|
||||
void rkisp_params_cfg(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id);
|
||||
|
||||
void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev);
|
||||
void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev, bool is_check);
|
||||
void rkisp_params_get_meshbuf_inf(struct rkisp_isp_params_vdev *params_vdev, void *meshbuf);
|
||||
int rkisp_params_set_meshbuf_size(struct rkisp_isp_params_vdev *params_vdev, void *meshsize);
|
||||
void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id);
|
||||
|
||||
@@ -460,10 +460,9 @@ isp_lsc_matrix_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
{
|
||||
int i, j;
|
||||
unsigned int sram_addr;
|
||||
unsigned int data;
|
||||
unsigned int data = rkisp_ioread32(params_vdev, ISP_LSC_CTRL);
|
||||
|
||||
if (is_check &&
|
||||
!(rkisp_ioread32(params_vdev, ISP_LSC_CTRL) & ISP_LSC_EN))
|
||||
if (is_check && (data & ISP_LSC_LUT_EN || !(data & ISP_LSC_EN)))
|
||||
return;
|
||||
|
||||
/* CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
|
||||
@@ -603,12 +602,13 @@ isp_lsc_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
* readback mode lsc lut AHB config to sram, once for single device,
|
||||
* need record to switch for multi-device.
|
||||
*/
|
||||
if (!IS_HDR_RDBK(dev->rd_mode))
|
||||
if (!IS_HDR_RDBK(dev->rd_mode)) {
|
||||
isp_lsc_matrix_cfg_ddr(params_vdev, arg);
|
||||
else if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
|
||||
else
|
||||
} else {
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
|
||||
params_rec->others.lsc_cfg = *arg;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* program x size tables */
|
||||
@@ -1327,8 +1327,8 @@ isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
|
||||
rkisp_iowrite32(params_vdev, val, ISP21_RAWAWB_WRAM_DATA_BASE);
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
|
||||
rkisp_write(params_vdev->dev, ISP21_RAWAWB_WRAM_DATA_BASE, val, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2143,10 +2143,9 @@ isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (params_vdev->dev->hw_dev->is_single)
|
||||
isp_rawawb_cfg_sram(params_vdev, arg, false);
|
||||
else
|
||||
memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
|
||||
arg->sw_rawawb_wp_blk_wei_w,
|
||||
ISP21_RAWAWB_WEIGHT_NUM);
|
||||
memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
|
||||
arg->sw_rawawb_wp_blk_wei_w,
|
||||
ISP21_RAWAWB_WEIGHT_NUM);
|
||||
|
||||
/* avoid to override the old enable value */
|
||||
value = rkisp_ioread32(params_vdev, ISP21_RAWAWB_CTRL);
|
||||
@@ -2370,8 +2369,7 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false);
|
||||
else
|
||||
*arg_rec = *arg;
|
||||
*arg_rec = *arg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -536,10 +536,9 @@ isp_lsc_matrix_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
{
|
||||
int i, j;
|
||||
unsigned int sram_addr;
|
||||
unsigned int data;
|
||||
unsigned int data = rkisp_ioread32(params_vdev, ISP_LSC_CTRL);
|
||||
|
||||
if (is_check &&
|
||||
!(rkisp_ioread32(params_vdev, ISP_LSC_CTRL) & ISP_LSC_EN))
|
||||
if (is_check && (data & ISP_LSC_LUT_EN || !(data & ISP_LSC_EN)))
|
||||
return;
|
||||
|
||||
/* CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
|
||||
@@ -679,12 +678,13 @@ isp_lsc_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
* readback mode lsc lut AHB config to sram, once for single device,
|
||||
* need record to switch for multi-device.
|
||||
*/
|
||||
if (!IS_HDR_RDBK(dev->rd_mode))
|
||||
if (!IS_HDR_RDBK(dev->rd_mode)) {
|
||||
isp_lsc_matrix_cfg_ddr(params_vdev, arg);
|
||||
else if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
|
||||
else
|
||||
} else {
|
||||
params_rec->others.lsc_cfg = *arg;
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* program x size tables */
|
||||
@@ -2910,8 +2910,7 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false);
|
||||
else
|
||||
*arg_rec = *arg;
|
||||
*arg_rec = *arg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -555,11 +555,11 @@ isp_lsc_matrix_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
bool is_check, u32 id)
|
||||
{
|
||||
struct rkisp_device *dev = params_vdev->dev;
|
||||
u32 sram_addr, data, table;
|
||||
u32 data = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id);
|
||||
u32 sram_addr, table;
|
||||
int i, j;
|
||||
|
||||
if (is_check &&
|
||||
!(isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id) & ISP_LSC_EN))
|
||||
if (is_check && (data & ISP3X_LSC_LUT_EN || !(data & ISP_LSC_EN)))
|
||||
return;
|
||||
|
||||
table = isp3_param_read_direct(params_vdev, ISP3X_LSC_STATUS);
|
||||
@@ -643,12 +643,13 @@ isp_lsc_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
* readback mode lsc lut AHB config to sram, once for single device,
|
||||
* need record to switch for multi-device.
|
||||
*/
|
||||
if (!IS_HDR_RDBK(dev->rd_mode))
|
||||
if (!IS_HDR_RDBK(dev->rd_mode)) {
|
||||
isp_lsc_matrix_cfg_ddr(params_vdev, arg);
|
||||
else if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false, id);
|
||||
else
|
||||
} else {
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_lsc_matrix_cfg_sram(params_vdev, arg, false, id);
|
||||
params_rec->others.lsc_cfg = *arg;
|
||||
}
|
||||
} else {
|
||||
/* two lsc sram table */
|
||||
params_rec->others.lsc_cfg = *arg;
|
||||
@@ -1576,20 +1577,19 @@ static void
|
||||
isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
const struct isp32_rawawb_meas_cfg *arg, bool is_check, u32 id)
|
||||
{
|
||||
u32 i, val = ISP32_MODULE_EN;
|
||||
u32 i, val = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id);
|
||||
|
||||
if (params_vdev->dev->isp_ver == ISP_V32 && is_check &&
|
||||
!(isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id) & val))
|
||||
if (params_vdev->dev->isp_ver != ISP_V32 ||
|
||||
(is_check && !(val & ISP32_MODULE_EN)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < ISP32_RAWAWB_WEIGHT_NUM / 5; i++) {
|
||||
isp3_param_write_direct(params_vdev,
|
||||
(arg->wp_blk_wei_w[5 * i] & 0x3f) |
|
||||
(arg->wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
|
||||
(arg->wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
|
||||
(arg->wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
|
||||
(arg->wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
|
||||
ISP3X_RAWAWB_WRAM_DATA_BASE);
|
||||
val = (arg->wp_blk_wei_w[5 * i] & 0x3f) |
|
||||
(arg->wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
|
||||
(arg->wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
|
||||
(arg->wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
|
||||
(arg->wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
|
||||
isp3_param_write_direct(params_vdev, val, ISP3X_RAWAWB_WRAM_DATA_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2255,9 +2255,7 @@ isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
if (params_vdev->dev->isp_ver == ISP_V32) {
|
||||
if (params_vdev->dev->hw_dev->is_single)
|
||||
isp_rawawb_cfg_sram(params_vdev, arg, false, id);
|
||||
else
|
||||
memcpy(arg_rec->wp_blk_wei_w, arg->wp_blk_wei_w,
|
||||
ISP32_RAWAWB_WEIGHT_NUM);
|
||||
memcpy(arg_rec->wp_blk_wei_w, arg->wp_blk_wei_w, ISP32_RAWAWB_WEIGHT_NUM);
|
||||
} else {
|
||||
for (i = 0; i < ISP32L_RAWAWB_WEIGHT_NUM; i++)
|
||||
isp3_param_write(params_vdev, arg->win_weight[i],
|
||||
@@ -2503,8 +2501,7 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false, id);
|
||||
else
|
||||
*arg_rec = *arg;
|
||||
*arg_rec = *arg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1430,13 +1430,12 @@ isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
|
||||
return;
|
||||
|
||||
for (i = 0; i < ISP3X_RAWAWB_WEIGHT_NUM / 5; i++) {
|
||||
isp3_param_write(params_vdev,
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i] & 0x3f) << 0 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
|
||||
ISP3X_RAWAWB_WRAM_DATA_BASE, id);
|
||||
val = (arg->sw_rawawb_wp_blk_wei_w[5 * i] & 0x3f) << 0 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
|
||||
(arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
|
||||
isp3_param_write_direct(params_vdev, val, ISP3X_RAWAWB_WRAM_DATA_BASE, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2288,10 +2287,9 @@ isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (params_vdev->dev->hw_dev->is_single)
|
||||
isp_rawawb_cfg_sram(params_vdev, arg, false, id);
|
||||
else
|
||||
memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
|
||||
arg->sw_rawawb_wp_blk_wei_w,
|
||||
ISP3X_RAWAWB_WEIGHT_NUM);
|
||||
memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
|
||||
arg->sw_rawawb_wp_blk_wei_w,
|
||||
ISP3X_RAWAWB_WEIGHT_NUM);
|
||||
|
||||
/* avoid to override the old enable value */
|
||||
value = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id);
|
||||
@@ -2502,8 +2500,7 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
|
||||
|
||||
if (dev->hw_dev->is_single)
|
||||
isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false, id);
|
||||
else
|
||||
*arg_rec = *arg;
|
||||
*arg_rec = *arg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -229,6 +229,11 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd)
|
||||
rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp;
|
||||
|
||||
rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence;
|
||||
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s stream:%d seq:%d buf:0x%x done\n",
|
||||
__func__, stream->id,
|
||||
stream->curr_buf->vb.sequence,
|
||||
stream->curr_buf->buff_addr[0]);
|
||||
} else {
|
||||
if (stream->ispdev->cap_dev.wrap_line &&
|
||||
stream->id == RKISP_STREAM_MP) {
|
||||
|
||||
@@ -628,6 +628,9 @@ rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev,
|
||||
ops->get_vsm_stats(stats_vdev, cur_stat_buf);
|
||||
}
|
||||
|
||||
if (cur_stat_buf && stats_vdev->dev->is_first_double)
|
||||
cur_stat_buf->meas_type |= ISP32_STAT_RTT_FST;
|
||||
|
||||
if (is_dummy) {
|
||||
spin_lock_irqsave(&stats_vdev->rd_lock, flags);
|
||||
if (!list_empty(&stats_vdev->stat)) {
|
||||
|
||||
@@ -87,12 +87,6 @@
|
||||
|
||||
static void rkisp_config_cmsk(struct rkisp_device *dev);
|
||||
|
||||
struct backup_reg {
|
||||
const u32 base;
|
||||
const u32 shd;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
static inline struct rkisp_device *sd_to_isp_dev(struct v4l2_subdev *sd)
|
||||
{
|
||||
return container_of(sd->v4l2_dev, struct rkisp_device, v4l2_dev);
|
||||
@@ -717,7 +711,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
|
||||
params_vdev->rdbk_times = dma2frm + 1;
|
||||
|
||||
run_next:
|
||||
rkisp_params_cfgsram(params_vdev);
|
||||
rkisp_params_cfgsram(params_vdev, true);
|
||||
stats_vdev->rdbk_drop = false;
|
||||
if (dev->is_frame_double) {
|
||||
is_upd = true;
|
||||
@@ -866,6 +860,9 @@ static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current)
|
||||
struct rkisp_buffer *buf;
|
||||
u32 i, val;
|
||||
|
||||
if (!dev->is_rtt_first)
|
||||
return;
|
||||
|
||||
for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) {
|
||||
stream = &dev->dmarx_dev.stream[i];
|
||||
if (!stream->ops)
|
||||
@@ -930,11 +927,16 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
goto end;
|
||||
if (!IS_HDR_RDBK(dev->rd_mode))
|
||||
goto end;
|
||||
if (dev->is_suspend) {
|
||||
if (dev->suspend_sync)
|
||||
complete(&dev->pm_cmpl);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
isp = hw->isp[i];
|
||||
if (!isp ||
|
||||
(isp && !(isp->isp_state & ISP_START)))
|
||||
(isp && (!(isp->isp_state & ISP_START) || isp->is_suspend)))
|
||||
continue;
|
||||
rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &len[i]);
|
||||
if (max < len[i]) {
|
||||
@@ -944,7 +946,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
}
|
||||
|
||||
/* wait 2 frame to start isp for fast */
|
||||
if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
|
||||
if (dev->is_rtt_first && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
|
||||
goto end;
|
||||
|
||||
if (max) {
|
||||
@@ -990,7 +992,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
/* first frame handle twice for thunderboot
|
||||
* first output stats to AIQ and wait new params to run second
|
||||
*/
|
||||
if (isp->is_pre_on && t.frame_id == 0) {
|
||||
if (isp->is_rtt_first && t.frame_id == 0) {
|
||||
isp->is_first_double = true;
|
||||
isp->skip_frame = 1;
|
||||
if (hw->unite != ISP_UNITE_ONE) {
|
||||
@@ -998,6 +1000,8 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
isp->is_frame_double = false;
|
||||
}
|
||||
rkisp_fast_switch_rx_buf(isp, false);
|
||||
} else {
|
||||
isp->is_rtt_first = false;
|
||||
}
|
||||
isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1;
|
||||
}
|
||||
@@ -1076,6 +1080,7 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
|
||||
|
||||
if (dev->is_first_double) {
|
||||
rkisp_fast_switch_rx_buf(dev, true);
|
||||
dev->is_rtt_first = false;
|
||||
dev->skip_frame = 0;
|
||||
dev->irq_ends = 0;
|
||||
return;
|
||||
@@ -1167,86 +1172,19 @@ static void rkisp_config_ism(struct rkisp_device *dev)
|
||||
rkisp_write(dev, CIF_ISP_IS_CTRL, 1, false);
|
||||
}
|
||||
|
||||
static int rkisp_reset_handle_v2x(struct rkisp_device *dev)
|
||||
static int rkisp_reset_handle(struct rkisp_device *dev)
|
||||
{
|
||||
void __iomem *base = dev->base_addr;
|
||||
void *reg_buf = NULL;
|
||||
u32 *reg, *reg1, i;
|
||||
struct backup_reg backup[] = {
|
||||
{
|
||||
.base = MI_MP_WR_Y_BASE,
|
||||
.shd = MI_MP_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_MP_WR_CB_BASE,
|
||||
.shd = MI_MP_WR_CB_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_MP_WR_CR_BASE,
|
||||
.shd = MI_MP_WR_CR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_Y_BASE,
|
||||
.shd = MI_SP_WR_Y_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_CB_BASE,
|
||||
.shd = MI_SP_WR_CB_BASE_AD_SHD,
|
||||
}, {
|
||||
.base = MI_SP_WR_CR_BASE,
|
||||
.shd = MI_SP_WR_CR_BASE_AD_SHD,
|
||||
}, {
|
||||
.base = MI_RAW0_WR_BASE,
|
||||
.shd = MI_RAW0_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW1_WR_BASE,
|
||||
.shd = MI_RAW1_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW2_WR_BASE,
|
||||
.shd = MI_RAW2_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW3_WR_BASE,
|
||||
.shd = MI_RAW3_WR_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW0_RD_BASE,
|
||||
.shd = MI_RAW0_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW1_RD_BASE,
|
||||
.shd = MI_RAW1_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_RAW2_RD_BASE,
|
||||
.shd = MI_RAW2_RD_BASE_SHD,
|
||||
}, {
|
||||
.base = MI_GAIN_WR_BASE,
|
||||
.shd = MI_GAIN_WR_BASE_SHD,
|
||||
}
|
||||
};
|
||||
|
||||
reg_buf = kzalloc(RKISP_ISP_SW_REG_SIZE, GFP_KERNEL);
|
||||
if (!reg_buf)
|
||||
return -ENOMEM;
|
||||
u32 val;
|
||||
|
||||
dev_info(dev->dev, "%s enter\n", __func__);
|
||||
rkisp_hw_reg_save(dev->hw_dev);
|
||||
|
||||
memcpy_fromio(reg_buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
rkisp_soft_reset(dev->hw_dev, true);
|
||||
|
||||
/* process special reg */
|
||||
reg = reg_buf + ISP_CTRL;
|
||||
*reg &= ~(CIF_ISP_CTRL_ISP_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_INFORM_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_CFG_UPD);
|
||||
reg = reg_buf + MI_WR_INIT;
|
||||
*reg = 0;
|
||||
reg = reg_buf + CSI2RX_CTRL0;
|
||||
*reg &= ~SW_CSI2RX_EN;
|
||||
/* skip mmu range */
|
||||
memcpy_toio(base, reg_buf, ISP21_MI_BAY3D_RD_BASE_SHD);
|
||||
memcpy_toio(base + CSI2RX_CTRL0, reg_buf + CSI2RX_CTRL0,
|
||||
RKISP_ISP_SW_REG_SIZE - CSI2RX_CTRL0);
|
||||
/* config shd_reg to base_reg */
|
||||
for (i = 0; i < ARRAY_SIZE(backup); i++) {
|
||||
reg = reg_buf + backup[i].base;
|
||||
reg1 = reg_buf + backup[i].shd;
|
||||
backup[i].val = *reg;
|
||||
writel(*reg1, base + backup[i].base);
|
||||
}
|
||||
rkisp_hw_reg_restore(dev->hw_dev);
|
||||
|
||||
val = CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR;
|
||||
rkisp_unite_set_bits(dev, CIF_ISP_IMSC, 0, val, true);
|
||||
|
||||
/* clear state */
|
||||
dev->isp_err_cnt = 0;
|
||||
@@ -1254,40 +1192,12 @@ static int rkisp_reset_handle_v2x(struct rkisp_device *dev)
|
||||
rkisp_set_state(&dev->isp_state, ISP_FRAME_END);
|
||||
dev->hw_dev->monitor.state = ISP_FRAME_END;
|
||||
|
||||
/* update module */
|
||||
reg = reg_buf + DUAL_CROP_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL);
|
||||
reg = reg_buf + SELF_RESIZE_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL);
|
||||
reg = reg_buf + MAIN_RESIZE_CTRL;
|
||||
if (*reg & 0xf)
|
||||
writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL);
|
||||
|
||||
/* update mi and isp, base_reg will update to shd_reg */
|
||||
force_cfg_update(dev);
|
||||
reg = reg_buf + ISP_CTRL;
|
||||
*reg |= CIF_ISP_CTRL_ISP_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_INFORM_ENABLE |
|
||||
CIF_ISP_CTRL_ISP_CFG_UPD;
|
||||
writel(*reg, base + ISP_CTRL);
|
||||
udelay(50);
|
||||
/* config base_reg */
|
||||
for (i = 0; i < ARRAY_SIZE(backup); i++)
|
||||
writel(backup[i].val, base + backup[i].base);
|
||||
/* mpfbc base_reg = shd_reg, write is base but read is shd */
|
||||
if (dev->isp_ver == ISP_V20)
|
||||
writel(rkisp_read_reg_cache(dev, ISP_MPFBC_HEAD_PTR),
|
||||
base + ISP_MPFBC_HEAD_PTR);
|
||||
rkisp_set_bits(dev, CIF_ISP_IMSC, 0, CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR, true);
|
||||
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
|
||||
if (!dev->hw_dev->is_idle)
|
||||
rkisp_trigger_read_back(dev, 1, 0, true);
|
||||
else
|
||||
rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, NULL);
|
||||
}
|
||||
kfree(reg_buf);
|
||||
dev_info(dev->dev, "%s exit\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
@@ -1301,11 +1211,6 @@ static void rkisp_restart_monitor(struct work_struct *work)
|
||||
struct rkisp_pipeline *p;
|
||||
int ret, i, j, timeout = 5, mipi_irq_cnt = 0;
|
||||
|
||||
if (!monitor->reset_handle) {
|
||||
monitor->is_en = false;
|
||||
return;
|
||||
}
|
||||
|
||||
dev_info(hw->dev, "%s enter\n", __func__);
|
||||
while (!(monitor->state & ISP_STOP) && monitor->is_en) {
|
||||
ret = wait_for_completion_timeout(&monitor->cmpl,
|
||||
@@ -1363,7 +1268,7 @@ static void rkisp_restart_monitor(struct work_struct *work)
|
||||
|
||||
/* restart isp */
|
||||
isp = hw->isp[hw->cur_dev_id];
|
||||
ret = monitor->reset_handle(isp);
|
||||
ret = rkisp_reset_handle(isp);
|
||||
if (ret) {
|
||||
monitor->is_en = false;
|
||||
break;
|
||||
@@ -1400,9 +1305,6 @@ static void rkisp_monitor_init(struct rkisp_device *dev)
|
||||
struct rkisp_monitor *monitor = &dev->hw_dev->monitor;
|
||||
|
||||
monitor->dev = dev->hw_dev;
|
||||
monitor->reset_handle = NULL;
|
||||
if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21)
|
||||
monitor->reset_handle = rkisp_reset_handle_v2x;
|
||||
|
||||
init_completion(&monitor->cmpl);
|
||||
INIT_WORK(&monitor->work, rkisp_restart_monitor);
|
||||
@@ -3105,7 +3007,8 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
|
||||
|
||||
pool->dbufs = dbufs;
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs);
|
||||
"%s type:0x%x first:%d dbufs[%d]:%p", __func__,
|
||||
dbufs->type, dbufs->is_first, i, dbufs);
|
||||
|
||||
if (dbufs->is_resmem) {
|
||||
dma = dbufs->dma;
|
||||
@@ -3491,7 +3394,7 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
rkisp_get_info(isp_dev, arg);
|
||||
break;
|
||||
case RKISP_CMD_GET_TB_HEAD_V32:
|
||||
if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) {
|
||||
if (isp_dev->tb_head.complete != RKISP_TB_OK) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -3811,6 +3714,7 @@ int rkisp_register_isp_subdev(struct rkisp_device *isp_dev,
|
||||
atomic_set(&isp_sdev->frm_sync_seq, 0);
|
||||
rkisp_monitor_init(isp_dev);
|
||||
INIT_WORK(&isp_dev->rdbk_work, rkisp_rdbk_work);
|
||||
init_completion(&isp_dev->pm_cmpl);
|
||||
return 0;
|
||||
err_cleanup_media_entity:
|
||||
media_entity_cleanup(&sd->entity);
|
||||
@@ -3850,8 +3754,7 @@ void rkisp_unregister_isp_subdev(struct rkisp_device *isp_dev)
|
||||
(cond) ? 0 : -ETIMEDOUT; \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
|
||||
static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
|
||||
void rkisp_save_tb_info(struct rkisp_device *isp_dev)
|
||||
{
|
||||
struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
|
||||
void *resmem_va = phys_to_virt(isp_dev->resmem_pa);
|
||||
@@ -3871,7 +3774,8 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
|
||||
if (size && size < isp_dev->resmem_size) {
|
||||
dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset,
|
||||
size, DMA_FROM_DEVICE);
|
||||
params_vdev->is_first_cfg = true;
|
||||
if (isp_dev->is_rtt_first)
|
||||
params_vdev->is_first_cfg = true;
|
||||
if (isp_dev->isp_ver == ISP_V32) {
|
||||
struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
|
||||
|
||||
@@ -3883,7 +3787,7 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
|
||||
tmp->cfg.module_ens,
|
||||
tmp->cfg.module_cfg_update);
|
||||
}
|
||||
if (param)
|
||||
if (param && (isp_dev->isp_state & ISP_STOP))
|
||||
params_vdev->ops->save_first_param(params_vdev, param);
|
||||
} else if (size > isp_dev->resmem_size) {
|
||||
v4l2_err(&isp_dev->v4l2_dev,
|
||||
@@ -3894,6 +3798,7 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
|
||||
memcpy(&isp_dev->tb_head, head, sizeof(*head));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
|
||||
void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
|
||||
{
|
||||
struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
|
||||
@@ -3941,11 +3846,10 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
|
||||
end:
|
||||
head = &isp_dev->tb_head;
|
||||
v4l2_info(&isp_dev->v4l2_dev,
|
||||
"thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n",
|
||||
"tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d\n",
|
||||
head->enable,
|
||||
head->complete,
|
||||
head->frm_total,
|
||||
head->hdr_mode,
|
||||
head->width,
|
||||
head->height,
|
||||
head->camera_num,
|
||||
|
||||
@@ -153,6 +153,8 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev);
|
||||
static inline void rkisp_chk_tb_over(struct rkisp_device *isp_dev) {}
|
||||
#endif
|
||||
|
||||
void rkisp_save_tb_info(struct rkisp_device *isp_dev);
|
||||
|
||||
void rkisp_mipi_isr(unsigned int mipi_mis, struct rkisp_device *dev);
|
||||
|
||||
void rkisp_mipi_v13_isr(unsigned int err1, unsigned int err2,
|
||||
|
||||
@@ -334,7 +334,8 @@ int serdes_set_pinctrl_default(struct serdes *serdes);
|
||||
int serdes_set_pinctrl_sleep(struct serdes *serdes);
|
||||
int serdes_device_suspend(struct serdes *serdes);
|
||||
int serdes_device_resume(struct serdes *serdes);
|
||||
void serdes_device_shutdown(struct serdes *serdes);
|
||||
void serdes_device_poweroff(struct serdes *serdes);
|
||||
int serdes_device_shutdown(struct serdes *serdes);
|
||||
int serdes_irq_init(struct serdes *serdes);
|
||||
void serdes_irq_exit(struct serdes *serdes);
|
||||
void serdes_auxadc_init(struct serdes *serdes);
|
||||
|
||||
@@ -376,7 +376,7 @@ int serdes_device_resume(struct serdes *serdes)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serdes_device_resume);
|
||||
|
||||
void serdes_device_shutdown(struct serdes *serdes)
|
||||
void serdes_device_poweroff(struct serdes *serdes)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -385,6 +385,29 @@ void serdes_device_shutdown(struct serdes *serdes)
|
||||
if (ret)
|
||||
dev_err(serdes->dev, "could not set sleep pins\n");
|
||||
}
|
||||
|
||||
if (!IS_ERR(serdes->vpower)) {
|
||||
ret = regulator_disable(serdes->vpower);
|
||||
if (ret)
|
||||
dev_err(serdes->dev, "fail to disable vpower regulator\n");
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serdes_device_poweroff);
|
||||
|
||||
int serdes_device_shutdown(struct serdes *serdes)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_ERR(serdes->vpower)) {
|
||||
ret = regulator_disable(serdes->vpower);
|
||||
if (ret) {
|
||||
dev_err(serdes->dev, "fail to disable vpower regulator\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serdes_device_shutdown);
|
||||
|
||||
|
||||
@@ -223,6 +223,14 @@ static int serdes_i2c_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void serdes_i2c_shutdown(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct serdes *serdes = dev_get_drvdata(dev);
|
||||
|
||||
serdes_device_shutdown(serdes);
|
||||
}
|
||||
|
||||
static int serdes_i2c_prepare(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
@@ -264,7 +272,7 @@ static int serdes_i2c_poweroff(struct device *dev)
|
||||
{
|
||||
struct serdes *serdes = dev_get_drvdata(dev);
|
||||
|
||||
serdes_device_shutdown(serdes);
|
||||
serdes_device_poweroff(serdes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -315,6 +323,7 @@ static struct i2c_driver serdes_i2c_driver = {
|
||||
.of_match_table = of_match_ptr(serdes_of_match),
|
||||
},
|
||||
.probe = serdes_i2c_probe,
|
||||
.shutdown = serdes_i2c_shutdown,
|
||||
};
|
||||
|
||||
static int __init serdes_i2c_init(void)
|
||||
|
||||
@@ -8,18 +8,78 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
#ifdef BBT_DEBUG
|
||||
#define BBT_DBG pr_err
|
||||
#define bbt_dbg pr_err
|
||||
#else
|
||||
#define BBT_DBG(args...)
|
||||
#define bbt_dbg(args...)
|
||||
#endif
|
||||
|
||||
#define BBT_VERSION_INVALID (0xFFFFFFFFU)
|
||||
#define BBT_VERSION_BLOCK_ABNORMAL (BBT_VERSION_INVALID - 1)
|
||||
#define BBT_VERSION_MAX (BBT_VERSION_INVALID - 8)
|
||||
|
||||
struct nanddev_bbt_info {
|
||||
u8 pattern[4];
|
||||
unsigned int version;
|
||||
u32 hash;
|
||||
};
|
||||
|
||||
static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
|
||||
|
||||
#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
|
||||
static void bbt_dbg_hex(char *s, void *buf, u32 len)
|
||||
{
|
||||
print_hex_dump(KERN_WARNING, s, DUMP_PREFIX_OFFSET, 4, 4, buf, len, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 js_hash(u8 *buf, u32 len)
|
||||
{
|
||||
u32 hash = 0x47C6A7E6;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
hash ^= ((hash << 5) + buf[i] + (hash >> 2));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static bool bbt_check_hash(u8 *buf, u32 len, u32 hash_cmp)
|
||||
{
|
||||
u32 hash;
|
||||
|
||||
/* compatible with no-hash version */
|
||||
if (hash_cmp == 0 || hash_cmp == 0xFFFFFFFF)
|
||||
return 1;
|
||||
|
||||
hash = js_hash(buf, len);
|
||||
if (hash != hash_cmp)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 bbt_nand_isbad_bypass(struct nand_device *nand, u32 block)
|
||||
{
|
||||
struct mtd_info *mtd = nanddev_to_mtd(nand);
|
||||
struct nand_pos pos;
|
||||
|
||||
nanddev_bbt_set_block_status(nand, block, NAND_BBT_BLOCK_STATUS_UNKNOWN);
|
||||
nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
|
||||
|
||||
return nanddev_isbad(nand, &pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* nanddev_read_bbt() - Read the BBT (Bad Block Table)
|
||||
* @nand: NAND device
|
||||
* @block: bbt block address
|
||||
* @update: true - get version and overwrite bbt.cache with new version;
|
||||
* false - get bbt version only;
|
||||
*
|
||||
* Initialize the in-memory BBT.
|
||||
*
|
||||
* Return: 0 in case of success, a negative error code otherwise.
|
||||
*/
|
||||
static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update)
|
||||
{
|
||||
unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
|
||||
@@ -30,7 +90,7 @@ static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update)
|
||||
u8 *data_buf, *oob_buf;
|
||||
struct nanddev_bbt_info *bbt_info;
|
||||
struct mtd_oob_ops ops;
|
||||
int bbt_page_num;
|
||||
u32 bbt_page_num;
|
||||
int ret = 0;
|
||||
unsigned int version = 0;
|
||||
|
||||
@@ -40,7 +100,7 @@ static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update)
|
||||
if (block >= nblocks)
|
||||
return -EINVAL;
|
||||
|
||||
/* Aligned to page size, and even pages is better */
|
||||
/* aligned to page size, and even pages is better */
|
||||
bbt_page_num = (sizeof(struct nanddev_bbt_info) + nbytes +
|
||||
mtd->writesize - 1) >> (ffs(mtd->writesize) - 1);
|
||||
bbt_page_num = (bbt_page_num + 1) / 2 * 2;
|
||||
@@ -64,29 +124,72 @@ static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update)
|
||||
ops.ooblen = bbt_page_num * mtd->oobsize;
|
||||
ops.ooboffs = 0;
|
||||
|
||||
/* store one entry for each block */
|
||||
ret = mtd_read_oob(mtd, block * mtd->erasesize, &ops);
|
||||
if (ret && ret != -EUCLEAN) {
|
||||
pr_err("%s fail %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
pr_err("read_bbt blk=%d fail=%d update=%d\n", block, ret, update);
|
||||
ret = 0;
|
||||
version = BBT_VERSION_BLOCK_ABNORMAL;
|
||||
goto out;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (oob_buf[0] != 0xff && !memcmp(bbt_pattern, bbt_info->pattern, 4))
|
||||
version = bbt_info->version;
|
||||
/* bad block or good block without bbt */
|
||||
if (memcmp(bbt_pattern, bbt_info->pattern, 4)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
BBT_DBG("read_bbt from blk=%d tag=%d ver=%d\n", block, update, version);
|
||||
/* good block with abnornal bbt */
|
||||
if (oob_buf[0] == 0xff ||
|
||||
!bbt_check_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4, bbt_info->hash)) {
|
||||
pr_err("read_bbt check fail blk=%d ret=%d update=%d\n", block, ret, update);
|
||||
ret = 0;
|
||||
version = BBT_VERSION_BLOCK_ABNORMAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* good block with good bbt */
|
||||
version = bbt_info->version;
|
||||
bbt_dbg("read_bbt from blk=%d ver=%d update=%d\n", block, version, update);
|
||||
if (update && version > nand->bbt.version) {
|
||||
memcpy(nand->bbt.cache, data_buf, nbytes);
|
||||
nand->bbt.version = version;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(oob_buf);
|
||||
kfree(data_buf);
|
||||
#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
|
||||
bbt_dbg_hex("bbt", data_buf, nbytes + sizeof(struct nanddev_bbt_info));
|
||||
if (version) {
|
||||
u8 *temp_buf = kzalloc(bbt_page_num * mtd->writesize, GFP_KERNEL);
|
||||
bool in_scan = nand->bbt.option & NANDDEV_BBT_SCANNED;
|
||||
|
||||
return ret < 0 ? -EIO : version;
|
||||
if (!temp_buf)
|
||||
goto out;
|
||||
|
||||
memcpy(temp_buf, nand->bbt.cache, nbytes);
|
||||
memcpy(nand->bbt.cache, data_buf, nbytes);
|
||||
|
||||
if (!in_scan)
|
||||
nand->bbt.option |= NANDDEV_BBT_SCANNED;
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
ret = nanddev_bbt_get_block_status(nand, block);
|
||||
if (ret != NAND_BBT_BLOCK_GOOD)
|
||||
bbt_dbg("bad block[0x%x], ret=%d\n", block, ret);
|
||||
}
|
||||
if (!in_scan)
|
||||
nand->bbt.option &= ~NANDDEV_BBT_SCANNED;
|
||||
memcpy(nand->bbt.cache, temp_buf, nbytes);
|
||||
kfree(temp_buf);
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
|
||||
return ret < 0 ? -EIO : (int)version;
|
||||
}
|
||||
|
||||
static int nanddev_write_bbt(struct nand_device *nand, u32 block)
|
||||
@@ -99,18 +202,18 @@ static int nanddev_write_bbt(struct nand_device *nand, u32 block)
|
||||
u8 *data_buf, *oob_buf;
|
||||
struct nanddev_bbt_info *bbt_info;
|
||||
struct mtd_oob_ops ops;
|
||||
int bbt_page_num;
|
||||
int ret = 0;
|
||||
u32 bbt_page_num;
|
||||
int ret = 0, version;
|
||||
struct nand_pos pos;
|
||||
|
||||
BBT_DBG("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
|
||||
bbt_dbg("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
|
||||
if (!nand->bbt.cache)
|
||||
return -ENOMEM;
|
||||
|
||||
if (block >= nblocks)
|
||||
return -EINVAL;
|
||||
|
||||
/* Aligned to page size, and even pages is better */
|
||||
/* aligned to page size, and even pages is better */
|
||||
bbt_page_num = (sizeof(struct nanddev_bbt_info) + nbytes +
|
||||
mtd->writesize - 1) >> (ffs(mtd->writesize) - 1);
|
||||
bbt_page_num = (bbt_page_num + 1) / 2 * 2;
|
||||
@@ -130,7 +233,9 @@ static int nanddev_write_bbt(struct nand_device *nand, u32 block)
|
||||
memcpy(data_buf, nand->bbt.cache, nbytes);
|
||||
memcpy(bbt_info, bbt_pattern, 4);
|
||||
bbt_info->version = nand->bbt.version;
|
||||
bbt_info->hash = js_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4);
|
||||
|
||||
/* store one entry for each block */
|
||||
nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
|
||||
ret = nand->ops->erase(nand, &pos);
|
||||
if (ret)
|
||||
@@ -144,10 +249,23 @@ static int nanddev_write_bbt(struct nand_device *nand, u32 block)
|
||||
ops.ooblen = bbt_page_num * mtd->oobsize;
|
||||
ops.ooboffs = 0;
|
||||
ret = mtd_write_oob(mtd, block * mtd->erasesize, &ops);
|
||||
if (ret) {
|
||||
nand->ops->erase(nand, &pos);
|
||||
goto out;
|
||||
}
|
||||
|
||||
version = nanddev_read_bbt(nand, block, false);
|
||||
if (version != bbt_info->version) {
|
||||
pr_err("bbt_write fail, blk=%d recheck fail %d-%d\n",
|
||||
block, version, bbt_info->version);
|
||||
nand->ops->erase(nand, &pos);
|
||||
ret = -EIO;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
out:
|
||||
kfree(oob_buf);
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -158,14 +276,30 @@ static int nanddev_bbt_format(struct nand_device *nand)
|
||||
struct mtd_info *mtd = nanddev_to_mtd(nand);
|
||||
struct nand_pos pos;
|
||||
u32 start_block, block;
|
||||
unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
|
||||
unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
|
||||
BITS_PER_LONG);
|
||||
|
||||
start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
|
||||
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
|
||||
if (nanddev_isbad(nand, &pos))
|
||||
if (nanddev_isbad(nand, &pos)) {
|
||||
if (bbt_nand_isbad_bypass(nand, 0)) {
|
||||
memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
|
||||
pr_err("bbt_format fail, test good block %d fail\n", 0);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!bbt_nand_isbad_bypass(nand, block)) {
|
||||
memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
|
||||
pr_err("bbt_format fail, test bad block %d fail\n", block);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
nanddev_bbt_set_block_status(nand, block,
|
||||
NAND_BBT_BLOCK_FACTORY_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
@@ -197,16 +331,34 @@ int nanddev_scan_bbt_in_flash(struct nand_device *nand)
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++)
|
||||
nanddev_read_bbt(nand, start_block + block, true);
|
||||
|
||||
nand->bbt.option |= NANDDEV_BBT_SCANNED;
|
||||
if (nand->bbt.version == 0) {
|
||||
nanddev_bbt_format(nand);
|
||||
ret = nanddev_bbt_format(nand);
|
||||
if (ret) {
|
||||
nand->bbt.option = 0;
|
||||
pr_err("%s format fail\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
ret = nanddev_bbt_in_flash_update(nand);
|
||||
if (ret) {
|
||||
nand->bbt.option = 0;
|
||||
pr_err("%s fail\n", __func__);
|
||||
pr_err("%s update fail\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
nand->bbt.option |= NANDDEV_BBT_SCANNED;
|
||||
#if defined(BBT_DEBUG)
|
||||
pr_err("scan_bbt success\n");
|
||||
if (nand->bbt.version) {
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
ret = nanddev_bbt_get_block_status(nand, block);
|
||||
if (ret != NAND_BBT_BLOCK_GOOD)
|
||||
bbt_dbg("bad block[0x%x], ret=%d\n", block, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -222,31 +374,31 @@ EXPORT_SYMBOL_GPL(nanddev_scan_bbt_in_flash);
|
||||
*/
|
||||
int nanddev_bbt_in_flash_update(struct nand_device *nand)
|
||||
{
|
||||
struct nand_pos pos;
|
||||
struct mtd_info *mtd = nanddev_to_mtd(nand);
|
||||
|
||||
if (nand->bbt.option & NANDDEV_BBT_SCANNED) {
|
||||
unsigned int nblocks = nanddev_neraseblocks(nand);
|
||||
u32 bbt_version[NANDDEV_BBT_SCAN_MAXBLOCKS];
|
||||
int start_block, block;
|
||||
u32 min_version, block_des;
|
||||
int ret, count = 0;
|
||||
int ret, count = 0, status;
|
||||
|
||||
start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
ret = nanddev_bbt_get_block_status(nand, start_block + block);
|
||||
if (ret == NAND_BBT_BLOCK_FACTORY_BAD) {
|
||||
bbt_version[block] = 0xFFFFFFFF;
|
||||
continue;
|
||||
}
|
||||
ret = nanddev_read_bbt(nand, start_block + block,
|
||||
false);
|
||||
if (ret < 0)
|
||||
bbt_version[block] = 0xFFFFFFFF;
|
||||
else if (ret == 0)
|
||||
bbt_version[block] = 0;
|
||||
status = nanddev_bbt_get_block_status(nand, start_block + block);
|
||||
ret = nanddev_read_bbt(nand, start_block + block, false);
|
||||
if (ret == 0 && status == NAND_BBT_BLOCK_FACTORY_BAD)
|
||||
bbt_version[block] = BBT_VERSION_INVALID;
|
||||
else if (ret == -EIO)
|
||||
bbt_version[block] = BBT_VERSION_INVALID;
|
||||
else if (ret == BBT_VERSION_BLOCK_ABNORMAL)
|
||||
bbt_version[block] = ret;
|
||||
else
|
||||
bbt_version[block] = ret;
|
||||
}
|
||||
get_min_ver:
|
||||
min_version = 0xFFFFFFFF;
|
||||
min_version = BBT_VERSION_MAX;
|
||||
block_des = 0;
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
if (bbt_version[block] < min_version) {
|
||||
@@ -255,25 +407,38 @@ get_min_ver:
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite the BBT_VERSION_BLOCK_ABNORMAL block */
|
||||
if (nand->bbt.version < min_version)
|
||||
nand->bbt.version = min_version + 4;
|
||||
|
||||
if (block_des > 0) {
|
||||
nand->bbt.version++;
|
||||
ret = nanddev_write_bbt(nand, block_des);
|
||||
bbt_version[block_des - start_block] = 0xFFFFFFFF;
|
||||
if (ret) {
|
||||
pr_err("%s blk= %d ret= %d\n", __func__,
|
||||
block_des, ret);
|
||||
goto get_min_ver;
|
||||
} else {
|
||||
count++;
|
||||
if (count < 2)
|
||||
goto get_min_ver;
|
||||
BBT_DBG("%s success\n", __func__);
|
||||
}
|
||||
} else {
|
||||
pr_err("%s failed\n", __func__);
|
||||
pr_err("bbt_update fail, blk=%d ret= %d\n", block_des, ret);
|
||||
|
||||
return -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bbt_version[block_des - start_block] = BBT_VERSION_INVALID;
|
||||
count++;
|
||||
if (count < 2)
|
||||
goto get_min_ver;
|
||||
bbt_dbg("bbt_update success\n");
|
||||
} else {
|
||||
pr_err("bbt_update failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
if (bbt_version[block] == BBT_VERSION_BLOCK_ABNORMAL) {
|
||||
block_des = start_block + block;
|
||||
nanddev_offs_to_pos(nand, block_des * mtd->erasesize, &pos);
|
||||
nand->ops->erase(nand, &pos);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -21,13 +21,119 @@
|
||||
#define BBT_DBG(args...)
|
||||
#endif
|
||||
|
||||
#define BBT_VERSION_INVALID (0xFFFFFFFFU)
|
||||
#define BBT_VERSION_BLOCK_ABNORMAL (BBT_VERSION_INVALID - 1)
|
||||
#define BBT_VERSION_MAX (BBT_VERSION_INVALID - 8)
|
||||
struct nanddev_bbt_info {
|
||||
u8 pattern[4];
|
||||
unsigned int version;
|
||||
u32 hash;
|
||||
};
|
||||
|
||||
static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
|
||||
|
||||
#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
|
||||
static void bbt_dbg_hex(char *s, void *buf, u32 len)
|
||||
{
|
||||
print_hex_dump(KERN_WARNING, s, DUMP_PREFIX_OFFSET, 4, 4, buf, len, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 js_hash(u8 *buf, u32 len)
|
||||
{
|
||||
u32 hash = 0x47C6A7E6;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
hash ^= ((hash << 5) + buf[i] + (hash >> 2));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static bool bbt_check_hash(u8 *buf, u32 len, u32 hash_cmp)
|
||||
{
|
||||
u32 hash;
|
||||
|
||||
/* compatible with no-hash version */
|
||||
if (hash_cmp == 0 || hash_cmp == 0xFFFFFFFF)
|
||||
return 1;
|
||||
|
||||
hash = js_hash(buf, len);
|
||||
if (hash != hash_cmp)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 bbt_nand_isbad_bypass(struct snand_mtd_dev *nand, u32 block)
|
||||
{
|
||||
struct mtd_info *mtd = snanddev_to_mtd(nand);
|
||||
|
||||
return sfc_nand_isbad_mtd(mtd, block * mtd->erasesize);
|
||||
}
|
||||
|
||||
static int bbt_mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
|
||||
{
|
||||
int i, ret = 0, bbt_page_num, page_addr, block;
|
||||
u8 *temp_buf;
|
||||
|
||||
bbt_page_num = ops->len >> mtd->writesize_shift;
|
||||
block = from >> mtd->erasesize_shift;
|
||||
|
||||
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
|
||||
if (!temp_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
|
||||
for (i = 0; i < bbt_page_num; i++) {
|
||||
ret = sfc_nand_read_page_raw(0, page_addr + i, (u32 *)temp_buf);
|
||||
if (ret < 0) {
|
||||
pr_err("%s fail %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(ops->datbuf + i * mtd->writesize, temp_buf, mtd->writesize);
|
||||
memcpy(ops->oobbuf + i * mtd->oobsize, temp_buf + mtd->writesize, mtd->oobsize);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(temp_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bbt_mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
|
||||
{
|
||||
int i, ret = 0, bbt_page_num, page_addr, block;
|
||||
u8 *temp_buf;
|
||||
|
||||
bbt_page_num = ops->len >> mtd->writesize_shift;
|
||||
block = to >> mtd->erasesize_shift;
|
||||
|
||||
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
|
||||
if (!temp_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
|
||||
for (i = 0; i < bbt_page_num; i++) {
|
||||
memcpy(temp_buf, ops->datbuf + i * mtd->writesize, mtd->writesize);
|
||||
memcpy(temp_buf + mtd->writesize, ops->oobbuf + i * mtd->oobsize, mtd->oobsize);
|
||||
|
||||
ret = sfc_nand_prog_page_raw(0, page_addr + i, (u32 *)temp_buf);
|
||||
if (ret < 0) {
|
||||
pr_err("%s fail %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(temp_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nanddev_read_bbt() - Read the BBT (Bad Block Table)
|
||||
* @nand: NAND device
|
||||
@@ -37,7 +143,7 @@ static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
|
||||
*
|
||||
* Initialize the in-memory BBT.
|
||||
*
|
||||
* Return: 0 in case of success, a negative error code otherwise.
|
||||
* Return: positive value means success, 0 means abnornal data, a negative error code otherwise.
|
||||
*/
|
||||
static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
|
||||
{
|
||||
@@ -46,13 +152,12 @@ static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
|
||||
unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
|
||||
BITS_PER_LONG) * sizeof(*nand->bbt.cache);
|
||||
struct mtd_info *mtd = snanddev_to_mtd(nand);
|
||||
u8 *data_buf, *oob_buf, *temp_buf;
|
||||
u8 *data_buf, *oob_buf;
|
||||
struct nanddev_bbt_info *bbt_info;
|
||||
struct mtd_oob_ops ops;
|
||||
u32 bbt_page_num;
|
||||
int ret = 0;
|
||||
unsigned int version = 0;
|
||||
u32 page_addr, i;
|
||||
|
||||
if (!nand->bbt.cache)
|
||||
return -ENOMEM;
|
||||
@@ -85,37 +190,65 @@ static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
|
||||
ops.ooboffs = 0;
|
||||
|
||||
/* Store one entry for each block */
|
||||
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
|
||||
if (!temp_buf) {
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
|
||||
return -ENOMEM;
|
||||
ret = bbt_mtd_read_oob(mtd, block * mtd->erasesize, &ops);
|
||||
if (ret && ret != -EUCLEAN) {
|
||||
pr_err("read_bbt blk=%d fail=%d update=%d\n", block, ret, update);
|
||||
ret = 0;
|
||||
version = BBT_VERSION_BLOCK_ABNORMAL;
|
||||
goto out;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
|
||||
for (i = 0; i < bbt_page_num; i++) {
|
||||
ret = sfc_nand_read_page_raw(0, page_addr + i, (u32 *)temp_buf);
|
||||
if (ret < 0) {
|
||||
pr_err("%s fail %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
kfree(temp_buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(ops.datbuf + i * mtd->writesize, temp_buf, mtd->writesize);
|
||||
memcpy(ops.oobbuf + i * mtd->oobsize, temp_buf + mtd->writesize, mtd->oobsize);
|
||||
/* bad block or good block without bbt */
|
||||
if (memcmp(bbt_pattern, bbt_info->pattern, 4)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
kfree(temp_buf);
|
||||
|
||||
if (oob_buf[0] != 0xff && !memcmp(bbt_pattern, bbt_info->pattern, 4))
|
||||
version = bbt_info->version;
|
||||
/* good block with abnornal bbt */
|
||||
if (oob_buf[0] == 0xff ||
|
||||
!bbt_check_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4, bbt_info->hash)) {
|
||||
pr_err("read_bbt check fail blk=%d ret=%d update=%d\n", block, ret, update);
|
||||
ret = 0;
|
||||
version = BBT_VERSION_BLOCK_ABNORMAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
BBT_DBG("read_bbt from blk=%d tag=%d ver=%d\n", block, update, version);
|
||||
/* good block with good bbt */
|
||||
version = bbt_info->version;
|
||||
BBT_DBG("read_bbt from blk=%d ver=%d update=%d\n", block, version, update);
|
||||
if (update && version > nand->bbt.version) {
|
||||
memcpy(nand->bbt.cache, data_buf, nbytes);
|
||||
nand->bbt.version = version;
|
||||
}
|
||||
|
||||
#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
|
||||
bbt_dbg_hex("bbt", data_buf, nbytes + sizeof(struct nanddev_bbt_info));
|
||||
if (version) {
|
||||
u8 *temp_buf = kzalloc(bbt_page_num * mtd->writesize, GFP_KERNEL);
|
||||
bool in_scan = nand->bbt.option & NANDDEV_BBT_SCANNED;
|
||||
|
||||
if (!temp_buf)
|
||||
goto out;
|
||||
|
||||
memcpy(temp_buf, nand->bbt.cache, nbytes);
|
||||
memcpy(nand->bbt.cache, data_buf, nbytes);
|
||||
|
||||
if (!in_scan)
|
||||
nand->bbt.option |= NANDDEV_BBT_SCANNED;
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
ret = snanddev_bbt_get_block_status(nand, block);
|
||||
if (ret != NAND_BBT_BLOCK_GOOD)
|
||||
BBT_DBG("bad block[0x%x], ret=%d\n", block, ret);
|
||||
}
|
||||
if (!in_scan)
|
||||
nand->bbt.option &= ~NANDDEV_BBT_SCANNED;
|
||||
memcpy(nand->bbt.cache, temp_buf, nbytes);
|
||||
kfree(temp_buf);
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
@@ -130,12 +263,11 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
|
||||
unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
|
||||
BITS_PER_LONG) * sizeof(*nand->bbt.cache);
|
||||
struct mtd_info *mtd = snanddev_to_mtd(nand);
|
||||
u8 *data_buf, *oob_buf, *temp_buf;
|
||||
u8 *data_buf, *oob_buf;
|
||||
struct nanddev_bbt_info *bbt_info;
|
||||
struct mtd_oob_ops ops;
|
||||
u32 bbt_page_num;
|
||||
int ret = 0;
|
||||
u32 page_addr, i;
|
||||
int ret = 0, version;
|
||||
|
||||
BBT_DBG("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
|
||||
if (!nand->bbt.cache)
|
||||
@@ -164,6 +296,7 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
|
||||
memcpy(data_buf, nand->bbt.cache, nbytes);
|
||||
memcpy(bbt_info, bbt_pattern, 4);
|
||||
bbt_info->version = nand->bbt.version;
|
||||
bbt_info->hash = js_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4);
|
||||
|
||||
/* Store one entry for each block */
|
||||
ret = sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
|
||||
@@ -171,34 +304,27 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
|
||||
goto out;
|
||||
|
||||
memset(&ops, 0, sizeof(struct mtd_oob_ops));
|
||||
ops.mode = MTD_OPS_PLACE_OOB;
|
||||
ops.datbuf = data_buf;
|
||||
ops.len = bbt_page_num * mtd->writesize;
|
||||
ops.oobbuf = oob_buf;
|
||||
ops.ooblen = bbt_page_num * mtd->oobsize;
|
||||
ops.ooboffs = 0;
|
||||
|
||||
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
|
||||
if (!temp_buf) {
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
|
||||
return -ENOMEM;
|
||||
ret = bbt_mtd_write_oob(mtd, block * mtd->erasesize, &ops);
|
||||
if (ret) {
|
||||
sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
|
||||
goto out;
|
||||
}
|
||||
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
|
||||
for (i = 0; i < bbt_page_num; i++) {
|
||||
memcpy(temp_buf, ops.datbuf + i * mtd->writesize, mtd->writesize);
|
||||
memcpy(temp_buf + mtd->writesize, ops.oobbuf + i * mtd->oobsize, mtd->oobsize);
|
||||
|
||||
ret = sfc_nand_prog_page_raw(0, page_addr + i, (u32 *)temp_buf);
|
||||
if (ret < 0) {
|
||||
pr_err("%s fail %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
kfree(temp_buf);
|
||||
goto out;
|
||||
}
|
||||
version = nanddev_read_bbt(nand, block, false);
|
||||
if (version != bbt_info->version) {
|
||||
pr_err("bbt_write fail, blk=%d recheck fail %d-%d\n",
|
||||
block, version, bbt_info->version);
|
||||
sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
|
||||
ret = -EIO;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
kfree(temp_buf);
|
||||
|
||||
out:
|
||||
kfree(data_buf);
|
||||
kfree(oob_buf);
|
||||
@@ -211,13 +337,29 @@ static int nanddev_bbt_format(struct snand_mtd_dev *nand)
|
||||
unsigned int nblocks = snanddev_neraseblocks(nand);
|
||||
struct mtd_info *mtd = snanddev_to_mtd(nand);
|
||||
u32 start_block, block;
|
||||
unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
|
||||
unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
|
||||
BITS_PER_LONG);
|
||||
|
||||
start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
|
||||
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
if (sfc_nand_isbad_mtd(mtd, block * mtd->erasesize))
|
||||
if (sfc_nand_isbad_mtd(mtd, block * mtd->erasesize)) {
|
||||
if (bbt_nand_isbad_bypass(nand, 0)) {
|
||||
memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
|
||||
pr_err("bbt_format fail, test good block %d fail\n", 0);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!bbt_nand_isbad_bypass(nand, block)) {
|
||||
memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
|
||||
pr_err("bbt_format fail, test bad block %d fail\n", block);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
snanddev_bbt_set_block_status(nand, block,
|
||||
NAND_BBT_BLOCK_FACTORY_BAD);
|
||||
NAND_BBT_BLOCK_FACTORY_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
@@ -243,14 +385,34 @@ static int nanddev_scan_bbt(struct snand_mtd_dev *nand)
|
||||
|
||||
nand->bbt.option |= NANDDEV_BBT_SCANNED;
|
||||
if (nand->bbt.version == 0) {
|
||||
nanddev_bbt_format(nand);
|
||||
ret = nanddev_bbt_format(nand);
|
||||
if (ret) {
|
||||
nand->bbt.option = 0;
|
||||
pr_err("%s format fail\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snanddev_bbt_update(nand);
|
||||
if (ret) {
|
||||
nand->bbt.option = 0;
|
||||
pr_err("%s fail\n", __func__);
|
||||
pr_err("%s update fail\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BBT_DEBUG)
|
||||
pr_err("scan_bbt success\n");
|
||||
if (nand->bbt.version) {
|
||||
for (block = 0; block < nblocks; block++) {
|
||||
ret = snanddev_bbt_get_block_status(nand, block);
|
||||
if (ret != NAND_BBT_BLOCK_GOOD)
|
||||
BBT_DBG("bad block[0x%x], ret=%d\n", block, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -304,32 +466,32 @@ EXPORT_SYMBOL_GPL(snanddev_bbt_cleanup);
|
||||
int snanddev_bbt_update(struct snand_mtd_dev *nand)
|
||||
{
|
||||
#ifdef CONFIG_MTD_NAND_BBT_USING_FLASH
|
||||
struct mtd_info *mtd = snanddev_to_mtd(nand);
|
||||
|
||||
if (nand->bbt.cache &&
|
||||
nand->bbt.option & NANDDEV_BBT_USE_FLASH) {
|
||||
unsigned int nblocks = snanddev_neraseblocks(nand);
|
||||
u32 bbt_version[NANDDEV_BBT_SCAN_MAXBLOCKS];
|
||||
int start_block, block;
|
||||
u32 min_version, block_des;
|
||||
int ret, count = 0;
|
||||
int ret, count = 0, status;
|
||||
|
||||
start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
ret = snanddev_bbt_get_block_status(nand, start_block + block);
|
||||
if (ret == NAND_BBT_BLOCK_FACTORY_BAD) {
|
||||
bbt_version[block] = 0xFFFFFFFF;
|
||||
continue;
|
||||
}
|
||||
ret = nanddev_read_bbt(nand, start_block + block,
|
||||
false);
|
||||
if (ret < 0)
|
||||
bbt_version[block] = 0xFFFFFFFF;
|
||||
else if (ret == 0)
|
||||
bbt_version[block] = 0;
|
||||
status = snanddev_bbt_get_block_status(nand, start_block + block);
|
||||
ret = nanddev_read_bbt(nand, start_block + block, false);
|
||||
|
||||
if (ret == 0 && status == NAND_BBT_BLOCK_FACTORY_BAD)
|
||||
bbt_version[block] = BBT_VERSION_INVALID;
|
||||
else if (ret == -EIO)
|
||||
bbt_version[block] = BBT_VERSION_INVALID;
|
||||
else if (ret == BBT_VERSION_BLOCK_ABNORMAL)
|
||||
bbt_version[block] = ret;
|
||||
else
|
||||
bbt_version[block] = ret;
|
||||
}
|
||||
get_min_ver:
|
||||
min_version = 0xFFFFFFFF;
|
||||
min_version = BBT_VERSION_MAX;
|
||||
block_des = 0;
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
if (bbt_version[block] < min_version) {
|
||||
@@ -338,25 +500,37 @@ get_min_ver:
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite the BBT_VERSION_BLOCK_ABNORMAL block */
|
||||
if (nand->bbt.version < min_version)
|
||||
nand->bbt.version = min_version + 4;
|
||||
|
||||
if (block_des > 0) {
|
||||
nand->bbt.version++;
|
||||
ret = nanddev_write_bbt(nand, block_des);
|
||||
bbt_version[block_des - start_block] = 0xFFFFFFFF;
|
||||
if (ret) {
|
||||
pr_err("%s blk= %d ret= %d\n", __func__,
|
||||
block_des, ret);
|
||||
goto get_min_ver;
|
||||
} else {
|
||||
count++;
|
||||
if (count < 2)
|
||||
goto get_min_ver;
|
||||
BBT_DBG("%s success\n", __func__);
|
||||
}
|
||||
} else {
|
||||
pr_err("%s failed\n", __func__);
|
||||
pr_err("bbt_update fail, blk=%d ret= %d\n", block_des, ret);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bbt_version[block_des - start_block] = BBT_VERSION_INVALID;
|
||||
count++;
|
||||
if (count < 2)
|
||||
goto get_min_ver;
|
||||
BBT_DBG("bbt_update success\n");
|
||||
} else {
|
||||
pr_err("bbt_update failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
|
||||
if (bbt_version[block] == BBT_VERSION_BLOCK_ABNORMAL) {
|
||||
block_des = start_block + block;
|
||||
sfc_nand_erase_mtd(mtd, block_des * mtd->erasesize);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -168,6 +168,8 @@ static void md_update_ss_toc(const struct md_region *entry)
|
||||
shdr->sh_flags = SHF_WRITE;
|
||||
shdr->sh_offset = minidump_elfheader.elf_offset;
|
||||
shdr->sh_entsize = 0;
|
||||
shdr->sh_addralign = shdr->sh_addr; /* backup */
|
||||
shdr->sh_entsize = entry->phys_addr; /* backup */
|
||||
|
||||
if (strstr((const char *)mdr->name, "note"))
|
||||
phdr->p_type = PT_NOTE;
|
||||
@@ -178,6 +180,7 @@ static void md_update_ss_toc(const struct md_region *entry)
|
||||
phdr->p_paddr = entry->phys_addr;
|
||||
phdr->p_filesz = phdr->p_memsz = mdr->region_size;
|
||||
phdr->p_flags = PF_R | PF_W;
|
||||
phdr->p_align = phdr->p_paddr; /* backup */
|
||||
minidump_elfheader.elf_offset += shdr->sh_size;
|
||||
mdr->md_valid = MD_REGION_VALID;
|
||||
minidump_table.md_ss_toc->ss_region_count++;
|
||||
@@ -274,8 +277,11 @@ int rk_minidump_update_region(int regno, const struct md_region *entry)
|
||||
phdr = elf_program(hdr, regno + 1);
|
||||
|
||||
shdr->sh_addr = (elf_addr_t)entry->virt_addr;
|
||||
shdr->sh_addralign = shdr->sh_addr; /* backup */
|
||||
shdr->sh_entsize = entry->phys_addr; /* backup */
|
||||
phdr->p_vaddr = entry->virt_addr;
|
||||
phdr->p_paddr = entry->phys_addr;
|
||||
phdr->p_align = phdr->p_paddr; /* backup */
|
||||
|
||||
err_unlock:
|
||||
read_unlock_irqrestore(&mdt_remove_lock, flags);
|
||||
@@ -675,6 +681,8 @@ static int rk_minidump_driver_probe(struct platform_device *pdev)
|
||||
phdr = (Elf64_Phdr *)(md_elf_mem + (ulong)ehdr->e_phoff);
|
||||
phdr += ehdr->e_phnum - 1;
|
||||
md_elf_size = phdr->p_memsz + phdr->p_offset;
|
||||
if (md_elf_size > r_size)
|
||||
md_elf_size = r_size;
|
||||
pr_info("Create /proc/rk_md/minidump, size:0x%llx...\n", md_elf_size);
|
||||
proc_rk_minidump = proc_create("minidump", 0400, base_dir, &rk_minidump_proc_ops);
|
||||
} else {
|
||||
|
||||
@@ -217,6 +217,10 @@ static int ohci_platform_probe(struct platform_device *dev)
|
||||
|
||||
device_wakeup_enable(hcd->self.controller);
|
||||
|
||||
if (of_device_is_compatible(dev->dev.of_node,
|
||||
"rockchip,rk3588-ohci"))
|
||||
device_enable_async_suspend(hcd->self.controller);
|
||||
|
||||
platform_set_drvdata(dev, hcd);
|
||||
|
||||
return err;
|
||||
|
||||
@@ -22,5 +22,7 @@
|
||||
#define BOOT_UMS (REBOOT_FLAG + 12)
|
||||
/* reboot system quiescent */
|
||||
#define BOOT_QUIESCENT (REBOOT_FLAG + 14)
|
||||
/* reboot by panic and capture ramdump in uboot through usb */
|
||||
#define BOOT_WINUSB (REBOOT_FLAG + 15)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1968,6 +1968,12 @@ struct rkisp_isp2x_luma_buffer {
|
||||
struct rkisp_mipi_luma luma[ISP2X_MIPI_RAW_MAX];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum {
|
||||
RKISP_RTT_MODE_NORMAL = 0,
|
||||
RKISP_RTT_MODE_MULTI_FRAME,
|
||||
RKISP_RTT_MODE_ONE_FRAME,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rkisp_thunderboot_resmem_head
|
||||
*/
|
||||
@@ -1976,10 +1982,12 @@ struct rkisp_thunderboot_resmem_head {
|
||||
__u16 complete;
|
||||
__u16 frm_total;
|
||||
__u16 hdr_mode;
|
||||
__u16 rtt_mode;
|
||||
__u16 width;
|
||||
__u16 height;
|
||||
__u16 camera_num;
|
||||
__u16 camera_index;
|
||||
__u16 md_flag;
|
||||
|
||||
__u32 exp_time[3];
|
||||
__u32 exp_gain[3];
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#define ISP32_MODULE_CSM ISP3X_MODULE_CSM
|
||||
#define ISP32_MODULE_CGC ISP3X_MODULE_CGC
|
||||
#define ISP32_MODULE_VSM BIT_ULL(45)
|
||||
|
||||
#define ISP32_MODULE_RTT_FST BIT_ULL(62)
|
||||
#define ISP32_MODULE_FORCE ISP3X_MODULE_FORCE
|
||||
|
||||
/* Measurement types */
|
||||
@@ -70,6 +70,7 @@
|
||||
#define ISP32_STAT_DHAZ ISP3X_STAT_DHAZ
|
||||
#define ISP32_STAT_VSM BIT(18)
|
||||
#define ISP32_STAT_INFO2DDR BIT(19)
|
||||
#define ISP32_STAT_RTT_FST BIT(31)
|
||||
|
||||
#define ISP32_MESH_BUF_NUM ISP3X_MESH_BUF_NUM
|
||||
|
||||
|
||||
Reference in New Issue
Block a user