* commit 'bc95e6862a':
  media: i2c: mis4001 driver update version 0.01.02
  arm64: dts: rockchip: rk3562: Add csu-clocks for vop
  drm/rockchip: vop2: Add csu clock support for rk3562
  arm64: dts: rockchip: rk3562: Add rockchip,csu for gmac
  ethernet: stmmac: dwmac-rk: Add csu clock support
  arm64: dts: rockchip: rk3562: Add csu device node
  Revert "arm64: dts: rockchip: rk3562-rk817-tablet-v10: Change clkin div to 5 for aclk vo"
  Revert "arm64: dts: rockchip: rk3562-evb1-lp4x-v10: Change clkin div to 5 for aclk vo"
  arm64: configs: rockchip_linux_defconfig: Enable CONFIG_ROCKCHIP_CSU
  arm64: configs: rockchip_defconfig: Enable CONFIG_ROCKCHIP_CSU
  soc: rockchip: Add clock subunit driver
  arm64: dts: rockchip: px30: add pwm irq configs
  PCI: rockchip: dw: Reserve msi_data in obj_info
  misc: rockchip: pcie-rkep: Support mmap bar resource and rw config space
  misc: rockchip: pcie-rkep: Adding more mmap resources
  media: rockchip: isp: fix wnd_num cause array access out of bounds
  mfd: rk806: Add RK806 support i2c
  PCI: rockchip: dw: Validate phy mode in suspend
  phy: rockchip: naneng-combphy: Add phy_validate support
  arm64: dts: rockchip: add lvds demo dts for rk3567/rk3568

Change-Id: I610c43a60826e361c65a6e1d4fa23da6a56653fa
This commit is contained in:
Tao Huang 2023-12-01 20:43:53 +08:00
commit fa453b17a5
39 changed files with 2060 additions and 529 deletions

View file

@ -152,14 +152,18 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-rkg11.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-single-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-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-one-vp-two-single-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-one-vp-two-single-channel-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
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-single-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb4-lp3-v10.dtb

View file

@ -1048,6 +1048,7 @@
pwm0: pwm@ff200000 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff200000 0x0 0x10>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1059,6 +1060,7 @@
pwm1: pwm@ff200010 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff200010 0x0 0x10>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1070,6 +1072,7 @@
pwm2: pwm@ff200020 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff200020 0x0 0x10>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1081,6 +1084,8 @@
pwm3: pwm@ff200030 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff200030 0x0 0x10>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1092,6 +1097,7 @@
pwm4: pwm@ff208000 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff208000 0x0 0x10>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1103,6 +1109,7 @@
pwm5: pwm@ff208010 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff208010 0x0 0x10>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1114,6 +1121,7 @@
pwm6: pwm@ff208020 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff208020 0x0 0x10>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@ -1125,6 +1133,8 @@
pwm7: pwm@ff208030 {
compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff208030 0x0 0x10>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";

View file

@ -179,18 +179,6 @@
};
};
&bus_soc {
rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
<1 0x00a000a8 0x7c39>,
<2 0x00a000a8 0x7c39>,
<3 0x00a000a8 0x7c39>,
<4 0x00a000a5 0xb007>,
<5 0x00a000a8 0x7034>,
<6 0x00a000a8 0x7034>,
<7 0x00a000a8 0x7034>,
<8 0x00a000a8 0x7001>;
};
&gmac0 {
/* Use rgmii-rxid mode to disable rx delay inside Soc */
phy-mode = "rgmii-rxid";

View file

@ -209,18 +209,6 @@
cpu-supply = <&vdd_cpu>;
};
&bus_soc {
rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
<1 0x00a000a8 0x7c39>,
<2 0x00a000a8 0x7c39>,
<3 0x00a000a8 0x7c39>,
<4 0x00a000a5 0xb007>,
<5 0x00a000a8 0x7034>,
<6 0x00a000a8 0x7034>,
<7 0x00a000a8 0x7034>,
<8 0x00a000a8 0x7001>;
};
&dfi {
status = "okay";
};

View file

@ -9,6 +9,7 @@
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/power/rk3562-power.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/soc/rockchip-csu.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
#include <dt-bindings/soc/rockchip-system-status.h>
#include <dt-bindings/suspend/rockchip-rk3562.h>
@ -361,20 +362,6 @@
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
};
bus_soc: bus-soc {
compatible = "rockchip,rk3562-bus";
rockchip,busfreq-policy = "smc";
rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
<1 0x00a000a8 0x7c39>,
<2 0x00a000a8 0x7c39>,
<3 0x00a000a8 0x7c39>,
<4 0x00a000a4 0xb007>,
<5 0x00a000a8 0x7034>,
<6 0x00a000a8 0x7034>,
<7 0x00a000a8 0x7034>,
<8 0x00a000a8 0x7001>;
};
cpuinfo {
compatible = "rockchip,cpuinfo";
nvmem-cells = <&otp_id>, <&otp_cpu_version>, <&cpu_code>;
@ -423,6 +410,23 @@
status = "disabled";
};
csu: csu {
compatible = "rockchip,rk3562-csu";
rockchip,clock = <CSU_GMAC_ACLK 1>,
<CSU_GMAC_PCLK 3>,
<CSU_VOP_ACLK 4>,
<CSU_MCU_CLK 2>;
rockchip,bus = <0 0x00a000a8 0x7001>,
<1 0x00a000a8 0x7c39>,
<2 0x00a000a8 0x7c39>,
<3 0x00a000a8 0x7c39>,
<4 0x00a000a4 0xb007>,
<5 0x00a000a8 0x7034>,
<6 0x00a000a8 0x7034>,
<7 0x00a000a8 0x7034>,
<8 0x00a000a8 0x7001>;
};
display_subsystem: display-subsystem {
compatible = "rockchip,display-subsystem";
ports = <&vop_out>;
@ -1896,6 +1900,8 @@
reset-names = "axi",
"ahb",
"dclk_vp0";
rockchip,csu = <&csu CSU_VOP_ACLK>;
rockchip,csu-names = "aclk";
iommus = <&vop_mmu>;
power-domains = <&power RK3562_PD_VO>;
rockchip,grf = <&ioc_grf>;
@ -2837,6 +2843,8 @@
"pclk_mac", "aclk_mac";
resets = <&cru SRST_A_GMAC>;
reset-names = "stmmaceth";
rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>;
rockchip,csu-names = "aclk", "pclk";
snps,mixed-burst;
snps,tso;
@ -2955,6 +2963,8 @@
"pclk_mac", "aclk_mac";
resets = <&cru SRST_A_MAC100>;
reset-names = "stmmaceth";
rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>;
rockchip,csu-names = "aclk", "pclk";
status = "disabled";
mdio1: mdio {

View file

@ -70,68 +70,14 @@
};
};
&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 {
&backlight1 {
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";
};
@ -152,10 +98,52 @@
status = "disabled";
};
&rgb_in_vp2 {
&hdmi_in_vp1 {
status = "okay";
};
&lvds0 {
status = "okay";
dual-channel;
ports {
port@1 {
reg = <1>;
lvds0_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds0>;
};
};
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds1_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds1>;
};
};
};
};
&lvds1_in_vp1 {
status = "okay";
};
&lvds1_in_vp2 {
status = "disabled";
};
&rgb_in_vp2 {
status = "disabled";
};
&vcc3v3_lcd0_n {
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@ -166,3 +154,11 @@
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -13,8 +13,8 @@
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3567 EVB2 LP4X V10 Board";
compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
model = "Rockchip RK3567 EVB2 LP4X V10 Board with one vp two single channel lvds";
compatible = "rockchip,rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds", "rockchip,rk3567";
/* panel: claa070wp03xg */
panel {
@ -34,7 +34,7 @@
timing0: timing0 {
clock-frequency = <134000000>;
hactive = <1600>;
hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
@ -75,15 +75,39 @@
};
};
&backlight1 {
status = "okay";
};
&backlight {
status = "okay";
};
&lvds {
&backlight1 {
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";
};
&lvds0 {
status = "okay";
dual-channel;
@ -110,50 +134,15 @@
};
};
&lvds_in_vp1 {
&lvds0_in_vp1 {
status = "okay";
};
&lvds1_in_vp1 {
status = "disabled";
status = "okay";
};
&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";
};
@ -161,7 +150,6 @@
status = "disabled";
};
&vcc3v3_lcd0_n {
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
enable-active-high;
@ -171,3 +159,11 @@
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -0,0 +1,136 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3567-evb2-lp4x-v10.dtsi"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3567 EVB2 LP4X V10 Board with single channel lvds";
compatible = "rockchip,rk3567-evb2-lp4x-v10-single-channel-lvds", "rockchip,rk3567";
/* panel: claa070wp03xg */
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 = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds0: endpoint {
remote-endpoint = <&lvds0_out_panel>;
};
};
};
};
};
&backlight {
status = "okay";
};
&backlight1 {
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";
};
&lvds0 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds0_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds0>;
};
};
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
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;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -0,0 +1,201 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3567-evb2-lp4x-v10.dtsi"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3567 EVB2 LP4X V10 Board with two vp two separate single channel lvds";
compatible = "rockchip,rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3567";
/**
* VP1 -> LVDS0 -> Panel0
* VP2 -> LVDS1 -> Panel1
*/
/* panel: claa070wp03xg */
panel-lvds0 {
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 = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds0: endpoint {
remote-endpoint = <&lvds0_out_panel>;
};
};
};
};
/* panel: claa070wp03xg */
panel-lvds1 {
compatible = "simple-panel";
backlight = <&backlight1>;
power-supply = <&vcc3v3_lcd1_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 = <&timing1>;
timing1: timing1 {
clock-frequency = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds1: endpoint {
remote-endpoint = <&lvds1_out_panel>;
};
};
};
};
};
&backlight {
status = "okay";
};
&backlight1 {
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";
};
&lvds0 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds0_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds0>;
};
};
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds1_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds1>;
};
};
};
};
&lvds1_in_vp1 {
status = "disabled";
};
&lvds1_in_vp2 {
status = "okay";
};
&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;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -1,14 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3568 EVB1 V10 Board with Dual LVDS";
compatible = "rockchip,rk3568-evb1-ddr4-v10-dual-lvds", "rockchip,rk3568";
};

