1
0
Fork 0

[kernel] merge commit 'a944eb3b84..444bbeb50c'

Add support for rm67199 dsi panel and nanopc-t6n (rev08).

Signed-off-by: hmz007 <hmz007@gmail.com>
master
hmz007 1 year ago
parent e2037f671e
commit 2165835b93

@ -27,6 +27,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3588-nanopi6-rev04.dtb \
rk3588-nanopi6-rev05.dtb \
rk3588-nanopi6-rev07.dtb \
rk3588-nanopi6-rev08.dtb \
rk3588-nanopi6-rev09.dtb
else

@ -0,0 +1,76 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 FriendlyElec Computer Tech. Co., Ltd.
* (http://www.friendlyelec.com)
*
* Copyright (c) 2022 Rockchip Electronics Co., Ltd.
*/
&mipi_dcphy1 {
status = "okay";
};
&dsi1_in_vp3 {
status = "okay";
};
&dsi1 {
status = "okay";
dsi1_panel: panel@0 {
compatible = "zhot,zh055oe041";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&lcd_rst1_gpio>;
reset-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>;
dsi-lanes = <4>;
video-mode = <0>;
width-mm = <68>;
height-mm = <121>;
panel-name = "ZH055,400dpi";
display-timings {
native-mode = <&dsi_timing1>;
dsi_timing1: timing0 {
clock-frequency = <133711000>;
hactive = <1080>;
vactive = <1920>;
hfront-porch = <26>;
hsync-len = <4>;
hback-porch = <34>;
vfront-porch = <8>;
vsync-len = <4>;
vback-porch = <16>;
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_dsi1: endpoint {
remote-endpoint = <&dsi_out_panel>;
};
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
dsi_out_panel: endpoint {
remote-endpoint = <&panel_in_dsi1>;
};
};
};
};

@ -0,0 +1,702 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2023 FriendlyElec Computer Tech. Co., Ltd.
* (http://www.friendlyelec.com)
*/
/dts-v1/;
#include "rk3588.dtsi"
#include "rk3588-nanopi6-common.dtsi"
#include "rk3588-nanopi6-mipi-55amoled.dtsi"
/ {
model = "FriendlyElec NanoPC-T6N";
compatible = "friendlyelec,nanopc-t6n", "rockchip,rk3588";
aliases {
ethernet0 = &r8125_u10;
};
dp0_sound: dp0-sound {
status = "okay";
compatible = "rockchip,hdmi";
rockchip,card-name= "rockchip,dp0";
rockchip,mclk-fs = <512>;
rockchip,cpu = <&spdif_tx2>;
rockchip,codec = <&dp0 1>;
};
dp1_sound: dp1-sound {
status = "okay";
compatible = "rockchip,hdmi";
rockchip,card-name= "rockchip,dp1";
rockchip,mclk-fs = <512>;
rockchip,cpu = <&spdif_tx5>;
rockchip,codec = <&dp1 1>;
};
rt5616_sound: rt5616-sound {
status = "okay";
compatible = "simple-audio-card";
pinctrl-names = "default";
pinctrl-0 = <&hp_det>;
simple-audio-card,name = "realtek,rt5616-codec";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,hp-det-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
simple-audio-card,hp-pin-name = "Headphone Jack";
simple-audio-card,widgets =
"Headphone", "Headphone Jack",
"Microphone", "Microphone Jack";
simple-audio-card,routing =
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR",
"MIC1", "Microphone Jack",
"Microphone Jack", "micbias1";
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&rt5616>;
};
};
gpio_leds: gpio-leds {
compatible = "gpio-leds";
sys_led: led-0 {
gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
label = "sys_led";
linux,default-trigger = "heartbeat";
pinctrl-names = "default";
pinctrl-0 = <&sys_led_pin>;
};
};
vcc5v0_host_30: vcc5v0-host-30 {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host30_en>;
regulator-name = "vcc5v0_host_30";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
vbus5v1_typec: vbus5v1-typec {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&typec5v1_pwren>;
regulator-name = "vbus5v1_typec";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
vcc3v3_pcie30: vcc3v3-pcie30 {
compatible = "regulator-fixed";
enable-active-high;
gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_m2_0_pwren>;
regulator-name = "vcc3v3_pcie30";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc5v0_sys>;
};
vdd_mpcie_3v3: vdd-mpcie-3v3 {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_m2_1_pwren>;
regulator-name = "vdd_mpcie_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc5v0_sys>;
};
};
&combphy1_ps {
status = "okay";
};
&dp0 {
status = "okay";
};
&dp0_in_vp0 {
status = "disabled";
};
&dp0_in_vp1 {
status = "disabled";
};
&dp0_in_vp2 {
status = "okay";
};
&dp1 {
status = "okay";
};
&dp1_in_vp0 {
status = "disabled";
};
&dp1_in_vp1 {
status = "okay";
};
&dp1_in_vp2 {
status = "disabled";
};
&dsi1_panel {
pinctrl-0 = <&lcd_rst0_gpio>;
reset-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
};
&gmac1 {
status = "disabled";
};
&hdmi0 {
enable-gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&hdmi0_in_vp0 {
status = "okay";
};
&hdmi0_in_vp1 {
status = "disabled";
};
&hdmi0_in_vp2 {
status = "disabled";
};
&hdmi0_sound {
status = "okay";
};
&hdptxphy_hdmi0 {
status = "okay";
};
&i2c3 {
pinctrl-0 = <&i2c3m0_xfer>;
/* connected with MIPI-CSI0 */
};
&i2c4 {
clock-frequency = <200000>;
pinctrl-0 = <&i2c4m3_xfer>;
status = "okay";
usbc1: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio4>;
interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
int-n-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc1_int>;
vbus-supply = <&vbus5v1_typec>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc1_role_sw: endpoint@0 {
remote-endpoint = <&dwc3_1_role_switch>;
};
};
};
usb_con1: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
source-pdos =
<PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc1_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy1_orientation_switch>;
};
};
port@1 {
reg = <1>;
dp1_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy1_dp_altmode_mux>;
};
};
};
};
};
};
&i2c5 {
clock-frequency = <200000>;
pinctrl-0 = <&i2c5m0_xfer>;
status = "okay";
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
pinctrl-names = "default";
pinctrl-0 = <&touch_dsi0_gpio>;
interrupt-parent = <&gpio3>;
interrupts = <RK_PC0 IRQ_TYPE_EDGE_FALLING>;
goodix,irq-gpio = <&gpio3 RK_PC0 IRQ_TYPE_EDGE_FALLING>;
goodix,rst-gpio = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
keep-otp-config;
};
};
&i2c6 {
clock-frequency = <200000>;
status = "okay";
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
int-n-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v0_typec>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_role_sw: endpoint@0 {
remote-endpoint = <&dwc3_0_role_switch>;
};
};
};
usb_con0: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
source-pdos =
<PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy0_orientation_switch>;
};
};
port@1 {
reg = <1>;
dp0_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
};
};
};
};
};
};
&i2c7 {
clock-frequency = <200000>;
status = "okay";
rt5616: rt5616@1b {
status = "okay";
#sound-dai-cells = <0>;
compatible = "rt5616";
reg = <0x1b>;
clocks = <&mclkout_i2s0>;
clock-names = "mclk";
assigned-clocks = <&mclkout_i2s0>;
assigned-clock-rates = <12288000>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_mclk>;
};
/* connected with MIPI-CSI1 */
};
&i2c8 {
pinctrl-0 = <&i2c8m2_xfer>;
/* connected with Header_2.54MM */
};
&i2s0_8ch {
status = "okay";
pinctrl-0 = <&i2s0_lrck
&i2s0_sclk
&i2s0_sdi0
&i2s0_sdo0>;
rockchip,trcm-sync-tx-only;
};
&i2s6_8ch {
status = "okay";
};
&i2s7_8ch {
status = "okay";
};
&mach {
hwrev = <8>;
model = "NanoPC-T6N";
};
&mdio1 {
status = "disabled";
};
&pcie2x1l0 {
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
rockchip,init-delay-ms = <500>;
vpcie3v3-supply = <&vdd_mpcie_3v3>;
status = "okay";
};
&pcie2x1l1 {
status = "disabled";
};
&pcie2x1l2 {
reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc_3v3_pcie20>;
status = "okay";
pcie@0,0 {
reg = <0x00400000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
r8125_u10: pcie@40,0 {
reg = <0x000000 0 0 0 0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
};
&pcie30phy {
status = "okay";
};
&pcie3x4 {
reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie30>;
status = "okay";
};
&pinctrl {
gpio-leds {
sys_led_pin: sys-led-pin {
rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
};
usr_led_pin: usr-led-pin {
rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
headphone {
hp_det: hp-det {
rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
lcd {
/omit-if-no-ref/
lcd_rst0_gpio: lcd-rst0-gpio {
rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
/omit-if-no-ref/
touch_dsi0_gpio: touch-dsi0-gpio {
rockchip,pins =
<3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
pcie {
pcie_m2_0_pwren: pcie-m20-pwren {
rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
pcie_m2_1_pwren: pcie-m21-pwren {
rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
sdmmc {
sd_s0_pwr: sd-s0-pwr {
rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
usb {
typec5v1_pwren: typec5v1-pwren {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
usbc1_int: usbc1-int {
rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
};
vcc5v0_host30_en: vcc5v0-host30-en {
rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
};
/omit-if-no-ref/
vcc5v0_host20_en: vcc5v0-host20-en {
rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&pwm2 {
pinctrl-0 = <&pwm2m1_pins>;
/* connected with MIPI-DSI0 */
};
&pwm11 {
pinctrl-0 = <&pwm11m3_pins>;
/* connected with MIPI-DSI1 */
};
&route_dsi1 {
status = "okay";
connect = <&vp3_out_dsi1>;
};
&spdif_tx2 {
status = "okay";
};
&spdif_tx5 {
status = "okay";
};
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
rockchip,typec-vbus-det;
status = "okay";
};
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
rockchip,typec-vbus-det;
status = "okay";
};
&u2phy2 {
status = "okay";
};
&u2phy2_host {
status = "okay";
};
&u2phy3 {
status = "okay";
};
&u2phy3_host {
phy-supply = <&vcc5v0_host_30>;
status = "okay";
};
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
&usbdp_phy0 {
orientation-switch;
rockchip,dp-lane-mux = <0 1 2 3 >;
svid = <0xff01>;
sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
usbdp_phy0_orientation_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_orien_sw>;
};
usbdp_phy0_dp_altmode_mux: endpoint@1 {
reg = <1>;
remote-endpoint = <&dp0_altmode_mux>;
};
};
};
&usbdp_phy0_dp {
status = "okay";
};
&usbdp_phy0_u3 {
status = "okay";
};
&usbdrd3_0 {
status = "okay";
};
&usbdrd_dwc3_0 {
dr_mode = "otg";
usb-role-switch;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
dwc3_0_role_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_role_sw>;
};
};
};
&usbdp_phy1 {
orientation-switch;
rockchip,dp-lane-mux = <0 1 2 3 >;
svid = <0xff01>;
sbu1-dc-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
usbdp_phy1_orientation_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc1_orien_sw>;
};
usbdp_phy1_dp_altmode_mux: endpoint@1 {
reg = <1>;
remote-endpoint = <&dp1_altmode_mux>;
};
};
};
&usbdp_phy1_dp {
status = "okay";
};
&usbdp_phy1_u3 {
status = "okay";
};
&usbdrd3_1 {
status = "okay";
};
&usbdrd_dwc3_1 {
dr_mode = "otg";
usb-role-switch;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
dwc3_1_role_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc1_role_sw>;
};
};
};
&usbhost3_0 {
status = "okay";
};
&usbhost_dwc3_0 {
dr_mode = "host";
status = "okay";
};
&vcc_3v3_sd_s0 {
/delete-property/ enable-active-high;
gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_LOW>;
};

@ -557,6 +557,8 @@ CONFIG_ROCKCHIP_LVDS=y
CONFIG_ROCKCHIP_RGB=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_FRIENDLYELEC=y
CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_SII902X=y
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
CONFIG_DRM_DW_HDMI_CEC=y

@ -1134,6 +1134,7 @@ CONFIG_ROCKCHIP_RGB=y
CONFIG_DRM_UDL=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_FRIENDLYELEC=y
CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
CONFIG_DRM_DISPLAY_CONNECTOR=y
CONFIG_DRM_SII902X=y
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y

@ -10,9 +10,11 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/regulator/consumer.h>
#include <video/mipi_display.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
@ -38,150 +40,163 @@ struct cmd_set_entry {
* There is no description in the Reference Manual about these commands.
* We received them from vendor, so just use them as is.
*/
static const struct cmd_set_entry manufacturer_cmd_set[] = {
{0xFE, 0x0B},
{0x28, 0x40},
{0x29, 0x4F},
{0xFE, 0x0E},
{0x4B, 0x00},
{0x4C, 0x0F},
{0x4D, 0x20},
{0x4E, 0x40},
{0x4F, 0x60},
{0x50, 0xA0},
{0x51, 0xC0},
{0x52, 0xE0},
{0x53, 0xFF},
{0xFE, 0x0D},
{0x18, 0x08},
{0x42, 0x00},
{0x08, 0x41},
{0x46, 0x02},
{0x72, 0x09},
{0xFE, 0x0A},
{0x24, 0x17},
{0x04, 0x07},
{0x1A, 0x0C},
{0x0F, 0x44},
{0xFE, 0x04},
{0x00, 0x0C},
{0x05, 0x08},
{0x06, 0x08},
{0x08, 0x08},
{0x09, 0x08},
{0x0A, 0xE6},
{0x0B, 0x8C},
{0x1A, 0x12},
{0x1E, 0xE0},
{0x29, 0x93},
{0x2A, 0x93},
{0x2F, 0x02},
{0x31, 0x02},
{0x33, 0x05},
{0x37, 0x2D},
{0x38, 0x2D},
{0x3A, 0x1E},
{0x3B, 0x1E},
{0x3D, 0x27},
{0x3F, 0x80},
{0x40, 0x40},
{0x41, 0xE0},
{0x4F, 0x2F},
{0x50, 0x1E},
{0xFE, 0x06},
{0x00, 0xCC},
{0x05, 0x05},
{0x07, 0xA2},
{0x08, 0xCC},
{0x0D, 0x03},
{0x0F, 0xA2},
{0x32, 0xCC},
{0x37, 0x05},
{0x39, 0x83},
{0x3A, 0xCC},
{0x41, 0x04},
{0x43, 0x83},
{0x44, 0xCC},
{0x49, 0x05},
{0x4B, 0xA2},
{0x4C, 0xCC},
{0x51, 0x03},
{0x53, 0xA2},
{0x75, 0xCC},
{0x7A, 0x03},
{0x7C, 0x83},
{0x7D, 0xCC},
{0x82, 0x02},
{0x84, 0x83},
{0x85, 0xEC},
{0x86, 0x0F},
{0x87, 0xFF},
{0x88, 0x00},
{0x8A, 0x02},
{0x8C, 0xA2},
{0x8D, 0xEA},
{0x8E, 0x01},
{0x8F, 0xE8},
{0xFE, 0x06},
{0x90, 0x0A},
{0x92, 0x06},
{0x93, 0xA0},
{0x94, 0xA8},
{0x95, 0xEC},
{0x96, 0x0F},
{0x97, 0xFF},
{0x98, 0x00},
{0x9A, 0x02},
{0x9C, 0xA2},
{0xAC, 0x04},
{0xFE, 0x06},
{0xB1, 0x12},
{0xB2, 0x17},
{0xB3, 0x17},
{0xB4, 0x17},
{0xB5, 0x17},
{0xB6, 0x11},
{0xB7, 0x08},
{0xB8, 0x09},
{0xB9, 0x06},
{0xBA, 0x07},
{0xBB, 0x17},
{0xBC, 0x17},
{0xBD, 0x17},
{0xBE, 0x17},
{0xBF, 0x17},
{0xC0, 0x17},
{0xC1, 0x17},
{0xC2, 0x17},
{0xC3, 0x17},
{0xC4, 0x0F},
{0xC5, 0x0E},
{0xC6, 0x00},
{0xC7, 0x01},
{0xC8, 0x10},
{0xFE, 0x06},
{0x95, 0xEC},
{0x8D, 0xEE},
{0x44, 0xEC},
{0x4C, 0xEC},
{0x32, 0xEC},
{0x3A, 0xEC},
{0x7D, 0xEC},
{0x75, 0xEC},
{0x00, 0xEC},
{0x08, 0xEC},
{0x85, 0xEC},
{0xA6, 0x21},
{0xA7, 0x05},
{0xA9, 0x06},
{0x82, 0x06},
{0x41, 0x06},
{0x7A, 0x07},
{0x37, 0x07},
{0x05, 0x06},
{0x49, 0x06},
{0x0D, 0x04},
{0x51, 0x04},
static const struct cmd_set_entry mcs_rm67191[] = {
{0xFE, 0x0B}, {0x28, 0x40}, {0x29, 0x4F}, {0xFE, 0x0E},
{0x4B, 0x00}, {0x4C, 0x0F}, {0x4D, 0x20}, {0x4E, 0x40},
{0x4F, 0x60}, {0x50, 0xA0}, {0x51, 0xC0}, {0x52, 0xE0},
{0x53, 0xFF}, {0xFE, 0x0D}, {0x18, 0x08}, {0x42, 0x00},
{0x08, 0x41}, {0x46, 0x02}, {0x72, 0x09}, {0xFE, 0x0A},
{0x24, 0x17}, {0x04, 0x07}, {0x1A, 0x0C}, {0x0F, 0x44},
{0xFE, 0x04}, {0x00, 0x0C}, {0x05, 0x08}, {0x06, 0x08},
{0x08, 0x08}, {0x09, 0x08}, {0x0A, 0xE6}, {0x0B, 0x8C},
{0x1A, 0x12}, {0x1E, 0xE0}, {0x29, 0x93}, {0x2A, 0x93},
{0x2F, 0x02}, {0x31, 0x02}, {0x33, 0x05}, {0x37, 0x2D},
{0x38, 0x2D}, {0x3A, 0x1E}, {0x3B, 0x1E}, {0x3D, 0x27},
{0x3F, 0x80}, {0x40, 0x40}, {0x41, 0xE0}, {0x4F, 0x2F},
{0x50, 0x1E}, {0xFE, 0x06}, {0x00, 0xCC}, {0x05, 0x05},
{0x07, 0xA2}, {0x08, 0xCC}, {0x0D, 0x03}, {0x0F, 0xA2},
{0x32, 0xCC}, {0x37, 0x05}, {0x39, 0x83}, {0x3A, 0xCC},
{0x41, 0x04}, {0x43, 0x83}, {0x44, 0xCC}, {0x49, 0x05},
{0x4B, 0xA2}, {0x4C, 0xCC}, {0x51, 0x03}, {0x53, 0xA2},
{0x75, 0xCC}, {0x7A, 0x03}, {0x7C, 0x83}, {0x7D, 0xCC},
{0x82, 0x02}, {0x84, 0x83}, {0x85, 0xEC}, {0x86, 0x0F},
{0x87, 0xFF}, {0x88, 0x00}, {0x8A, 0x02}, {0x8C, 0xA2},
{0x8D, 0xEA}, {0x8E, 0x01}, {0x8F, 0xE8}, {0xFE, 0x06},
{0x90, 0x0A}, {0x92, 0x06}, {0x93, 0xA0}, {0x94, 0xA8},
{0x95, 0xEC}, {0x96, 0x0F}, {0x97, 0xFF}, {0x98, 0x00},
{0x9A, 0x02}, {0x9C, 0xA2}, {0xAC, 0x04}, {0xFE, 0x06},
{0xB1, 0x12}, {0xB2, 0x17}, {0xB3, 0x17}, {0xB4, 0x17},
{0xB5, 0x17}, {0xB6, 0x11}, {0xB7, 0x08}, {0xB8, 0x09},
{0xB9, 0x06}, {0xBA, 0x07}, {0xBB, 0x17}, {0xBC, 0x17},
{0xBD, 0x17}, {0xBE, 0x17}, {0xBF, 0x17}, {0xC0, 0x17},
{0xC1, 0x17}, {0xC2, 0x17}, {0xC3, 0x17}, {0xC4, 0x0F},
{0xC5, 0x0E}, {0xC6, 0x00}, {0xC7, 0x01}, {0xC8, 0x10},
{0xFE, 0x06}, {0x95, 0xEC}, {0x8D, 0xEE}, {0x44, 0xEC},
{0x4C, 0xEC}, {0x32, 0xEC}, {0x3A, 0xEC}, {0x7D, 0xEC},
{0x75, 0xEC}, {0x00, 0xEC}, {0x08, 0xEC}, {0x85, 0xEC},
{0xA6, 0x21}, {0xA7, 0x05}, {0xA9, 0x06}, {0x82, 0x06},
{0x41, 0x06}, {0x7A, 0x07}, {0x37, 0x07}, {0x05, 0x06},
{0x49, 0x06}, {0x0D, 0x04}, {0x51, 0x04},
};
static const struct cmd_set_entry mcs_rm67199[] = {
{0xFE, 0xA0}, {0x2B, 0x18}, {0xFE, 0x70}, {0x7D, 0x05},
{0x5D, 0x0A}, {0x5A, 0x79}, {0x5C, 0x00}, {0x52, 0x00},
{0xFE, 0xD0}, {0x40, 0x02}, {0x13, 0x40}, {0xFE, 0x40},
{0x05, 0x08}, {0x06, 0x08}, {0x08, 0x08}, {0x09, 0x08},
{0x0A, 0xCA}, {0x0B, 0x88}, {0x20, 0x93}, {0x21, 0x93},
{0x24, 0x02}, {0x26, 0x02}, {0x28, 0x05}, {0x2A, 0x05},
{0x74, 0x2F}, {0x75, 0x1E}, {0xAD, 0x00}, {0xFE, 0x60},
{0x00, 0xCC}, {0x01, 0x00}, {0x02, 0x04}, {0x03, 0x00},
{0x04, 0x00}, {0x05, 0x07}, {0x06, 0x00}, {0x07, 0x88},
{0x08, 0x00}, {0x09, 0xCC}, {0x0A, 0x00}, {0x0B, 0x04},
{0x0C, 0x00}, {0x0D, 0x00}, {0x0E, 0x05}, {0x0F, 0x00},
{0x10, 0x88}, {0x11, 0x00}, {0x12, 0xCC}, {0x13, 0x0F},
{0x14, 0xFF}, {0x15, 0x04}, {0x16, 0x00}, {0x17, 0x06},
{0x18, 0x00}, {0x19, 0x96}, {0x1A, 0x00}, {0x24, 0xCC},
{0x25, 0x00}, {0x26, 0x02}, {0x27, 0x00}, {0x28, 0x00},
{0x29, 0x06}, {0x2A, 0x06}, {0x2B, 0x82}, {0x2D, 0x00},
{0x2F, 0xCC}, {0x30, 0x00}, {0x31, 0x02}, {0x32, 0x00},
{0x33, 0x00}, {0x34, 0x07}, {0x35, 0x06}, {0x36, 0x82},
{0x37, 0x00}, {0x38, 0xCC}, {0x39, 0x00}, {0x3A, 0x02},
{0x3B, 0x00}, {0x3D, 0x00}, {0x3F, 0x07}, {0x40, 0x00},
{0x41, 0x88}, {0x42, 0x00}, {0x43, 0xCC}, {0x44, 0x00},
{0x45, 0x02}, {0x46, 0x00}, {0x47, 0x00}, {0x48, 0x06},
{0x49, 0x02}, {0x4A, 0x8A}, {0x4B, 0x00}, {0x5F, 0xCA},
{0x60, 0x01}, {0x61, 0xE8}, {0x62, 0x09}, {0x63, 0x00},
{0x64, 0x07}, {0x65, 0x00}, {0x66, 0x30}, {0x67, 0x80},
{0x9B, 0x03}, {0xA9, 0x07}, {0xAA, 0x06}, {0xAB, 0x02},
{0xAC, 0x10}, {0xAD, 0x11}, {0xAE, 0x05}, {0xAF, 0x04},
{0xB0, 0x10}, {0xB1, 0x10}, {0xB2, 0x10}, {0xB3, 0x10},
{0xB4, 0x10}, {0xB5, 0x10}, {0xB6, 0x10}, {0xB7, 0x10},
{0xB8, 0x10}, {0xB9, 0x10}, {0xBA, 0x04}, {0xBB, 0x05},
{0xBC, 0x00}, {0xBD, 0x01}, {0xBE, 0x0A}, {0xBF, 0x10},
{0xC0, 0x11}, {0xFE, 0xA0}, {0x22, 0x00},
};
static const struct cmd_set_entry mcs_zh055oe[] = {
{0xFE, 0xA0}, {0x2B, 0x18}, {0xFE, 0x70}, {0x7D, 0x35},
{0x5D, 0x0A}, {0x5A, 0x79}, {0x5C, 0x00}, {0x52, 0x00},
{0xFE, 0xD0}, {0x40, 0x02}, {0x13, 0x40}, {0xFE, 0x40},
{0x05, 0x08}, {0x06, 0x08}, {0x08, 0x08}, {0x09, 0x08},
{0x0A, 0xCA}, {0x0B, 0x88}, {0x20, 0x93}, {0x21, 0x93},
{0x24, 0x02}, {0x26, 0x02}, {0x28, 0x05}, {0x2A, 0x05},
{0x74, 0x2F}, {0x75, 0x1E}, {0xAD, 0x00}, {0xFE, 0x50},
{0xDA, 0x01}, {0x44, 0x05}, {0x42, 0x05}, {0x40, 0x05},
{0x3A, 0x05}, {0x38, 0x05}, {0x36, 0x05}, {0x34, 0x05},
{0x32, 0x05}, {0x30, 0x05}, {0x2A, 0x05}, {0x28, 0x05},
{0x26, 0x04}, {0x24, 0x04}, {0x22, 0x04}, {0x20, 0x04},
{0x1E, 0x04}, {0x1C, 0x04}, {0x1A, 0x04}, {0x18, 0x03},
{0x16, 0x03}, {0x14, 0x03}, {0x12, 0x03}, {0x10, 0x03},
{0x0E, 0x03}, {0x0C, 0x03}, {0x0A, 0x02}, {0x08, 0x02},
{0x06, 0x02}, {0x04, 0x02}, {0x02, 0x03}, {0xD0, 0x02},
{0xCE, 0x02}, {0x00, 0x00}, {0x45, 0xA7}, {0x43, 0xA0},
{0x41, 0x99}, {0x3B, 0x8C}, {0x39, 0x80}, {0x37, 0x6A},
{0x35, 0x54}, {0x33, 0x3F}, {0x31, 0x2A}, {0x2B, 0x15},
{0x29, 0x01}, {0x27, 0xED}, {0x25, 0xD9}, {0x23, 0xB0},
{0x21, 0x89}, {0x1F, 0x62}, {0x1D, 0x3A}, {0x1B, 0x11},
{0x19, 0xE9}, {0x17, 0xBF}, {0x15, 0x8B}, {0x13, 0x71},
{0x11, 0x56}, {0x0F, 0x34}, {0x0D, 0x0E}, {0x0B, 0xF5},
{0x09, 0xD9}, {0x07, 0xB8}, {0x05, 0x8F}, {0x03, 0x5E},
{0xD1, 0x7E}, {0xCF, 0x76}, {0x01, 0x00}, {0x86, 0x05},
{0x84, 0x05}, {0x82, 0x05}, {0x80, 0x05}, {0x7E, 0x05},
{0x7C, 0x05}, {0x7A, 0x05}, {0x78, 0x05}, {0x76, 0x05},
{0x74, 0x05}, {0x72, 0x05}, {0x70, 0x04}, {0x6E, 0x04},
{0x6C, 0x04}, {0x6A, 0x04}, {0x68, 0x04}, {0x66, 0x04},
{0x64, 0x04}, {0x62, 0x03}, {0x60, 0x03}, {0x5E, 0x03},
{0x5C, 0x03}, {0x5A, 0x03}, {0x58, 0x03}, {0x52, 0x03},
{0x50, 0x02}, {0x4E, 0x02}, {0x4C, 0x02}, {0x4A, 0x02},
{0x48, 0x03}, {0xD4, 0x02}, {0xD2, 0x02}, {0x46, 0x00},
{0x87, 0xAC}, {0x85, 0xA9}, {0x83, 0xA3}, {0x81, 0x96},
{0x7F, 0x8A}, {0x7D, 0x74}, {0x7B, 0x5E}, {0x79, 0x49},
{0x77, 0x34}, {0x75, 0x1F}, {0x73, 0x0B}, {0x71, 0xF7},
{0x6F, 0xE3}, {0x6D, 0xBB}, {0x6B, 0x93}, {0x69, 0x6B},
{0x67, 0x42}, {0x65, 0x1A}, {0x63, 0xF1}, {0x61, 0xC6},
{0x5F, 0x91}, {0x5D, 0x76}, {0x5B, 0x5B}, {0x59, 0x39},
{0x53, 0x12}, {0x51, 0xF9}, {0x4F, 0xDD}, {0x4D, 0xBC},
{0x4B, 0x93}, {0x49, 0x63}, {0xD5, 0x83}, {0xD3, 0x7B},
{0x47, 0x00}, {0xCC, 0x06}, {0xCA, 0x06}, {0xC8, 0x06},
{0xC6, 0x06}, {0xC4, 0x06}, {0xC2, 0x06}, {0xC0, 0x06},
{0xBE, 0x06}, {0xBC, 0x05}, {0xBA, 0x05}, {0xB8, 0x05},
{0xB6, 0x05}, {0xB4, 0x05}, {0xB2, 0x05}, {0xB0, 0x05},
{0xAE, 0x04}, {0xAC, 0x04}, {0xA6, 0x04}, {0xA4, 0x04},
{0x9E, 0x04}, {0x9C, 0x03}, {0x9A, 0x03}, {0x98, 0x03},
{0x96, 0x03}, {0x94, 0x03}, {0x92, 0x03}, {0x90, 0x03},
{0x8E, 0x02}, {0x8C, 0x02}, {0x8A, 0x03}, {0xD8, 0x02},
{0xD6, 0x02}, {0x88, 0x00}, {0xCD, 0x77}, {0xCB, 0x73},
{0xC9, 0x6B}, {0xC7, 0x5D}, {0xC5, 0x50}, {0xC3, 0x36},
{0xC1, 0x1C}, {0xBF, 0x03}, {0xBD, 0xEA}, {0xBB, 0xD1},
{0xB9, 0xB8}, {0xB7, 0xA0}, {0xB5, 0x87}, {0xB3, 0x56},
{0xB1, 0x26}, {0xAF, 0xF5}, {0xAD, 0xC4}, {0xA7, 0x92},
{0xA5, 0x5F}, {0x9F, 0x29}, {0x9D, 0xE6}, {0x9B, 0xC4},
{0x99, 0xA2}, {0x97, 0x77}, {0x95, 0x48}, {0x93, 0x2B},
{0x91, 0x0D}, {0x8F, 0xED}, {0x8D, 0xCD}, {0x8B, 0xB1},
{0xD9, 0xBD}, {0xD7, 0xB6}, {0x89, 0x00}, {0xFE, 0x60},
{0x00, 0xCC}, {0x01, 0x00}, {0x02, 0x04}, {0x03, 0x00},
{0x04, 0x00}, {0x05, 0x07}, {0x06, 0x00}, {0x07, 0x88},
{0x08, 0x00}, {0x09, 0xCC}, {0x0A, 0x00}, {0x0B, 0x04},
{0x0C, 0x00}, {0x0D, 0x00}, {0x0E, 0x05}, {0x0F, 0x00},
{0x10, 0x88}, {0x11, 0x00}, {0x12, 0xCC}, {0x13, 0x0F},
{0x14, 0xFF}, {0x15, 0x04}, {0x16, 0x00}, {0x17, 0x06},
{0x18, 0x00}, {0x19, 0x96}, {0x1A, 0x00}, {0x24, 0xCC},
{0x25, 0x00}, {0x26, 0x02}, {0x27, 0x00}, {0x28, 0x00},
{0x29, 0x06}, {0x2A, 0x06}, {0x2B, 0x82}, {0x2D, 0x00},
{0x2F, 0xCC}, {0x30, 0x00}, {0x31, 0x02}, {0x32, 0x00},
{0x33, 0x00}, {0x34, 0x07}, {0x35, 0x06}, {0x36, 0x82},
{0x37, 0x00}, {0x38, 0xCC}, {0x39, 0x00}, {0x3A, 0x02},
{0x3B, 0x00}, {0x3D, 0x00}, {0x3F, 0x07}, {0x40, 0x00},
{0x41, 0x88}, {0x42, 0x00}, {0x43, 0xCC}, {0x44, 0x00},
{0x45, 0x02}, {0x46, 0x00}, {0x47, 0x00}, {0x48, 0x06},
{0x49, 0x02}, {0x4A, 0x8A}, {0x4B, 0x00}, {0x5F, 0xCA},
{0x60, 0x01}, {0x61, 0xE8}, {0x62, 0x09}, {0x63, 0x00},
{0x64, 0x07}, {0x65, 0x00}, {0x66, 0x30}, {0x67, 0x80},
{0x9B, 0x03}, {0xA9, 0x07}, {0xAA, 0x06}, {0xAB, 0x02},
{0xAC, 0x10}, {0xAD, 0x11}, {0xAE, 0x05}, {0xAF, 0x04},
{0xB0, 0x10}, {0xB1, 0x10}, {0xB2, 0x10}, {0xB3, 0x10},
{0xB4, 0x10}, {0xB5, 0x10}, {0xB6, 0x10}, {0xB7, 0x10},
{0xB8, 0x10}, {0xB9, 0x10}, {0xBA, 0x04}, {0xBB, 0x05},
{0xBC, 0x00}, {0xBD, 0x01}, {0xBE, 0x0A}, {0xBF, 0x10},
{0xC0, 0x11}, {0xFE, 0xA0}, {0x22, 0x00},
};
static const u32 rad_bus_formats[] = {
@ -205,10 +220,19 @@ struct rad_panel {
bool prepared;
bool enabled;
const struct drm_display_mode *mode;
const struct rad_platform_data *pdata;
};
struct rad_platform_data {
int (*enable)(struct rad_panel *panel);
struct cmd_set_entry const *cmds;
size_t num_cmds;
};
static const struct drm_display_mode default_mode = {
.clock = 132000,
.clock = 121000,
.hdisplay = 1080,
.hsync_start = 1080 + 20,
.hsync_end = 1080 + 20 + 2,
@ -228,14 +252,15 @@ static inline struct rad_panel *to_rad_panel(struct drm_panel *panel)
return container_of(panel, struct rad_panel, panel);
}
static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi)
static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi,
struct cmd_set_entry const *cmd_set,
size_t count)
{
size_t i;
size_t count = ARRAY_SIZE(manufacturer_cmd_set);
int ret = 0;
for (i = 0; i < count; i++) {
const struct cmd_set_entry *entry = &manufacturer_cmd_set[i];
const struct cmd_set_entry *entry = cmd_set++;
u8 buffer[2] = { entry->cmd, entry->param };
ret = mipi_dsi_generic_write(dsi, &buffer, sizeof(buffer));
@ -273,11 +298,19 @@ static int rad_panel_prepare(struct drm_panel *panel)
if (ret)
return ret;
if (rad->reset)
gpiod_direction_output(rad->reset, 1);
/* At lest 10ms needed between power-on and reset-out as RM specifies */
usleep_range(10000, 12000);
if (rad->reset) {
gpiod_set_value_cansleep(rad->reset, 1);
usleep_range(3000, 5000);
gpiod_set_value_cansleep(rad->reset, 0);
usleep_range(18000, 20000);
/*
* 50ms delay after reset-out, as per manufacturer initalization
* sequence.
*/
msleep(50);
}
rad->prepared = true;
@ -313,20 +346,22 @@ static int rad_panel_unprepare(struct drm_panel *panel)
return 0;
}
static int rad_panel_enable(struct drm_panel *panel)
static int rm67191_enable(struct rad_panel *panel)
{
struct rad_panel *rad = to_rad_panel(panel);
struct mipi_dsi_device *dsi = rad->dsi;
struct mipi_dsi_device *dsi = panel->dsi;
struct device *dev = &dsi->dev;
u8 dsi_mode;
int color_format = color_format_from_dsi_format(dsi->format);
int ret;
if (rad->enabled)
if (panel->enabled)
return 0;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
ret = rad_panel_push_cmd_list(dsi);
ret = rad_panel_push_cmd_list(dsi,
panel->pdata->cmds,
panel->pdata->num_cmds);
if (ret < 0) {
dev_err(dev, "Failed to send MCS (%d)\n", ret);
goto fail;
@ -347,7 +382,8 @@ static int rad_panel_enable(struct drm_panel *panel)
usleep_range(15000, 17000);
/* Set DSI mode */
ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2);
dsi_mode = (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? 0x0B : 0x00;
ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, dsi_mode }, 2);
if (ret < 0) {
dev_err(dev, "Failed to set DSI mode (%d)\n", ret);
goto fail;
@ -386,18 +422,116 @@ static int rad_panel_enable(struct drm_panel *panel)
goto fail;
}
backlight_enable(rad->backlight);
backlight_enable(panel->backlight);
rad->enabled = true;
panel->enabled = true;
return 0;
fail:
gpiod_set_value_cansleep(rad->reset, 1);
gpiod_set_value_cansleep(panel->reset, 1);
return ret;
}
static int rm67199_enable(struct rad_panel *panel)
{
struct mipi_dsi_device *dsi = panel->dsi;
struct device *dev = &dsi->dev;
u8 dsi_mode;
int color_format = color_format_from_dsi_format(dsi->format);
int ret;
if (panel->enabled)
return 0;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
ret = rad_panel_push_cmd_list(dsi,
panel->pdata->cmds,
panel->pdata->num_cmds);
if (ret < 0) {
dev_err(dev, "Failed to send MCS (%d)\n", ret);
goto fail;
}
/* Select User Command Set table (CMD1) */
ret = mipi_dsi_generic_write(dsi, (u8[]){ WRMAUCCTR, 0x00 }, 2);
if (ret < 0)
goto fail;
/* Set DSI mode */
dsi_mode = (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? 0x0B : 0x00;
ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, dsi_mode }, 2);
if (ret < 0) {
dev_err(dev, "Failed to set DSI mode (%d)\n", ret);
goto fail;
}
/* Set tear ON */
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
if (ret < 0) {
dev_err(dev, "Failed to set tear ON (%d)\n", ret);
goto fail;
}
/* Set tear scanline */
ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x00);
if (ret < 0) {
dev_err(dev, "Failed to set tear scanline (%d)\n", ret);
goto fail;
}
/* Set pixel format */
ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format);
dev_dbg(dev, "Interface color format set to 0x%x\n",
color_format);
if (ret < 0) {
dev_err(dev, "Failed to set pixel format (%d)\n", ret);
goto fail;
}
/* Exit sleep mode */
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
dev_err(dev, "Failed to exit sleep mode (%d)\n", ret);
goto fail;
}
/*
* Although, 120ms seems a lot, this is the amount of delay that the
* manufacturer suggests it should be used between the sleep-out and
* display-on commands
*/
msleep(120);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret < 0) {
dev_err(dev, "Failed to set display ON (%d)\n", ret);
goto fail;
}
/*
* Also, 100ms delay between display-on and backlight enable as per
* manufacturer initialization sequence.
*/
msleep(100);
backlight_enable(panel->backlight);
panel->enabled = true;
return 0;
fail:
gpiod_set_value_cansleep(panel->reset, 1);
return ret;
}
static int rad_panel_enable(struct drm_panel *panel)
{
struct rad_panel *rad = to_rad_panel(panel);
return rad->pdata->enable(rad);
}
static int rad_panel_disable(struct drm_panel *panel)
{
struct rad_panel *rad = to_rad_panel(panel);
@ -436,13 +570,14 @@ static int rad_panel_disable(struct drm_panel *panel)
static int rad_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct rad_panel *rad = to_rad_panel(panel);
struct drm_display_mode *mode;
mode = drm_mode_duplicate(connector->dev, &default_mode);
mode = drm_mode_duplicate(connector->dev, rad->mode);
if (!mode) {
dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
default_mode.hdisplay, default_mode.vdisplay,
drm_mode_vrefresh(&default_mode));
rad->mode->hdisplay, rad->mode->vdisplay,
drm_mode_vrefresh(rad->mode));
return -ENOMEM;
}
@ -460,27 +595,6 @@ static int rad_panel_get_modes(struct drm_panel *panel,
return 1;
}
static int rad_bl_get_brightness(struct backlight_device *bl)
{
struct mipi_dsi_device *dsi = bl_get_data(bl);
struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
u16 brightness;
int ret;
if (!rad->prepared)
return 0;
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
if (ret < 0)
return ret;
bl->props.brightness = brightness;
return brightness & 0xff;
}
static int rad_bl_update_status(struct backlight_device *bl)
{
struct mipi_dsi_device *dsi = bl_get_data(bl);
@ -501,7 +615,6 @@ static int rad_bl_update_status(struct backlight_device *bl)
static const struct backlight_ops rad_bl_ops = {
.update_status = rad_bl_update_status,
.get_brightness = rad_bl_get_brightness,
};
static const struct drm_panel_funcs rad_panel_funcs = {
@ -512,6 +625,28 @@ static const struct drm_panel_funcs rad_panel_funcs = {
.get_modes = rad_panel_get_modes,
};
int panel_rad_loader_protect(struct drm_panel *panel)
{
struct rad_panel *p;
int err;
if (panel->funcs != &rad_panel_funcs) {
dev_dbg(panel->dev, "not rad-panel\n");
return -ENODEV;
}
p = to_rad_panel(panel);
err = regulator_bulk_enable(p->num_supplies, p->supplies);
if (err)
return err;
p->prepared = true;
p->enabled = true;
return 0;
}
EXPORT_SYMBOL(panel_rad_loader_protect);
static const char * const rad_supply_names[] = {
"v3p3",
"v1p8",
@ -534,15 +669,46 @@ static int rad_init_regulators(struct rad_panel *rad)
return devm_regulator_bulk_get(dev, rad->num_supplies, rad->supplies);
};
static const struct rad_platform_data rad_rm67191 = {
.enable = &rm67191_enable,
.cmds = mcs_rm67191,
.num_cmds = ARRAY_SIZE(mcs_rm67191),
};
static const struct rad_platform_data rad_rm67199 = {
.enable = &rm67199_enable,
.cmds = mcs_rm67199,
.num_cmds = ARRAY_SIZE(mcs_rm67199),
};
static const struct rad_platform_data rad_zh055oe = {
.enable = &rm67199_enable,
.cmds = mcs_zh055oe,
.num_cmds = ARRAY_SIZE(mcs_zh055oe),
};
static const struct of_device_id rad_of_match[] = {
{ .compatible = "raydium,rm67191", .data = &rad_rm67191 },
{ .compatible = "raydium,rm67199", .data = &rad_rm67199 },
{ .compatible = "zhot,zh055oe041", .data = &rad_zh055oe },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rad_of_match);
static int rad_panel_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
const struct of_device_id *of_id = of_match_device(rad_of_match, dev);
struct device_node *np = dev->of_node;
struct device_node *child;
struct rad_panel *panel;
struct backlight_properties bl_props;
int ret;
u32 video_mode;
if (!of_id || !of_id->data)
return -ENODEV;
panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL);
if (!panel)
return -ENOMEM;
@ -550,23 +716,46 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, panel);
panel->dsi = dsi;
panel->pdata = of_id->data;
panel->mode = &default_mode;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_EOT_PACKET;
child = of_get_child_by_name(np, "display-timings");
of_node_put(child);
if (child) {
struct drm_display_mode *mode;
mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
if (!mode)
return -ENOMEM;
if (!of_get_drm_display_mode(np, mode, NULL, OF_USE_NATIVE_MODE))
panel->mode = mode;
}
ret = of_property_read_u32(np, "video-mode", &video_mode);
if (!ret) {
switch (video_mode) {
case 0:
/* burst mode */
dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST;
dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_VIDEO;
break;
case 1:
/* non-burst mode with sync event */
dsi->mode_flags |= MIPI_DSI_MODE_VIDEO;
break;
case 2:
/* non-burst mode with sync pulse */
dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_VIDEO;
break;
case 3:
/* command mode */
dsi->mode_flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS |
MIPI_DSI_MODE_VSYNC_FLUSH;
break;
default:
dev_warn(dev, "invalid video mode %d\n", video_mode);
@ -580,9 +769,14 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi)
return ret;
}
panel->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(panel->reset))
return PTR_ERR(panel->reset);
panel->reset = devm_gpiod_get_optional(dev, "reset",
GPIOD_ASIS |
GPIOD_FLAGS_BIT_NONEXCLUSIVE);
if (IS_ERR(panel->reset)) {
ret = PTR_ERR(panel->reset);
dev_err(dev, "Failed to get reset gpio (%d)\n", ret);
return ret;
}
memset(&bl_props, 0, sizeof(bl_props));
bl_props.type = BACKLIGHT_RAW;
@ -638,12 +832,6 @@ static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
rad_panel_unprepare(&rad->panel);
}
static const struct of_device_id rad_of_match[] = {
{ .compatible = "raydium,rm67191", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rad_of_match);
static struct mipi_dsi_driver rad_panel_driver = {
.driver = {
.name = "panel-raydium-rm67191",

@ -16,4 +16,14 @@ static inline int panel_simple_loader_protect(struct drm_panel *panel)
return 0;
}
#endif
#if IS_REACHABLE(CONFIG_DRM_PANEL_RAYDIUM_RM67191)
int panel_rad_loader_protect(struct drm_panel *panel);
#else
static inline int panel_rad_loader_protect(struct drm_panel *panel)
{
return 0;
}
#endif
#endif /* PANEL_SIMPLE_H */

@ -970,8 +970,10 @@ static int dw_mipi_dsi2_encoder_loader_protect(struct drm_encoder *encoder,
{
struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder);
if (dsi2->panel)
if (dsi2->panel) {
panel_rad_loader_protect(dsi2->panel);
panel_simple_loader_protect(dsi2->panel);
}
dw_mipi_dsi2_loader_protect(dsi2, on);

@ -364,6 +364,12 @@ static int gt1x_parse_dt(struct device *dev)
}
#endif
#if GTP_DRIVER_SEND_CFG
gt1x_keep_otp_config = of_property_read_bool(dev->of_node, "keep-otp-config");
#else
gt1x_keep_otp_config = true;
#endif
return 0;
}

@ -73,6 +73,7 @@ u32 gt1x_abs_x_max;
u32 gt1x_abs_y_max;
int gt1x_halt;
bool gt1x_ics_slot_report;
bool gt1x_keep_otp_config;
#if GTP_DEBUG_NODE
static ssize_t gt1x_debug_read_proc(struct file *, char __user *, size_t, loff_t *);
@ -629,14 +630,26 @@ s32 gt1x_init_panel(void)
}
set_reg_bit(gt1x_config[MODULE_SWITCH3_LOC], 5, !gt1x_wakeup_level);
#endif /* END GTP_CUSTOM_CFG */
#endif /* END GTP_DRIVER_SEND_CFG */
#else /* DRIVER NOT SEND CONFIG */
cfg_len = GTP_CONFIG_MAX_LENGTH;
ret = gt1x_i2c_read(GTP_REG_CONFIG_DATA, gt1x_config, cfg_len);
if (ret < 0) {
return ret;
if (gt1x_keep_otp_config) {
cfg_len = GTP_CONFIG_MAX_LENGTH;
ret = gt1x_i2c_read(GTP_REG_CONFIG_DATA, gt1x_config, cfg_len);
if (ret < 0) {
GTP_ERROR("Failed to read CONFIG data, sensor_id %d", gt1x_version.sensor_id);
return ret;
} else {
int i;
u16 checksum = 0;
for (i = 0; i < cfg_len - 4; i += 2) {
checksum += (gt1x_config[i] << 8) + gt1x_config[i + 1];
}
checksum = 0 - checksum;
if (!checksum || checksum != ((gt1x_config[i] << 8) + gt1x_config[i + 1])) {
GTP_ERROR("Invalid config data, checksum %04x", checksum);
}
}
}
#endif /* END GTP_DRIVER_SEND_CFG */
GTP_DEBUG_FUNC();
/* match resolution when gt1x_abs_x_max & gt1x_abs_y_max have been set already */
@ -657,7 +670,10 @@ s32 gt1x_init_panel(void)
GTP_INFO("X_MAX=%d,Y_MAX=%d,TRIGGER=0x%02x,WAKEUP_LEVEL=%d", gt1x_abs_x_max, gt1x_abs_y_max, gt1x_int_type, gt1x_wakeup_level);
gt1x_cfg_length = cfg_len;
ret = gt1x_send_cfg(gt1x_config, gt1x_cfg_length);
if (!gt1x_keep_otp_config) {
ret = gt1x_send_cfg(gt1x_config, gt1x_cfg_length);
}
return ret;
}

@ -534,6 +534,7 @@ extern s32 gt1x_i2c_read(u16 addr, u8 *buffer, s32 len);
extern s32 gt1x_i2c_read_dbl_check(u16 addr, u8 *buffer, s32 len);
extern bool gt1x_ics_slot_report;
extern bool gt1x_keep_otp_config;
extern u8 gt1x_config[];
extern u32 gt1x_cfg_length;
extern u8 gt1x_int_type;

Loading…
Cancel
Save