Guest User

Untitled

a guest
Oct 18th, 2018
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 68.25 KB | None | 0 0
  1. From 6d8ddf32722560b47f04a1f1c133a0138d6cb458 Mon Sep 17 00:00:00 2001
  2. From: Vasily Khoruzhick <anarsoul@gmail.com>
  3. Date: Tue, 24 Jul 2018 10:17:28 -0700
  4. Subject: [PATCH 01/17] Pine64 panel WIP
  5.  
  6. ---
  7. drivers/gpu/drm/panel/Kconfig | 9 +
  8. drivers/gpu/drm/panel/Makefile | 1 +
  9. .../drm/panel/panel-feiyang-fy07024di26a30d.c | 284 ++++++++++++++++++
  10. 3 files changed, 294 insertions(+)
  11. create mode 100644 drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
  12.  
  13. diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
  14. index 6020c30a33b3..147745ef70e1 100644
  15. --- a/drivers/gpu/drm/panel/Kconfig
  16. +++ b/drivers/gpu/drm/panel/Kconfig
  17. @@ -55,6 +55,15 @@ config DRM_PANEL_ILITEK_ILI9881C
  18. Say Y if you want to enable support for panels based on the
  19. Ilitek ILI9881c controller.
  20.  
  21. +config DRM_PANEL_FEIYANG_FY07024DI26A30D
  22. + tristate "Feiyang FY07024DI26A30D Panel"
  23. + depends on OF
  24. + depends on DRM_MIPI_DSI
  25. + depends on BACKLIGHT_CLASS_DEVICE
  26. + help
  27. + Say Y if you want to enable support for Feiyang
  28. + FY07024DI26A30D panel
  29. +
  30. config DRM_PANEL_INNOLUX_P079ZCA
  31. tristate "Innolux P079ZCA panel"
  32. depends on OF
  33. diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
  34. index 5ccaaa9d13af..24e08cf68e70 100644
  35. --- a/drivers/gpu/drm/panel/Makefile
  36. +++ b/drivers/gpu/drm/panel/Makefile
  37. @@ -19,3 +19,4 @@ obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
  38. obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
  39. obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
  40. obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
  41. +obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
  42. diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
  43. new file mode 100644
  44. index 000000000000..9f82b544a789
  45. --- /dev/null
  46. +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
  47. @@ -0,0 +1,284 @@
  48. +// SPDX-License-Identifier: GPL-2.0+
  49. +/*
  50. + * Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
  51. + */
  52. +
  53. +#include <linux/backlight.h>
  54. +#include <linux/delay.h>
  55. +#include <linux/device.h>
  56. +#include <linux/err.h>
  57. +#include <linux/errno.h>
  58. +#include <linux/fb.h>
  59. +#include <linux/kernel.h>
  60. +#include <linux/module.h>
  61. +
  62. +#include <linux/gpio/consumer.h>
  63. +#include <linux/regulator/consumer.h>
  64. +
  65. +#include <drm/drm_mipi_dsi.h>
  66. +#include <drm/drm_modes.h>
  67. +#include <drm/drm_panel.h>
  68. +
  69. +#include <video/mipi_display.h>
  70. +
  71. +struct fy07024di26a30d {
  72. + struct drm_panel panel;
  73. + struct mipi_dsi_device *dsi;
  74. +
  75. + struct backlight_device *backlight;
  76. + struct regulator *dvdd;
  77. + struct regulator *avdd;
  78. + struct gpio_desc *reset;
  79. +};
  80. +
  81. +struct fy07024di26a30d_cmd {
  82. + u8 cmd;
  83. + u8 data;
  84. +};
  85. +
  86. +static struct fy07024di26a30d_cmd fy07024di26a30d_init[] = {
  87. + { .cmd = 0x80, .data = 0x58 },
  88. + { .cmd = 0x81, .data = 0x47 },
  89. + { .cmd = 0x82, .data = 0xD4 },
  90. + { .cmd = 0x83, .data = 0x88 },
  91. + { .cmd = 0x84, .data = 0xA9 },
  92. + { .cmd = 0x85, .data = 0xC3 },
  93. + { .cmd = 0x86, .data = 0x82 },
  94. +};
  95. +
  96. +static inline struct fy07024di26a30d *panel_to_fy07024di26a30d(struct drm_panel *panel)
  97. +{
  98. + return container_of(panel, struct fy07024di26a30d, panel);
  99. +}
  100. +
  101. +static int fy07024di26a30d_send_cmd_data(struct fy07024di26a30d *ctx, u8 cmd, u8 data)
  102. +{
  103. + int ret;
  104. +
  105. + ret = mipi_dsi_dcs_write(ctx->dsi, cmd,
  106. + (u8[]){ data }, 1);
  107. + if (ret < 0)
  108. + return ret;
  109. +
  110. + return 0;
  111. +}
  112. +
  113. +static int fy07024di26a30d_prepare(struct drm_panel *panel)
  114. +{
  115. + struct fy07024di26a30d *ctx = panel_to_fy07024di26a30d(panel);
  116. + unsigned int i;
  117. + int ret;
  118. + u8 mode;
  119. +
  120. + gpiod_set_value(ctx->reset, 1);
  121. + msleep(50);
  122. +
  123. + msleep(100);
  124. +
  125. + gpiod_set_value(ctx->reset, 0);
  126. + msleep(20);
  127. +
  128. + gpiod_set_value(ctx->reset, 1);
  129. + msleep(200);
  130. +
  131. + for (i = 0; i < ARRAY_SIZE(fy07024di26a30d_init); i++) {
  132. + struct fy07024di26a30d_cmd *cmd = &fy07024di26a30d_init[i];
  133. +
  134. + ret = fy07024di26a30d_send_cmd_data(ctx, cmd->cmd,
  135. + cmd->data);
  136. +
  137. + if (ret)
  138. + return ret;
  139. + }
  140. +
  141. + //mipi_dsi_dcs_get_power_mode(ctx->dsi, &mode);
  142. + //pr_info("%s: mode: %.8x\n", __func__, (unsigned)mode);
  143. +
  144. + //ret = mipi_dsi_dcs_set_tear_on(ctx->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
  145. + //if (ret)
  146. + // return ret;
  147. +
  148. + //mipi_dsi_dcs_exit_sleep_mode(ctx->dsi);
  149. + //if (ret)
  150. + // return ret;
  151. + //mipi_dsi_dcs_get_power_mode(ctx->dsi, &mode);
  152. + //pr_info("%s: mode: %.8x\n", __func__, (unsigned)mode);
  153. +
  154. + return 0;
  155. +}
  156. +
  157. +static int fy07024di26a30d_enable(struct drm_panel *panel)
  158. +{
  159. + struct fy07024di26a30d *ctx = panel_to_fy07024di26a30d(panel);
  160. +
  161. + msleep(120);
  162. +
  163. + backlight_enable(ctx->backlight);
  164. +
  165. + return 0;
  166. +}
  167. +
  168. +static int fy07024di26a30d_disable(struct drm_panel *panel)
  169. +{
  170. + struct fy07024di26a30d *ctx = panel_to_fy07024di26a30d(panel);
  171. +
  172. + backlight_disable(ctx->backlight);
  173. + gpiod_set_value(ctx->reset, 0);
  174. +
  175. + return 0;
  176. +}
  177. +
  178. +static int fy07024di26a30d_unprepare(struct drm_panel *panel)
  179. +{
  180. + struct fy07024di26a30d *ctx = panel_to_fy07024di26a30d(panel);
  181. +
  182. + //mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
  183. + //gpiod_set_value(ctx->reset, 0);
  184. +
  185. + return 0;
  186. +}
  187. +
  188. +static const struct drm_display_mode default_mode = {
  189. + .clock = 55000,
  190. + .hdisplay = 1024,
  191. + .hsync_start = 1024 + 396,
  192. + .hsync_end = 1024 + 396 + 20,
  193. + .htotal = 1024 + 396 + 20 + 100,
  194. + .vdisplay = 600,
  195. + .vsync_start = 600 + 12,
  196. + .vsync_end = 600 + 12 + 2,
  197. + .vtotal = 600 + 12 + 2 + 21,
  198. + .vrefresh = 60,
  199. +};
  200. +
  201. +static int fy07024di26a30d_get_modes(struct drm_panel *panel)
  202. +{
  203. + struct drm_connector *connector = panel->connector;
  204. + struct fy07024di26a30d *ctx = panel_to_fy07024di26a30d(panel);
  205. + struct drm_display_mode *mode;
  206. +
  207. + mode = drm_mode_duplicate(panel->drm, &default_mode);
  208. + if (!mode) {
  209. + dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",
  210. + default_mode.hdisplay, default_mode.vdisplay,
  211. + default_mode.vrefresh);
  212. + return -ENOMEM;
  213. + }
  214. +
  215. + drm_mode_set_name(mode);
  216. +
  217. + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  218. + drm_mode_probed_add(connector, mode);
  219. +
  220. + panel->connector->display_info.width_mm = 62;
  221. + panel->connector->display_info.height_mm = 110;
  222. +
  223. + return 1;
  224. +}
  225. +
  226. +static const struct drm_panel_funcs fy07024di26a30d_funcs = {
  227. + .prepare = fy07024di26a30d_prepare,
  228. + .unprepare = fy07024di26a30d_unprepare,
  229. + .enable = fy07024di26a30d_enable,
  230. + .disable = fy07024di26a30d_disable,
  231. + .get_modes = fy07024di26a30d_get_modes,
  232. +};
  233. +
  234. +static int fy07024di26a30d_dsi_probe(struct mipi_dsi_device *dsi)
  235. +{
  236. + struct device_node *np;
  237. + struct fy07024di26a30d *ctx;
  238. + int ret;
  239. +
  240. + ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL);
  241. + if (!ctx)
  242. + return -ENOMEM;
  243. +
  244. + ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd");
  245. + if (IS_ERR(ctx->dvdd))
  246. + return PTR_ERR(ctx->dvdd);
  247. +
  248. + ctx->avdd = devm_regulator_get(&dsi->dev, "avdd");
  249. + if (IS_ERR(ctx->avdd))
  250. + return PTR_ERR(ctx->avdd);
  251. +
  252. + ret = regulator_enable(ctx->dvdd);
  253. + if (ret < 0) {
  254. + dev_err(&dsi->dev, "failed to enable dvdd: %d\n", ret);
  255. + return ret;
  256. + }
  257. +
  258. + msleep(100);
  259. +
  260. + ret = regulator_enable(ctx->avdd);
  261. + if (ret < 0) {
  262. + dev_err(&dsi->dev, "failed to enable avdd: %d\n", ret);
  263. + regulator_disable(ctx->dvdd);
  264. + return ret;
  265. + }
  266. +
  267. + mipi_dsi_set_drvdata(dsi, ctx);
  268. + ctx->dsi = dsi;
  269. +
  270. + drm_panel_init(&ctx->panel);
  271. + ctx->panel.dev = &dsi->dev;
  272. + ctx->panel.funcs = &fy07024di26a30d_funcs;
  273. +
  274. + ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
  275. + if (IS_ERR(ctx->reset)) {
  276. + dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
  277. + return PTR_ERR(ctx->reset);
  278. + }
  279. +
  280. + np = of_parse_phandle(dsi->dev.of_node, "backlight", 0);
  281. + if (np) {
  282. + ctx->backlight = of_find_backlight_by_node(np);
  283. + of_node_put(np);
  284. +
  285. + if (!ctx->backlight)
  286. + return -EPROBE_DEFER;
  287. + }
  288. +
  289. + ret = drm_panel_add(&ctx->panel);
  290. + if (ret < 0)
  291. + return ret;
  292. +
  293. + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;
  294. + dsi->format = MIPI_DSI_FMT_RGB888;
  295. + dsi->lanes = 4;
  296. +
  297. + return mipi_dsi_attach(dsi);
  298. +}
  299. +
  300. +static int fy07024di26a30d_dsi_remove(struct mipi_dsi_device *dsi)
  301. +{
  302. + struct fy07024di26a30d *ctx = mipi_dsi_get_drvdata(dsi);
  303. +
  304. + mipi_dsi_detach(dsi);
  305. + drm_panel_remove(&ctx->panel);
  306. +
  307. + if (ctx->backlight)
  308. + put_device(&ctx->backlight->dev);
  309. +
  310. + return 0;
  311. +}
  312. +
  313. +static const struct of_device_id fy07024di26a30d_of_match[] = {
  314. + { .compatible = "feiyang,fy07024di26a30d" },
  315. + { }
  316. +};
  317. +MODULE_DEVICE_TABLE(of, fy07024di26a30d_of_match);
  318. +
  319. +static struct mipi_dsi_driver fy07024di26a30d_dsi_driver = {
  320. + .probe = fy07024di26a30d_dsi_probe,
  321. + .remove = fy07024di26a30d_dsi_remove,
  322. + .driver = {
  323. + .name = "fy07024di26a30d-dsi",
  324. + .of_match_table = fy07024di26a30d_of_match,
  325. + },
  326. +};
  327. +module_mipi_dsi_driver(fy07024di26a30d_dsi_driver);
  328. +
  329. +MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>");
  330. +MODULE_DESCRIPTION("Feiyang FY07024DI26A30D Panel Driver");
  331. +MODULE_LICENSE("GPL v2");
  332. --
  333. 2.19.1
  334.  
  335.  
  336. From 2c927dc91912e615ff8b8720ef92e6ec6dfdda68 Mon Sep 17 00:00:00 2001
  337. From: Vasily Khoruzhick <anarsoul@gmail.com>
  338. Date: Tue, 24 Jul 2018 10:17:55 -0700
  339. Subject: [PATCH 02/17] A64 DSI CCU WIP
  340.  
  341. ---
  342. drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 10 ++++++----
  343. drivers/clk/sunxi-ng/ccu_nkm.c | 7 +++++++
  344. drivers/clk/sunxi-ng/ccu_nkm.h | 2 ++
  345. 3 files changed, 15 insertions(+), 4 deletions(-)
  346.  
  347. diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  348. index d0e30192f0cf..5680ed5fd875 100644
  349. --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  350. +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  351. @@ -160,11 +160,13 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
  352. #define SUN50I_A64_PLL_MIPI_REG 0x040
  353.  
  354. static struct ccu_nkm pll_mipi_clk = {
  355. - .enable = BIT(31),
  356. + .enable = BIT(31) | BIT(23) | BIT(22),
  357. .lock = BIT(28),
  358. .n = _SUNXI_CCU_MULT(8, 4),
  359. .k = _SUNXI_CCU_MULT_MIN(4, 2, 2),
  360. .m = _SUNXI_CCU_DIV(0, 4),
  361. + //.min_rate = 550000000,
  362. + //.max_rate = 1400000000,
  363. .common = {
  364. .reg = 0x040,
  365. .hw.init = CLK_HW_INIT("pll-mipi", "pll-video0",
  366. @@ -515,8 +517,8 @@ static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
  367. static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
  368. 0x104, 0, 4, 24, 3, BIT(31), 0);
  369.  
  370. -static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
  371. -static const u8 tcon0_table[] = { 0, 2, };
  372. +static const char * const tcon0_parents[] = { "pll-mipi", };
  373. +static const u8 tcon0_table[] = { 0, };
  374. static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
  375. tcon0_table, 0x118, 24, 3, BIT(31),
  376. CLK_SET_RATE_PARENT);
  377. @@ -579,7 +581,7 @@ static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-periph0" };
  378. static const u8 dsi_dphy_table[] = { 0, 2, };
  379. static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
  380. dsi_dphy_parents, dsi_dphy_table,
  381. - 0x168, 0, 4, 8, 2, BIT(31), CLK_SET_RATE_PARENT);
  382. + 0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT);
  383.  
  384. static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
  385. 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
  386. diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
  387. index 841840e35e61..884d6f54ab6d 100644
  388. --- a/drivers/clk/sunxi-ng/ccu_nkm.c
  389. +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
  390. @@ -122,6 +122,13 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
  391. _nkm.min_m = 1;
  392. _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
  393.  
  394. +#if 0
  395. + if (rate < nkm->min_rate)
  396. + rate = nkm->min_rate;
  397. + if (rate > nkm->max_rate)
  398. + rate = nkm->max_rate;
  399. +#endif
  400. +
  401. if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
  402. rate *= nkm->fixed_post_div;
  403.  
  404. diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
  405. index cc6efb70a102..c82590481188 100644
  406. --- a/drivers/clk/sunxi-ng/ccu_nkm.h
  407. +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
  408. @@ -35,6 +35,8 @@ struct ccu_nkm {
  409. struct ccu_mux_internal mux;
  410.  
  411. unsigned int fixed_post_div;
  412. + unsigned int min_rate;
  413. + unsigned int max_rate;
  414.  
  415. struct ccu_common common;
  416. };
  417. --
  418. 2.19.1
  419.  
  420.  
  421. From b4d6b59401e4af84bdf4210493ac6a6219bb7227 Mon Sep 17 00:00:00 2001
  422. From: Vasily Khoruzhick <anarsoul@gmail.com>
  423. Date: Tue, 24 Jul 2018 10:18:55 -0700
  424. Subject: [PATCH 03/17] pinebook bl WIP
  425.  
  426. ---
  427. arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 10 ++++++++++
  428. 1 file changed, 10 insertions(+)
  429.  
  430. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
  431. index 897e60cbe38d..e2e426334cfe 100644
  432. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
  433. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
  434. @@ -22,12 +22,22 @@
  435. ethernet0 = &rtl8723cs;
  436. };
  437.  
  438. + vdd_bl: regulator@0 {
  439. + compatible = "regulator-fixed";
  440. + regulator-name = "bl-3v3";
  441. + regulator-min-microvolt = <3300000>;
  442. + regulator-max-microvolt = <3300000>;
  443. + gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
  444. + enable-active-high;
  445. + };
  446. +
  447. backlight: backlight {
  448. compatible = "pwm-backlight";
  449. pwms = <&pwm 0 50000 0>;
  450. brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>;
  451. default-brightness-level = <2>;
  452. enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */
  453. + power-supply = <&vdd_bl>;
  454. };
  455.  
  456. chosen {
  457. --
  458. 2.19.1
  459.  
  460.  
  461. From 69f64b9fb15d9fb0093fc3a26aac04477b2587ac Mon Sep 17 00:00:00 2001
  462. From: Vasily Khoruzhick <anarsoul@gmail.com>
  463. Date: Tue, 24 Jul 2018 10:19:09 -0700
  464. Subject: [PATCH 04/17] A64 DSI DTS wip
  465.  
  466. ---
  467. .../dts/allwinner/sun50i-a64-pine64-plus.dts | 45 ++++++++++++++++
  468. arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 54 +++++++++++++++++++
  469. 2 files changed, 99 insertions(+)
  470.  
  471. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
  472. index 24f1aac366d6..bd3a965591bd 100644
  473. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
  474. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
  475. @@ -41,14 +41,53 @@
  476. */
  477.  
  478. #include "sun50i-a64-pine64.dts"
  479. +#include <dt-bindings/pwm/pwm.h>
  480.  
  481. / {
  482. model = "Pine64+";
  483. compatible = "pine64,pine64-plus", "allwinner,sun50i-a64";
  484.  
  485. + pwm_bl: backlight {
  486. + compatible = "pwm-backlight";
  487. + pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
  488. + brightness-levels = <1 2 4 8 16 32 64 128 255>;
  489. + default-brightness-level = <8>;
  490. + enable-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
  491. + };
  492. +
  493. +
  494. /* TODO: Camera, touchscreen, etc. */
  495. };
  496.  
  497. +&de {
  498. + status = "okay";
  499. +};
  500. +
  501. +&mixer0 {
  502. + status = "okay";
  503. +};
  504. +
  505. +&tcon0 {
  506. + status = "okay";
  507. +};
  508. +
  509. +&dphy {
  510. + status = "okay";
  511. +};
  512. +
  513. +&dsi {
  514. + status = "okay";
  515. +
  516. + panel@0 {
  517. + compatible = "feiyang,fy07024di26a30d", "simple-panel";
  518. + reg = <0>;
  519. + reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
  520. + backlight = <&pwm_bl>;
  521. + avdd-supply = <&reg_dc1sw>;
  522. + dvdd-supply = <&reg_dldo2>;
  523. + };
  524. +};
  525. +
  526. &emac {
  527. pinctrl-names = "default";
  528. pinctrl-0 = <&rgmii_pins>;
  529. @@ -63,3 +102,9 @@
  530. reg = <1>;
  531. };
  532. };
  533. +
  534. +&r_pwm {
  535. + pinctrl-names = "default";
  536. + pinctrl-0 = <&r_pwm_pin>;
  537. + status = "okay";
  538. +};
  539. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  540. index 522b9d9a8188..40b77c4a20e7 100644
  541. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  542. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  543. @@ -349,6 +349,11 @@
  544. #address-cells = <1>;
  545. #size-cells = <0>;
  546. reg = <1>;
  547. +
  548. + tcon0_out_dsi: endpoint@1 {
  549. + reg = <1>;
  550. + remote-endpoint = <&dsi_in_tcon0>;
  551. + };
  552. };
  553. };
  554. };
  555. @@ -707,6 +712,55 @@
  556. status = "disabled";
  557. };
  558.  
  559. + ths: thermal-sensor@1c25000 {
  560. + compatible = "allwinner,sun50i-a64-ths";
  561. + reg = <0x01c25000 0x100>;
  562. + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
  563. + clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
  564. + clock-names = "bus", "mod";
  565. + resets = <&ccu RST_BUS_THS>;
  566. + #io-channel-cells = <0>;
  567. + #thermal-sensor-cells = <1>;
  568. + };
  569. +
  570. + dsi: dsi@1ca0000 {
  571. + compatible = "allwinner,sun50i-a64-mipi-dsi";
  572. + reg = <0x01ca0000 0x1000>;
  573. + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
  574. + clocks = <&ccu CLK_BUS_MIPI_DSI>,
  575. + <&ccu CLK_DSI_DPHY>;
  576. + clock-names = "bus", "mod";
  577. + resets = <&ccu RST_BUS_MIPI_DSI>;
  578. + phys = <&dphy>;
  579. + phy-names = "dphy";
  580. + status = "disabled";
  581. +
  582. + ports {
  583. + #address-cells = <1>;
  584. + #size-cells = <0>;
  585. +
  586. + port@0 {
  587. + #address-cells = <1>;
  588. + #size-cells = <0>;
  589. + reg = <0>;
  590. +
  591. + dsi_in_tcon0: endpoint {
  592. + remote-endpoint = <&tcon0_out_dsi>;
  593. + };
  594. + };
  595. + };
  596. + };
  597. +
  598. + dphy: d-phy@1ca1000 {
  599. + compatible = "allwinner,sun50i-a64-mipi-dphy";
  600. + reg = <0x01ca1000 0x1000>;
  601. + clocks = <&ccu CLK_BUS_MIPI_DSI>;
  602. + clock-names = "bus";
  603. + resets = <&ccu RST_BUS_MIPI_DSI>;
  604. + status = "disabled";
  605. + #phy-cells = <0>;
  606. + };
  607. +
  608. uart0: serial@1c28000 {
  609. compatible = "snps,dw-apb-uart";
  610. reg = <0x01c28000 0x400>;
  611. --
  612. 2.19.1
  613.  
  614.  
  615. From 3e6b7e8a18aefddf802eaf331475631b651363dc Mon Sep 17 00:00:00 2001
  616. From: Vasily Khoruzhick <anarsoul@gmail.com>
  617. Date: Tue, 24 Jul 2018 17:40:28 -0700
  618. Subject: [PATCH 05/17] ccu wip
  619.  
  620. ---
  621. drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 6 +++---
  622. drivers/clk/sunxi-ng/ccu_nkm.c | 4 +---
  623. 2 files changed, 4 insertions(+), 6 deletions(-)
  624.  
  625. diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  626. index 5680ed5fd875..e710a098d324 100644
  627. --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  628. +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  629. @@ -165,8 +165,8 @@ static struct ccu_nkm pll_mipi_clk = {
  630. .n = _SUNXI_CCU_MULT(8, 4),
  631. .k = _SUNXI_CCU_MULT_MIN(4, 2, 2),
  632. .m = _SUNXI_CCU_DIV(0, 4),
  633. - //.min_rate = 550000000,
  634. - //.max_rate = 1400000000,
  635. + .min_rate = 300000000,
  636. + .max_rate = 1400000000,
  637. .common = {
  638. .reg = 0x040,
  639. .hw.init = CLK_HW_INIT("pll-mipi", "pll-video0",
  640. @@ -517,7 +517,7 @@ static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
  641. static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
  642. 0x104, 0, 4, 24, 3, BIT(31), 0);
  643.  
  644. -static const char * const tcon0_parents[] = { "pll-mipi", };
  645. +static const char * const tcon0_parents[] = { "pll-mipi", "pll-video-2x" };
  646. static const u8 tcon0_table[] = { 0, };
  647. static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
  648. tcon0_table, 0x118, 24, 3, BIT(31),
  649. diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
  650. index 884d6f54ab6d..01e6df4c1232 100644
  651. --- a/drivers/clk/sunxi-ng/ccu_nkm.c
  652. +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
  653. @@ -122,12 +122,10 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
  654. _nkm.min_m = 1;
  655. _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
  656.  
  657. -#if 0
  658. if (rate < nkm->min_rate)
  659. rate = nkm->min_rate;
  660. - if (rate > nkm->max_rate)
  661. + if (nkm->max_rate && (rate > nkm->max_rate))
  662. rate = nkm->max_rate;
  663. -#endif
  664.  
  665. if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
  666. rate *= nkm->fixed_post_div;
  667. --
  668. 2.19.1
  669.  
  670.  
  671. From 79bdbd811779351add3472c01751fc84f47c091e Mon Sep 17 00:00:00 2001
  672. From: Vasily Khoruzhick <anarsoul@gmail.com>
  673. Date: Tue, 24 Jul 2018 17:40:42 -0700
  674. Subject: [PATCH 06/17] mipi dsi irq wip
  675.  
  676. ---
  677. drivers/gpu/drm/sun4i/sun4i_tcon.c | 21 ++++++---
  678. drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
  679. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 65 ++++++++++++++++++++++++++
  680. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 3 +-
  681. 4 files changed, 82 insertions(+), 8 deletions(-)
  682.  
  683. diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  684. index 67f34799074b..8869fa6a69a1 100644
  685. --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
  686. +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  687. @@ -669,12 +669,23 @@ static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
  688. spin_unlock_irqrestore(&dev->event_lock, flags);
  689. }
  690.  
  691. -static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  692. +void sun4i_tcon_handle_vblank(struct sun4i_tcon *tcon)
  693. {
  694. - struct sun4i_tcon *tcon = private;
  695. struct drm_device *drm = tcon->drm;
  696. struct sun4i_crtc *scrtc = tcon->crtc;
  697. struct sunxi_engine *engine = scrtc->engine;
  698. +
  699. + drm_crtc_handle_vblank(&scrtc->crtc);
  700. + sun4i_tcon_finish_page_flip(drm, scrtc);
  701. +
  702. + if (engine->ops->vblank_quirk)
  703. + engine->ops->vblank_quirk(engine);
  704. +}
  705. +EXPORT_SYMBOL(sun4i_tcon_handle_vblank);
  706. +
  707. +static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  708. +{
  709. + struct sun4i_tcon *tcon = private;
  710. unsigned int status;
  711.  
  712. regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
  713. @@ -684,9 +695,6 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  714. SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT)))
  715. return IRQ_NONE;
  716.  
  717. - drm_crtc_handle_vblank(&scrtc->crtc);
  718. - sun4i_tcon_finish_page_flip(drm, scrtc);
  719. -
  720. /* Acknowledge the interrupt */
  721. regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
  722. SUN4I_TCON_GINT0_VBLANK_INT(0) |
  723. @@ -694,8 +702,7 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  724. SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT,
  725. 0);
  726.  
  727. - if (engine->ops->vblank_quirk)
  728. - engine->ops->vblank_quirk(engine);
  729. + sun4i_tcon_handle_vblank(tcon);
  730.  
  731. return IRQ_HANDLED;
  732. }
  733. diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
  734. index 7428e967d61c..11605c54fd9b 100644
  735. --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
  736. +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
  737. @@ -279,6 +279,7 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
  738. const struct drm_display_mode *mode);
  739. void sun4i_tcon_set_status(struct sun4i_tcon *crtc,
  740. const struct drm_encoder *encoder, bool enable);
  741. +void sun4i_tcon_handle_vblank(struct sun4i_tcon *crtc);
  742.  
  743. extern const struct of_device_id sun4i_tcon_of_table[];
  744.  
  745. diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  746. index d8d4e9723854..4892b76b0cd8 100644
  747. --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  748. +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  749. @@ -25,6 +25,7 @@
  750. #include <drm/drm_panel.h>
  751.  
  752. #include "sun4i_drv.h"
  753. +#include "sun4i_tcon.h"
  754. #include "sun6i_mipi_dsi.h"
  755.  
  756. #include <video/mipi_display.h>
  757. @@ -32,6 +33,10 @@
  758. #define SUN6I_DSI_CTL_REG 0x000
  759. #define SUN6I_DSI_CTL_EN BIT(0)
  760.  
  761. +#define SUN6I_DSI_GINT_REG 0x004
  762. +#define SUN6I_DSI_GINT_VIDEO_VBLK_ENABLE BIT(2)
  763. +#define SUN6I_DSI_GINT_VIDEO_VBLK_INT BIT(18)
  764. +
  765. #define SUN6I_DSI_BASIC_CTL_REG 0x00c
  766. #define SUN6I_DSI_BASIC_CTL_TRAIL_INV(n) (((n) & 0xf) << 4)
  767. #define SUN6I_DSI_BASIC_CTL_TRAIL_FILL BIT(3)
  768. @@ -738,6 +743,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
  769. udelay(1000);
  770.  
  771. sun6i_dsi_start(dsi, DSI_START_HSD);
  772. +
  773. + regmap_write(dsi->regs, SUN6I_DSI_GINT_REG,
  774. + SUN6I_DSI_GINT_VIDEO_VBLK_ENABLE);
  775. }
  776.  
  777. static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
  778. @@ -746,6 +754,8 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
  779.  
  780. DRM_DEBUG_DRIVER("Disabling DSI output\n");
  781.  
  782. + regmap_write(dsi->regs, SUN6I_DSI_GINT_REG, 0);
  783. +
  784. if (!IS_ERR(dsi->panel)) {
  785. drm_panel_disable(dsi->panel);
  786. drm_panel_unprepare(dsi->panel);
  787. @@ -968,6 +978,46 @@ static ssize_t sun6i_dsi_transfer(struct mipi_dsi_host *host,
  788. return ret;
  789. }
  790.  
  791. +static irqreturn_t sun6i_dsi_handler(int irq, void *private)
  792. +{
  793. + struct sun6i_dsi *dsi = private;
  794. + struct sun4i_tcon *tcon = dsi->tcon;
  795. + unsigned int status;
  796. +
  797. + regmap_read(dsi->regs, SUN6I_DSI_GINT_REG, &status);
  798. +
  799. + if (!(status & SUN6I_DSI_GINT_VIDEO_VBLK_INT))
  800. + return IRQ_NONE;
  801. +
  802. + regmap_update_bits(dsi->regs, SUN6I_DSI_GINT_REG,
  803. + SUN6I_DSI_GINT_VIDEO_VBLK_INT,
  804. + SUN6I_DSI_GINT_VIDEO_VBLK_INT);
  805. +
  806. + sun4i_tcon_handle_vblank(tcon);
  807. +
  808. + return IRQ_HANDLED;
  809. +}
  810. +static int sun6i_dsi_init_irq(struct device *dev, struct sun6i_dsi *dsi)
  811. +{
  812. + struct platform_device *pdev = to_platform_device(dev);
  813. + int irq, ret;
  814. +
  815. + irq = platform_get_irq(pdev, 0);
  816. + if (irq < 0) {
  817. + dev_err(dev, "Couldn't retrieve the DSI interrupt\n");
  818. + return irq;
  819. + }
  820. +
  821. + ret = devm_request_irq(dev, irq, sun6i_dsi_handler, 0,
  822. + dev_name(dev), dsi);
  823. + if (ret) {
  824. + dev_err(dev, "Couldn't request the IRQ\n");
  825. + return ret;
  826. + }
  827. +
  828. + return 0;
  829. +}
  830. +
  831. static const struct mipi_dsi_host_ops sun6i_dsi_host_ops = {
  832. .attach = sun6i_dsi_attach,
  833. .detach = sun6i_dsi_detach,
  834. @@ -988,6 +1038,7 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
  835. struct drm_device *drm = data;
  836. struct sun4i_drv *drv = drm->dev_private;
  837. struct sun6i_dsi *dsi = dev_get_drvdata(dev);
  838. + struct sun4i_tcon *tcon;
  839. int ret;
  840.  
  841. if (!dsi->panel)
  842. @@ -995,6 +1046,19 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
  843.  
  844. dsi->drv = drv;
  845.  
  846. + list_for_each_entry(tcon, &drv->tcon_list, list)
  847. + if (tcon->id == 0)
  848. + dsi->tcon = tcon;
  849. +
  850. + if (!dsi->tcon)
  851. + return -EPROBE_DEFER;
  852. +
  853. + if (dsi->quirks->use_dsi_irq) {
  854. + ret = sun6i_dsi_init_irq(dev, dsi);
  855. + if (ret)
  856. + return ret;
  857. + }
  858. +
  859. drm_encoder_helper_add(&dsi->encoder,
  860. &sun6i_dsi_enc_helper_funcs);
  861. ret = drm_encoder_init(drm,
  862. @@ -1195,6 +1259,7 @@ static const struct sun6i_dsi_quirks sun6i_a31_quirks = {
  863.  
  864. static const struct sun6i_dsi_quirks sun50i_a64_quirks = {
  865. .mod_clk_freq = 148500000,
  866. + .use_dsi_irq = true,
  867. };
  868.  
  869. static const struct of_device_id sun6i_dsi_of_table[] = {
  870. diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
  871. index d08a930867b2..cfbbedb99905 100644
  872. --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
  873. +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
  874. @@ -38,15 +38,16 @@ struct sun6i_dsi {
  875.  
  876. struct device *dev;
  877. struct sun4i_drv *drv;
  878. + struct sun4i_tcon *tcon;
  879. struct mipi_dsi_device *device;
  880. struct drm_panel *panel;
  881.  
  882. const struct sun6i_dsi_quirks *quirks;
  883. -
  884. };
  885.  
  886. struct sun6i_dsi_quirks {
  887. long mod_clk_freq;
  888. + bool use_dsi_irq;
  889. };
  890.  
  891. static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
  892. --
  893. 2.19.1
  894.  
  895.  
  896. From fd544868a846aa902f1ae9774c42bdbde781d079 Mon Sep 17 00:00:00 2001
  897. From: Vasily Khoruzhick <anarsoul@gmail.com>
  898. Date: Tue, 24 Jul 2018 17:49:42 -0700
  899. Subject: [PATCH 07/17] mipi dsi: don't hardcode tcoon_div
  900.  
  901. ---
  902. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 8 ++++++--
  903. 1 file changed, 6 insertions(+), 2 deletions(-)
  904.  
  905. diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  906. index 4892b76b0cd8..79b8f1d70cc8 100644
  907. --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  908. +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  909. @@ -379,8 +379,12 @@ static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
  910. if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
  911. unsigned int bpp = mipi_dsi_pixel_format_to_bpp(device->format);
  912. u32 line_num, edge0, edge1, sync_point = 40;
  913. - /* FIXME: we need actual tcon_div here */
  914. - u32 tcon_div = 6;
  915. + unsigned long dclk_rate, dclk_parent_rate;
  916. + u32 tcon_div;
  917. +
  918. + dclk_rate = clk_get_rate(dsi->tcon->dclk);
  919. + dclk_parent_rate = clk_get_rate(clk_get_parent(dsi->tcon->dclk));
  920. + tcon_div = dclk_parent_rate / dclk_rate;
  921.  
  922. line_num = mode->htotal * bpp / (8 * device->lanes);
  923. edge1 = sync_point + (mode->hdisplay + mode->htotal - mode->hsync_start + 20) * bpp / (8 * device->lanes);
  924. --
  925. 2.19.1
  926.  
  927.  
  928. From 94ff092406a837bb28d426161c98cea7e25ad0b3 Mon Sep 17 00:00:00 2001
  929. From: Vasily Khoruzhick <anarsoul@gmail.com>
  930. Date: Tue, 24 Jul 2018 23:40:31 -0700
  931. Subject: [PATCH 08/17] working DSI
  932.  
  933. ---
  934. drivers/gpu/drm/sun4i/sun4i_tcon.c | 2 +-
  935. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 18 ++++++++++++++----
  936. 2 files changed, 15 insertions(+), 5 deletions(-)
  937.  
  938. diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  939. index 8869fa6a69a1..64ed55ee4dbe 100644
  940. --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
  941. +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  942. @@ -1218,7 +1218,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
  943. SUN4I_TCON1_CTL_SRC_SEL_MASK,
  944. tcon->id);
  945. }
  946. -#if 1
  947. +#if 0
  948. /* Test pattern - white */
  949. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  950. SUN4I_TCON0_CTL_SRC_SEL_MASK,
  951. diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  952. index 79b8f1d70cc8..3d277396b1ac 100644
  953. --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  954. +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  955. @@ -366,8 +366,14 @@ static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
  956. static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
  957. struct drm_display_mode *mode)
  958. {
  959. + u32 vfp = mode->vtotal - mode->vdisplay - (mode->vtotal - mode->vsync_start);
  960. + u32 start_delay = mode->vtotal - vfp + 1;
  961. + if (start_delay > mode->vtotal)
  962. + start_delay -= mode->vtotal;
  963. + if (!start_delay)
  964. + start_delay = 1;
  965. //return mode->vtotal - (mode->vsync_end - mode->vdisplay) + 1;
  966. - return mode->vtotal - mode->vdisplay - 10;
  967. + return start_delay;
  968. }
  969.  
  970. static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
  971. @@ -578,8 +584,8 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
  972. regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE0_REG,
  973. SUN6I_DSI_BASIC_SIZE0_VSA(mode->vsync_end -
  974. mode->vsync_start) |
  975. - SUN6I_DSI_BASIC_SIZE0_VBP(mode->vsync_start -
  976. - mode->vdisplay));
  977. + SUN6I_DSI_BASIC_SIZE0_VBP(mode->vtotal -
  978. + mode->vsync_end));
  979.  
  980. regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE1_REG,
  981. SUN6I_DSI_BASIC_SIZE1_VACT(mode->vdisplay) |
  982. @@ -987,9 +993,13 @@ static irqreturn_t sun6i_dsi_handler(int irq, void *private)
  983. struct sun6i_dsi *dsi = private;
  984. struct sun4i_tcon *tcon = dsi->tcon;
  985. unsigned int status;
  986. + static int cnt;
  987.  
  988. regmap_read(dsi->regs, SUN6I_DSI_GINT_REG, &status);
  989.  
  990. + cnt++;
  991. + if (!(cnt % 60))
  992. + pr_info("%s %.8x\n", __func__, status);
  993. if (!(status & SUN6I_DSI_GINT_VIDEO_VBLK_INT))
  994. return IRQ_NONE;
  995.  
  996. @@ -1263,7 +1273,7 @@ static const struct sun6i_dsi_quirks sun6i_a31_quirks = {
  997.  
  998. static const struct sun6i_dsi_quirks sun50i_a64_quirks = {
  999. .mod_clk_freq = 148500000,
  1000. - .use_dsi_irq = true,
  1001. + //.use_dsi_irq = true,
  1002. };
  1003.  
  1004. static const struct of_device_id sun6i_dsi_of_table[] = {
  1005. --
  1006. 2.19.1
  1007.  
  1008.  
  1009. From d10a541628554f0ac3be3ba31bd1e74546b6061d Mon Sep 17 00:00:00 2001
  1010. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1011. Date: Wed, 15 Aug 2018 09:59:19 +0200
  1012. Subject: [PATCH 09/17] drm: added panel driver for a FullHD 5" LCD SHARP
  1013. LS050T1SX01
  1014.  
  1015. ---
  1016. .../display/panel/sharp,ls050t1sx01.txt | 22 +
  1017. drivers/gpu/drm/panel/Kconfig | 8 +
  1018. drivers/gpu/drm/panel/Makefile | 1 +
  1019. .../gpu/drm/panel/panel-sharp-ls050t1sx01.c | 375 ++++++++++++++++++
  1020. 4 files changed, 406 insertions(+)
  1021. create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  1022. create mode 100644 drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1023.  
  1024. diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt b/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  1025. new file mode 100644
  1026. index 000000000000..bb0ba34c3813
  1027. --- /dev/null
  1028. +++ b/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  1029. @@ -0,0 +1,22 @@
  1030. +Sharp Microelectronics 5.0" qHD TFT LCD panel
  1031. +
  1032. +Required properties:
  1033. +- compatible: should be "sharp,ls050t1sx01-qhd"
  1034. +- reg: DSI virtual channel of the peripheral
  1035. +- power-supply: phandle of the regulator that provides the supply voltage
  1036. +
  1037. +Optional properties:
  1038. +- backlight: phandle of the backlight device attached to the panel
  1039. +- reset-gpios: a GPIO spec for the reset pin
  1040. +
  1041. +Example:
  1042. +
  1043. + mdss_dsi@fd922800 {
  1044. + panel@0 {
  1045. + compatible = "sharp,ls050t1sx01";
  1046. + reg = <0>;
  1047. + avdd-supply = <&pm8941_l22>;
  1048. + backlight = <&pm8941_wled>;
  1049. + reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
  1050. + };
  1051. + };
  1052. diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
  1053. index 147745ef70e1..248aa99c6e5c 100644
  1054. --- a/drivers/gpu/drm/panel/Kconfig
  1055. +++ b/drivers/gpu/drm/panel/Kconfig
  1056. @@ -187,6 +187,14 @@ config DRM_PANEL_SHARP_LS043T1LE01
  1057. Say Y here if you want to enable support for Sharp LS043T1LE01 qHD
  1058. (540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard
  1059.  
  1060. +config DRM_PANEL_SHARP_LS050T1SX01
  1061. + tristate "Sharp LS050T1SX01 FullHD video mode panel"
  1062. + depends on OF
  1063. + depends on DRM_MIPI_DSI
  1064. + depends on BACKLIGHT_CLASS_DEVICE
  1065. + help
  1066. + Say Y here if you want to enable support for Sharp LS050T1SX01
  1067. +
  1068. config DRM_PANEL_SITRONIX_ST7789V
  1069. tristate "Sitronix ST7789V panel"
  1070. depends on OF && SPI
  1071. diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
  1072. index 24e08cf68e70..1e13757c0905 100644
  1073. --- a/drivers/gpu/drm/panel/Makefile
  1074. +++ b/drivers/gpu/drm/panel/Makefile
  1075. @@ -17,6 +17,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
  1076. obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
  1077. obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
  1078. obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
  1079. +obj-$(CONFIG_DRM_PANEL_SHARP_LS050T1SX01) += panel-sharp-ls050t1sx01.o
  1080. obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
  1081. obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
  1082. obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
  1083. diff --git a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1084. new file mode 100644
  1085. index 000000000000..17b481acb28c
  1086. --- /dev/null
  1087. +++ b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1088. @@ -0,0 +1,375 @@
  1089. +#include <linux/backlight.h>
  1090. +#include <linux/gpio/consumer.h>
  1091. +#include <linux/module.h>
  1092. +#include <linux/of.h>
  1093. +#include <linux/regulator/consumer.h>
  1094. +
  1095. +#include <drm/drmP.h>
  1096. +#include <drm/drm_crtc.h>
  1097. +#include <drm/drm_mipi_dsi.h>
  1098. +#include <drm/drm_panel.h>
  1099. +
  1100. +#include <video/mipi_display.h>
  1101. +
  1102. +struct sharp_panel {
  1103. + struct drm_panel base;
  1104. + struct mipi_dsi_device *dsi;
  1105. +
  1106. + struct backlight_device *backlight;
  1107. + struct regulator *supply;
  1108. + struct gpio_desc *reset_gpio;
  1109. +
  1110. + bool prepared;
  1111. + bool enabled;
  1112. +
  1113. + const struct drm_display_mode *mode;
  1114. +};
  1115. +
  1116. +static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
  1117. +{
  1118. + return container_of(panel, struct sharp_panel, base);
  1119. +}
  1120. +
  1121. +
  1122. +static int sharp_panel_off(struct sharp_panel *sharp)
  1123. +{
  1124. + struct mipi_dsi_device *dsi = sharp->dsi;
  1125. + int ret;
  1126. +
  1127. + printk("sharp_panel_off()\n");
  1128. +
  1129. + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
  1130. +
  1131. + ret = mipi_dsi_dcs_set_display_off(dsi);
  1132. + if (ret < 0)
  1133. + return ret;
  1134. +
  1135. + ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
  1136. + if (ret < 0)
  1137. + return ret;
  1138. +
  1139. + return 0;
  1140. +}
  1141. +
  1142. +static int sharp_panel_on(struct sharp_panel *sharp)
  1143. +{
  1144. + struct mipi_dsi_device *dsi = sharp->dsi;
  1145. + int ret;
  1146. +
  1147. + printk("sharp_panel_on()\n");
  1148. + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  1149. +
  1150. + ret = mipi_dsi_dcs_set_display_on(dsi);
  1151. + if (ret < 0)
  1152. + return ret;
  1153. +
  1154. + return 0;
  1155. +}
  1156. +
  1157. +static int sharp_panel_init(struct sharp_panel *sharp)
  1158. +{
  1159. + struct mipi_dsi_device *dsi = sharp->dsi;
  1160. + int ret;
  1161. +
  1162. + printk("sharp_panel_init()\n");
  1163. +
  1164. + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  1165. +
  1166. + ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
  1167. + if (ret < 0)
  1168. + return ret;
  1169. +
  1170. + msleep(120);
  1171. +
  1172. + return 0;
  1173. +}
  1174. +
  1175. +static int sharp_panel_disable(struct drm_panel *panel)
  1176. +{
  1177. + struct sharp_panel *sharp = to_sharp_panel(panel);
  1178. +
  1179. + printk("sharp_panel_disable()\n");
  1180. + if (!sharp->enabled)
  1181. + return 0;
  1182. +
  1183. + if (sharp->backlight) {
  1184. + backlight_disable(sharp->backlight);
  1185. + }
  1186. +
  1187. + sharp->enabled = false;
  1188. +
  1189. + return 0;
  1190. +}
  1191. +
  1192. +static int sharp_panel_unprepare(struct drm_panel *panel)
  1193. +{
  1194. + struct sharp_panel *sharp = to_sharp_panel(panel);
  1195. + int ret;
  1196. +
  1197. + printk("sharp_panel_unprepare()\n");
  1198. +
  1199. + if (!sharp->prepared)
  1200. + return 0;
  1201. +
  1202. + ret = sharp_panel_off(sharp);
  1203. + if (ret < 0) {
  1204. + dev_err(panel->dev, "failed to set panel off: %d\n", ret);
  1205. + return ret;
  1206. + }
  1207. +
  1208. + msleep(120);
  1209. +
  1210. + if (sharp->supply) {
  1211. + regulator_disable(sharp->supply);
  1212. + }
  1213. + if (sharp->reset_gpio)
  1214. + gpiod_set_value(sharp->reset_gpio, 0);
  1215. +
  1216. + sharp->prepared = false;
  1217. +
  1218. + return 0;
  1219. +}
  1220. +
  1221. +static int sharp_panel_prepare(struct drm_panel *panel)
  1222. +{
  1223. + struct sharp_panel *sharp = to_sharp_panel(panel);
  1224. + int ret;
  1225. +
  1226. + printk("sharp_panel_prepare()\n");
  1227. +
  1228. + if (sharp->prepared)
  1229. + return 0;
  1230. +
  1231. + if (sharp->supply) {
  1232. + ret = regulator_enable(sharp->supply);
  1233. + if (ret < 0)
  1234. + return ret;
  1235. + msleep(20);
  1236. + }
  1237. +
  1238. + printk("sharp->reset_gpio\n");
  1239. + if (sharp->reset_gpio) {
  1240. + gpiod_set_value(sharp->reset_gpio, 1);
  1241. + msleep(1);
  1242. + gpiod_set_value(sharp->reset_gpio, 0);
  1243. + msleep(1);
  1244. + gpiod_set_value(sharp->reset_gpio, 1);
  1245. + msleep(10);
  1246. + }
  1247. +
  1248. + ret = sharp_panel_init(sharp);
  1249. + if (ret < 0) {
  1250. + dev_err(panel->dev, "failed to init panel: %d\n", ret);
  1251. + goto poweroff;
  1252. + }
  1253. +
  1254. + ret = sharp_panel_on(sharp);
  1255. + if (ret < 0) {
  1256. + dev_err(panel->dev, "failed to set panel on: %d\n", ret);
  1257. + goto poweroff;
  1258. + }
  1259. +
  1260. + sharp->prepared = true;
  1261. +
  1262. + /* wait for 6 frames before continuing */
  1263. + msleep(120);
  1264. + return 0;
  1265. +
  1266. +poweroff:
  1267. + if (sharp->supply) {
  1268. + regulator_disable(sharp->supply);
  1269. + }
  1270. + if (sharp->reset_gpio)
  1271. + gpiod_set_value(sharp->reset_gpio, 0);
  1272. + return ret;
  1273. +}
  1274. +
  1275. +
  1276. +
  1277. +static int sharp_panel_enable(struct drm_panel *panel)
  1278. +{
  1279. + struct sharp_panel *sharp = to_sharp_panel(panel);
  1280. +
  1281. + printk("sharp_panel_enable()\n");
  1282. +
  1283. + if (sharp->enabled)
  1284. + return 0;
  1285. +
  1286. + if (sharp->backlight) {
  1287. + backlight_enable(sharp->backlight);
  1288. + }
  1289. +
  1290. + sharp->enabled = true;
  1291. +
  1292. + return 0;
  1293. +}
  1294. +
  1295. +static const struct drm_display_mode default_mode = {
  1296. + .clock = 144000,
  1297. + .hdisplay = 1080,
  1298. + .hsync_start = 1080 + 50,
  1299. + .hsync_end = 1080 + 50 + 8,
  1300. + .htotal = 1080 + 50 + 8 + 62,
  1301. + .vdisplay = 1920,
  1302. + .vsync_start = 1920 + 73,
  1303. + .vsync_end = 1920 + 73 + 2,
  1304. + .vtotal = 1920 + 73 + 2 + 5,
  1305. + .vrefresh = 60,
  1306. +};
  1307. +
  1308. +static int sharp_panel_get_modes(struct drm_panel *panel)
  1309. +{
  1310. + struct drm_display_mode *mode;
  1311. + struct drm_connector *connector = panel->connector;
  1312. + struct sharp_panel *sharp = to_sharp_panel(panel);
  1313. +
  1314. + printk("sharp_panel_get_modes()\n");
  1315. + printk("drm_mode_duplcate()\n");
  1316. + mode = drm_mode_duplicate(panel->drm, &default_mode);
  1317. + if (!mode) {
  1318. + dev_err(&sharp->dsi->dev, "failed to add mode %ux%ux@%u\n",
  1319. + default_mode.hdisplay, default_mode.vdisplay,
  1320. + default_mode.vrefresh);
  1321. + return -ENOMEM;
  1322. + }
  1323. +
  1324. + printk("drm_mode_set_name()\n");
  1325. + drm_mode_set_name(mode);
  1326. +
  1327. + printk("mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED\n");
  1328. + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  1329. + drm_mode_p robed_add(connector, mode);
  1330. +
  1331. + panel->connector->display_info.width_mm = 54;
  1332. + panel->connector->display_info.height_mm = 95;
  1333. +
  1334. + printk("return 1\n");
  1335. + return 1;
  1336. +}
  1337. +
  1338. +static const struct of_device_id sharp_of_match[] = {
  1339. + { .compatible = "sharp,ls050t1sx01", },
  1340. + { }
  1341. +};
  1342. +MODULE_DEVICE_TABLE(of, sharp_of_match);
  1343. +
  1344. +static const struct drm_panel_funcs sharp_panel_funcs = {
  1345. + .disable = sharp_panel_disable,
  1346. + .unprepare = sharp_panel_unprepare,
  1347. + .prepare = sharp_panel_prepare,
  1348. + .enable = sharp_panel_enable,
  1349. + .get_modes = sharp_panel_get_modes,
  1350. +};
  1351. +
  1352. +static int sharp_panel_add(struct sharp_panel *sharp)
  1353. +{
  1354. + struct device *dev = &sharp->dsi->dev;
  1355. +
  1356. + printk("sharp_panel_add()\n");
  1357. + sharp->mode = &default_mode;
  1358. +
  1359. + sharp->supply = devm_regulator_get(dev, "avdd");
  1360. + if (IS_ERR(sharp->supply)) {
  1361. + dev_err(dev, "cannot get avdd supply %ld\n", PTR_ERR(sharp->supply));
  1362. + sharp->supply = NULL;
  1363. + }
  1364. +
  1365. + sharp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
  1366. + if (IS_ERR(sharp->reset_gpio)) {
  1367. + dev_err(dev, "cannot get reset-gpios %ld\n",
  1368. + PTR_ERR(sharp->reset_gpio));
  1369. + sharp->reset_gpio = NULL;
  1370. + } else {
  1371. + gpiod_set_value(sharp->reset_gpio, 0);
  1372. + }
  1373. +
  1374. + sharp->backlight = devm_of_find_backlight(dev);
  1375. +
  1376. + if (IS_ERR(sharp->backlight)) {
  1377. + dev_err(dev, "cannot get backlight %ld\n", PTR_ERR(sharp->backlight));
  1378. + sharp->backlight = NULL;
  1379. + }
  1380. + drm_panel_init(&sharp->base);
  1381. + sharp->base.funcs = &sharp_panel_funcs;
  1382. + sharp->base.dev = &sharp->dsi->dev;
  1383. +
  1384. + return drm_panel_add(&sharp->base);
  1385. +}
  1386. +
  1387. +static void sharp_panel_del(struct sharp_panel *sharp)
  1388. +{
  1389. + printk("sharp_panel_del()\n");
  1390. + if (sharp->base.dev)
  1391. + drm_panel_remove(&sharp->base);
  1392. +}
  1393. +
  1394. +static int sharp_panel_probe(struct mipi_dsi_device *dsi)
  1395. +{
  1396. + struct sharp_panel *sharp;
  1397. + int ret;
  1398. + printk("sharp_panel_probe()\n");
  1399. +
  1400. + dsi->lanes = 4;
  1401. + dsi->format = MIPI_DSI_FMT_RGB888;
  1402. + dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
  1403. + MIPI_DSI_MODE_VIDEO_HSE |
  1404. + MIPI_DSI_CLOCK_NON_CONTINUOUS |
  1405. + MIPI_DSI_MODE_EOT_PACKET;
  1406. +
  1407. + sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL);
  1408. + if (!sharp)
  1409. + return -ENOMEM;
  1410. +
  1411. + mipi_dsi_set_drvdata(dsi, sharp);
  1412. +
  1413. + sharp->dsi = dsi;
  1414. +
  1415. + ret = sharp_panel_add(sharp);
  1416. + if (ret < 0)
  1417. + return ret;
  1418. +
  1419. + return mipi_dsi_attach(dsi);
  1420. +}
  1421. +
  1422. +static int sharp_panel_remove(struct mipi_dsi_device *dsi)
  1423. +{
  1424. + struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
  1425. + int ret;
  1426. +
  1427. + printk("sharp_panel_remove()\n");
  1428. + ret = sharp_panel_disable(&sharp->base);
  1429. + if (ret < 0)
  1430. + dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
  1431. +
  1432. + ret = mipi_dsi_detach(dsi);
  1433. + if (ret < 0)
  1434. + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
  1435. +
  1436. + drm_panel_detach(&sharp->base);
  1437. + sharp_panel_del(sharp);
  1438. +
  1439. + return 0;
  1440. +}
  1441. +
  1442. +static void sharp_panel_shutdown(struct mipi_dsi_device *dsi)
  1443. +{
  1444. + struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
  1445. + printk("sharp_panel_shutdown()\n");
  1446. +
  1447. + sharp_panel_disable(&sharp->base);
  1448. +}
  1449. +
  1450. +static struct mipi_dsi_driver sharp_panel_driver = {
  1451. + .driver = {
  1452. + .name = "panel-sharp-ls050t1sx01",
  1453. + .of_match_table = sharp_of_match,
  1454. + },
  1455. + .probe = sharp_panel_probe,
  1456. + .remove = sharp_panel_remove,
  1457. + .shutdown = sharp_panel_shutdown,
  1458. +};
  1459. +module_mipi_dsi_driver(sharp_panel_driver);
  1460. +
  1461. +MODULE_AUTHOR("Roman Beranek <roman.beranek@prusa3d.com>");
  1462. +MODULE_DESCRIPTION("Sharp LS050T1SX01 R63311-based FullHD video mode panel driver");
  1463. +MODULE_LICENSE("GPL v2");
  1464. --
  1465. 2.19.1
  1466.  
  1467.  
  1468. From 77124564533c41578b6e8436653b7ec09adea032 Mon Sep 17 00:00:00 2001
  1469. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1470. Date: Wed, 15 Aug 2018 14:03:43 +0200
  1471. Subject: [PATCH 10/17] ls050t1sx01 on olinuxino
  1472.  
  1473. ---
  1474. .../dts/allwinner/sun50i-a64-olinuxino.dts | 28 +++++++++++
  1475. .../gpu/drm/panel/panel-sharp-ls050t1sx01.c | 46 +++++++++----------
  1476. 2 files changed, 51 insertions(+), 23 deletions(-)
  1477.  
  1478. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1479. index eec2a538b585..f471cd6962cf 100644
  1480. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1481. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1482. @@ -289,3 +289,31 @@
  1483. pinctrl-0 = <&uart3_pins>;
  1484. status = "okay";
  1485. };
  1486. +
  1487. +&de {
  1488. + status = "okay";
  1489. +};
  1490. +
  1491. +&mixer0 {
  1492. + status = "okay";
  1493. +};
  1494. +
  1495. +&tcon0 {
  1496. + status = "okay";
  1497. +};
  1498. +
  1499. +&dphy {
  1500. + status = "okay";
  1501. +};
  1502. +
  1503. +&dsi {
  1504. + status = "okay";
  1505. +
  1506. + panel@0 {
  1507. + compatible = "sharp,ls050t1sx01", "simple-panel";
  1508. + reg = <0>;
  1509. + enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* PB7 */
  1510. + reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; /* PB5 */
  1511. + avdd-supply = <&reg_dldo2>;
  1512. + };
  1513. +};
  1514. diff --git a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1515. index 17b481acb28c..4fe93ec770ed 100644
  1516. --- a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1517. +++ b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1518. @@ -1,4 +1,3 @@
  1519. -#include <linux/backlight.h>
  1520. #include <linux/gpio/consumer.h>
  1521. #include <linux/module.h>
  1522. #include <linux/of.h>
  1523. @@ -15,9 +14,9 @@ struct sharp_panel {
  1524. struct drm_panel base;
  1525. struct mipi_dsi_device *dsi;
  1526.  
  1527. - struct backlight_device *backlight;
  1528. struct regulator *supply;
  1529. struct gpio_desc *reset_gpio;
  1530. + struct gpio_desc *enable_gpio;
  1531.  
  1532. bool prepared;
  1533. bool enabled;
  1534. @@ -92,10 +91,6 @@ static int sharp_panel_disable(struct drm_panel *panel)
  1535. if (!sharp->enabled)
  1536. return 0;
  1537.  
  1538. - if (sharp->backlight) {
  1539. - backlight_disable(sharp->backlight);
  1540. - }
  1541. -
  1542. sharp->enabled = false;
  1543.  
  1544. return 0;
  1545. @@ -147,13 +142,18 @@ static int sharp_panel_prepare(struct drm_panel *panel)
  1546. msleep(20);
  1547. }
  1548.  
  1549. + if (sharp->enable_gpio) {
  1550. + gpiod_set_value(sharp->enable_gpio, 1);
  1551. + msleep(100);
  1552. + }
  1553. +
  1554. printk("sharp->reset_gpio\n");
  1555. if (sharp->reset_gpio) {
  1556. - gpiod_set_value(sharp->reset_gpio, 1);
  1557. - msleep(1);
  1558. gpiod_set_value(sharp->reset_gpio, 0);
  1559. - msleep(1);
  1560. + msleep(20);
  1561. gpiod_set_value(sharp->reset_gpio, 1);
  1562. + msleep(50);
  1563. + gpiod_set_value(sharp->reset_gpio, 0);
  1564. msleep(10);
  1565. }
  1566.  
  1567. @@ -176,11 +176,12 @@ static int sharp_panel_prepare(struct drm_panel *panel)
  1568. return 0;
  1569.  
  1570. poweroff:
  1571. - if (sharp->supply) {
  1572. - regulator_disable(sharp->supply);
  1573. - }
  1574. + if (sharp->enable_gpio)
  1575. + gpiod_set_value(sharp->enable_gpio, 0);
  1576. + if (sharp->supply)
  1577. + regulator_disable(sharp->supply);
  1578. if (sharp->reset_gpio)
  1579. - gpiod_set_value(sharp->reset_gpio, 0);
  1580. + gpiod_set_value(sharp->reset_gpio, 0);
  1581. return ret;
  1582. }
  1583.  
  1584. @@ -195,10 +196,6 @@ static int sharp_panel_enable(struct drm_panel *panel)
  1585. if (sharp->enabled)
  1586. return 0;
  1587.  
  1588. - if (sharp->backlight) {
  1589. - backlight_enable(sharp->backlight);
  1590. - }
  1591. -
  1592. sharp->enabled = true;
  1593.  
  1594. return 0;
  1595. @@ -238,7 +235,7 @@ static int sharp_panel_get_modes(struct drm_panel *panel)
  1596.  
  1597. printk("mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED\n");
  1598. mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  1599. - drm_mode_p robed_add(connector, mode);
  1600. + drm_mode_probed_add(connector, mode);
  1601.  
  1602. panel->connector->display_info.width_mm = 54;
  1603. panel->connector->display_info.height_mm = 95;
  1604. @@ -283,12 +280,15 @@ static int sharp_panel_add(struct sharp_panel *sharp)
  1605. gpiod_set_value(sharp->reset_gpio, 0);
  1606. }
  1607.  
  1608. - sharp->backlight = devm_of_find_backlight(dev);
  1609. -
  1610. - if (IS_ERR(sharp->backlight)) {
  1611. - dev_err(dev, "cannot get backlight %ld\n", PTR_ERR(sharp->backlight));
  1612. - sharp->backlight = NULL;
  1613. + sharp->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
  1614. + if (IS_ERR(sharp->enable_gpio)) {
  1615. + dev_err(dev, "cannot get enable-gpios %ld\n",
  1616. + PTR_ERR(sharp->enable_gpio));
  1617. + sharp->enable_gpio = NULL;
  1618. + } else {
  1619. + gpiod_set_value(sharp->enable_gpio, 0);
  1620. }
  1621. +
  1622. drm_panel_init(&sharp->base);
  1623. sharp->base.funcs = &sharp_panel_funcs;
  1624. sharp->base.dev = &sharp->dsi->dev;
  1625. --
  1626. 2.19.1
  1627.  
  1628.  
  1629. From 5da271027538410fdaf83a35d77e1f57a13e8e4a Mon Sep 17 00:00:00 2001
  1630. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1631. Date: Wed, 15 Aug 2018 14:45:31 +0200
  1632. Subject: [PATCH 11/17] sun50i-a64-olinuxino.dts: add missing nodes & sort the
  1633. list
  1634.  
  1635. ---
  1636. .../dts/allwinner/sun50i-a64-olinuxino.dts | 62 +++++++++----------
  1637. 1 file changed, 30 insertions(+), 32 deletions(-)
  1638.  
  1639. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1640. index f471cd6962cf..c90a682d4d49 100644
  1641. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1642. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  1643. @@ -52,6 +52,8 @@
  1644.  
  1645. aliases {
  1646. serial0 = &uart0;
  1647. + serial2 = &uart2;
  1648. + serial3 = &uart3;
  1649. };
  1650.  
  1651. chosen {
  1652. @@ -75,10 +77,6 @@
  1653. };
  1654. };
  1655.  
  1656. -&de {
  1657. - status = "okay";
  1658. -};
  1659. -
  1660. &codec {
  1661. status = "okay";
  1662. };
  1663. @@ -91,6 +89,26 @@
  1664. status = "okay";
  1665. };
  1666.  
  1667. +&de {
  1668. + status = "okay";
  1669. +};
  1670. +
  1671. +&dphy {
  1672. + status = "okay";
  1673. +};
  1674. +
  1675. +&dsi {
  1676. + status = "okay";
  1677. +
  1678. + panel@0 {
  1679. + compatible = "sharp,ls050t1sx01", "simple-panel";
  1680. + reg = <0>;
  1681. + enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* PB7 */
  1682. + reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; /* PB5 */
  1683. + avdd-supply = <&reg_dldo2>;
  1684. + };
  1685. +};
  1686. +
  1687. &hdmi {
  1688. hdmi-supply = <&reg_dldo1>;
  1689. status = "okay";
  1690. @@ -102,6 +120,10 @@
  1691. };
  1692. };
  1693.  
  1694. +&mixer0 {
  1695. + status = "okay";
  1696. +};
  1697. +
  1698. &mixer1 {
  1699. status = "okay";
  1700. };
  1701. @@ -268,6 +290,10 @@
  1702. "Speaker", "LINEOUT";
  1703. };
  1704.  
  1705. +&tcon0 {
  1706. + status = "okay";
  1707. +};
  1708. +
  1709. &tcon1 {
  1710. status = "okay";
  1711. };
  1712. @@ -289,31 +315,3 @@
  1713. pinctrl-0 = <&uart3_pins>;
  1714. status = "okay";
  1715. };
  1716. -
  1717. -&de {
  1718. - status = "okay";
  1719. -};
  1720. -
  1721. -&mixer0 {
  1722. - status = "okay";
  1723. -};
  1724. -
  1725. -&tcon0 {
  1726. - status = "okay";
  1727. -};
  1728. -
  1729. -&dphy {
  1730. - status = "okay";
  1731. -};
  1732. -
  1733. -&dsi {
  1734. - status = "okay";
  1735. -
  1736. - panel@0 {
  1737. - compatible = "sharp,ls050t1sx01", "simple-panel";
  1738. - reg = <0>;
  1739. - enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* PB7 */
  1740. - reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; /* PB5 */
  1741. - avdd-supply = <&reg_dldo2>;
  1742. - };
  1743. -};
  1744. --
  1745. 2.19.1
  1746.  
  1747.  
  1748. From 87cf41089c177ba269578b00b0c5d4ecbeffffa5 Mon Sep 17 00:00:00 2001
  1749. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1750. Date: Wed, 15 Aug 2018 15:25:01 +0200
  1751. Subject: [PATCH 12/17] ls050t1sx01: return error from probe when suply/gpios
  1752. are unavailable
  1753.  
  1754. ---
  1755. drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c | 6 +++---
  1756. 1 file changed, 3 insertions(+), 3 deletions(-)
  1757.  
  1758. diff --git a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1759. index 4fe93ec770ed..da91541b8d12 100644
  1760. --- a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1761. +++ b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  1762. @@ -268,14 +268,14 @@ static int sharp_panel_add(struct sharp_panel *sharp)
  1763. sharp->supply = devm_regulator_get(dev, "avdd");
  1764. if (IS_ERR(sharp->supply)) {
  1765. dev_err(dev, "cannot get avdd supply %ld\n", PTR_ERR(sharp->supply));
  1766. - sharp->supply = NULL;
  1767. + return PTR_ERR(sharp->supply);
  1768. }
  1769.  
  1770. sharp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
  1771. if (IS_ERR(sharp->reset_gpio)) {
  1772. dev_err(dev, "cannot get reset-gpios %ld\n",
  1773. PTR_ERR(sharp->reset_gpio));
  1774. - sharp->reset_gpio = NULL;
  1775. + return PTR_ERR(sharp->reset_gpio);
  1776. } else {
  1777. gpiod_set_value(sharp->reset_gpio, 0);
  1778. }
  1779. @@ -284,7 +284,7 @@ static int sharp_panel_add(struct sharp_panel *sharp)
  1780. if (IS_ERR(sharp->enable_gpio)) {
  1781. dev_err(dev, "cannot get enable-gpios %ld\n",
  1782. PTR_ERR(sharp->enable_gpio));
  1783. - sharp->enable_gpio = NULL;
  1784. + return PTR_ERR(sharp->enable_gpio);
  1785. } else {
  1786. gpiod_set_value(sharp->enable_gpio, 0);
  1787. }
  1788. --
  1789. 2.19.1
  1790.  
  1791.  
  1792. From 8423e560cae1e32fdb1291f67081e7fd8b52dbe4 Mon Sep 17 00:00:00 2001
  1793. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1794. Date: Wed, 15 Aug 2018 16:32:28 +0200
  1795. Subject: [PATCH 13/17] dts: added mixer0 to sun50i-a64
  1796.  
  1797. ---
  1798. arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 10 ++++++----
  1799. 1 file changed, 6 insertions(+), 4 deletions(-)
  1800.  
  1801. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1802. index 40b77c4a20e7..6f3c5febd2af 100644
  1803. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1804. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1805. @@ -114,7 +114,7 @@
  1806.  
  1807. de: display-engine {
  1808. compatible = "allwinner,sun50i-a64-display-engine";
  1809. - allwinner,pipelines = <&mixer1>;
  1810. + allwinner,pipelines = <&mixer0>, <&mixer1>;
  1811. status = "disabled";
  1812. };
  1813.  
  1814. @@ -226,7 +226,8 @@
  1815. ranges = <0 0x1000000 0x400000>;
  1816.  
  1817. display_clocks: clock@0 {
  1818. - compatible = "allwinner,sun50i-a64-de2-clk";
  1819. + compatible = "allwinner,sun50i-h5-de2-clk",
  1820. + "allwinner,sun50i-a64-de2-clk";
  1821. reg = <0x0 0x100000>;
  1822. clocks = <&ccu CLK_DE>,
  1823. <&ccu CLK_BUS_DE>;
  1824. @@ -327,8 +328,9 @@
  1825. clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
  1826. clock-names = "ahb", "tcon-ch0";
  1827. clock-output-names = "tcon-pixel-clock";
  1828. - resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
  1829. - reset-names = "lcd", "lvds";
  1830. + resets = <&ccu RST_BUS_TCON0>;
  1831. + reset-names = "lcd";
  1832. + status = "disabled";
  1833.  
  1834. ports {
  1835. #address-cells = <1>;
  1836. --
  1837. 2.19.1
  1838.  
  1839.  
  1840. From 17e51fdd8a3ef425232e385103fda0d122b5f680 Mon Sep 17 00:00:00 2001
  1841. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1842. Date: Wed, 15 Aug 2018 16:52:31 +0200
  1843. Subject: [PATCH 14/17] sunxi-ng: select SUN8I_DE2_CCU by default
  1844.  
  1845. ---
  1846. drivers/clk/sunxi-ng/Kconfig | 2 ++
  1847. 1 file changed, 2 insertions(+)
  1848.  
  1849. diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
  1850. index 826674d090fd..e20182aa9748 100644
  1851. --- a/drivers/clk/sunxi-ng/Kconfig
  1852. +++ b/drivers/clk/sunxi-ng/Kconfig
  1853. @@ -63,6 +63,8 @@ config SUN8I_V3S_CCU
  1854.  
  1855. config SUN8I_DE2_CCU
  1856. bool "Support for the Allwinner SoCs DE2 CCU"
  1857. + default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
  1858. + depends on DRM_SUN4I && (MACH_SUN8I || (ARM64 && ARCH_SUNXI))
  1859.  
  1860. config SUN8I_R40_CCU
  1861. bool "Support for the Allwinner R40 CCU"
  1862. --
  1863. 2.19.1
  1864.  
  1865.  
  1866. From 364691f471c276f35f9df4051470dc9146c1491b Mon Sep 17 00:00:00 2001
  1867. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1868. Date: Wed, 29 Aug 2018 14:13:43 +0200
  1869. Subject: [PATCH 15/17] drm/sun4i: integration of anarsoul's A64 MIPI DSI work
  1870. into 4.18
  1871.  
  1872. ---
  1873. arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 6 ++----
  1874. drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 4 ++--
  1875. drivers/gpu/drm/sun4i/Kconfig | 3 ++-
  1876. drivers/gpu/drm/sun4i/sun4i_tcon.c | 11 ++++++++---
  1877. 4 files changed, 14 insertions(+), 10 deletions(-)
  1878.  
  1879. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1880. index 6f3c5febd2af..165e8ce73dd0 100644
  1881. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1882. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
  1883. @@ -226,8 +226,7 @@
  1884. ranges = <0 0x1000000 0x400000>;
  1885.  
  1886. display_clocks: clock@0 {
  1887. - compatible = "allwinner,sun50i-h5-de2-clk",
  1888. - "allwinner,sun50i-a64-de2-clk";
  1889. + compatible = "allwinner,sun50i-a64-de2-clk";
  1890. reg = <0x0 0x100000>;
  1891. clocks = <&ccu CLK_DE>,
  1892. <&ccu CLK_BUS_DE>;
  1893. @@ -321,8 +320,7 @@
  1894. };
  1895.  
  1896. tcon0: lcd-controller@1c0c000 {
  1897. - compatible = "allwinner,sun50i-a64-tcon-lcd",
  1898. - "allwinner,sun8i-a83t-tcon-lcd";
  1899. + compatible = "allwinner,sun50i-a64-tcon-lcd";
  1900. reg = <0x01c0c000 0x1000>;
  1901. interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
  1902. clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
  1903. diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  1904. index e710a098d324..e33716e0233a 100644
  1905. --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  1906. +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
  1907. @@ -517,8 +517,8 @@ static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
  1908. static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
  1909. 0x104, 0, 4, 24, 3, BIT(31), 0);
  1910.  
  1911. -static const char * const tcon0_parents[] = { "pll-mipi", "pll-video-2x" };
  1912. -static const u8 tcon0_table[] = { 0, };
  1913. +static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
  1914. +static const u8 tcon0_table[] = { 0, 2, };
  1915. static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
  1916. tcon0_table, 0x118, 24, 3, BIT(31),
  1917. CLK_SET_RATE_PARENT);
  1918. diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
  1919. index c2c042287c19..cbe64a51463b 100644
  1920. --- a/drivers/gpu/drm/sun4i/Kconfig
  1921. +++ b/drivers/gpu/drm/sun4i/Kconfig
  1922. @@ -52,6 +52,7 @@ config DRM_SUN6I_DSI
  1923.  
  1924. config DRM_SUN8I_DW_HDMI
  1925. tristate "Support for Allwinner version of DesignWare HDMI"
  1926. + default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
  1927. depends on DRM_SUN4I
  1928. select DRM_DW_HDMI
  1929. help
  1930. @@ -61,7 +62,7 @@ config DRM_SUN8I_DW_HDMI
  1931.  
  1932. config DRM_SUN8I_MIXER
  1933. tristate "Support for Allwinner Display Engine 2.0 Mixer"
  1934. - default MACH_SUN8I
  1935. + default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
  1936. help
  1937. Choose this option if you have an Allwinner SoC with the
  1938. Allwinner Display Engine 2.0, which has a mixer to do some
  1939. diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  1940. index 64ed55ee4dbe..070db858ed78 100644
  1941. --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
  1942. +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
  1943. @@ -349,9 +349,8 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
  1944. * the display clock * 15, but uses an hardcoded 3000...
  1945. */
  1946. regmap_write(tcon->regs, SUN4I_TCON_SAFE_PERIOD_REG,
  1947. - 0x03390023);
  1948. - //SUN4I_TCON_SAFE_PERIOD_NUM(3000) |
  1949. - //SUN4I_TCON_SAFE_PERIOD_MODE(3));
  1950. + SUN4I_TCON_SAFE_PERIOD_NUM((mode->crtc_clock * 15) / 1000) |
  1951. + SUN4I_TCON_SAFE_PERIOD_MODE(3));
  1952.  
  1953. /* Enable the output on the pins */
  1954. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG,
  1955. @@ -1448,6 +1447,11 @@ static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
  1956. .needs_edp_reset = true,
  1957. };
  1958.  
  1959. +static const struct sun4i_tcon_quirks sun50i_a64_lcd_quirks = {
  1960. + .supports_lvds = true,
  1961. + .has_channel_0 = true,
  1962. +};
  1963. +
  1964. /* sun4i_drv uses this list to check if a device node is a TCON */
  1965. const struct of_device_id sun4i_tcon_of_table[] = {
  1966. { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
  1967. @@ -1462,6 +1466,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
  1968. { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
  1969. { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
  1970. { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
  1971. + { .compatible = "allwinner,sun50i-a64-tcon-lcd", .data = &sun50i_a64_lcd_quirks },
  1972. { }
  1973. };
  1974. MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
  1975. --
  1976. 2.19.1
  1977.  
  1978.  
  1979. From ff02f5f0aea46a75768ab277c52c69a65b9cdad0 Mon Sep 17 00:00:00 2001
  1980. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  1981. Date: Wed, 29 Aug 2018 14:14:52 +0200
  1982. Subject: [PATCH 16/17] drm/sun4i: MIPI-DSI fixes for non-burst video mode
  1983.  
  1984. ---
  1985. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 88 ++++++++++----------------
  1986. 1 file changed, 35 insertions(+), 53 deletions(-)
  1987.  
  1988. diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  1989. index 3d277396b1ac..74cd4c3ae051 100644
  1990. --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  1991. +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
  1992. @@ -417,9 +417,9 @@ static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
  1993. val |= SUN6I_DSI_BASIC_CTL_VIDEO_BURST;
  1994. regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, val);
  1995. } else {
  1996. - if ((mode->hsync_end - mode->hdisplay) > 20) {
  1997. + if ((mode->hsync_start - mode->hdisplay) > 20) {
  1998. /* Maaaaaagic */
  1999. - u16 drq = (mode->hsync_end - mode->hdisplay) - 20;
  2000. + u16 drq = (mode->hsync_start - mode->hdisplay) - 20;
  2001.  
  2002. drq *= mipi_dsi_pixel_format_to_bpp(device->format);
  2003. drq /= 32;
  2004. @@ -520,37 +520,58 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
  2005. * minimal size is therefore 10 bytes
  2006. */
  2007. #define HSA_PACKET_OVERHEAD 10
  2008. - hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
  2009. - (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
  2010. + if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2011. + hsa = 0;
  2012. + else
  2013. + hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
  2014. + (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
  2015.  
  2016. /*
  2017. * The backporch is set using a blanking packet (4 bytes +
  2018. * payload + 2 bytes). Its minimal size is therefore 6 bytes
  2019. */
  2020. #define HBP_PACKET_OVERHEAD 6
  2021. - hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
  2022. - (mode->hsync_start - mode->hdisplay) * Bpp - HBP_PACKET_OVERHEAD);
  2023. + if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2024. + hbp = 0;
  2025. + else
  2026. + hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
  2027. + (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
  2028. +
  2029.  
  2030. /*
  2031. - * The frontporch is set using a blanking packet (4 bytes +
  2032. - * payload + 2 bytes). Its minimal size is therefore 6 bytes
  2033. + * hblk seems to be the line + porches length.
  2034. */
  2035. -#define HFP_PACKET_OVERHEAD 6
  2036. - hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
  2037. - (mode->htotal - mode->hsync_end) * Bpp - HFP_PACKET_OVERHEAD);
  2038. +#define HBLK_PACKET_OVERHEAD 10
  2039. + if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2040. + hblk = mode->hdisplay * Bpp;
  2041. + else
  2042. + hblk = mode->htotal * Bpp
  2043. + - (hsa + HSA_PACKET_OVERHEAD)
  2044. + - HBLK_PACKET_OVERHEAD;
  2045.  
  2046. /*
  2047. - * hblk seems to be the line + porches length.
  2048. + * The frontporch is set using a blanking packet (4 bytes +
  2049. + * payload + 2 bytes). Its minimal size is therefore 6 bytes
  2050. */
  2051. - hblk = mode->htotal * Bpp - hsa;
  2052. +#define HFP_PACKET_OVERHEAD 6
  2053. + if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2054. + hfp = 0;
  2055. + else
  2056. + hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
  2057. + hblk - (4 + mode->hdisplay * Bpp + 2) - (4 + hbp + 2));
  2058.  
  2059. + /* vblk */
  2060. /*
  2061. * And I'm not entirely sure what vblk is about. The driver in
  2062. * Allwinner BSP is using a rather convoluted calculation
  2063. * there only for 4 lanes. However, using 0 (the !4 lanes
  2064. * case) even with a 4 lanes screen seems to work...
  2065. */
  2066. - vblk = 0;
  2067. + if (device->lanes != 4 || device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
  2068. + vblk = 0;
  2069. + } else {
  2070. + vblk = 4 - (mode->htotal * Bpp * mode->vtotal - (4 + hblk + 2)) % 4;
  2071. + }
  2072.  
  2073. /* How many bytes do we need to send all payloads? */
  2074. bytes = max_t(size_t, max(max(hfp, hblk), max(hsa, hbp)), vblk);
  2075. @@ -591,65 +612,26 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
  2076. SUN6I_DSI_BASIC_SIZE1_VACT(mode->vdisplay) |
  2077. SUN6I_DSI_BASIC_SIZE1_VT(mode->vtotal));
  2078.  
  2079. - /*
  2080. - * A sync period is composed of a blanking packet (4 bytes +
  2081. - * payload + 2 bytes) and a sync event packet (4 bytes). Its
  2082. - * minimal size is therefore 10 bytes
  2083. - */
  2084. -#define HSA_PACKET_OVERHEAD 10
  2085. - if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2086. - hsa = 0;
  2087. - else
  2088. - hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
  2089. - (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
  2090. regmap_write(dsi->regs, SUN6I_DSI_BLK_HSA0_REG,
  2091. sun6i_dsi_build_blk0_pkt(device->channel, hsa));
  2092. regmap_write(dsi->regs, SUN6I_DSI_BLK_HSA1_REG,
  2093. sun6i_dsi_build_blk1_pkt(0, buffer, hsa));
  2094.  
  2095. - /*
  2096. - * The backporch is set using a blanking packet (4 bytes +
  2097. - * payload + 2 bytes). Its minimal size is therefore 6 bytes
  2098. - */
  2099. -#define HBP_PACKET_OVERHEAD 6
  2100. - if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2101. - hbp = 0;
  2102. - else
  2103. - hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
  2104. - (mode->hsync_start - mode->hdisplay) * Bpp - HBP_PACKET_OVERHEAD);
  2105. regmap_write(dsi->regs, SUN6I_DSI_BLK_HBP0_REG,
  2106. sun6i_dsi_build_blk0_pkt(device->channel, hbp));
  2107. regmap_write(dsi->regs, SUN6I_DSI_BLK_HBP1_REG,
  2108. sun6i_dsi_build_blk1_pkt(0, buffer, hbp));
  2109.  
  2110. - /*
  2111. - * The frontporch is set using a blanking packet (4 bytes +
  2112. - * payload + 2 bytes). Its minimal size is therefore 6 bytes
  2113. - */
  2114. -#define HFP_PACKET_OVERHEAD 6
  2115. - if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2116. - hfp = 0;
  2117. - else
  2118. - hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
  2119. - (mode->htotal - mode->hsync_end) * Bpp - HFP_PACKET_OVERHEAD);
  2120. regmap_write(dsi->regs, SUN6I_DSI_BLK_HFP0_REG,
  2121. sun6i_dsi_build_blk0_pkt(device->channel, hfp));
  2122. regmap_write(dsi->regs, SUN6I_DSI_BLK_HFP1_REG,
  2123. sun6i_dsi_build_blk1_pkt(0, buffer, hfp));
  2124.  
  2125. - /*
  2126. - * hblk seems to be the line + porches length.
  2127. - */
  2128. - if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
  2129. - hblk = mode->hdisplay * Bpp;
  2130. - else
  2131. - hblk = mode->htotal * Bpp - hsa;
  2132. regmap_write(dsi->regs, SUN6I_DSI_BLK_HBLK0_REG,
  2133. sun6i_dsi_build_blk0_pkt(device->channel, hblk));
  2134. regmap_write(dsi->regs, SUN6I_DSI_BLK_HBLK1_REG,
  2135. sun6i_dsi_build_blk1_pkt(0, buffer, hblk));
  2136.  
  2137. - /* vblk */
  2138. regmap_write(dsi->regs, SUN6I_DSI_BLK_VBLK0_REG,
  2139. sun6i_dsi_build_blk0_pkt(device->channel, vblk));
  2140. regmap_write(dsi->regs, SUN6I_DSI_BLK_VBLK1_REG,
  2141. --
  2142. 2.19.1
  2143.  
  2144.  
  2145. From a03b9811d3f800ab82622e15dd334b2c6bb22389 Mon Sep 17 00:00:00 2001
  2146. From: =?UTF-8?q?Roman=20Ber=C3=A1nek?= <roman.beranek@prusa3d.com>
  2147. Date: Wed, 29 Aug 2018 14:22:35 +0200
  2148. Subject: [PATCH 17/17] drm: LS050T1SX01 LCD panel fixes
  2149.  
  2150. ---
  2151. .../display/panel/sharp,ls050t1sx01.txt | 14 ++--
  2152. .../dts/allwinner/sun50i-a64-olinuxino.dts | 2 +-
  2153. .../gpu/drm/panel/panel-sharp-ls050t1sx01.c | 70 ++++---------------
  2154. 3 files changed, 20 insertions(+), 66 deletions(-)
  2155.  
  2156. diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt b/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  2157. index bb0ba34c3813..0bf6ddd5b90f 100644
  2158. --- a/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  2159. +++ b/Documentation/devicetree/bindings/display/panel/sharp,ls050t1sx01.txt
  2160. @@ -1,12 +1,10 @@
  2161. -Sharp Microelectronics 5.0" qHD TFT LCD panel
  2162. +Sharp Microelectronics 5.0" fullHD TFT LCD panel
  2163.  
  2164. Required properties:
  2165. -- compatible: should be "sharp,ls050t1sx01-qhd"
  2166. +- compatible: should be "sharp,ls050t1sx01"
  2167. - reg: DSI virtual channel of the peripheral
  2168. - power-supply: phandle of the regulator that provides the supply voltage
  2169. -
  2170. -Optional properties:
  2171. -- backlight: phandle of the backlight device attached to the panel
  2172. +- enable-gpios: a GPIO spec for the reset pin
  2173. - reset-gpios: a GPIO spec for the reset pin
  2174.  
  2175. Example:
  2176. @@ -15,8 +13,8 @@ Example:
  2177. panel@0 {
  2178. compatible = "sharp,ls050t1sx01";
  2179. reg = <0>;
  2180. - avdd-supply = <&pm8941_l22>;
  2181. - backlight = <&pm8941_wled>;
  2182. - reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
  2183. + power-supply = <&pm8941_l22>;
  2184. + enable-gpios = <&pm8941_gpios 18 GPIO_ACTIVE_HIGH>;
  2185. + reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_LOW>;
  2186. };
  2187. };
  2188. diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  2189. index c90a682d4d49..4ca85c94cae5 100644
  2190. --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  2191. +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
  2192. @@ -105,7 +105,7 @@
  2193. reg = <0>;
  2194. enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* PB7 */
  2195. reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; /* PB5 */
  2196. - avdd-supply = <&reg_dldo2>;
  2197. + power-supply = <&reg_dldo2>;
  2198. };
  2199. };
  2200.  
  2201. diff --git a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  2202. index da91541b8d12..328663ac8a5d 100644
  2203. --- a/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  2204. +++ b/drivers/gpu/drm/panel/panel-sharp-ls050t1sx01.c
  2205. @@ -30,55 +30,24 @@ static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
  2206. }
  2207.  
  2208.  
  2209. -static int sharp_panel_off(struct sharp_panel *sharp)
  2210. +static int sharp_panel_init(struct sharp_panel *sharp)
  2211. {
  2212. struct mipi_dsi_device *dsi = sharp->dsi;
  2213. int ret;
  2214.  
  2215. - printk("sharp_panel_off()\n");
  2216. -
  2217. - dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
  2218. -
  2219. - ret = mipi_dsi_dcs_set_display_off(dsi);
  2220. - if (ret < 0)
  2221. - return ret;
  2222. -
  2223. - ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
  2224. + ret = mipi_dsi_dcs_soft_reset(dsi);
  2225. if (ret < 0)
  2226. return ret;
  2227. -
  2228. - return 0;
  2229. -}
  2230. -
  2231. -static int sharp_panel_on(struct sharp_panel *sharp)
  2232. -{
  2233. - struct mipi_dsi_device *dsi = sharp->dsi;
  2234. - int ret;
  2235. -
  2236. - printk("sharp_panel_on()\n");
  2237. - dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  2238. + msleep(10);
  2239.  
  2240. ret = mipi_dsi_dcs_set_display_on(dsi);
  2241. if (ret < 0)
  2242. return ret;
  2243.  
  2244. - return 0;
  2245. -}
  2246. -
  2247. -static int sharp_panel_init(struct sharp_panel *sharp)
  2248. -{
  2249. - struct mipi_dsi_device *dsi = sharp->dsi;
  2250. - int ret;
  2251. -
  2252. - printk("sharp_panel_init()\n");
  2253. -
  2254. - dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  2255. -
  2256. ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
  2257. if (ret < 0)
  2258. return ret;
  2259. -
  2260. - msleep(120);
  2261. + msleep(120); // min 6 frames
  2262.  
  2263. return 0;
  2264. }
  2265. @@ -106,13 +75,13 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
  2266. if (!sharp->prepared)
  2267. return 0;
  2268.  
  2269. - ret = sharp_panel_off(sharp);
  2270. - if (ret < 0) {
  2271. - dev_err(panel->dev, "failed to set panel off: %d\n", ret);
  2272. - return ret;
  2273. - }
  2274. + ret = mipi_dsi_dcs_set_display_off(sharp->dsi);
  2275. + if (ret < 0) return ret;
  2276. + msleep(20);
  2277.  
  2278. - msleep(120);
  2279. + ret = mipi_dsi_dcs_enter_sleep_mode(sharp->dsi);
  2280. + if (ret < 0) return ret;
  2281. + msleep(80);
  2282.  
  2283. if (sharp->supply) {
  2284. regulator_disable(sharp->supply);
  2285. @@ -163,12 +132,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
  2286. goto poweroff;
  2287. }
  2288.  
  2289. - ret = sharp_panel_on(sharp);
  2290. - if (ret < 0) {
  2291. - dev_err(panel->dev, "failed to set panel on: %d\n", ret);
  2292. - goto poweroff;
  2293. - }
  2294. -
  2295. sharp->prepared = true;
  2296.  
  2297. /* wait for 6 frames before continuing */
  2298. @@ -220,8 +183,6 @@ static int sharp_panel_get_modes(struct drm_panel *panel)
  2299. struct drm_connector *connector = panel->connector;
  2300. struct sharp_panel *sharp = to_sharp_panel(panel);
  2301.  
  2302. - printk("sharp_panel_get_modes()\n");
  2303. - printk("drm_mode_duplcate()\n");
  2304. mode = drm_mode_duplicate(panel->drm, &default_mode);
  2305. if (!mode) {
  2306. dev_err(&sharp->dsi->dev, "failed to add mode %ux%ux@%u\n",
  2307. @@ -230,10 +191,8 @@ static int sharp_panel_get_modes(struct drm_panel *panel)
  2308. return -ENOMEM;
  2309. }
  2310.  
  2311. - printk("drm_mode_set_name()\n");
  2312. drm_mode_set_name(mode);
  2313.  
  2314. - printk("mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED\n");
  2315. mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  2316. drm_mode_probed_add(connector, mode);
  2317.  
  2318. @@ -265,9 +224,9 @@ static int sharp_panel_add(struct sharp_panel *sharp)
  2319. printk("sharp_panel_add()\n");
  2320. sharp->mode = &default_mode;
  2321.  
  2322. - sharp->supply = devm_regulator_get(dev, "avdd");
  2323. + sharp->supply = devm_regulator_get(dev, "power");
  2324. if (IS_ERR(sharp->supply)) {
  2325. - dev_err(dev, "cannot get avdd supply %ld\n", PTR_ERR(sharp->supply));
  2326. + dev_err(dev, "cannot get power supply %ld\n", PTR_ERR(sharp->supply));
  2327. return PTR_ERR(sharp->supply);
  2328. }
  2329.  
  2330. @@ -311,10 +270,7 @@ static int sharp_panel_probe(struct mipi_dsi_device *dsi)
  2331.  
  2332. dsi->lanes = 4;
  2333. dsi->format = MIPI_DSI_FMT_RGB888;
  2334. - dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
  2335. - MIPI_DSI_MODE_VIDEO_HSE |
  2336. - MIPI_DSI_CLOCK_NON_CONTINUOUS |
  2337. - MIPI_DSI_MODE_EOT_PACKET;
  2338. + dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
  2339.  
  2340. sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL);
  2341. if (!sharp)
  2342. --
  2343. 2.19.1
Add Comment
Please, Sign In to add comment