View file

@ -6,12 +6,12 @@
/dts-v1/;
#include <dt-bindings/display/rockchip_vop.h>
#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi"
#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-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";
model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds";
compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568";
};
&vp0 {

View file

@ -0,0 +1,14 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds";
compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568";
};

View file

@ -27,7 +27,7 @@
timing0: timing0 {
clock-frequency = <134000000>;
hactive = <1600>;
hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
@ -68,11 +68,11 @@
};
};
&backlight1 {
&backlight {
status = "okay";
};
&backlight {
&backlight1 {
status = "okay";
};
@ -100,7 +100,7 @@
status = "okay";
};
&lvds {
&lvds0 {
status = "okay";
dual-channel;
@ -114,6 +114,10 @@
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
status = "okay";
@ -127,30 +131,18 @@
};
};
&lvds_in_vp1 {
status = "okay";
};
&lvds1_in_vp1 {
status = "disabled";
status = "okay";
};
&lvds1_in_vp2 {
status = "okay";
status = "disabled";
};
&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;
@ -160,3 +152,11 @@
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -0,0 +1,133 @@
// 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"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3568 EVB1 V10 Board with single channel lvds";
compatible = "rockchip,rk3568-evb1-ddr4-v10-single-channel-lvds", "rockchip,rk3568";
/* panel: claa070wp03xg */
panel-lvds0 {
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 = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds0: endpoint {
remote-endpoint = <&lvds0_out_panel>;
};
};
};
};
};
&backlight {
status = "okay";
};
&backlight1 {
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";
};
&lvds0 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds0_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds0>;
};
};
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
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;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -0,0 +1,198 @@
// 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"
#include "rk3568-android.dtsi"
/ {
model = "Rockchip RK3568 EVB1 V10 Board with two vp two separate single channel lvds";
compatible = "rockchip,rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3568";
/**
* VP1 -> LVDS0 -> Panel0
* VP2 -> LVDS1 -> Panel1
*/
/* panel: claa070wp03xg */
panel-lvds0 {
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 = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds0: endpoint {
remote-endpoint = <&lvds0_out_panel>;
};
};
};
};
/* panel: claa070wp03xg */
panel-lvds1 {
compatible = "simple-panel";
backlight = <&backlight1>;
power-supply = <&vcc3v3_lcd1_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 = <&timing1>;
timing1: timing1 {
clock-frequency = <67000000>;
hactive = <800>;
vactive = <1280>;
hback-porch = <60>;
hfront-porch = <60>;
vback-porch = <4>;
vfront-porch = <2>;
hsync-len = <8>;
vsync-len = <8>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
panel_in_lvds1: endpoint {
remote-endpoint = <&lvds1_out_panel>;
};
};
};
};
};
&backlight {
status = "okay";
};
&backlight1 {
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";
};
&lvds0 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds0_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds0>;
};
};
};
};
&lvds0_in_vp1 {
status = "okay";
};
&lvds1 {
status = "okay";
ports {
port@1 {
reg = <1>;
lvds1_out_panel: endpoint {
remote-endpoint = <&panel_in_lvds1>;
};
};
};
};
&lvds1_in_vp1 {
status = "disabled";
};
&lvds1_in_vp2 {
status = "okay";
};
&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;
};
&video_phy0 {
status = "okay";
};
&video_phy1 {
status = "okay";
};

View file

@ -899,6 +899,7 @@ CONFIG_CPU_RK3562=y
CONFIG_CPU_RK3568=y
CONFIG_CPU_RK3588=y
CONFIG_ROCKCHIP_CPUINFO=y
CONFIG_ROCKCHIP_CSU=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_IPA=y

View file

@ -514,6 +514,7 @@ CONFIG_CPU_RK3568=y
CONFIG_CPU_RK3588=y
CONFIG_ROCKCHIP_AMP=y
CONFIG_ROCKCHIP_CPUINFO=y
CONFIG_ROCKCHIP_CSU=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_IPA=y

View file

