Skip to content

Instantly share code, notes, and snippets.

@anarsoul
Created June 25, 2018 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anarsoul/5db7dc1637d587ba02c6ab46a770cdba to your computer and use it in GitHub Desktop.
Save anarsoul/5db7dc1637d587ba02c6ab46a770cdba to your computer and use it in GitHub Desktop.
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
index ed715426fffc..bd0871ece01b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
@@ -41,14 +41,51 @@
*/
#include "sun50i-a64-pine64.dts"
+#include <dt-bindings/pwm/pwm.h>
/ {
model = "Pine64+";
compatible = "pine64,pine64-plus", "allwinner,sun50i-a64";
+ pwm_bl: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <1 2 4 8 16 32 64 128 255>;
+ default-brightness-level = <8>;
+ enable-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
+ };
+
+
/* TODO: Camera, touchscreen, etc. */
};
+&de {
+ status = "okay";
+};
+
+&mixer0 {
+ status = "okay";
+};
+
+&tcon0 {
+ status = "okay";
+};
+
+&dphy {
+ status = "okay";
+};
+
+&dsi {
+ status = "okay";
+
+ panel@0 {
+ compatible = "feiyang,fy07024di26a30d", "simple-panel";
+ reg = <0>;
+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_LOW>; /* PD24 */
+ backlight = <&pwm_bl>;
+ };
+};
+
&emac {
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
@@ -63,3 +100,13 @@
reg = <1>;
};
};
+
+&r_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_pwm_pin>;
+ status = "okay";
+};
+
+&reg_dldo2 {
+ regulator-always-on;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 71474dc4fab1..375202628982 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -263,8 +263,8 @@
};
&reg_dldo2 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
regulator-name = "vcc-mipi";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 5cc818b7e192..89c216dc32ae 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -436,6 +436,11 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+ tcon0_out_dsi: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dsi_in_tcon0>;
+ };
};
};
};
@@ -820,6 +825,44 @@
#thermal-sensor-cells = <1>;
};
+ dsi: dsi@1ca0000 {
+ compatible = "allwinner,sun50i-a64-mipi-dsi";
+ reg = <0x01ca0000 0x1000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_MIPI_DSI>;
+ clock-names = "bus";
+ resets = <&ccu RST_BUS_MIPI_DSI>;
+ phys = <&dphy>;
+ phy-names = "dphy";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ dsi_in_tcon0: endpoint {
+ remote-endpoint = <&tcon0_out_dsi>;
+ };
+ };
+ };
+ };
+
+ dphy: d-phy@1ca1000 {
+ compatible = "allwinner,sun6i-a31-mipi-dphy";
+ reg = <0x01ca1000 0x1000>;
+ clocks = <&ccu CLK_BUS_MIPI_DSI>,
+ <&ccu CLK_DSI_DPHY>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_MIPI_DSI>;
+ status = "disabled";
+ #phy-cells = <0>;
+ };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
@@ -1119,6 +1162,19 @@
#size-cells = <0>;
};
+
+ r_pwm: pwm@1f03800 {
+ compatible = "allwinner,sun50i-a64-pwm",
+ "allwinner,sun5i-a13-pwm";
+ reg = <0x01f03800 0x400>;
+ clocks = <&osc24M>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_pwm_pin>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun50i-a64-r-pinctrl";
reg = <0x01f02c00 0x400>;
@@ -1139,6 +1195,12 @@
pins = "PL8", "PL9";
function = "s_i2c";
};
+
+ r_pwm_pin: pwm {
+ pins = "PL10";
+ function = "s_pwm";
+ };
+
};
r_rsb: rsb@1f03400 {
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index cbf1ab404ee7..2658d649d429 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2389,6 +2389,30 @@ static const struct panel_desc_dsi boe_tv080wum_nl0 = {
.lanes = 4,
};
+static const struct drm_display_mode feiyang_fy07024di26a30d_mode = {
+ .clock = 48960,
+ .hdisplay = 1024,
+ .hsync_start = 1024 + 40,
+ .hsync_end = 1024 + 40 + 104,
+ .htotal = 1024 + 40 + 104 + 144,
+ .vdisplay = 600,
+ .vsync_start = 600 + 1,
+ .vsync_end = 600 + 1 + 3,
+ .vtotal = 600 + 1 + 3 + 18,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc feiyang_fy07024di26a30d = {
+ .modes = &feiyang_fy07024di26a30d_mode,
+ .num_modes = 1,
+ .bpc = 8,
+ .size = {
+ .width = 163,
+ .height = 97,
+ },
+ .bus_format = MIPI_DSI_FMT_RGB888,
+};
+
static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
.clock = 71000,
.hdisplay = 800,
@@ -2481,6 +2505,9 @@ static const struct of_device_id dsi_of_match[] = {
}, {
.compatible = "boe,tv080wum-nl0",
.data = &boe_tv080wum_nl0
+ }, {
+ .compatible = "feiyang,fy07024di26a30d",
+ .data = &feiyang_fy07024di26a30d,
}, {
.compatible = "lg,ld070wx3-sl01",
.data = &lg_ld070wx3_sl01
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index bfbf761f0c1d..0637d1fc9ade 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -10,6 +10,7 @@
#include <linux/component.h>
#include <linux/crc-ccitt.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
@@ -957,6 +958,7 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
return -ENOMEM;
dev_set_drvdata(dev, dsi);
dsi->dev = dev;
+ dsi->quirks = of_device_get_match_data(dev);
dsi->host.ops = &sun6i_dsi_host_ops;
dsi->host.dev = dev;
@@ -980,17 +982,20 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
return PTR_ERR(dsi->reset);
}
- dsi->mod_clk = devm_clk_get(dev, "mod");
- if (IS_ERR(dsi->mod_clk)) {
- dev_err(dev, "Couldn't get the DSI mod clock\n");
- return PTR_ERR(dsi->mod_clk);
+ if (dsi->quirks->has_mod_clock) {
+ dsi->mod_clk = devm_clk_get(dev, "mod");
+ if (IS_ERR(dsi->mod_clk)) {
+ dev_err(dev, "Couldn't get the DSI mod clock\n");
+ return PTR_ERR(dsi->mod_clk);
+ }
}
/*
* In order to operate properly, that clock seems to be always
* set to 297MHz.
*/
- clk_set_rate_exclusive(dsi->mod_clk, 297000000);
+ if (dsi->mod_clk)
+ clk_set_rate_exclusive(dsi->mod_clk, 297000000);
dphy_node = of_parse_phandle(dev->of_node, "phys", 0);
ret = sun6i_dphy_probe(dsi, dphy_node);
@@ -1022,7 +1027,8 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
pm_runtime_disable(dev);
sun6i_dphy_remove(dsi);
err_unprotect_clk:
- clk_rate_exclusive_put(dsi->mod_clk);
+ if (dsi->mod_clk)
+ clk_rate_exclusive_put(dsi->mod_clk);
return ret;
}
@@ -1035,7 +1041,8 @@ static int sun6i_dsi_remove(struct platform_device *pdev)
mipi_dsi_host_unregister(&dsi->host);
pm_runtime_disable(dev);
sun6i_dphy_remove(dsi);
- clk_rate_exclusive_put(dsi->mod_clk);
+ if (dsi->mod_clk)
+ clk_rate_exclusive_put(dsi->mod_clk);
return 0;
}
@@ -1045,7 +1052,8 @@ static int sun6i_dsi_runtime_resume(struct device *dev)
struct sun6i_dsi *dsi = dev_get_drvdata(dev);
reset_control_deassert(dsi->reset);
- clk_prepare_enable(dsi->mod_clk);
+ if (dsi->mod_clk)
+ clk_prepare_enable(dsi->mod_clk);
/*
* Enable the DSI block.
@@ -1073,7 +1081,8 @@ static int sun6i_dsi_runtime_suspend(struct device *dev)
{
struct sun6i_dsi *dsi = dev_get_drvdata(dev);
- clk_disable_unprepare(dsi->mod_clk);
+ if (dsi->mod_clk)
+ clk_disable_unprepare(dsi->mod_clk);
reset_control_assert(dsi->reset);
return 0;
@@ -1085,8 +1094,17 @@ static const struct dev_pm_ops sun6i_dsi_pm_ops = {
NULL)
};
+static const struct sun6i_dsi_quirks sun6i_a31_quirks = {
+ .has_mod_clock = true,
+};
+
+static const struct sun6i_dsi_quirks sun50i_a64_quirks = {
+ .has_mod_clock = false,
+};
+
static const struct of_device_id sun6i_dsi_of_table[] = {
- { .compatible = "allwinner,sun6i-a31-mipi-dsi" },
+ { .compatible = "allwinner,sun6i-a31-mipi-dsi", .data = &sun6i_a31_quirks },
+ { .compatible = "allwinner,sun50i-a64-mipi-dsi", .data = &sun50i_a64_quirks },
{ }
};
MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index dbbc5b3ecbda..31bf48ad3c2d 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -35,6 +35,13 @@ struct sun6i_dsi {
struct sun4i_drv *drv;
struct mipi_dsi_device *device;
struct drm_panel *panel;
+
+ const struct sun6i_dsi_quirks *quirks;
+
+};
+
+struct sun6i_dsi_quirks {
+ bool has_mod_clock; /* a64 does not have mod clock */
};
static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment