From: Sandeep Panda <spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
Sandeep Panda <spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
abhinavk-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
nganji-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
jsanka-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
chandanu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
Subject: [[RFC]DPU PATCH 3/4] drm/panel: add Innolux TV123WAM eDP panel driver
Date: Wed, 18 Apr 2018 17:50:01 +0530 [thread overview]
Message-ID: <1524054002-17869-4-git-send-email-spanda@codeaurora.org> (raw)
In-Reply-To: <1524054002-17869-1-git-send-email-spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Add support for Innolux TV123WAM 12.3" panel which
is an eDP panel.
Signed-off-by: Sandeep Panda <spanda@codeaurora.org>
---
drivers/gpu/drm/panel/panel-innolux-tv123wam.c | 299 +++++++++++++++++++++++++
1 file changed, 299 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-innolux-tv123wam.c
diff --git a/drivers/gpu/drm/panel/panel-innolux-tv123wam.c b/drivers/gpu/drm/panel/panel-innolux-tv123wam.c
new file mode 100644
index 0000000..f149fa9
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-innolux-tv123wam.c
@@ -0,0 +1,299 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <drm/drmP.h>
+#include <drm/drm_panel.h>
+#include <video/display_timing.h>
+#include <video/videomode.h>
+
+struct panel_edp_2k_desc {
+ const struct drm_display_mode *modes;
+ unsigned int num_modes;
+ struct {
+ unsigned int width;
+ unsigned int height;
+ } size;
+ u32 bpc;
+ u32 bus_flags;
+};
+
+struct panel_edp_2k_data {
+ struct drm_panel base;
+ bool enabled;
+ bool prepared;
+
+ const struct panel_edp_2k_desc *desc;
+
+ struct regulator *supply;
+ struct gpio_desc *enable_gpio;
+ struct backlight_device *backlight;
+};
+
+static const struct drm_display_mode innolux_edp_2k_mode = {
+ .clock = 206016,
+ .hdisplay = 2160,
+ .hsync_start = 2160 + 80,
+ .hsync_end = 2160 + 80 + 48,
+ .htotal = 2160 + 80 + 48 + 32,
+ .vdisplay = 1440,
+ .vsync_start = 1440 + 27,
+ .vsync_end = 1440 + 27 + 3,
+ .vtotal = 1440 + 27 + 3 + 10,
+ .vrefresh = 60,
+ .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
+};
+
+static const struct panel_edp_2k_desc innolux_edp_2k = {
+ .modes = &innolux_edp_2k_mode,
+ .num_modes = 1,
+ .size = {
+ .width = 223,
+ .height = 125,
+ },
+ .bpc = 8,
+ .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+};
+
+static const struct of_device_id platform_of_match[] = {
+ {
+ .compatible = "innolux, edp_2k_panel",
+ .data = &innolux_edp_2k,
+ },
+};
+
+static inline struct panel_edp_2k_data *
+to_panel_edp_2k_data(struct drm_panel *panel)
+{
+ return container_of(panel, struct panel_edp_2k_data, base);
+}
+
+static int panel_edp_2k_disable(struct drm_panel *panel)
+{
+ struct panel_edp_2k_data *pdata = to_panel_edp_2k_data(panel);
+
+ if (!pdata->enabled)
+ return 0;
+
+ if (pdata->backlight) {
+ pdata->backlight->props.power = FB_BLANK_POWERDOWN;
+ pdata->backlight->props.state |= BL_CORE_FBBLANK;
+ backlight_update_status(pdata->backlight);
+ }
+
+ pdata->enabled = false;
+
+ return 0;
+}
+
+static int panel_edp_2k_unprepare(struct drm_panel *panel)
+{
+ struct panel_edp_2k_data *pdata = to_panel_edp_2k_data(panel);
+
+ if (!pdata->prepared)
+ return 0;
+
+ if (pdata->enable_gpio)
+ gpiod_set_value_cansleep(pdata->enable_gpio, 0);
+
+ regulator_disable(pdata->supply);
+
+ pdata->prepared = false;
+
+ return 0;
+}
+
+static int panel_edp_2k_prepare(struct drm_panel *panel)
+{
+ struct panel_edp_2k_data *pdata = to_panel_edp_2k_data(panel);
+ int ret;
+
+ if (pdata->prepared)
+ return 0;
+
+ ret = regulator_enable(pdata->supply);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to enable supply: %d\n", ret);
+ return ret;
+ }
+
+ if (pdata->enable_gpio)
+ gpiod_set_value_cansleep(pdata->enable_gpio, 1);
+
+ pdata->prepared = true;
+
+ return 0;
+}
+
+static int panel_edp_2k_enable(struct drm_panel *panel)
+{
+ struct panel_edp_2k_data *pdata = to_panel_edp_2k_data(panel);
+
+ if (pdata->enabled)
+ return 0;
+
+ if (pdata->backlight) {
+ pdata->backlight->props.state &= ~BL_CORE_FBBLANK;
+ pdata->backlight->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(pdata->backlight);
+ }
+
+ pdata->enabled = true;
+
+ return 0;
+}
+
+static int panel_edp_2k_get_modes(struct drm_panel *panel)
+{
+ struct panel_edp_2k_data *pdata = to_panel_edp_2k_data(panel);
+ struct drm_connector *connector = pdata->base.connector;
+ struct drm_device *drm = pdata->base.drm;
+ struct drm_display_mode *mode;
+ unsigned int i, num = 0;
+
+ if (!pdata->desc || !connector || !drm)
+ return 0;
+
+ for (i = 0; i < pdata->desc->num_modes; i++) {
+ const struct drm_display_mode *m = &pdata->desc->modes[i];
+
+ mode = drm_mode_duplicate(drm, m);
+ if (!mode) {
+ dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
+ m->hdisplay, m->vdisplay, m->vrefresh);
+ continue;
+ }
+
+ mode->type |= DRM_MODE_TYPE_DRIVER;
+
+ if (pdata->desc->num_modes == 1)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_set_name(mode);
+
+ drm_mode_probed_add(connector, mode);
+ num++;
+ }
+
+ connector->display_info.bpc = pdata->desc->bpc;
+ connector->display_info.width_mm = pdata->desc->size.width;
+ connector->display_info.height_mm = pdata->desc->size.height;
+ connector->display_info.bus_flags = pdata->desc->bus_flags;
+
+ return num;
+}
+
+static const struct drm_panel_funcs panel_edp_2k_funcs = {
+ .disable = panel_edp_2k_disable,
+ .unprepare = panel_edp_2k_unprepare,
+ .prepare = panel_edp_2k_prepare,
+ .enable = panel_edp_2k_enable,
+ .get_modes = panel_edp_2k_get_modes,
+};
+
+static int panel_edp_2k_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *id;
+ struct device_node *backlight;
+ struct panel_edp_2k_data *pdata;
+ int ret;
+
+ id = of_match_node(platform_of_match, pdev->dev.of_node);
+ if (!id)
+ return -ENODEV;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->enabled = false;
+ pdata->desc = id->data;
+
+ pdata->supply = devm_regulator_get(dev, "power");
+ if (IS_ERR(pdata->supply))
+ return PTR_ERR(pdata->supply);
+
+ pdata->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(pdata->enable_gpio)) {
+ ret = PTR_ERR(pdata->enable_gpio);
+ dev_err(dev, "failed to request GPIO: %d\n", ret);
+ return ret;
+ }
+
+ backlight = of_parse_phandle(dev->of_node, "backlight", 0);
+ if (backlight) {
+ pdata->backlight = of_find_backlight_by_node(backlight);
+ of_node_put(backlight);
+
+ if (!pdata->backlight)
+ return -EPROBE_DEFER;
+ }
+
+ drm_panel_init(&pdata->base);
+ pdata->base.dev = dev;
+ pdata->base.funcs = &panel_edp_2k_funcs;
+
+ ret = drm_panel_add(&pdata->base);
+ if (ret < 0)
+ goto free_backlight;
+
+ dev_set_drvdata(dev, pdata);
+
+ return 0;
+
+free_backlight:
+ if (pdata->backlight)
+ put_device(&pdata->backlight->dev);
+
+ return ret;
+}
+
+static int panel_edp_2k_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct panel_edp_2k_data *pdata = dev_get_drvdata(dev);
+
+ drm_panel_detach(&pdata->base);
+ drm_panel_remove(&pdata->base);
+
+ panel_edp_2k_disable(&pdata->base);
+ panel_edp_2k_unprepare(&pdata->base);
+
+ if (pdata->backlight)
+ put_device(&pdata->backlight->dev);
+
+ return 0;
+}
+
+static struct platform_driver panel_edp_2k_driver = {
+ .driver = {
+ .name = "innolux-2k-edp-panel",
+ .of_match_table = platform_of_match,
+ },
+ .probe = panel_edp_2k_probe,
+ .remove = panel_edp_2k_remove,
+};
+
+static int __init panel_edp_2k_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&panel_edp_2k_driver);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+module_init(panel_edp_2k_init);
+
+static void __exit panel_edp_2k_exit(void)
+{
+ platform_driver_unregister(&panel_edp_2k_driver);
+}
+module_exit(panel_edp_2k_exit);
+
+MODULE_DESCRIPTION("Innolux 2k eDP panel driver");
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno
next prev parent reply other threads:[~2018-04-18 12:20 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20180419072054epcas5p364c0eae57d11ff5ff22890223a79c271@epcas5p3.samsung.com>
2018-04-18 12:19 ` [[RFC]DPU PATCH 0/4] Add suppport for sn65dsi86 bridge chip and Innolux 2k edp panel driver Sandeep Panda
[not found] ` <1524054002-17869-1-git-send-email-spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-04-18 12:19 ` [[RFC]DPU PATCH 1/4] drm/bridge: add support for sn65dsi86 bridge driver Sandeep Panda
2018-04-18 14:11 ` Sean Paul
2018-04-18 18:31 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
2018-04-19 4:37 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
[not found] ` <1524054002-17869-2-git-send-email-spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-04-19 15:14 ` Jordan Crouse
[not found] ` <20180419151438.GA18652-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-04-19 18:18 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
2018-04-18 12:20 ` [[RFC]DPU PATCH 2/4] dt-bindings: drm/bridge: Document sn65dsi86 bridge bindings Sandeep Panda
2018-04-18 13:58 ` Sean Paul
2018-04-18 18:08 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
2018-04-18 12:20 ` Sandeep Panda [this message]
2018-04-18 12:20 ` [[RFC]DPU PATCH 4/4] dt-bindings: Add Innolux TV123WAM panel bindings Sandeep Panda
2018-04-24 14:43 ` Rob Herring
2018-04-25 2:16 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
[not found] ` <cb59510635f0e7c010588a4603ae3f0f-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-04-25 14:40 ` Rob Herring
2018-04-18 14:12 ` [[RFC]DPU PATCH 0/4] Add suppport for sn65dsi86 bridge chip and Innolux 2k edp panel driver Sean Paul
2018-04-18 18:36 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
2018-04-26 7:08 ` Andrzej Hajda
2018-04-19 17:56 Sandeep Panda
[not found] ` <1524160568-27583-1-git-send-email-spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-04-19 17:56 ` [[RFC]DPU PATCH 3/4] drm/panel: add Innolux TV123WAM eDP " Sandeep Panda
[not found] ` <1524160568-27583-4-git-send-email-spanda-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-04-20 19:43 ` Sean Paul
2018-04-24 9:53 ` spanda-sgV2jX0FEOL9JmXXK+q4OQ
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1524054002-17869-4-git-send-email-spanda@codeaurora.org \
--to=spanda-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
--cc=abhinavk-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=chandanu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
--cc=jsanka-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=nganji-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.