@ -46,6 +46,7 @@
#include <linux/rockchip/cpu.h>
#include <linux/workqueue.h>
#include <linux/types.h>
#include <soc/rockchip/rockchip_csu.h>
#include <soc/rockchip/rockchip_dmc.h>
#include <soc/rockchip/rockchip-system-status.h>
#include <uapi/linux/videodev2.h>
@ -885,6 +886,7 @@ struct vop2 {
struct clk *pclk;
struct reset_control *ahb_rst;
struct reset_control *axi_rst;
struct csu_clk *csu_aclk;
/* list_head of extend clk */
struct list_head extend_clk_list_head;
@ -6111,6 +6113,27 @@ static int vop2_crtc_get_inital_acm_info(struct drm_crtc *crtc)
return 0;
}
static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
unsigned long aclk_rate = 0, dclk_rate = 0;
u32 csu_div = 0;
if (!vop2->csu_aclk)
return;
aclk_rate = clk_get_rate(vop2->aclk);
dclk_rate = clk_get_rate(vp->dclk);
if (!dclk_rate)
return;
/* aclk >= 1/2 * dclk */
csu_div = aclk_rate * 2 / dclk_rate;
rockchip_csu_set_div(vop2->csu_aclk, csu_div);
}
static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
@ -6190,6 +6213,8 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
}
vop2_crtc_csu_set_rate(crtc);
} else {
vop2_crtc_atomic_disable(crtc, NULL);
}
@ -8123,6 +8148,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_sta
if (is_vop3(vop2))
vop3_setup_pipe_dly(vp, NULL);
vop2_crtc_csu_set_rate(crtc);
vop2_cfg_done(crtc);
/*
@ -11974,6 +12000,10 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(vop2->axi_rst);
}
vop2->csu_aclk = rockchip_csu_get(dev, "aclk");
if (IS_ERR(vop2->csu_aclk))
vop2->csu_aclk = NULL;
vop2->irq = platform_get_irq(pdev, 0);
if (vop2->irq < 0) {
DRM_DEV_ERROR(dev, "cannot find irq for vop2\n");

View file

@ -27,7 +27,7 @@
#include <media/v4l2-subdev.h>
#include <linux/pinctrl/consumer.h>
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02)
#ifndef V4L2_CID_DIGITAL_GAIN
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
@ -165,177 +165,177 @@ static const struct regval mis4001_global_regs[] = {
* mipi_datarate per lane 337.5Mbps, 2lane
*/
static const struct regval mis4001_linear_10_2560x1440_regs[] = {
{0x300a, 0x01},
{0x3006, 0x02},
{0x4220, 0x2b},
{0x4221, 0x6b},
{0x4222, 0xab},
{0x4223, 0xeb},
{0x3011, 0x2b},
{0x3302, 0x02},
{0x3307, 0x64},
{0x3306, 0x01},
{0x3309, 0x01},
{0x3308, 0x03},
{0x330a, 0x04},
{0x330b, 0x09},
{0x310f, 0x68},
{0x310e, 0x0d},
{0x310d, 0x25},
{0x310c, 0x06},
{0x3115, 0x10},
{0x3114, 0x00},
{0x3117, 0x0f},
{0x3116, 0x0a},
{0x3111, 0xfc},
{0x3110, 0x00},
{0x3113, 0x9d},
{0x3112, 0x06},
{0x3128, 0x0f},//FW<4096 FFF
{0x3129, 0xff},
{0x3012, 0x03},
{0x3f00, 0x01},
{0x3f02, 0x07},
{0x3f01, 0x00},
{0x3f04, 0x2a},
{0x3f03, 0x00},
{0x3f06, 0xa5},
{0x3f05, 0x04},
{0x3f08, 0xff},
{0x3f07, 0x1f},
{0x3f0a, 0xa4},
{0x3f09, 0x01},
{0x3f0c, 0x38},
{0x3f0b, 0x00},
{0x3f0e, 0xff},
{0x3f0d, 0x1f},
{0x3f10, 0xff},
{0x3f0f, 0x1f},
{0x3f13, 0x07},
{0x3f12, 0x00},
{0x3f15, 0x9d},
{0x3f14, 0x01},
{0x3f17, 0x31},
{0x3f16, 0x00},
{0x3f19, 0x73},
{0x3f18, 0x01},
{0x3f1b, 0x00},
{0x3f1a, 0x00},
{0x3f1d, 0xa9},
{0x3f1c, 0x04},
{0x3f1f, 0xff},
{0x3f1e, 0x1f},
{0x3f21, 0xff},
{0x3f20, 0x1f},
{0x3f23, 0x85},
{0x3f22, 0x00},
{0x3f25, 0x27},
{0x3f24, 0x01},
{0x3f28, 0x46},
{0x3f27, 0x00},
{0x3f2a, 0x07},
{0x3f29, 0x00},
{0x3f2c, 0x3f},
{0x3f2b, 0x00},
{0x3f2e, 0x70},
{0x3f2d, 0x01},
{0x3f30, 0x38},
{0x3f2f, 0x00},
{0x3f32, 0x3f},
{0x3f31, 0x00},
{0x3f34, 0xd1},
{0x3f33, 0x00},
{0x3f36, 0xc0},
{0x3f35, 0x00},
{0x3f38, 0x2f},
{0x3f37, 0x02},
{0x3f3a, 0x5d},
{0x3f39, 0x02},
{0x3f4f, 0x5d},
{0x3f4e, 0x02},
{0x3f51, 0x5d},
{0x3f50, 0x02},
{0x3f53, 0x5d},
{0x3f52, 0x02},
{0x3f55, 0x5d},
{0x3f54, 0x02},
{0x3f3c, 0x9a},
{0x3f3b, 0x00},
{0x3f3e, 0x09},
{0x3f3d, 0x04},
{0x3f40, 0x93},
{0x3f3f, 0x01},
{0x3f42, 0x8f},
{0x3f41, 0x00},
{0x3f44, 0xb0},
{0x3f43, 0x04},
{0x3129, 0x45},
{0x3128, 0x00},
{0x312b, 0x4a},
{0x312a, 0x00},
{0x312f, 0xb2},
{0x312e, 0x00},
{0x3124, 0x09},
{0x4200, 0x09},
{0x4201, 0x00},
{0x4214, 0x60},
{0x420E, 0x94},
{0x4240, 0x8d},
{0x4242, 0x03},
{0x4224, 0x00},
{0x4225, 0x0a},
{0x4226, 0xa0},
{0x4227, 0x05},
{0x4228, 0x00},
{0x4229, 0x0a},
{0x422a, 0xa0},
{0x422b, 0x05},
{0x422c, 0x00},
{0x422d, 0x0a},
{0x422e, 0xa0},
{0x422f, 0x05},
{0x4230, 0x00},
{0x4231, 0x0a},
{0x4232, 0xa0},
{0x4233, 0x05},
{0x4509, 0x0f},
{0x4505, 0x00},
{0x4501, 0xff},
{0x4502, 0x33},
{0x4503, 0x11},
{0x4501, 0xf0},
{0x4502, 0x30},
{0x4503, 0x10},
{0x3A01, 0xA0},
{0x401E, 0x3C},
{0x401d, 0xa0},
{0x3012, 0x03},
{0x3E00, 0x00},
{0x3E01, 0x10},
{0x400D, 0x30},
{0x3500, 0x1b}, //1b/13
{0x3501, 0x03},
{0x3508, 0x0a},
{0x3508, 0x04},
{0x3513, 0x01},
{0x3514, 0x09},
{0x3515, 0x0b},
{0x3702, 0x80},
{0x3704, 0x80},
{0x3706, 0x80},
{0x3708, 0x80},
{0x400D, 0x30}, //优化奇偶行及行噪
{0x4004, 0x20}, //RCS CM电流最小优化横带
{0x4005, 0x0c},
{0x4009, 0x09},
{0x400a, 0x48},
{0x4006, 0x86},
{0x4019, 0x08},
{0x4003, 0x0a},
{0x3f42, 0x58},
{0x3f49, 0x60},
{0x3f38, 0x4d},
{REG_NULL, 0x00},
{0x300a, 0x01},
{0x3006, 0x02},
{0x4220, 0x2b},
{0x4221, 0x6b},
{0x4222, 0xab},
{0x4223, 0xeb},
{0x3011, 0x2b},
{0x3302, 0x02},
{0x3307, 0x64},
{0x3306, 0x01},
{0x3309, 0x01},
{0x3308, 0x03},
{0x330a, 0x04},
{0x330b, 0x09},
{0x310f, 0x68},
{0x310e, 0x0d},
{0x310d, 0x25},
{0x310c, 0x06},
{0x3115, 0x10},
{0x3114, 0x00},
{0x3117, 0x0f},
{0x3116, 0x0a},
{0x3111, 0xfc},
{0x3110, 0x00},
{0x3113, 0x9d},
{0x3112, 0x06},
{0x3128, 0x0f},//FW<4096 FFF
{0x3129, 0xff},
{0x3012, 0x03},
{0x3f00, 0x01},
{0x3f02, 0x07},
{0x3f01, 0x00},
{0x3f04, 0x2a},
{0x3f03, 0x00},
{0x3f06, 0xa5},
{0x3f05, 0x04},
{0x3f08, 0xff},
{0x3f07, 0x1f},
{0x3f0a, 0xa4},
{0x3f09, 0x01},
{0x3f0c, 0x38},
{0x3f0b, 0x00},
{0x3f0e, 0xff},
{0x3f0d, 0x1f},
{0x3f10, 0xff},
{0x3f0f, 0x1f},
{0x3f13, 0x07},
{0x3f12, 0x00},
{0x3f15, 0x9d},
{0x3f14, 0x01},
{0x3f17, 0x31},
{0x3f16, 0x00},
{0x3f19, 0x73},
{0x3f18, 0x01},
{0x3f1b, 0x00},
{0x3f1a, 0x00},
{0x3f1d, 0xa9},
{0x3f1c, 0x04},
{0x3f1f, 0xff},
{0x3f1e, 0x1f},
{0x3f21, 0xff},
{0x3f20, 0x1f},
{0x3f23, 0x85},
{0x3f22, 0x00},
{0x3f25, 0x27},
{0x3f24, 0x01},
{0x3f28, 0x46},
{0x3f27, 0x00},
{0x3f2a, 0x07},
{0x3f29, 0x00},
{0x3f2c, 0x3f},
{0x3f2b, 0x00},
{0x3f2e, 0x70},
{0x3f2d, 0x01},
{0x3f30, 0x38},
{0x3f2f, 0x00},
{0x3f32, 0x3f},
{0x3f31, 0x00},
{0x3f34, 0xd1},
{0x3f33, 0x00},
{0x3f36, 0xc0},
{0x3f35, 0x00},
{0x3f38, 0x2f},
{0x3f37, 0x02},
{0x3f3a, 0x5d},
{0x3f39, 0x02},
{0x3f4f, 0x5d},
{0x3f4e, 0x02},
{0x3f51, 0x5d},
{0x3f50, 0x02},
{0x3f53, 0x5d},
{0x3f52, 0x02},
{0x3f55, 0x5d},
{0x3f54, 0x02},
{0x3f3c, 0x9a},
{0x3f3b, 0x00},
{0x3f3e, 0x09},
{0x3f3d, 0x04},
{0x3f40, 0x93},
{0x3f3f, 0x01},
{0x3f42, 0x8f},
{0x3f41, 0x00},
{0x3f44, 0xb0},
{0x3f43, 0x04},
{0x3129, 0x45},
{0x3128, 0x00},
{0x312b, 0x4a},
{0x312a, 0x00},
{0x312f, 0xb2},
{0x312e, 0x00},
{0x3124, 0x09},
{0x4200, 0x09},
{0x4201, 0x00},
{0x4214, 0x60},
{0x420E, 0x94},
{0x4240, 0x8d},
{0x4242, 0x03},
{0x4224, 0x00},
{0x4225, 0x0a},
{0x4226, 0xa0},
{0x4227, 0x05},
{0x4228, 0x00},
{0x4229, 0x0a},
{0x422a, 0xa0},
{0x422b, 0x05},
{0x422c, 0x00},
{0x422d, 0x0a},
{0x422e, 0xa0},
{0x422f, 0x05},
{0x4230, 0x00},
{0x4231, 0x0a},
{0x4232, 0xa0},
{0x4233, 0x05},
{0x4509, 0x0f},
{0x4505, 0x00},
{0x4501, 0xff},
{0x4502, 0x33},
{0x4503, 0x11},
{0x4501, 0xf0},
{0x4502, 0x30},
{0x4503, 0x10},
{0x3A01, 0xA0},
{0x401E, 0x3C},
{0x401d, 0xa0},
{0x3012, 0x03},
{0x3E00, 0x00},
{0x3E01, 0x10},
{0x400D, 0x30},
{0x3500, 0x1b}, //1b/13
{0x3501, 0x03},
{0x3508, 0x0a},
{0x3508, 0x04},
{0x3513, 0x01},
{0x3514, 0x09},
{0x3515, 0x0b},
{0x3702, 0x80},
{0x3704, 0x80},
{0x3706, 0x80},
{0x3708, 0x80},
{0x400D, 0x30}, //优化奇偶行及行噪
{0x4004, 0x20}, //RCS CM电流最小优化横带
{0x4005, 0x0c},
{0x4009, 0x09},
{0x400a, 0x48},
{0x4006, 0x86},
{0x4019, 0x08},
{0x4003, 0x0a},
{0x3f42, 0x58},
{0x3f49, 0x60},
{0x3f38, 0x4d},
{REG_NULL, 0x00},
};
static const struct mis4001_mode supported_modes[] = {
@ -483,6 +483,7 @@ static int mis4001_set_gain_reg(struct mis4001 *mis4001, u32 gain)
{
u8 gain_h, gain_l, u8Reg0x3102, u8Reg0x3a00, u8Reg0x3a01, u8Reg0x4003;
int ret = 0;
u8 u8Reg0x401d = 0;
if (gain < 128)
gain = 128;
@ -490,89 +491,97 @@ static int mis4001_set_gain_reg(struct mis4001 *mis4001, u32 gain)
gain = MIS4001_GAIN_MAX;
if (128 <= gain && gain < 256) {//128 * 2
gain_h = 0;
gain_l = (gain-128)/4 ;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160; //128->160, 高亮偏粉
} else if (gain >= 256 && gain < 512) {//128 * 4
gain_h = 1;
gain_l = (gain-256)/8;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (gain >= 512 && gain < 1024) {//128 * 8
gain_h = 2;
gain_l = (gain-512)/16;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (gain >= 1024 && gain < 2048) {//128 * 16
gain_h = 3;
gain_l = (gain-1024)/32;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (2048 <= gain && gain < 4096) {//128 * 32 Dgain
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = ((gain-2048)/16 + 128);
u8Reg0x3a01 = (u8Reg0x3a01<160)?160:u8Reg0x3a01;
} else if (gain >= 4096 && gain < 8192) {//128 * 64
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 1;
u8Reg0x3a01 =((gain-4096)/16);
} else if (gain >= 8192 && gain < 12288) {//128 * 96
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 2;
u8Reg0x3a01 = ((gain-8192)/16);
} else if (gain >= 12288 && gain < 16384) {//128 * 128
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 3;
u8Reg0x3a01 = ((gain-12288)/16);
} else if (gain >= 16384 && gain < 20480) {//128 * 160
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 4;
u8Reg0x3a01 = ((gain-16384)/16);
} else if (gain >= 20480 && gain < 24576) {//128 * 192
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 5;
u8Reg0x3a01 = ((gain-20480)/16);
} else if (gain >= 24576 && gain < 28672) {//128 * 224
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 6;
u8Reg0x3a01 = ((gain-24576)/16);
} else if (gain >= 28672 && gain < 32768) {//128 * 256
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 7;
u8Reg0x3a01 = ((gain-28672)/16);
} else {
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 7;
u8Reg0x3a01 = 255;
}
gain_h = 0;
gain_l = (gain - 128) / 4;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160; //128->160, 高亮偏粉
} else if (gain >= 256 && gain < 512) {//128 * 4
gain_h = 1;
gain_l = (gain - 256) / 8;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (gain >= 512 && gain < 1024) {//128 * 8
gain_h = 2;
gain_l = (gain - 512) / 16;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (gain >= 1024 && gain < 2048) {//128 * 16
gain_h = 3;
gain_l = (gain - 1024) / 32;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = 160;
} else if (gain >= 2048 && gain < 4096) {//128 * 32 Dgain
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 0;
u8Reg0x3a01 = ((gain - 2048) / 16 + 128);
u8Reg0x3a01 = (u8Reg0x3a01 < 160) ? 160 : u8Reg0x3a01;
} else if (gain >= 4096 && gain < 8192) {//128 * 64
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 1;
u8Reg0x3a01 = ((gain - 4096) / 16);
} else if (gain >= 8192 && gain < 12288) {//128 * 96
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 2;
u8Reg0x3a01 = ((gain - 8192) / 16);
} else if (gain >= 12288 && gain < 16384) {//128 * 128
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 3;
u8Reg0x3a01 = ((gain - 12288) / 16);
} else if (gain >= 16384 && gain < 20480) {//128 * 160
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 4;
u8Reg0x3a01 = ((gain - 16384) / 16);
} else if (gain >= 20480 && gain < 24576) {//128 * 192
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 5;
u8Reg0x3a01 = ((gain - 20480) / 16);
} else if (gain >= 24576 && gain < 28672) {//128 * 224
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 6;
u8Reg0x3a01 = ((gain - 24576) / 16);
} else if (gain >= 28672 && gain < 32768) {//128 * 256
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 7;
u8Reg0x3a01 = ((gain - 28672) / 16);
} else {
gain_h = 3;
gain_l = 31;
u8Reg0x3a00 = 7;
u8Reg0x3a01 = 255;
}
u8Reg0x3102 = ((gain_h << 5)|gain_l);
u8Reg0x3102 = ((gain_h << 5) | gain_l);
// 竖条纹优化,但低增益下需添加防止太阳黑子逻辑
if (128 <= gain && gain <= 256)
if (gain >= 128 && gain <= 256) {
u8Reg0x4003 = 0xb;
else
u8Reg0x401d = 0xa0;
} else {
u8Reg0x4003 = 0xa;
u8Reg0x401d = 0xa7;
}
ret = mis4001_write_reg(mis4001->client,
0x4003,
0x401d,
MIS4001_REG_VALUE_08BIT,
u8Reg0x4003);
u8Reg0x401d);
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_DIG_GAIN,
MIS4001_REG_VALUE_08BIT,
u8Reg0x3a00);
0x4003,
MIS4001_REG_VALUE_08BIT,
u8Reg0x4003);
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_DIG_GAIN,
MIS4001_REG_VALUE_08BIT,
u8Reg0x3a00);
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_DIG_FINE_GAIN,
MIS4001_REG_VALUE_08BIT,
@ -1211,10 +1220,8 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl)
s64 max;
int ret = 0;
u32 val = 0;
u32 u32Read0x3102 = 0;
u32 exp_h = 0;
u32 exp_l = 0;
u32 u32Reg0x4007, expmin, expmax, exp_value = 0;
u32 u32Reg0x4007, expmin, expmax;
u64 sleep_time = 0;
/* Propagate change of current control to all related controls */
switch (ctrl->id) {
@ -1245,6 +1252,25 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl)
MIS4001_REG_EXPOSURE_L,
MIS4001_REG_VALUE_08BIT,
MIS4001_FETCH_EXP_L(val));
/* Special strategy: To solve the problem of exposure layering:
* When the exposure is not fully filled, the gain will be increased,
* resulting in layering phenomenon
*/
//When the exposure time is 1/200 (0.005) s, the exp register is 196
expmin = (mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator)
* mis4001->cur_mode->vts_def * 1 / 200;
expmax = mis4001->cur_mode->vts_def - expmin;
if (((expmin <= val) && (expmax >= val)))
u32Reg0x4007 = 0x78;
else
u32Reg0x4007 = 0xc4;
ret |= mis4001_write_reg(mis4001->client,
0x4007,
MIS4001_REG_VALUE_08BIT,
u32Reg0x4007);
}
break;
case V4L2_CID_ANALOGUE_GAIN:
@ -1254,17 +1280,29 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_VBLANK:
dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
mis4001->cur_vts = ctrl->val + mis4001->cur_mode->height;
ret = mis4001_write_reg(mis4001->client,
MIS4001_REG_VTS_H,
MIS4001_REG_CTRL_MODE,
MIS4001_REG_VALUE_08BIT,
(ctrl->val + mis4001->cur_mode->height)
>> 8);
0x02);
sleep_time = mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator *
mis4001->cur_mode->vts_def / mis4001->cur_vts;
sleep_time = div_u64(1000000, sleep_time);
usleep_range(sleep_time, sleep_time + 1000);
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_VTS_H,
MIS4001_REG_VALUE_08BIT,
(ctrl->val + mis4001->cur_mode->height)
>> 8);
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_VTS_L,
MIS4001_REG_VALUE_08BIT,
(ctrl->val + mis4001->cur_mode->height)
& 0xff);
mis4001->cur_vts = ctrl->val + mis4001->cur_mode->height;
ret |= mis4001_write_reg(mis4001->client,
MIS4001_REG_CTRL_MODE,
MIS4001_REG_VALUE_08BIT,
0x00);
if (mis4001->cur_vts != mis4001->cur_mode->vts_def)
mis4001_modify_fps_info(mis4001);
break;
@ -1294,38 +1332,6 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl)
__func__, ctrl->id, ctrl->val);
break;
}
ret = mis4001_read_reg(mis4001->client,
MIS4001_REG_ANA_GAIN,
MIS4001_REG_VALUE_08BIT,
&u32Read0x3102);
ret |= mis4001_read_reg(mis4001->client,
MIS4001_REG_EXPOSURE_H,
MIS4001_REG_VALUE_08BIT,
&exp_h);
ret |= mis4001_read_reg(mis4001->client,
MIS4001_REG_EXPOSURE_L,
MIS4001_REG_VALUE_08BIT,
&exp_l);
exp_value = ((exp_h << 8) | exp_l);
/* Special strategy: To solve the problem of exposure layering:
* When the exposure is not fully filled, the gain will be increased,
* resulting in layering phenomenon */
//When the exposure time is 1/200 (0.005) s, the exp register is 196
expmin = (mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator)
* mis4001->cur_mode->vts_def * 1/200;
expmax = mis4001->cur_mode->vts_def - expmin;
if((127 == u32Read0x3102) &&
((expmin <= exp_value) && (expmax >= exp_value)))
u32Reg0x4007 = 0x78;
else
u32Reg0x4007 = 0xc4;
ret = mis4001_write_reg(mis4001->client,
0x4007,
MIS4001_REG_VALUE_08BIT,
u32Reg0x4007);
pm_runtime_put(&client->dev);

