From 484d7b1bd6ec1acec8cf8374c58deb7c97260c5c Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Mon, 26 Jun 2023 17:11:37 +0800 Subject: [PATCH] misc: Add rk628 misc drivers Customers may use rk628 drivers on different platforms. Hence we need drivers that do not rely on the FB/DRM display framework. Signed-off-by: Algea Cao Change-Id: Iaab679e4a72d0fb0e5a76bee89b8e1bdac60f4a7 --- drivers/misc/Kconfig | 2 + drivers/misc/Makefile | 1 + drivers/misc/rk628/Kconfig | 27 + drivers/misc/rk628/Makefile | 10 + drivers/misc/rk628/panel.c | 245 +++++ drivers/misc/rk628/panel.h | 18 + drivers/misc/rk628/rk628.c | 1310 +++++++++++++++++++++++ drivers/misc/rk628/rk628.h | 484 +++++++++ drivers/misc/rk628/rk628_combrxphy.c | 567 ++++++++++ drivers/misc/rk628/rk628_combrxphy.h | 16 + drivers/misc/rk628/rk628_combtxphy.c | 309 ++++++ drivers/misc/rk628/rk628_combtxphy.h | 82 ++ drivers/misc/rk628/rk628_config.c | 52 + drivers/misc/rk628/rk628_config.h | 24 + drivers/misc/rk628/rk628_cru.c | 472 ++++++++ drivers/misc/rk628/rk628_cru.h | 159 +++ drivers/misc/rk628/rk628_csi.c | 434 ++++++++ drivers/misc/rk628/rk628_csi.h | 86 ++ drivers/misc/rk628/rk628_dsi.c | 1310 +++++++++++++++++++++++ drivers/misc/rk628/rk628_dsi.h | 158 +++ drivers/misc/rk628/rk628_gpio.h | 296 +++++ drivers/misc/rk628/rk628_grf.h | 263 +++++ drivers/misc/rk628/rk628_gvi.c | 230 ++++ drivers/misc/rk628/rk628_gvi.h | 218 ++++ drivers/misc/rk628/rk628_hdmirx.c | 777 ++++++++++++++ drivers/misc/rk628/rk628_hdmirx.h | 633 +++++++++++ drivers/misc/rk628/rk628_hdmitx.c | 1198 +++++++++++++++++++++ drivers/misc/rk628/rk628_hdmitx.h | 350 ++++++ drivers/misc/rk628/rk628_lvds.c | 126 +++ drivers/misc/rk628/rk628_lvds.h | 15 + drivers/misc/rk628/rk628_pinctrl.c | 326 ++++++ drivers/misc/rk628/rk628_pinctrl.h | 19 + drivers/misc/rk628/rk628_post_process.c | 268 +++++ drivers/misc/rk628/rk628_post_process.h | 15 + drivers/misc/rk628/rk628_rgb.c | 166 +++ drivers/misc/rk628/rk628_rgb.h | 17 + 36 files changed, 10683 insertions(+) create mode 100644 drivers/misc/rk628/Kconfig create mode 100644 drivers/misc/rk628/Makefile create mode 100644 drivers/misc/rk628/panel.c create mode 100644 drivers/misc/rk628/panel.h create mode 100644 drivers/misc/rk628/rk628.c create mode 100644 drivers/misc/rk628/rk628.h create mode 100644 drivers/misc/rk628/rk628_combrxphy.c create mode 100644 drivers/misc/rk628/rk628_combrxphy.h create mode 100644 drivers/misc/rk628/rk628_combtxphy.c create mode 100644 drivers/misc/rk628/rk628_combtxphy.h create mode 100644 drivers/misc/rk628/rk628_config.c create mode 100644 drivers/misc/rk628/rk628_config.h create mode 100644 drivers/misc/rk628/rk628_cru.c create mode 100644 drivers/misc/rk628/rk628_cru.h create mode 100644 drivers/misc/rk628/rk628_csi.c create mode 100644 drivers/misc/rk628/rk628_csi.h create mode 100644 drivers/misc/rk628/rk628_dsi.c create mode 100644 drivers/misc/rk628/rk628_dsi.h create mode 100644 drivers/misc/rk628/rk628_gpio.h create mode 100644 drivers/misc/rk628/rk628_grf.h create mode 100644 drivers/misc/rk628/rk628_gvi.c create mode 100644 drivers/misc/rk628/rk628_gvi.h create mode 100644 drivers/misc/rk628/rk628_hdmirx.c create mode 100644 drivers/misc/rk628/rk628_hdmirx.h create mode 100644 drivers/misc/rk628/rk628_hdmitx.c create mode 100644 drivers/misc/rk628/rk628_hdmitx.h create mode 100644 drivers/misc/rk628/rk628_lvds.c create mode 100644 drivers/misc/rk628/rk628_lvds.h create mode 100644 drivers/misc/rk628/rk628_pinctrl.c create mode 100644 drivers/misc/rk628/rk628_pinctrl.h create mode 100644 drivers/misc/rk628/rk628_post_process.c create mode 100644 drivers/misc/rk628/rk628_post_process.h create mode 100644 drivers/misc/rk628/rk628_rgb.c create mode 100644 drivers/misc/rk628/rk628_rgb.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 276c7c4fef15..8481b9613bc9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -5,6 +5,8 @@ menu "Misc devices" +source "drivers/misc/rk628/Kconfig" + config RK803 tristate "RK803" default n diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b296e760fd47..14642c54a2bc 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -3,6 +3,7 @@ # Makefile for misc devices that really don't fit anywhere else. # +obj-y += rk628/ obj-$(CONFIG_RK803) += rk803.o obj-y += rockchip/ obj-$(CONFIG_LT7911D_FB_NOTIFIER) += lt7911d-fb-notifier.o diff --git a/drivers/misc/rk628/Kconfig b/drivers/misc/rk628/Kconfig new file mode 100644 index 000000000000..7f89f18f42a1 --- /dev/null +++ b/drivers/misc/rk628/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 +menu "RK628 misc driver" +config RK628_MISC + tristate "rk628 misc driver" + default n + help + Say y here to enable Rockchip rk628 misc driver. + This option is used to support rgb/hdmi/bt1120 input and dsi/lvds/gvi/hdmi output. + +config RK628_MISC_HDMITX + bool "rk628 misc hdmitx driver" + default n + depends on RK628_MISC + depends on DRM + help + Say y here to enable Rockchip rk628 misc hdmitx driver. + This option is used to support hdmi output. + +config ROCKCHIP_THUNDER_BOOT_RK628 + bool "Rockchip RK628 Thunder Boot support" + default n + depends on RK628_MISC + help + Say y here to enable Rockchip rk628 thunder boot support. + This option make the kernel boot faster. + +endmenu diff --git a/drivers/misc/rk628/Makefile b/drivers/misc/rk628/Makefile new file mode 100644 index 000000000000..cb4285a06f89 --- /dev/null +++ b/drivers/misc/rk628/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +rk628_misc-$(CONFIG_RK628_MISC) += rk628.o rk628_cru.o rk628_config.o rk628_post_process.o \ + rk628_combrxphy.o rk628_hdmirx.o rk628_combtxphy.o rk628_dsi.o \ + panel.o rk628_lvds.o rk628_rgb.o rk628_gvi.o rk628_pinctrl.o \ + rk628_csi.o + +rk628_misc-$(CONFIG_RK628_MISC_HDMITX) += rk628_hdmitx.o + +obj-$(CONFIG_RK628_MISC) += rk628_misc.o diff --git a/drivers/misc/rk628/panel.c b/drivers/misc/rk628/panel.c new file mode 100644 index 000000000000..a0a35030779f --- /dev/null +++ b/drivers/misc/rk628/panel.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Rockchip Electronics Co. Ltd. + * + * Author: Guochun Huang + */ + +#include "rk628.h" +#include +#include + +#include "panel.h" + +static int +dsi_panel_parse_cmds(const u8 *data, int blen, struct panel_cmds *pcmds) +{ + unsigned int len; + char *buf, *bp; + struct cmd_ctrl_hdr *dchdr; + int i, cnt; + + if (!pcmds) + return -EINVAL; + + buf = kmemdup(data, blen, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + /* scan init commands */ + bp = buf; + len = blen; + cnt = 0; + while (len > sizeof(*dchdr)) { + dchdr = (struct cmd_ctrl_hdr *)bp; + + if (dchdr->dlen > len) { + pr_err("%s: error, len=%d", __func__, dchdr->dlen); + return -EINVAL; + } + + bp += sizeof(*dchdr); + len -= sizeof(*dchdr); + bp += dchdr->dlen; + len -= dchdr->dlen; + cnt++; + } + + if (len != 0) { + pr_err("%s: dcs_cmd=%x len=%d error!", __func__, buf[0], blen); + kfree(buf); + return -EINVAL; + } + + pcmds->cmds = kcalloc(cnt, sizeof(struct cmd_desc), GFP_KERNEL); + if (!pcmds->cmds) { + kfree(buf); + return -ENOMEM; + } + + pcmds->cmd_cnt = cnt; + pcmds->buf = buf; + pcmds->blen = blen; + + bp = buf; + len = blen; + for (i = 0; i < cnt; i++) { + dchdr = (struct cmd_ctrl_hdr *)bp; + len -= sizeof(*dchdr); + bp += sizeof(*dchdr); + pcmds->cmds[i].dchdr = *dchdr; + pcmds->cmds[i].payload = bp; + bp += dchdr->dlen; + len -= dchdr->dlen; + } + + return 0; +} + +static int dsi_panel_get_cmds(struct rk628 *rk628, struct device_node *dsi_np) +{ + struct device_node *np; + const void *data; + int len; + int ret, err; + + np = of_find_node_by_name(dsi_np, "rk628-panel"); + if (!np) + return -EINVAL; + + data = of_get_property(np, "panel-init-sequence", &len); + if (data) { + rk628->panel->on_cmds = kcalloc(1, sizeof(struct panel_cmds), GFP_KERNEL); + if (!rk628->panel->on_cmds) + return -ENOMEM; + + err = dsi_panel_parse_cmds(data, len, rk628->panel->on_cmds); + if (err) { + dev_err(rk628->dev, "failed to parse dsi panel init sequence\n"); + ret = err; + goto init_err; + } + } + + data = of_get_property(np, "panel-exit-sequence", &len); + if (data) { + rk628->panel->off_cmds = kcalloc(1, sizeof(struct panel_cmds), GFP_KERNEL); + if (!rk628->panel->off_cmds) { + ret = -ENOMEM; + goto on_err; + } + + err = dsi_panel_parse_cmds(data, len, rk628->panel->off_cmds); + if (err) { + dev_err(rk628->dev, "failed to parse dsi panel exit sequence\n"); + ret = err; + goto exit_err; + } + } + + return 0; + +exit_err: + kfree(rk628->panel->off_cmds); +on_err: + kfree(rk628->panel->on_cmds->cmds); + kfree(rk628->panel->on_cmds->buf); +init_err: + kfree(rk628->panel->on_cmds); + + return ret; +} + +int rk628_panel_info_get(struct rk628 *rk628, struct device_node *np) +{ + struct panel_simple *panel; + struct device *dev = rk628->dev; + struct device_node *backlight; + int ret; + + panel = devm_kzalloc(dev, sizeof(struct panel_simple), GFP_KERNEL); + if (!panel) + return -ENOMEM; + + panel->supply = devm_regulator_get(dev, "power"); + if (IS_ERR(panel->supply)) { + ret = PTR_ERR(panel->supply); + dev_err(dev, "failed to get power regulator: %d\n", ret); + return ret; + } + + panel->enable_gpio = devm_gpiod_get_optional(dev, "panel-enable", GPIOD_OUT_LOW); + if (IS_ERR(panel->enable_gpio)) { + ret = PTR_ERR(panel->enable_gpio); + dev_err(dev, "failed to request panel enable GPIO: %d\n", ret); + return ret; + } + + panel->reset_gpio = devm_gpiod_get_optional(dev, "panel-reset", GPIOD_OUT_LOW); + if (IS_ERR(panel->reset_gpio)) { + ret = PTR_ERR(panel->reset_gpio); + dev_err(dev, "failed to request panel reset GPIO: %d\n", ret); + return ret; + } + + backlight = of_parse_phandle(dev->of_node, "panel-backlight", 0); + if (backlight) { + panel->backlight = of_find_backlight_by_node(backlight); + of_node_put(backlight); + + if (!panel->backlight) { + dev_err(dev, "failed to find backlight\n"); + return -EPROBE_DEFER; + } + + } + + rk628->panel = panel; + + if (rk628->output_mode == OUTPUT_MODE_DSI) { + ret = dsi_panel_get_cmds(rk628, np); + if (ret) { + dev_err(dev, "failed to get cmds\n"); + return ret; + } + } + + return 0; +} + +void rk628_panel_prepare(struct rk628 *rk628) +{ + int ret; + + if (rk628->panel->supply) { + ret = regulator_enable(rk628->panel->supply); + if (ret) + dev_info(rk628->dev, "failed to enable panel power supply\n"); + } + + if (rk628->panel->enable_gpio) { + gpiod_set_value(rk628->panel->enable_gpio, 0); + mdelay(120); + gpiod_set_value(rk628->panel->enable_gpio, 1); + mdelay(120); + } + + if (rk628->panel->reset_gpio) { + gpiod_set_value(rk628->panel->reset_gpio, 0); + mdelay(120); + gpiod_set_value(rk628->panel->reset_gpio, 1); + mdelay(120); + gpiod_set_value(rk628->panel->reset_gpio, 0); + mdelay(120); + } +} + +void rk628_panel_enable(struct rk628 *rk628) +{ + if (rk628->panel->backlight) + backlight_enable(rk628->panel->backlight); +} + +void rk628_panel_unprepare(struct rk628 *rk628) +{ + + if (rk628->panel->reset_gpio) { + gpiod_set_value(rk628->panel->reset_gpio, 1); + mdelay(120); + } + + if (rk628->panel->enable_gpio) { + gpiod_set_value(rk628->panel->enable_gpio, 0); + mdelay(120); + } + + if (rk628->panel->supply) + regulator_disable(rk628->panel->supply); +} + +void rk628_panel_disable(struct rk628 *rk628) +{ + if (rk628->panel->backlight) + backlight_disable(rk628->panel->backlight); + +} diff --git a/drivers/misc/rk628/panel.h b/drivers/misc/rk628/panel.h new file mode 100644 index 000000000000..07a34cf3ee17 --- /dev/null +++ b/drivers/misc/rk628/panel.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. + * + * Author: Guochun Huang + */ +#ifndef _PANEL_H +#define _PANEL_H + +#include "rk628.h" + +int rk628_panel_info_get(struct rk628 *rk628, struct device_node *np); +void rk628_panel_prepare(struct rk628 *rk628); +void rk628_panel_enable(struct rk628 *rk628); +void rk628_panel_unprepare(struct rk628 *rk628); +void rk628_panel_disable(struct rk628 *rk628); +#endif + diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c new file mode 100644 index 000000000000..15df730c8048 --- /dev/null +++ b/drivers/misc/rk628/rk628.c @@ -0,0 +1,1310 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Rockchip Electronics Co. Ltd. + * + * Author: Wyon Bi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include