View file

@ -1178,6 +1178,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev,
ISP2X_REG_WR_MASK);
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx);
if (arg->subwin_en[0])
@ -2291,6 +2297,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
return;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
memset(weight15x15, 0, sizeof(weight15x15));
for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@ -2338,6 +2350,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
}
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
/* avoid to override the old enable value */
hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL);
hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK;

View file

@ -461,6 +461,12 @@ isp_sihst_config(struct rkisp_isp_params_vdev *params_vdev,
};
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
for (i = 0; i < ISP2X_SIHIST_WIN_NUM; i++) {
/* avoid to override the old enable value */
hist_ctrl = rkisp_ioread32(params_vdev, ISP_HIST_HIST_CTRL + i * 0x10);
@ -1758,6 +1764,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev,
ISP2X_REG_WR_MASK);
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx);
if (arg->subwin_en[0])
@ -2831,6 +2843,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
return;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
memset(weight15x15, 0, sizeof(weight15x15));
for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@ -2879,6 +2897,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
}
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
/* avoid to override the old enable value */
hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL);
hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK;

View file

@ -1436,6 +1436,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev,
value &= ISP3X_RAWAE_BIG_EN;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx);
if (arg->subwin_en[0])
@ -2413,6 +2419,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
return;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
memset(weight15x15, 0, sizeof(weight15x15));
for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@ -2463,6 +2475,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
}
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
/* avoid to override the old enable value */
hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id);
hist_ctrl &= ISP3X_RAWHIST_EN;

View file

@ -1291,6 +1291,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev,
value &= ISP3X_RAWAE_BIG_EN;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx);
if (arg->subwin_en[0])
@ -2424,6 +2430,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
return;
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
memset(weight15x15, 0, sizeof(weight15x15));
for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@ -2471,6 +2483,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev,
}
wnd_num_idx = arg->wnd_num;
if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
dev_err(params_vdev->dev->dev,
"%s invalid wnd_num:%d, set to %d\n",
__func__, arg->wnd_num, wnd_num_idx);
}
/* avoid to override the old enable value */
hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id);
hist_ctrl &= ISP3X_RAWHIST_EN;

View file

@ -1274,6 +1274,14 @@ config MFD_RK806
through SPI interface. The device supports multiple sub-devices
including interrupts, LDO & DCDC regulators, and onkey.
config MFD_RK806_I2C
tristate "RK806 Power Management chip with I2C"
select MFD_RK806
select REGMAP_I2C
select REGMAP_IRQ
help
If you say yes here you get support for the RK806 PM chips with I2c interface.
config MFD_RK806_SPI
tristate "RK806 Power Management chip with SPI"
select MFD_RK806

View file

@ -231,6 +231,7 @@ obj-$(CONFIG_MFD_RK630) += rk630.o
obj-$(CONFIG_MFD_RK630_I2C) += rk630-i2c.o
obj-$(CONFIG_MFD_RK630_SPI) += rk630-spi.o
obj-$(CONFIG_MFD_RK806) += rk806-core.o
obj-$(CONFIG_MFD_RK806_I2C) += rk806-i2c.o
obj-$(CONFIG_MFD_RK806_SPI) += rk806-spi.o
obj-$(CONFIG_MFD_RK808) += rk808.o
obj-$(CONFIG_MFD_RK1000) += rk1000-core.o

View file

@ -352,13 +352,13 @@ static const struct regmap_access_table rk806_volatile_table = {
.n_yes_ranges = ARRAY_SIZE(rk806_yes_ranges),
};
const struct regmap_config rk806_regmap_config_spi = {
const struct regmap_config rk806_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.volatile_table = &rk806_volatile_table,
};
EXPORT_SYMBOL_GPL(rk806_regmap_config_spi);
EXPORT_SYMBOL_GPL(rk806_regmap_config);
static struct kobject *rk806_kobj[2];
static struct rk806 *rk806_master;
@ -825,6 +825,12 @@ int rk806_device_exit(struct rk806 *rk806)
}
EXPORT_SYMBOL_GPL(rk806_device_exit);
const struct of_device_id rk806_of_match[] = {
{ .compatible = "rockchip,rk806", },
{ }
};
EXPORT_SYMBOL_GPL(rk806_of_match);
MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
MODULE_DESCRIPTION("rk806 MFD Driver");
MODULE_LICENSE("GPL v2");

62
drivers/mfd/rk806-i2c.c Normal file
View file

@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0
/*
* rk806-i2c.c -- I2C access for Rockchip RK806
*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*
* Author: Xu Shengfei <xsf@rock-chips.com>
*/
#include <linux/i2c.h>
#include <linux/mfd/rk806.h>
#include <linux/regmap.h>
static int rk806_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct rk806 *rk806;
rk806 = devm_kzalloc(&client->dev, sizeof(*rk806), GFP_KERNEL);
if (!rk806)
return -ENOMEM;
i2c_set_clientdata(client, rk806);
rk806->dev = &client->dev;
rk806->irq = client->irq;
if (!client->irq) {
dev_err(&client->dev, "No interrupt support, no core IRQ\n");
return -EINVAL;
}
rk806->regmap = devm_regmap_init_i2c(client, &rk806_regmap_config);
if (IS_ERR(rk806->regmap)) {
dev_err(&client->dev, "regmap initialization failed\n");
return PTR_ERR(rk806->regmap);
}
return rk806_device_init(rk806);
}
static int rk806_remove(struct i2c_client *client)
{
struct rk806 *rk806 = i2c_get_clientdata(client);
rk806_device_exit(rk806);
return 0;
}
static struct i2c_driver rk806_i2c_driver = {
.driver = {
.name = "rk806",
.of_match_table = of_match_ptr(rk806_of_match),
},
.probe = rk806_i2c_probe,
.remove = rk806_remove,
};
module_i2c_driver(rk806_i2c_driver);
MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
MODULE_DESCRIPTION("RK806 I2C Interface Driver");
MODULE_LICENSE("GPL");

View file

@ -12,12 +12,6 @@
#include <linux/regmap.h>
#include <linux/spi/spi.h>
static const struct of_device_id rk806_spi_of_match_table[] = {
{ .compatible = "rockchip,rk806", },
{ }
};
MODULE_DEVICE_TABLE(of, rk806_spi_of_match_table);
static int rk806_spi_write(struct spi_device *spi,
char addr,
const char *data,
@ -101,7 +95,7 @@ static int rk806_spi_probe(struct spi_device *spi)
rk806->regmap = devm_regmap_init(&spi->dev,
&rk806_regmap_bus_spi,
&spi->dev,
&rk806_regmap_config_spi);
&rk806_regmap_config);
if (IS_ERR(rk806->regmap)) {
dev_err(rk806->dev, "Failed to initialize register map\n");
return PTR_ERR(rk806->regmap);
@ -127,7 +121,7 @@ static struct spi_driver rk806_spi_driver = {
.driver = {
.name = "rk806",
.owner = THIS_MODULE,
.of_match_table = rk806_spi_of_match_table,
.of_match_table = of_match_ptr(rk806_of_match),
},
.probe = rk806_spi_probe,
.remove = rk806_spi_remove,

View file

@ -91,6 +91,10 @@ static DEFINE_MUTEX(rkep_mutex);
#define RKEP_EP_VIRTUAL_ID_MAX (8 * 4096)
#define RKEP_EP_ELBI_TIEMOUT_US 100000
#define PCIE_RK3568_RC_DBI_BASE 0xf6000000
#define PCIE_RK3588_RC_DBI_BASE 0xf5000000
#define PCIE_DBI_SIZE 0x400000
struct pcie_rkep_msix_context {
struct pci_dev *dev;
u16 msg_id;
@ -102,12 +106,14 @@ struct pcie_rkep {
void __iomem *bar0;
void __iomem *bar2;
void __iomem *bar4;
struct miscdevice dev;
int cur_mmap_res;
struct msix_entry msix_entries[RKEP_NUM_MSIX_VECTORS];
struct pcie_rkep_msix_context msix_ctx[RKEP_NUM_MSIX_VECTORS];
struct pcie_rkep_msix_context msi_ctx[RKEP_NUM_MSI_VECTORS];
bool msi_enable;
bool msix_enable;
struct miscdevice dev;
struct dma_trx_obj *dma_obj;
struct pcie_ep_obj_info *obj_info;
struct page *user_pages; /* Allocated physical memory for user space */
@ -275,33 +281,73 @@ static ssize_t pcie_rkep_write(struct file *file, const char __user *buf,
{
struct pcie_file *pcie_file = file->private_data;
struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
u32 *bar0_buf;
int loop, i = 0;
size_t raw_count = count;
struct pci_dev *dev = pcie_rkep->pdev;
unsigned int size = count;
loff_t init_off = *ppos, off = *ppos;
u8 *data;
count = (count % 4) ? (count - count % 4) : count;
if (count > BAR_0_SZ)
return -EINVAL;
bar0_buf = kzalloc(count, GFP_KERNEL);
if (!bar0_buf)
data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
if (copy_from_user(bar0_buf, buf, count)) {
raw_count = -EFAULT;
goto exit;
if (off > dev->cfg_size) {
kfree(data);
return 0;
}
if (off + count > dev->cfg_size) {
size = dev->cfg_size - off;
count = size;
}
for (loop = 0; loop < count / 4; loop++) {
iowrite32(bar0_buf[i], pcie_rkep->bar0 + loop * 4);
i++;
if (copy_from_user(data, buf, count)) {
kfree(data);
return -EFAULT;
}
exit:
kfree(bar0_buf);
if ((off & 1) && size) {
pci_write_config_byte(dev, off, data[off - init_off]);
off++;
size--;
}
return raw_count;
if ((off & 3) && size > 2) {
u16 val = data[off - init_off];
val |= (u16) data[off - init_off + 1] << 8;
pci_write_config_word(dev, off, val);
off += 2;
size -= 2;
}
while (size > 3) {
u32 val = data[off - init_off];
val |= (u32) data[off - init_off + 1] << 8;
val |= (u32) data[off - init_off + 2] << 16;
val |= (u32) data[off - init_off + 3] << 24;
pci_write_config_dword(dev, off, val);
off += 4;
size -= 4;
}
if (size >= 2) {
u16 val = data[off - init_off];
val |= (u16) data[off - init_off + 1] << 8;
pci_write_config_word(dev, off, val);
off += 2;
size -= 2;
}
if (size) {
pci_write_config_byte(dev, off, data[off - init_off]);
off++;
--size;
}
kfree(data);
return count;
}
static ssize_t pcie_rkep_read(struct file *file, char __user *buf,
@ -309,33 +355,82 @@ static ssize_t pcie_rkep_read(struct file *file, char __user *buf,
{
struct pcie_file *pcie_file = file->private_data;
struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
u32 *bar0_buf;
int loop, i = 0;
size_t raw_count = count;
struct pci_dev *dev = pcie_rkep->pdev;
unsigned int size = count;
loff_t init_off = *ppos, off = *ppos;
u8 *data;
count = (count % 4) ? (count - count % 4) : count;
if (count > BAR_0_SZ)
return -EINVAL;
bar0_buf = kzalloc(count, GFP_ATOMIC);
if (!bar0_buf)
data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
for (loop = 0; loop < count / 4; loop++) {
bar0_buf[i] = ioread32(pcie_rkep->bar0 + loop * 4);
i++;
if (off > dev->cfg_size) {
kfree(data);
return 0;
}
if (off + count > dev->cfg_size) {
size = dev->cfg_size - off;
count = size;
}
if (copy_to_user(buf, bar0_buf, count)) {
raw_count = -EFAULT;
goto exit;
if ((off & 1) && size) {
u8 val;
pci_read_config_byte(dev, off, &val);
data[off - init_off] = val;
off++;
size--;
}
exit:
kfree(bar0_buf);
if ((off & 3) && size > 2) {
u16 val;
return raw_count;
pci_read_config_word(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
off += 2;
size -= 2;
}
while (size > 3) {
u32 val;
pci_read_config_dword(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
data[off - init_off + 2] = (val >> 16) & 0xff;
data[off - init_off + 3] = (val >> 24) & 0xff;
off += 4;
size -= 4;
}
if (size >= 2) {
u16 val;
pci_read_config_word(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
off += 2;
size -= 2;
}
if (size > 0) {
u8 val;
pci_read_config_byte(dev, off, &val);
data[off - init_off] = val;
off++;
--size;
}
if (copy_to_user(buf, data, count)) {
kfree(data);
return -EFAULT;
}
kfree(data);
return count;
}
static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma)
@ -343,26 +438,81 @@ static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma)
u64 addr;
struct pcie_file *pcie_file = file->private_data;
struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
struct pci_dev *dev = pcie_rkep->pdev;
size_t size = vma->vm_end - vma->vm_start;
resource_size_t bar_size;
int err;
if (size > RKEP_USER_MEM_SIZE) {
dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n");
switch (pcie_rkep->cur_mmap_res) {
case PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI:
if (size > PCIE_DBI_SIZE) {
dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n");
return -EINVAL;
}
addr = PCIE_RK3568_RC_DBI_BASE;
break;
case PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI:
if (size > PCIE_DBI_SIZE) {
dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n");
return -EINVAL;
}
addr = PCIE_RK3588_RC_DBI_BASE;
break;
case PCIE_EP_MMAP_RESOURCE_BAR0:
bar_size = pci_resource_len(dev, 0);
if (size > bar_size) {
dev_warn(&pcie_rkep->pdev->dev, "bar0 mmap size is out of limitation\n");
return -EINVAL;
}
addr = pci_resource_start(dev, 0);
break;
case PCIE_EP_MMAP_RESOURCE_BAR2:
bar_size = pci_resource_len(dev, 2);
if (size > bar_size) {
dev_warn(&pcie_rkep->pdev->dev, "bar2 mmap size is out of limitation\n");
return -EINVAL;
}
addr = pci_resource_start(dev, 2);
break;
case PCIE_EP_MMAP_RESOURCE_BAR4:
bar_size = pci_resource_len(dev, 4);
if (size > bar_size) {
dev_warn(&pcie_rkep->pdev->dev, "bar4 mmap size is out of limitation\n");
return -EINVAL;
}
addr = pci_resource_start(dev, 4);
break;
case PCIE_EP_MMAP_RESOURCE_USER_MEM:
if (size > RKEP_USER_MEM_SIZE) {
dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n");
return -EINVAL;
}
if (!pcie_rkep->user_pages) {
dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n");
return -EINVAL;
}
addr = page_to_phys(pcie_rkep->user_pages);
break;
default:
dev_err(&pcie_rkep->pdev->dev, "cur mmap_res %d is unsurreport\n", pcie_rkep->cur_mmap_res);
return -EINVAL;
}
if (!pcie_rkep->user_pages) {
dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n");
return -EINVAL;
}
addr = page_to_phys(pcie_rkep->user_pages);
vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, size, vma->vm_page_prot)) {
dev_err(&pcie_rkep->pdev->dev, "io_remap_pfn_range failed\n");
if (pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_BAR2 ||
pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_USER_MEM)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
err = remap_pfn_range(vma, vma->vm_start,
__phys_to_pfn(addr),
size, vma->vm_page_prot);
if (err)
return -EAGAIN;
}
return 0;
}
@ -375,6 +525,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a
struct pcie_ep_dma_cache_cfg cfg;
struct pcie_ep_dma_block_req dma;
void __user *uarg = (void __user *)args;
int mmap_res;
int ret;
int index;
u64 addr;
@ -462,6 +613,20 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a
return -EFAULT;
}
break;
case PCIE_EP_SET_MMAP_RESOURCE:
ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res));
if (ret) {
dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n");
return -EFAULT;
}
if (mmap_res >= PCIE_EP_MMAP_RESOURCE_MAX || mmap_res < 0) {
dev_err(&pcie_rkep->pdev->dev, "mmap index %d is out of number\n", mmap_res);
return -EINVAL;
}
pcie_rkep->cur_mmap_res = mmap_res;
break;
default:
break;
}
@ -478,7 +643,7 @@ static const struct file_operations pcie_rkep_fops = {
.mmap = pcie_rkep_mmap,
.fasync = pcie_rkep_fasync,
.release = pcie_rkep_release,
.llseek = no_llseek,
.llseek = default_llseek,
};
static inline void pcie_rkep_writel_dbi(struct pcie_rkep *pcie_rkep, u32 reg, u32 val)
@ -985,6 +1150,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pcie_dw_dmatest_unregister(pcie_rkep->dma_obj);
goto err_register_obj;
}
pcie_rkep->cur_mmap_res = PCIE_EP_MMAP_RESOURCE_USER_MEM;
dev_err(&pdev->dev, "successfully allocate continuouse buffer for userspace\n");
#endif

View file

@ -25,6 +25,7 @@
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <linux/soc/rockchip/rk_vendor_storage.h>
#include <soc/rockchip/rockchip_csu.h>
#include "stmmac_platform.h"
#include "dwmac-rk-tool.h"
@ -82,6 +83,9 @@ struct rk_priv_data {
unsigned char otp_data;
unsigned int bgs_increment;
struct csu_clk *csu_aclk;
struct csu_clk *csu_pclk;
};
/* XPCS */
@ -2354,6 +2358,21 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
return 0;
}
static int rk_gmac_csu_init(struct plat_stmmacenet_data *plat)
{
struct rk_priv_data *bsp_priv = plat->bsp_priv;
struct device *dev = &bsp_priv->pdev->dev;
bsp_priv->csu_aclk = rockchip_csu_get(dev, "aclk");
if (IS_ERR(bsp_priv->csu_aclk))
bsp_priv->csu_aclk = NULL;
bsp_priv->csu_pclk = rockchip_csu_get(dev, "pclk");
if (IS_ERR(bsp_priv->csu_pclk))
bsp_priv->csu_pclk = NULL;
return 0;
}
static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
{
int phy_iface = bsp_priv->phy_iface;
@ -2399,6 +2418,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
bsp_priv->ops->set_clock_selection(bsp_priv,
bsp_priv->clock_input, true);
rockchip_csu_disable(bsp_priv->csu_aclk);
rockchip_csu_disable(bsp_priv->csu_pclk);
/**
* if (!IS_ERR(bsp_priv->clk_mac))
* clk_prepare_enable(bsp_priv->clk_mac);
@ -2434,6 +2456,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
clk_disable_unprepare(bsp_priv->clk_xpcs_eee);
rockchip_csu_enable(bsp_priv->csu_aclk);
rockchip_csu_enable(bsp_priv->csu_pclk);
/**
* if (!IS_ERR(bsp_priv->clk_mac))
* clk_disable_unprepare(bsp_priv->clk_mac);
@ -2866,6 +2891,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
goto err_remove_config_dt;
}
rk_gmac_csu_init(plat_dat);
ret = rk_gmac_clk_init(plat_dat);
if (ret)
goto err_remove_config_dt;

View file

@ -8,6 +8,7 @@
* Author: Simon Xue <xxm@rock-chips.com>
*/
#include <dt-bindings/phy/phy.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/iopoll.h>
@ -2175,6 +2176,12 @@ static int __maybe_unused rockchip_dw_pcie_suspend(struct device *dev)
no_l2:
rk_pcie_disable_ltssm(rk_pcie);
ret = phy_validate(rk_pcie->phy, PHY_TYPE_PCIE, 0, NULL);
if (ret && ret != -EOPNOTSUPP) {
dev_err(dev, "PHY is reused by other controller, check the dts!\n");
return ret;
}
/* make sure assert phy success */
usleep_range(200, 300);

View file

@ -275,9 +275,42 @@ static int rockchip_combphy_exit(struct phy *phy)
return 0;
}
static const char *rockchip_combphy_mode2str(enum phy_mode mode)
{
switch (mode) {
case PHY_TYPE_SATA:
return "SATA";
case PHY_TYPE_PCIE:
return "PCIe";
case PHY_TYPE_USB3:
return "USB3";
case PHY_TYPE_SGMII:
case PHY_TYPE_QSGMII:
return "GMII";
default:
return "Unknown";
}
}
static int rockchip_combphy_validate(struct phy *phy, enum phy_mode mode, int submode,
union phy_configure_opts *opts)
{
struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
if (mode != priv->mode) {
dev_err(priv->dev, "expected mode is %s, but current mode is %s\n",
rockchip_combphy_mode2str(mode),
rockchip_combphy_mode2str(priv->mode));
return -EINVAL;
}
return 0;
}
static const struct phy_ops rochchip_combphy_ops = {
.init = rockchip_combphy_init,
.exit = rockchip_combphy_exit,
.validate = rockchip_combphy_validate,
.owner = THIS_MODULE,
};

View file

@ -44,6 +44,12 @@ config ROCKCHIP_CPUINFO
If unsure, say N.
config ROCKCHIP_CSU
tristate "Rockchip Clock Subunit Driver"
depends on ARCH_ROCKCHIP
help
This adds the clock subunit driver for Rockchip SoCs.
config ROCKCHIP_GRF
tristate "Rockchip General Register Files support"
help

View file

@ -4,6 +4,7 @@
#
obj-$(CONFIG_ROCKCHIP_AMP) += rockchip_amp.o
obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o
obj-$(CONFIG_ROCKCHIP_CSU) += rockchip_csu.o
obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS) += rockchip_decompress.o
obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS_USER) += rockchip_decompress_user.o

View file

@ -0,0 +1,377 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023, Rockchip Electronics Co., Ltd.
* Author: Finley Xiao <finley.xiao@rock-chips.com>
*/
#include <linux/arm-smccc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/rockchip/rockchip_sip.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <soc/rockchip/rockchip_csu.h>
struct csu_bus {
unsigned int id;
unsigned int cfg_val;
unsigned int en_mask;
unsigned int disable_count;
};
struct csu_clk {
unsigned int clk_id;
unsigned int bus_id;
};
struct rockchip_csu {
struct device *dev;
struct csu_bus *bus;
struct csu_clk *clk;
unsigned int bus_cnt;
unsigned int clk_cnt;
};
static struct rockchip_csu *rk_csu;
static DEFINE_MUTEX(csu_lock);
static int rockchip_csu_sip_config(struct device *dev, u32 bus_id, u32 cfg,
u32 enable_msk)
{
struct arm_smccc_res res;
dev_dbg(dev, "id=%u, cfg=0x%x, en_mask=0x%x\n", bus_id, cfg, enable_msk);
res = sip_smc_bus_config(bus_id, cfg, enable_msk);
return res.a0;
}
struct csu_clk *rockchip_csu_get(struct device *dev, const char *name)
{
struct of_phandle_args args;
struct csu_clk *clk = ERR_PTR(-ENOENT);
unsigned int clk_id = 0;
int index = 0, i = 0;
if (!dev || !dev->of_node)
return ERR_PTR(-ENODEV);
if (!rk_csu || !rk_csu->bus || !rk_csu->clk)
return ERR_PTR(-ENODEV);
if (name)
index = of_property_match_string(dev->of_node,
"rockchip,csu-names",
name);
if (of_parse_phandle_with_fixed_args(dev->of_node, "rockchip,csu", 1,
index, &args)) {
dev_err(dev, "Missing the phandle args name %s\n", name);
return ERR_PTR(-ENODEV);
}
clk_id = args.args[0];
for (i = 0; i < rk_csu->clk_cnt; i++) {
if (clk_id == rk_csu->clk[i].clk_id) {
clk = &rk_csu->clk[i];
break;
}
}
return clk;
}
EXPORT_SYMBOL(rockchip_csu_get);
static int csu_disable(struct csu_clk *clk, bool disable)
{
struct csu_bus *bus = NULL;
unsigned int en_mask = 0;
int ret = 0;
if (IS_ERR_OR_NULL(clk))
return 0;
if (clk->bus_id >= rk_csu->bus_cnt)
return 0;
bus = &rk_csu->bus[clk->bus_id];
if (!bus)
return 0;
mutex_lock(&csu_lock);
if (disable)
bus->disable_count++;
else if (bus->disable_count > 0)
bus->disable_count--;
if (bus->disable_count)
en_mask = bus->en_mask & CSU_EN_MASK;
else
en_mask = bus->en_mask;
ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, bus->cfg_val, en_mask);
if (ret)
dev_err(rk_csu->dev, "csu sip config disable error\n");
mutex_unlock(&csu_lock);
return ret;
}
int rockchip_csu_enable(struct csu_clk *clk)
{
return csu_disable(clk, false);
}
EXPORT_SYMBOL(rockchip_csu_enable);
int rockchip_csu_disable(struct csu_clk *clk)
{
return csu_disable(clk, true);
}
EXPORT_SYMBOL(rockchip_csu_disable);
int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div)
{
struct csu_bus *bus = NULL;
unsigned int cfg_val = 0;
int ret = 0;
if (IS_ERR_OR_NULL(clk))
return 0;
if (clk->bus_id >= rk_csu->bus_cnt)
return 0;
bus = &rk_csu->bus[clk->bus_id];
if (!bus)
return 0;
mutex_lock(&csu_lock);
if (div > CSU_MAX_DIV)
div = CSU_MAX_DIV;
cfg_val = (bus->cfg_val & ~CSU_DIV_MASK) | ((div - 1) & CSU_DIV_MASK);
ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, cfg_val, bus->en_mask);
if (ret)
dev_err(rk_csu->dev, "csu sip config freq error\n");
mutex_unlock(&csu_lock);
return ret;
}
EXPORT_SYMBOL(rockchip_csu_set_div);
static int rockchip_csu_parse_clk(struct rockchip_csu *csu)
{
struct device *dev = csu->dev;
struct device_node *np = dev->of_node;
char *prop_name = "rockchip,clock";
struct csu_clk *tmp;
const struct property *prop;
int count, i;
prop = of_find_property(np, prop_name, NULL);
if (!prop)
return -EINVAL;
if (!prop->value)
return -ENODATA;
count = of_property_count_u32_elems(np, prop_name);
if (count < 0)
return -EINVAL;
if (count % 2)
return -EINVAL;
tmp = devm_kcalloc(dev, count / 2, sizeof(*tmp), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
for (i = 0; i < count / 2; i++) {
of_property_read_u32_index(np, prop_name, 2 * i,
&tmp[i].clk_id);
of_property_read_u32_index(np, prop_name, 2 * i + 1,
&tmp[i].bus_id);
}
csu->clk = tmp;
csu->clk_cnt = count / 2;
return 0;
}
static int rockchip_csu_parse_bus_table(struct rockchip_csu *csu)
{
struct device *dev = csu->dev;
struct device_node *np = dev->of_node;
char *prop_name = "rockchip,bus";
struct csu_bus *tmp;
const struct property *prop;
int count, i;
prop = of_find_property(np, prop_name, NULL);
if (!prop)
return -EINVAL;
if (!prop->value)
return -ENODATA;
count = of_property_count_u32_elems(np, prop_name);
if (count < 0)
return -EINVAL;
if (count % 3)
return -EINVAL;
tmp = devm_kcalloc(dev, count / 3, sizeof(*tmp), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
for (i = 0; i < count / 3; i++) {
of_property_read_u32_index(np, prop_name, 3 * i,
&tmp[i].id);
of_property_read_u32_index(np, prop_name, 3 * i + 1,
&tmp[i].cfg_val);
of_property_read_u32_index(np, prop_name, 3 * i + 2,
&tmp[i].en_mask);
}
csu->bus = tmp;
csu->bus_cnt = count / 3;
return 0;
}
static int rockchip_csu_bus_table(struct rockchip_csu *csu)
{
struct device *dev = csu->dev;
struct csu_bus *bus;
int i;
if (rockchip_csu_parse_bus_table(csu))
return -EINVAL;
for (i = 0; i < csu->bus_cnt; i++) {
bus = &csu->bus[i];
if (!bus || !bus->cfg_val) {
dev_info(dev, "bus %d cfg-val invalid\n", i);
continue;
}
if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask))
dev_err(dev, "csu sip config error\n");
}
return 0;
}
static int rockchip_csu_bus_node(struct rockchip_csu *csu)
{
struct device *dev = csu->dev;
struct device_node *np = dev->of_node;
struct device_node *child;
struct csu_bus *bus;
int bus_cnt = 0, i = 0;
for_each_available_child_of_node(np, child)
bus_cnt++;
if (bus_cnt <= 0)
return 0;
csu->bus = devm_kcalloc(dev, bus_cnt, sizeof(*csu->bus), GFP_KERNEL);
if (!csu->bus)
return -ENOMEM;
csu->bus_cnt = bus_cnt;
for_each_available_child_of_node(np, child) {
bus = &csu->bus[i++];
if (of_property_read_u32_index(child, "bus-id", 0, &bus->id)) {
dev_info(dev, "get bus-id error\n");
continue;
}
if (of_property_read_u32_index(child, "cfg-val", 0,
&bus->cfg_val)) {
dev_info(dev, "get cfg-val error\n");
continue;
}
if (!bus->cfg_val) {
dev_info(dev, "cfg-val invalid\n");
continue;
}
if (of_property_read_u32_index(child, "enable-msk", 0,
&bus->en_mask)) {
dev_info(dev, "get enable_msk error\n");
continue;
}
if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask))
dev_info(dev, "csu smc config error\n");
}
return 0;
}
static const struct of_device_id rockchip_csu_of_match[] = {
{ .compatible = "rockchip,rk3562-csu", },
{ },
};
MODULE_DEVICE_TABLE(of, rockchip_csu_of_match);
static int rockchip_csu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct rockchip_csu *csu;
int ret = 0;
csu = devm_kzalloc(dev, sizeof(*csu), GFP_KERNEL);
if (!csu)
return -ENOMEM;
csu->dev = dev;
platform_set_drvdata(pdev, csu);
rockchip_csu_parse_clk(csu);
if (of_find_property(np, "rockchip,bus", NULL))
ret = rockchip_csu_bus_table(csu);
else
ret = rockchip_csu_bus_node(csu);
if (!ret)
rk_csu = csu;
return ret;
}
static struct platform_driver rockchip_csu_driver = {
.probe = rockchip_csu_probe,
.driver = {
.name = "rockchip,csu",
.of_match_table = rockchip_csu_of_match,
},
};
static int __init rockchip_csu_init(void)
{
int ret;
ret = platform_driver_register(&rockchip_csu_driver);
if (ret) {
pr_err("failed to register csu driver\n");
return ret;
}
return 0;
}
static void __exit rockchip_csu_exit(void)
{
return platform_driver_unregister(&rockchip_csu_driver);
}
subsys_initcall(rockchip_csu_init);
module_exit(rockchip_csu_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>");
MODULE_DESCRIPTION("Rockchip clock subunit driver");

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (c) 2023 Rockchip Electronics Co. Ltd.
* Author: Finley Xiao <finley.xiao@rock-chips.com>
*/
#ifndef _DT_BINDINGS_ROCKCHIP_CSU_H
#define _DT_BINDINGS_ROCKCHIP_CSU_H
#define CSU_GMAC_ACLK 0
#define CSU_GMAC_PCLK 1
#define CSU_VOP_ACLK 2
#define CSU_MCU_CLK 3
#endif

View file

@ -6,6 +6,7 @@
#ifndef __LINUX_REGULATOR_RK806_H
#define __LINUX_REGULATOR_RK806_H
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@ -518,7 +519,8 @@ struct rk806 {
int vb_lo_irq;
};
extern const struct regmap_config rk806_regmap_config_spi;
extern const struct regmap_config rk806_regmap_config;
extern const struct of_device_id rk806_of_match[];
int rk806_device_init(struct rk806 *rk806);
int rk806_device_exit(struct rk806 *rk806);
int rk806_field_write(struct rk806 *rk806,

View file

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2023, Rockchip Electronics Co., Ltd
*/
#ifndef __SOC_ROCKCHIP_CSU_H
#define __SOC_ROCKCHIP_CSU_H
#include <dt-bindings/soc/rockchip-csu.h>
#define CSU_MAX_DIV 8
#define CSU_DIV_MASK 0x7
#define CSU_EN_MASK 0xefff
struct csu_clk;
#if IS_REACHABLE(CONFIG_ROCKCHIP_CSU)
struct csu_clk *rockchip_csu_get(struct device *dev, const char *name);
int rockchip_csu_enable(struct csu_clk *clk);
int rockchip_csu_disable(struct csu_clk *clk);
int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div);
#else
static inline struct csu_clk *
rockchip_csu_get(struct device *dev, const char *name)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline int rockchip_csu_enable(struct csu_clk *clk)
{
return -EOPNOTSUPP;
}
static inline int rockchip_csu_disable(struct csu_clk *clk)
{
return -EOPNOTSUPP;
}
static inline int
rockchip_csu_set_div(struct csu_clk *clk, unsigned int div)
{
return -EOPNOTSUPP;
}
#endif
#endif

View file

@ -74,6 +74,9 @@ enum pcie_ep_mmap_resource {
PCIE_EP_MMAP_RESOURCE_BAR0,
PCIE_EP_MMAP_RESOURCE_BAR2,
PCIE_EP_MMAP_RESOURCE_BAR4,
PCIE_EP_MMAP_RESOURCE_USER_MEM,
PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI,
PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI,
PCIE_EP_MMAP_RESOURCE_MAX,
};
@ -87,7 +90,8 @@ struct pcie_ep_obj_info {
__u16 mode;
__u16 submode;
} devmode;
__u8 reserved[0x1F4];
__u32 msi_data[0x8];
__u8 reserved[0x1D4];
__u32 irq_type_rc; /* Generate in ep isr, valid only for rc, clear in rc */
struct pcie_ep_obj_irq_dma_status dma_status_rc; /* Generate in ep isr, valid only for rc, clear in rc */
@ -103,7 +107,7 @@ struct pcie_ep_obj_info {
#define PCIE_DMA_IRQ_MASK_ALL _IOW(PCIE_BASE, 3, int)
#define PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER _IOW(PCIE_BASE, 4, int)
#define PCIE_EP_GET_USER_INFO _IOR(PCIE_BASE, 5, struct pcie_ep_user_data)
#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, enum pcie_ep_mmap_resource)
#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, int)
#define PCIE_EP_RAISE_ELBI _IOW(PCIE_BASE, 7, int)
#define PCIE_EP_REQUEST_VIRTUAL_ID _IOR(PCIE_BASE, 16, int)
#define PCIE_EP_RELEASE_VIRTUAL_ID _IOW(PCIE_BASE, 17, int)