All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Add DRM driver for Hisilicon hi1710
@ 2016-02-29  0:58 lijianhua
  2016-02-29  0:58 ` [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver lijianhua
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

This patch set adds a new drm driver for Hisilicon hi1710.
hi1710 is an BMC controller, and now we use it in arm64 board.
In this patch set, we just support basic function for hi1710 display subsystem.
hi1710 display subsytem is connected to arm64 by PCIe as bellow:

+---------+        +-----------+
|         |  PCIe  |   hi1710  |
|  arm64  |<------>|  display  |
|         |        | subsystem |
+---------+        +-----------+

Hardware Detail for hi1710 display subsystem
--------
  The display sybsystem of hi1710 is show as bellow:
  +----+     +------+     +------+     +------------+
  |    |     |      |     |      |     |            |
  | FB |---->|  DE  |---->| VDAC |---->|  External  |
  |    |     |      |     |      |     |    VGA     |
  +----+     +------+     +------+     +------------+

 - DE(Display Engine) is the display controller.
 - VDAC(Video Digital-to-Analog Converter) converts the RGB digital data stream 
 from DE to VGA analog signals. 

lijianhua (7):
  drm/hisilicon:Add hisilicon hibmc master driver.
  drm/hisilicon:Add plane for DE
  drm/hisilicon:Add crtc for DE
  drm/hisilicon:Add encoder for VDAC
  drm/hisilicon:Add connector for VDAC
  drm/hisilicon:Add fbdev
  MAINTAINERS:Add maintainer for hibmc DRM driver

 MAINTAINERS                                       |   7 +
 drivers/gpu/drm/Kconfig                           |   2 +
 drivers/gpu/drm/Makefile                          |   1 +
 drivers/gpu/drm/hisilicon/Kconfig                 |   4 +
 drivers/gpu/drm/hisilicon/Makefile                |   4 +
 drivers/gpu/drm/hisilicon/hibmc/Kconfig           |  13 +
 drivers/gpu/drm/hisilicon/hibmc/Makefile          |   5 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    | 437 +++++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h    |  20 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 374 +++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  56 +++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c | 290 +++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c    |  83 ++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h    | 484 ++++++++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c  | 162 ++++++++
 15 files changed, 1942 insertions(+)
 create mode 100644 drivers/gpu/drm/hisilicon/Kconfig
 create mode 100644 drivers/gpu/drm/hisilicon/Makefile
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c

-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver.
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  9:40   ` Emil Velikov
  2016-02-29  0:58 ` [PATCH 2/7] drm/hisilicon:Add plane for DE lijianhua
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add hibmc DRM master driver for hi1710 which used in arm64 board.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/Kconfig                         |   2 +
 drivers/gpu/drm/Makefile                        |   1 +
 drivers/gpu/drm/hisilicon/Kconfig               |   4 +
 drivers/gpu/drm/hisilicon/Makefile              |   4 +
 drivers/gpu/drm/hisilicon/hibmc/Kconfig         |  13 +
 drivers/gpu/drm/hisilicon/hibmc/Makefile        |   5 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 301 +++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h |  49 +++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c  |  83 ++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h  | 484 ++++++++++++++++++++++++
 10 files changed, 946 insertions(+)
 create mode 100644 drivers/gpu/drm/hisilicon/Kconfig
 create mode 100644 drivers/gpu/drm/hisilicon/Makefile
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 8ae7ab6..600f94d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -269,3 +269,5 @@ source "drivers/gpu/drm/imx/Kconfig"
 source "drivers/gpu/drm/vc4/Kconfig"
 
 source "drivers/gpu/drm/etnaviv/Kconfig"
+
+source "drivers/gpu/drm/hisilicon/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 61766de..6055483 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -74,3 +74,4 @@ obj-y			+= panel/
 obj-y			+= bridge/
 obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
 obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
+obj-y			+= hisilicon/
diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig
new file mode 100644
index 0000000..1f10e17
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/Kconfig
@@ -0,0 +1,4 @@
+# hisilicon drm device configuration.
+# Please keep this sorted alphabetically.
+
+source "drivers/gpu/drm/hisilicon/hibmc/Kconfig"
diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile
new file mode 100644
index 0000000..487d5b0
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/Makefile
@@ -0,0 +1,4 @@
+# Makefile for hisilicon drm drivers.
+# Please keep this list sorted alphabetically
+
+obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/
\ No newline at end of file
diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
new file mode 100644
index 0000000..c60ace6
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
@@ -0,0 +1,13 @@
+config DRM_HISI_HIBMC
+	tristate "DRM Support for hisilicon hibmc dispi vga interface"
+	depends on DRM && PCI
+	select DRM_KMS_HELPER
+	select DRM_KMS_FB_HELPER
+	select DRM_GEM_CMA_HELPER
+	select DRM_KMS_CMA_HELPER
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	help
+	  Choose this option for qemu.
+	  If M is selected the module will be called hibmc-drm.
diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
new file mode 100644
index 0000000..28e59bb
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -0,0 +1,5 @@
+ccflags-y := -Iinclude/drm
+hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_hw.o
+
+obj-$(CONFIG_DRM_HISI_HIBMC)	+=hibmc-drm.o
+#obj-y	+= hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
new file mode 100644
index 0000000..444ced8
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/console.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drmP.h>
+
+#include "hibmc_drm_drv.h"
+#include "hibmc_drm_hw.h"
+
+unsigned char __iomem *mmio_bmc_vga;
+
+static const struct file_operations hibmc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= drm_open,
+	.release	= drm_release,
+	.unlocked_ioctl	= drm_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= drm_compat_ioctl,
+#endif
+	.poll		= drm_poll,
+	.read		= drm_read,
+	.llseek		= no_llseek,
+};
+
+int hibmc_enable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	return 0;
+}
+
+void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+}
+
+static struct drm_driver hibmc_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET |
+						DRIVER_ATOMIC,
+	.fops			= &hibmc_fops,
+	.name			= "hibmc-drm",
+	.desc			= "hibmc drm driver",
+	.date			= "20151218",
+	.major			= 1,
+	.minor			= 0,
+	.get_vblank_counter = drm_vblank_no_hw_counter,
+	.enable_vblank		= hibmc_enable_vblank,
+	.disable_vblank	= hibmc_disable_vblank,
+	.gem_free_object        = drm_gem_cma_free_object,
+	.gem_vm_ops				= &drm_gem_cma_vm_ops,
+	.dumb_create            = drm_gem_cma_dumb_create,
+	.dumb_map_offset        = drm_gem_cma_dumb_map_offset,
+	.dumb_destroy           = drm_gem_dumb_destroy,
+};
+
+static int hibmc_pm_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct hibmc_private *hiprivate = drm_dev->dev_private;
+
+	drm_kms_helper_poll_disable(drm_dev);
+
+	if (hiprivate->fbdev.initialized) {
+		console_lock();
+		fb_set_suspend(hiprivate->fbdev.helper.fbdev, 1);
+		console_unlock();
+	}
+
+	return 0;
+}
+
+static int hibmc_pm_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct hibmc_private *hiprivate = drm_dev->dev_private;
+
+	drm_helper_resume_force_mode(drm_dev);
+
+	if (hiprivate->fbdev.initialized) {
+		console_lock();
+		fb_set_suspend(hiprivate->fbdev.helper.fbdev, 0);
+		console_unlock();
+	}
+
+	drm_kms_helper_poll_enable(drm_dev);
+	return 0;
+}
+
+static const struct dev_pm_ops hibmc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
+				hibmc_pm_resume)
+};
+
+int hibmc_hw_config(void)
+{
+	unsigned int reg;
+
+	/* On hardware reset, power mode 0 is default. */
+	set_power_mode(POWER_MODE_CTRL_MODE_MODE0);
+
+	/* Enable display power gate & LOCALMEM power gate*/
+	reg = PEEK32(CURRENT_GATE);
+	reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, ON);
+	reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, ON);
+	set_current_gate(reg);
+
+	/* Reset the memory controller. If the memory controller
+	 * is not reset in chip,the system might hang when sw accesses
+	 * the memory.The memory should be resetted after
+	 * changing the MXCLK.
+	 */
+	reg = PEEK32(MISC_CTRL);
+	reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, RESET);
+	POKE32(MISC_CTRL, reg);
+
+	reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
+	POKE32(MISC_CTRL, reg);
+
+	/* We can add more initialization as needed. */
+
+	return 0;
+}
+
+int hibmc_hw_map(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+	struct pci_dev *pdev = dev->pdev;
+	resource_size_t addr, size, ioaddr, iosize;
+
+	ioaddr = pci_resource_start(pdev, 1);
+	iosize = MB(2);
+
+	hiprivate->mmio = ioremap_nocache(ioaddr, iosize);
+	if (!hiprivate->mmio) {
+		DRM_ERROR("Cannot map mmio region\n");
+		return -ENOMEM;
+	}
+
+	mmio_bmc_vga = hiprivate->mmio;
+
+	addr = pci_resource_start(pdev, 0);
+	size = MB(16);
+
+	hiprivate->fb_map = ioremap(addr, size);
+	if (!hiprivate->fb_map) {
+		DRM_ERROR("Cannot map framebuffer\n");
+		return -ENOMEM;
+	}
+	hiprivate->fb_base = addr;
+	hiprivate->fb_size = size;
+
+	return 0;
+}
+
+void hibmc_hw_fini(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+
+	if (hiprivate->mmio)
+		iounmap(hiprivate->mmio);
+	if (hiprivate->fb_map)
+		iounmap(hiprivate->fb_map);
+}
+
+int hibmc_hw_init(struct drm_device *dev)
+{
+	int ret;
+
+	ret = hibmc_hw_map(dev);
+	if (ret)
+		return ret;
+
+	hibmc_hw_config();
+
+	return 0;
+}
+
+static int hibmc_unload(struct drm_device *dev)
+{
+	hibmc_hw_fini(dev);
+	dev->dev_private = NULL;
+	return 0;
+}
+
+static int hibmc_load(struct drm_device *dev, unsigned long flags)
+{
+	struct hibmc_private *hiprivate;
+	int ret;
+
+	hiprivate = devm_kzalloc(dev->dev, sizeof(*hiprivate), GFP_KERNEL);
+	if (!hiprivate)
+		return -ENOMEM;
+	dev->dev_private = hiprivate;
+	hiprivate->dev = dev;
+
+	ret = hibmc_hw_init(dev);
+	if (ret)
+		goto err;
+	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+	if (ret) {
+		DRM_ERROR("failed to initialize vblank.\n");
+		return ret;
+	}
+	/* reset all the states of crtc/plane/encoder/connector */
+	drm_mode_config_reset(dev);
+
+	return 0;
+
+err:
+	hibmc_unload(dev);
+	DRM_ERROR("failed to initialize drm driver.\n");
+	return ret;
+}
+
+static int hibmc_pci_probe(struct pci_dev *pdev,
+			   const struct pci_device_id *ent)
+{
+	struct drm_device *dev;
+	int ret;
+
+	dev = drm_dev_alloc(&hibmc_driver, &pdev->dev);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->pdev = pdev;
+	pci_set_drvdata(pdev, dev);
+
+	ret = pci_enable_device(pdev);
+	if (ret)
+		goto err_free;
+
+	ret = hibmc_load(dev, 0);
+	if (ret)
+		goto err_disable;
+
+	ret = drm_dev_register(dev, 0);
+	if (ret)
+		goto err_unload;
+
+	return 0;
+
+err_unload:
+	hibmc_unload(dev);
+err_disable:
+	pci_disable_device(pdev);
+err_free:
+	drm_dev_unref(dev);
+
+	return ret;
+}
+
+static void hibmc_pci_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_dev_unregister(dev);
+	hibmc_unload(dev);
+	drm_dev_unref(dev);
+}
+
+static struct pci_device_id hibmc_pci_table[] = {
+	{PCI_VENDOR_ID_HIS, PCI_DEVID_HS_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0,}
+};
+
+static struct pci_driver hibmc_pci_driver = {
+	.name =		"hibmc-drm",
+	.id_table =	hibmc_pci_table,
+	.probe =	hibmc_pci_probe,
+	.remove =	hibmc_pci_remove,
+	.driver.pm =    &hibmc_pm_ops,
+};
+
+static int __init hibmc_init(void)
+{
+	return drm_pci_init(&hibmc_driver, &hibmc_pci_driver);
+}
+
+static void __exit hibmc_exit(void)
+{
+	drm_pci_exit(&hibmc_driver, &hibmc_pci_driver);
+}
+
+module_init(hibmc_init);
+module_exit(hibmc_exit);
+
+MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
+MODULE_AUTHOR("lijianhua <lijianhua@huawei.com>");
+MODULE_DESCRIPTION("DRM Driver for Hisilicon BMC Hi1710");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
new file mode 100644
index 0000000..5db7902
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef HIBMC_DRM_DRV_H
+#define HIBMC_DRM_DRV_H
+
+/* Vendor and Device id for HISILICON Graphics chip*/
+#define PCI_VENDOR_ID_HIS 0x19e5
+#define PCI_DEVID_HS_VGA 0x1711
+
+struct hibmc_framebuffer {
+	struct drm_framebuffer fb;
+	struct drm_gem_cma_object *obj;
+	bool is_fbdev_fb;
+};
+
+struct hibmc_fbdev {
+	struct hibmc_framebuffer fb;
+	struct drm_fb_helper helper;
+	bool initialized;
+};
+
+struct hibmc_private {
+	/* hw */
+	void __iomem   *mmio;
+	void __iomem   *fb_map;
+	unsigned long  fb_base;
+	unsigned long  fb_size;
+
+	/* drm */
+	struct drm_device  *dev;
+	struct drm_plane plane;
+	struct drm_crtc crtc;
+	struct drm_encoder encoder;
+	struct drm_connector connector;
+	bool mode_config_initialized;
+
+	/* fbdev */
+	struct hibmc_fbdev fbdev;
+};
+
+#endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
new file mode 100644
index 0000000..8eb7b26
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/io.h>
+
+#include "hibmc_drm_hw.h"
+
+/*
+ * It can operate in one of three modes: 0, 1 or Sleep.
+ */
+void set_power_mode(unsigned int power_mode)
+{
+	unsigned int control_value = 0;
+
+	control_value = PEEK32(POWER_MODE_CTRL);
+
+	switch (power_mode) {
+	case POWER_MODE_CTRL_MODE_MODE0:
+		control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
+					  MODE, MODE0);
+		break;
+
+	case POWER_MODE_CTRL_MODE_MODE1:
+		control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
+					  MODE, MODE1);
+		break;
+
+	case POWER_MODE_CTRL_MODE_SLEEP:
+		control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
+					  MODE, SLEEP);
+		break;
+
+	default:
+		break;
+	}
+
+    /* Set up other fields in Power Control Register */
+	if (power_mode == POWER_MODE_CTRL_MODE_SLEEP) {
+		control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
+					  OSC_INPUT,  OFF);
+	} else {
+		control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
+					  OSC_INPUT,  ON);
+	}
+    /* Program new power mode. */
+	POKE32(POWER_MODE_CTRL, control_value);
+}
+
+unsigned int get_power_mode(void)
+{
+	return FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE);
+}
+
+void set_current_gate(unsigned int gate)
+{
+	unsigned int gate_reg;
+	unsigned int mode;
+
+	/* Get current power mode. */
+	mode = get_power_mode();
+
+	switch (mode) {
+	case POWER_MODE_CTRL_MODE_MODE0:
+		gate_reg = MODE0_GATE;
+		break;
+
+	case POWER_MODE_CTRL_MODE_MODE1:
+		gate_reg = MODE1_GATE;
+		break;
+
+	default:
+		gate_reg = MODE0_GATE;
+		break;
+	}
+	POKE32(gate_reg, gate);
+}
+
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
new file mode 100644
index 0000000..52787d4
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
@@ -0,0 +1,484 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+ #ifndef HIBMC_DRM_HW_H
+#define HIBMC_DRM_HW_H
+
+#define F(v)    v
+
+/* register definition */
+#define DE_STATE1                                        0x100054
+#define DE_STATE1_DE_ABORT                               F(0 : 0)
+#define DE_STATE1_DE_ABORT_OFF                           0
+#define DE_STATE1_DE_ABORT_ON                            1
+
+#define DE_STATE2                                        0x100058
+#define DE_STATE2_DE_FIFO                                F(3 : 3)
+#define DE_STATE2_DE_FIFO_NOTEMPTY                       0
+#define DE_STATE2_DE_FIFO_EMPTY                          1
+#define DE_STATE2_DE_STATUS                              F(2 : 2)
+#define DE_STATE2_DE_STATUS_IDLE                         0
+#define DE_STATE2_DE_STATUS_BUSY                         1
+#define DE_STATE2_DE_MEM_FIFO                            F(1 : 1)
+#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY                   0
+#define DE_STATE2_DE_MEM_FIFO_EMPTY                      1
+
+#define MISC_CTRL                                     0x000004
+#define MISC_CTRL_DAC_POWER                           F(20 : 20)
+#define MISC_CTRL_DAC_POWER_ON                        0
+#define MISC_CTRL_DAC_POWER_OFF                       1
+#define MISC_CTRL_LOCALMEM_RESET                      F(6 : 6)
+#define MISC_CTRL_LOCALMEM_RESET_RESET                0
+#define MISC_CTRL_LOCALMEM_RESET_NORMAL               1
+
+#define CURRENT_GATE                                  0x000040
+#define CURRENT_GATE_MCLK                             F(15 : 14)
+#define CURRENT_GATE_CSC                              F(4 : 4)
+#define CURRENT_GATE_CSC_OFF                          0
+#define CURRENT_GATE_CSC_ON                           1
+#define CURRENT_GATE_DE                               F(3 : 3)
+#define CURRENT_GATE_DE_OFF                           0
+#define CURRENT_GATE_DE_ON                            1
+#define CURRENT_GATE_DISPLAY                          F(2 : 2)
+#define CURRENT_GATE_DISPLAY_OFF                      0
+#define CURRENT_GATE_DISPLAY_ON                       1
+#define CURRENT_GATE_LOCALMEM                         F(1 : 1)
+#define CURRENT_GATE_LOCALMEM_OFF                     0
+#define CURRENT_GATE_LOCALMEM_ON                      1
+#define CURRENT_GATE_DMA                              F(0 : 0)
+#define CURRENT_GATE_DMA_OFF                          0
+#define CURRENT_GATE_DMA_ON                           1
+
+#define MODE0_GATE                                    0x000044
+#define MODE1_GATE                                    0x000048
+#define POWER_MODE_CTRL                               0x00004C
+
+#define POWER_MODE_CTRL_OSC_INPUT                     F(3 : 3)
+#define POWER_MODE_CTRL_OSC_INPUT_OFF                 0
+#define POWER_MODE_CTRL_OSC_INPUT_ON                  1
+#define POWER_MODE_CTRL_ACPI                          F(2 : 2)
+#define POWER_MODE_CTRL_ACPI_OFF                      0
+#define POWER_MODE_CTRL_ACPI_ON                       1
+#define POWER_MODE_CTRL_MODE                          F(1 : 0)
+#define POWER_MODE_CTRL_MODE_MODE0                    0
+#define POWER_MODE_CTRL_MODE_MODE1                    1
+#define POWER_MODE_CTRL_MODE_SLEEP                    2
+
+#define PANEL_PLL_CTRL                                0x00005C
+#define PANEL_PLL_CTRL_BYPASS                         F(18 : 18)
+#define PANEL_PLL_CTRL_BYPASS_OFF                     0
+#define PANEL_PLL_CTRL_BYPASS_ON                      1
+#define PANEL_PLL_CTRL_POWER                          F(17 : 17)
+#define PANEL_PLL_CTRL_POWER_OFF                      0
+#define PANEL_PLL_CTRL_POWER_ON                       1
+#define PANEL_PLL_CTRL_INPUT                          F(16 : 16)
+#define PANEL_PLL_CTRL_INPUT_OSC                      0
+#define PANEL_PLL_CTRL_INPUT_TESTCLK                  1
+
+#define PANEL_PLL_CTRL_POD                        F(15 : 14)
+#define PANEL_PLL_CTRL_OD                         F(13 : 12)
+
+#define PANEL_PLL_CTRL_N                              F(11 : 8)
+#define PANEL_PLL_CTRL_M                              F(7 : 0)
+
+#define CRT_PLL_CTRL                                  0x000060
+/* Video Control */
+
+#define VIDEO_DISPLAY_CTRL                              0x080040
+#define VIDEO_DISPLAY_CTRL_PLANE                        F(2 : 2)
+#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE                0
+#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE                 1
+
+/* Video Alpha Control */
+
+#define VIDEO_ALPHA_DISPLAY_CTRL                        0x080080
+#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE                  F(2 : 2)
+#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE          0
+#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE           1
+
+/* Panel Cursor Control */
+#define ALPHA_DISPLAY_CTRL                            0x080100
+#define ALPHA_DISPLAY_CTRL_PLANE                      F(2 : 2)
+#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE              0
+#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE               1
+
+/* CRT Graphics Control */
+#define CRT_DISPLAY_CTRL                              0x080200
+#define CRT_DISPLAY_CTRL_RESERVED_1_MASK              F(31 : 27)
+#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE      0
+#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE       0x1F
+
+/* register definition */
+#define CRT_DISPLAY_CTRL_DPMS                         F(31 : 30)
+#define CRT_DISPLAY_CTRL_DPMS_0                       0
+#define CRT_DISPLAY_CTRL_DPMS_1                       1
+#define CRT_DISPLAY_CTRL_DPMS_2                       2
+#define CRT_DISPLAY_CTRL_DPMS_3                       3
+
+/* register definition */
+#define CRT_DISPLAY_CTRL_CRTSELECT                    F(25 : 25)
+#define CRT_DISPLAY_CTRL_CRTSELECT_VGA                0
+#define CRT_DISPLAY_CTRL_CRTSELECT_CRT                1
+
+#define CRT_DISPLAY_CTRL_CLOCK_PHASE                  F(14 : 14)
+#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH      0
+#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW       1
+#define CRT_DISPLAY_CTRL_VSYNC_PHASE                  F(13 : 13)
+#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH      0
+#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW       1
+#define CRT_DISPLAY_CTRL_HSYNC_PHASE                  F(12 : 12)
+#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH      0
+#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW       1
+#define CRT_DISPLAY_CTRL_BLANK                        F(10 : 10)
+#define CRT_DISPLAY_CTRL_BLANK_OFF                    0
+#define CRT_DISPLAY_CTRL_BLANK_ON                     1
+#define CRT_DISPLAY_CTRL_TIMING                       F(8 : 8)
+#define CRT_DISPLAY_CTRL_TIMING_DISABLE               0
+#define CRT_DISPLAY_CTRL_TIMING_ENABLE                1
+#define CRT_DISPLAY_CTRL_PLANE                        F(2 : 2)
+#define CRT_DISPLAY_CTRL_PLANE_DISABLE                0
+#define CRT_DISPLAY_CTRL_PLANE_ENABLE                 1
+#define CRT_DISPLAY_CTRL_FORMAT                       F(1 : 0)
+#define CRT_DISPLAY_CTRL_FORMAT_8                     0
+#define CRT_DISPLAY_CTRL_FORMAT_16                    1
+#define CRT_DISPLAY_CTRL_FORMAT_32                    2
+#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK           0xFF000200
+
+#define CRT_FB_ADDRESS                                0x080204
+#define CRT_FB_ADDRESS_STATUS                         F(31 : 31)
+#define CRT_FB_ADDRESS_STATUS_CURRENT                 0
+#define CRT_FB_ADDRESS_STATUS_PENDING                 1
+#define CRT_FB_ADDRESS_EXT                            F(27 : 27)
+#define CRT_FB_ADDRESS_EXT_LOCAL                      0
+#define CRT_FB_ADDRESS_EXT_EXTERNAL                   1
+#define CRT_FB_ADDRESS_ADDRESS                        F(25 : 0)
+
+#define CRT_FB_WIDTH                                  0x080208
+#define CRT_FB_WIDTH_WIDTH                            F(29 : 16)
+#define CRT_FB_WIDTH_OFFSET                           F(13 : 0)
+
+#define CRT_HORIZONTAL_TOTAL                          0x08020C
+#define CRT_HORIZONTAL_TOTAL_TOTAL                    F(27 : 16)
+#define CRT_HORIZONTAL_TOTAL_DISPLAY_END              F(11 : 0)
+
+#define CRT_HORIZONTAL_SYNC                           0x080210
+#define CRT_HORIZONTAL_SYNC_WIDTH                     F(23 : 16)
+#define CRT_HORIZONTAL_SYNC_START                     F(11 : 0)
+
+#define CRT_VERTICAL_TOTAL                            0x080214
+#define CRT_VERTICAL_TOTAL_TOTAL                      F(26 : 16)
+#define CRT_VERTICAL_TOTAL_DISPLAY_END                F(10 : 0)
+
+#define CRT_VERTICAL_SYNC                             0x080218
+#define CRT_VERTICAL_SYNC_HEIGHT                      F(21 : 16)
+#define CRT_VERTICAL_SYNC_START                       F(10 : 0)
+
+/* Auto Centering */
+#define CRT_AUTO_CENTERING_TL                     0x080280
+#define CRT_AUTO_CENTERING_TL_TOP                 F(26 : 16)
+#define CRT_AUTO_CENTERING_TL_LEFT                F(10 : 0)
+
+#define CRT_AUTO_CENTERING_BR                     0x080284
+#define CRT_AUTO_CENTERING_BR_BOTTOM              F(26 : 16)
+#define CRT_AUTO_CENTERING_BR_RIGHT               F(10 : 0)
+
+/* register to control panel output */
+#define DISPLAY_CONTROL_HISILE                    0x80288
+
+/* register and values for PLL control */
+#define CRT_PLL1_HS                            0x802a8
+#define CRT_PLL1_HS_25MHZ	               0x23d40f02
+#define CRT_PLL1_HS_40MHZ	               0x23940801
+#define CRT_PLL1_HS_65MHZ	               0x23940d01
+#define CRT_PLL1_HS_78MHZ	               0x23540F82
+#define CRT_PLL1_HS_74MHZ	               0x23941dc2
+#define CRT_PLL1_HS_80MHZ	               0x23941001
+#define CRT_PLL1_HS_80MHZ_1152	           0x23540fc2
+#define CRT_PLL1_HS_108MHZ	               0x23b41b01
+#define CRT_PLL1_HS_162MHZ	               0x23480681
+#define CRT_PLL1_HS_148MHZ	               0x23541dc2
+#define CRT_PLL1_HS_193MHZ	               0x234807c1
+
+#define CRT_PLL2_HS                         0x802ac
+#define CRT_PLL2_HS_25MHZ	               0x206B851E
+#define CRT_PLL2_HS_40MHZ	               0x30000000
+#define CRT_PLL2_HS_65MHZ	               0x40000000
+#define CRT_PLL2_HS_78MHZ	               0x50E147AE
+#define CRT_PLL2_HS_74MHZ	               0x602B6AE7
+#define CRT_PLL2_HS_80MHZ	               0x70000000
+#define CRT_PLL2_HS_108MHZ	               0x80000000
+#define CRT_PLL2_HS_162MHZ	               0xA0000000
+#define CRT_PLL2_HS_148MHZ	               0xB0CCCCCD
+#define CRT_PLL2_HS_193MHZ	               0xC0872B02
+
+/* Palette RAM */
+
+/* Panel Palette register starts at 0x080400 ~ 0x0807FC */
+#define PANEL_PALETTE_RAM                             0x080400
+
+/* Panel Palette register starts at 0x080C00 ~ 0x080FFC */
+#define CRT_PALETTE_RAM                               0x080C00
+
+#define DMA_ABORT_INTERRUPT                             0x0D0020
+#define DMA_ABORT_INTERRUPT_ABORT_1                     F(5 : 5)
+#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE              0
+#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT               1
+
+/* cursor control */
+#define HWC_ADDRESS                         0x0
+#define HWC_ADDRESS_ENABLE                  F(31 : 31)
+#define HWC_ADDRESS_ENABLE_DISABLE          0
+#define HWC_ADDRESS_ENABLE_ENABLE           1
+#define HWC_ADDRESS_EXT                     F(27 : 27)
+#define HWC_ADDRESS_EXT_LOCAL               0
+#define HWC_ADDRESS_EXT_EXTERNAL            1
+#define HWC_ADDRESS_CS                      F(26 : 26)
+#define HWC_ADDRESS_CS_0                    0
+#define HWC_ADDRESS_CS_1                    1
+#define HWC_ADDRESS_ADDRESS                 F(25 : 0)
+
+#define HWC_LOCATION                        0x4
+#define HWC_LOCATION_Y                      F(26 : 16)
+#define HWC_LOCATION_LEFT                   F(11 : 11)
+#define HWC_LOCATION_LEFT_INSIDE            0
+#define HWC_LOCATION_LEFT_OUTSIDE           1
+#define HWC_LOCATION_X                      F(10 : 0)
+
+#define HWC_COLOR_12                        0x8
+
+#define HWC_COLOR_3                         0xC
+
+/* accelate 2d graphic */
+#define DE_SOURCE                                       0x0
+#define DE_SOURCE_WRAP                                  F(31 : 31)
+#define DE_SOURCE_WRAP_DISABLE                          0
+#define DE_SOURCE_WRAP_ENABLE                           1
+#define DE_SOURCE_X_K1                                  F(29 : 16)
+#define DE_SOURCE_Y_K2                                  F(15 : 0)
+#define DE_SOURCE_X_K1_MONO                             F(20 : 16)
+
+#define DE_DESTINATION                                  0x4
+#define DE_DESTINATION_WRAP                             F(31 : 31)
+#define DE_DESTINATION_WRAP_DISABLE                     0
+#define DE_DESTINATION_WRAP_ENABLE                      1
+#define DE_DESTINATION_X                                F(28 : 16)
+#define DE_DESTINATION_Y                                F(15 : 0)
+
+#define DE_DIMENSION                                    0x8
+#define DE_DIMENSION_X                                  F(28 : 16)
+#define DE_DIMENSION_Y_ET                               F(15 : 0)
+
+#define DE_CONTROL                                      0xC
+#define DE_CONTROL_STATUS                               F(31 : 31)
+#define DE_CONTROL_STATUS_STOP                          0
+#define DE_CONTROL_STATUS_START                         1
+#define DE_CONTROL_PATTERN                              F(30 : 30)
+#define DE_CONTROL_PATTERN_MONO                         0
+#define DE_CONTROL_PATTERN_COLOR                        1
+#define DE_CONTROL_UPDATE_DESTINATION_X                 F(29 : 29)
+#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE         0
+#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE          1
+#define DE_CONTROL_QUICK_START                          F(28 : 28)
+#define DE_CONTROL_QUICK_START_DISABLE                  0
+#define DE_CONTROL_QUICK_START_ENABLE                   1
+#define DE_CONTROL_DIRECTION                            F(27 : 27)
+#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT              0
+#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT              1
+#define DE_CONTROL_MAJOR                                F(26 : 26)
+#define DE_CONTROL_MAJOR_X                              0
+#define DE_CONTROL_MAJOR_Y                              1
+#define DE_CONTROL_STEP_X                               F(25 : 25)
+#define DE_CONTROL_STEP_X_POSITIVE                      1
+#define DE_CONTROL_STEP_X_NEGATIVE                      0
+#define DE_CONTROL_STEP_Y                               F(24 : 24)
+#define DE_CONTROL_STEP_Y_POSITIVE                      1
+#define DE_CONTROL_STEP_Y_NEGATIVE                      0
+#define DE_CONTROL_STRETCH                              F(23 : 23)
+#define DE_CONTROL_STRETCH_DISABLE                      0
+#define DE_CONTROL_STRETCH_ENABLE                       1
+#define DE_CONTROL_HOST                                 F(22 : 22)
+#define DE_CONTROL_HOST_COLOR                           0
+#define DE_CONTROL_HOST_MONO                            1
+#define DE_CONTROL_LAST_PIXEL                           F(21 : 21)
+#define DE_CONTROL_LAST_PIXEL_OFF                       0
+#define DE_CONTROL_LAST_PIXEL_ON                        1
+#define DE_CONTROL_COMMAND                              F(20 : 16)
+#define DE_CONTROL_COMMAND_BITBLT                       0
+#define DE_CONTROL_COMMAND_RECTANGLE_FILL               1
+#define DE_CONTROL_COMMAND_DE_TILE                      2
+#define DE_CONTROL_COMMAND_TRAPEZOID_FILL               3
+#define DE_CONTROL_COMMAND_ALPHA_BLEND                  4
+#define DE_CONTROL_COMMAND_RLE_STRIP                    5
+#define DE_CONTROL_COMMAND_SHORT_STROKE                 6
+#define DE_CONTROL_COMMAND_LINE_DRAW                    7
+#define DE_CONTROL_COMMAND_HOST_WRITE                   8
+#define DE_CONTROL_COMMAND_HOST_READ                    9
+#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP         10
+#define DE_CONTROL_COMMAND_ROTATE                       11
+#define DE_CONTROL_COMMAND_FONT                         12
+#define DE_CONTROL_COMMAND_TEXTURE_LOAD                 15
+#define DE_CONTROL_ROP_SELECT                           F(15 : 15)
+#define DE_CONTROL_ROP_SELECT_ROP3                      0
+#define DE_CONTROL_ROP_SELECT_ROP2                      1
+#define DE_CONTROL_ROP2_SOURCE                          F(14 : 14)
+#define DE_CONTROL_ROP2_SOURCE_BITMAP                   0
+#define DE_CONTROL_ROP2_SOURCE_PATTERN                  1
+#define DE_CONTROL_MONO_DATA                            F(13 : 12)
+#define DE_CONTROL_MONO_DATA_NOT_PACKED                 0
+#define DE_CONTROL_MONO_DATA_8_PACKED                   1
+#define DE_CONTROL_MONO_DATA_16_PACKED                  2
+#define DE_CONTROL_MONO_DATA_32_PACKED                  3
+#define DE_CONTROL_REPEAT_ROTATE                        F(11 : 11)
+#define DE_CONTROL_REPEAT_ROTATE_DISABLE                0
+#define DE_CONTROL_REPEAT_ROTATE_ENABLE                 1
+#define DE_CONTROL_TRANSPARENCY_MATCH                   F(10 : 10)
+#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE            0
+#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT       1
+#define DE_CONTROL_TRANSPARENCY_SELECT                  F(9 : 9)
+#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE           0
+#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION      1
+#define DE_CONTROL_TRANSPARENCY                         F(8 : 8)
+#define DE_CONTROL_TRANSPARENCY_DISABLE                 0
+#define DE_CONTROL_TRANSPARENCY_ENABLE                  1
+#define DE_CONTROL_ROP                                  F(7 : 0)
+
+/* Pseudo fields. */
+
+#define DE_CONTROL_SHORT_STROKE_DIR                     F(27 : 24)
+#define DE_CONTROL_SHORT_STROKE_DIR_225                 0
+#define DE_CONTROL_SHORT_STROKE_DIR_135                 1
+#define DE_CONTROL_SHORT_STROKE_DIR_315                 2
+#define DE_CONTROL_SHORT_STROKE_DIR_45                  3
+#define DE_CONTROL_SHORT_STROKE_DIR_270                 4
+#define DE_CONTROL_SHORT_STROKE_DIR_90                  5
+#define DE_CONTROL_SHORT_STROKE_DIR_180                 8
+#define DE_CONTROL_SHORT_STROKE_DIR_0                   10
+#define DE_CONTROL_ROTATION                             F(25 : 24)
+#define DE_CONTROL_ROTATION_0                           0
+#define DE_CONTROL_ROTATION_270                         1
+#define DE_CONTROL_ROTATION_90                          2
+#define DE_CONTROL_ROTATION_180                         3
+
+#define DE_PITCH                                        0x000010
+#define DE_PITCH_DESTINATION                            F(28 : 16)
+#define DE_PITCH_SOURCE                                 F(12 : 0)
+
+#define DE_FOREGROUND                                   0x000014
+
+#define DE_BACKGROUND                                   0x000018
+
+#define DE_STRETCH_FORMAT                               0x00001C
+#define DE_STRETCH_FORMAT_PATTERN_XY                    F(30 : 30)
+#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL             0
+#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE          1
+#define DE_STRETCH_FORMAT_PATTERN_Y                     F(29 : 27)
+#define DE_STRETCH_FORMAT_PATTERN_X                     F(25 : 23)
+#define DE_STRETCH_FORMAT_PIXEL_FORMAT                  F(21 : 20)
+#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8                0
+#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16               1
+#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32               2
+#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24               3
+
+#define DE_STRETCH_FORMAT_ADDRESSING                    F(19 : 16)
+#define DE_STRETCH_FORMAT_ADDRESSING_XY                 0
+#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR             15
+#define DE_STRETCH_FORMAT_SOURCE_HEIGHT                 F(11 : 0)
+
+#define DE_COLOR_COMPARE                                0x000020
+
+#define DE_COLOR_COMPARE_MASK                           0x000024
+
+#define DE_MASKS                                        0x000028
+
+#define DE_CLIP_TL                                      0x00002C
+
+#define DE_CLIP_BR                                      0x000030
+
+#define DE_WINDOW_WIDTH                                 0x00003C
+#define DE_WINDOW_WIDTH_DESTINATION                     F(28 : 16)
+#define DE_WINDOW_WIDTH_SOURCE                          F(12 : 0)
+
+#define DE_WINDOW_SOURCE_BASE                           0x000040
+#define DE_WINDOW_SOURCE_BASE_EXT                       F(27 : 27)
+#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL                 0
+#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL              1
+#define DE_WINDOW_SOURCE_BASE_CS                        F(26 : 26)
+#define DE_WINDOW_SOURCE_BASE_CS_0                      0
+#define DE_WINDOW_SOURCE_BASE_CS_1                      1
+#define DE_WINDOW_SOURCE_BASE_ADDRESS                   F(25 : 0)
+
+#define DE_WINDOW_DESTINATION_BASE                      0x000044
+#define DE_WINDOW_DESTINATION_BASE_EXT                  F(27 : 27)
+#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL            0
+#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL         1
+#define DE_WINDOW_DESTINATION_BASE_CS                   F(26 : 26)
+#define DE_WINDOW_DESTINATION_BASE_CS_0                 0
+#define DE_WINDOW_DESTINATION_BASE_CS_1                 1
+#define DE_WINDOW_DESTINATION_BASE_ADDRESS              F(25 : 0)
+
+/* Internal macros */
+#define _F_START(f)             (0 ? f)
+#define _F_END(f)               (1 ? f)
+#define _F_SIZE(f)              (1 + _F_END(f) - _F_START(f))
+#define _F_MASK(f)              (((1 << _F_SIZE(f)) - 1) << _F_START(f))
+#define _F_NORMALIZE(v, f)      (((v) & _F_MASK(f)) >> _F_START(f))
+#define _F_DENORMALIZE(v, f)    (((v) << _F_START(f)) & _F_MASK(f))
+
+/* Global macros */
+#define FIELD_GET(x, reg, field) \
+( \
+	_F_NORMALIZE((x), reg ## _ ## field) \
+)
+
+#define FIELD_SET(x, reg, field, value) \
+( \
+	(x & ~_F_MASK(reg ## _ ## field)) \
+	| _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
+)
+
+#define FIELD_VALUE(x, reg, field, value) \
+( \
+	(x & ~_F_MASK(reg ## _ ## field)) \
+	| _F_DENORMALIZE(value, reg ## _ ## field) \
+)
+
+#define FIELD_CLEAR(reg, field) \
+( \
+	~_F_MASK(reg ## _ ## field) \
+)
+
+/* Field Macros */
+#define FIELD_START(field)              (0 ? field)
+#define FIELD_END(field)                (1 ? field)
+#define FIELD_SIZE(field) \
+	(1 + FIELD_END(field) - FIELD_START(field))
+#define FIELD_MASK(field) \
+	(((1 << (FIELD_SIZE(field) - 1)) |\
+	((1 << (FIELD_SIZE(field) - 1)) - 1)) << FIELD_START(field))
+#define FIELD_NORMALIZE(reg, field) \
+	(((reg) & FIELD_MASK(field)) >> FIELD_START(field))
+#define FIELD_DENORMALIZE(field, value) \
+	(((value) << FIELD_START(field)) & FIELD_MASK(field))
+#define RGB(r, g, b) \
+( \
+	(unsigned long)(((r) << 16) | ((g) << 8) | (b)) \
+)
+
+#define PEEK32(addr) readl((addr) + mmio_bmc_vga)
+#define POKE32(addr, data) writel((data), (addr) + mmio_bmc_vga)
+extern unsigned char __iomem *mmio_bmc_vga;
+
+#define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
+
+#define MB(x) ((x) << 20)
+
+void set_power_mode(unsigned int power_mode);
+void set_current_gate(unsigned int gate);
+
+#endif
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/7] drm/hisilicon:Add plane for DE
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
  2016-02-29  0:58 ` [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  0:58 ` [PATCH 3/7] drm/hisilicon:Add crtc " lijianhua
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add plane funcs and helper funcs for DE.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile        |   2 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c  | 158 ++++++++++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |  48 +++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h |   2 +
 4 files changed, 209 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index 28e59bb..bca651b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,5 +1,5 @@
 ccflags-y := -Iinclude/drm
-hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_hw.o
+hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_hw.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC)	+=hibmc-drm.o
 #obj-y	+= hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
new file mode 100644
index 0000000..35a675c
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drmP.h>
+
+#include "hibmc_drm_drv.h"
+#include "hibmc_drm_hw.h"
+
+/* ---------------------------------------------------------------------- */
+
+static int
+hibmc_plane_prepare_fb(struct drm_plane *plane,
+		       const struct drm_plane_state *new_state)
+{
+	/* do nothing */
+	return 0;
+}
+
+static void hibmc_plane_cleanup_fb(struct drm_plane *plane,
+				   const struct drm_plane_state *old_state)
+{
+	/* do nothing */
+}
+
+static int hibmc_plane_atomic_check(struct drm_plane *plane,
+				    struct drm_plane_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_crtc_state *crtc_state;
+	u32 src_x = state->src_x >> 16;
+	u32 src_y = state->src_y >> 16;
+	u32 src_w = state->src_w >> 16;
+	u32 src_h = state->src_h >> 16;
+	int crtc_x = state->crtc_x;
+	int crtc_y = state->crtc_y;
+	u32 crtc_w = state->crtc_w;
+	u32 crtc_h = state->crtc_h;
+
+	if (!crtc || !fb)
+		return 0;
+
+	crtc_state = drm_atomic_get_crtc_state(state->state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	if (src_w != crtc_w || src_h != crtc_h) {
+		DRM_ERROR("Scale not support!!!\n");
+		return -EINVAL;
+	}
+
+	if (src_x + src_w > fb->width ||
+	    src_y + src_h > fb->height)
+		return -EINVAL;
+
+	if (crtc_x < 0 || crtc_y < 0)
+		return -EINVAL;
+
+	if (crtc_x + crtc_w > crtc_state->adjusted_mode.hdisplay ||
+	    crtc_y + crtc_h > crtc_state->adjusted_mode.vdisplay)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void hibmc_plane_atomic_update(struct drm_plane *plane,
+				      struct drm_plane_state *old_state)
+{
+	struct drm_plane_state	*state	= plane->state;
+	u32 reg;
+	unsigned int line_length;
+
+	/* now just support one plane */
+	POKE32(CRT_FB_ADDRESS, 0);
+	reg = state->fb->width * (state->fb->bits_per_pixel >> 3);
+	/* now line_pad is 16 */
+	reg = PADDING(16, reg);
+
+	line_length = state->fb->width * state->fb->bits_per_pixel / 8;
+	line_length = PADDING(16, line_length);
+	POKE32(CRT_FB_WIDTH,
+	       FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, reg) |
+	      FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, line_length));
+
+	/* SET PIXEL FORMAT */
+	reg = PEEK32(CRT_DISPLAY_CTRL);
+	reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL,
+			  FORMAT, state->fb->bits_per_pixel >> 4);
+	POKE32(CRT_DISPLAY_CTRL, reg);
+}
+
+static void hibmc_plane_atomic_disable(struct drm_plane *plane,
+				       struct drm_plane_state *old_state)
+{
+}
+
+static const u32 channel_formats1[] = {
+	DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888, DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGBA8888, DRM_FORMAT_BGRA8888, DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888
+};
+
+static struct drm_plane_funcs hibmc_plane_funcs = {
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
+	.set_property = drm_atomic_helper_plane_set_property,
+	.destroy = drm_plane_cleanup,
+	.reset = drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = {
+	.prepare_fb = hibmc_plane_prepare_fb,
+	.cleanup_fb = hibmc_plane_cleanup_fb,
+	.atomic_check = hibmc_plane_atomic_check,
+	.atomic_update = hibmc_plane_atomic_update,
+	.atomic_disable = hibmc_plane_atomic_disable,
+};
+
+int hibmc_plane_init(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+	struct drm_plane *plane = &hiprivate->plane;
+	int ret = 0;
+
+	/*
+	 * plane init
+	 * TODO: Now only support primary plane, overlay planes
+	 * need to do.
+	 */
+	ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
+				       channel_formats1,
+				       ARRAY_SIZE(channel_formats1),
+				       DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret) {
+		DRM_ERROR("fail to init plane!!!\n");
+		return ret;
+	}
+
+	drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 444ced8..d7e03c5 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -102,6 +102,46 @@ static const struct dev_pm_ops hibmc_pm_ops = {
 				hibmc_pm_resume)
 };
 
+static const struct drm_mode_config_funcs mode_config_funcs = {
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+int hibmc_kms_init(struct hibmc_private *hiprivate)
+{
+	int ret;
+
+	drm_mode_config_init(hiprivate->dev);
+	hiprivate->mode_config_initialized = true;
+
+	hiprivate->dev->mode_config.min_width = 0;
+	hiprivate->dev->mode_config.min_height = 0;
+	hiprivate->dev->mode_config.max_width = 1920;
+	hiprivate->dev->mode_config.max_height = 1440;
+
+	hiprivate->dev->mode_config.fb_base = hiprivate->fb_base;
+	hiprivate->dev->mode_config.preferred_depth = 24;
+	hiprivate->dev->mode_config.prefer_shadow = 0;
+
+	hiprivate->dev->mode_config.funcs = (void *)&mode_config_funcs;
+
+	ret = hibmc_plane_init(hiprivate->dev);
+	if (ret) {
+		DRM_ERROR("fail to init plane!!!\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void hibmc_kms_fini(struct hibmc_private *hiprivate)
+{
+	if (hiprivate->mode_config_initialized) {
+		drm_mode_config_cleanup(hiprivate->dev);
+		hiprivate->mode_config_initialized = false;
+	}
+}
+
 int hibmc_hw_config(void)
 {
 	unsigned int reg;
@@ -188,6 +228,9 @@ int hibmc_hw_init(struct drm_device *dev)
 
 static int hibmc_unload(struct drm_device *dev)
 {
+	struct hibmc_private *hiprivate = dev->dev_private;
+
+	hibmc_kms_fini(hiprivate);
 	hibmc_hw_fini(dev);
 	dev->dev_private = NULL;
 	return 0;
@@ -207,6 +250,11 @@ static int hibmc_load(struct drm_device *dev, unsigned long flags)
 	ret = hibmc_hw_init(dev);
 	if (ret)
 		goto err;
+
+	ret = hibmc_kms_init(hiprivate);
+	if (ret)
+		goto err;
+
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret) {
 		DRM_ERROR("failed to initialize vblank.\n");
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 5db7902..08c82ae 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -46,4 +46,6 @@ struct hibmc_private {
 	struct hibmc_fbdev fbdev;
 };
 
+int hibmc_plane_init(struct drm_device *dev);
+
 #endif
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/7] drm/hisilicon:Add crtc for DE
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
  2016-02-29  0:58 ` [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver lijianhua
  2016-02-29  0:58 ` [PATCH 2/7] drm/hisilicon:Add plane for DE lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  0:58 ` [PATCH 4/7] drm/hisilicon:Add encoder for VDAC lijianhua
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add crtc funcs and helper funcs for DE.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c  | 279 ++++++++++++++++++++++++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h  |  20 ++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |   6 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h |   1 +
 4 files changed, 306 insertions(+)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 35a675c..5d3ed66 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -18,6 +18,7 @@
 
 #include "hibmc_drm_drv.h"
 #include "hibmc_drm_hw.h"
+#include "hibmc_drm_de.h"
 
 /* ---------------------------------------------------------------------- */
 
@@ -156,3 +157,281 @@ int hibmc_plane_init(struct drm_device *dev)
 	return 0;
 }
 
+static void hibmc_crtc_enable(struct drm_crtc *crtc)
+{
+	unsigned int reg;
+	/* power mode 0 is default. */
+	set_power_mode(POWER_MODE_CTRL_MODE_MODE0);
+
+	/* Enable display power gate & LOCALMEM power gate*/
+	reg = PEEK32(CURRENT_GATE);
+	reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, ON);
+	reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, ON);
+	set_current_gate(reg);
+}
+
+static void hibmc_crtc_disable(struct drm_crtc *crtc)
+{
+	unsigned int reg;
+
+	set_power_mode(POWER_MODE_CTRL_MODE_SLEEP);
+
+	/* Enable display power gate & LOCALMEM power gate*/
+	reg = PEEK32(CURRENT_GATE);
+	reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, OFF);
+	reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, OFF);
+	set_current_gate(reg);
+}
+
+int hibmc_crtc_atomic_check(struct drm_crtc *crtc,
+			    struct drm_crtc_state *state)
+{
+	return 0;
+}
+
+unsigned int format_pll_reg(void)
+{
+	unsigned int pllreg = 0;
+	struct panel_pll pll = {0};
+
+	/* Note that all PLL's have the same format. Here,
+     * we just use Panel PLL parameter to work out the bit
+     * fields in the register.On returning a 32 bit number, the value can
+     * be applied to any PLL in the calling function.
+     */
+	pllreg = FIELD_SET(0, PANEL_PLL_CTRL, BYPASS, OFF) |
+	FIELD_SET(0, PANEL_PLL_CTRL, POWER,  ON) |
+	FIELD_SET(0, PANEL_PLL_CTRL, INPUT,  OSC) |
+	FIELD_VALUE(0, PANEL_PLL_CTRL, POD,    pll.POD) |
+	FIELD_VALUE(0, PANEL_PLL_CTRL, OD,     pll.OD) |
+	FIELD_VALUE(0, PANEL_PLL_CTRL, N,      pll.N) |
+	FIELD_VALUE(0, PANEL_PLL_CTRL, M,      pll.M);
+
+	return pllreg;
+}
+
+void set_vclock_hisilicon(unsigned long pll)
+{
+	unsigned long tmp0, tmp1;
+
+    /* 1. outer_bypass_n=0 */
+	tmp0 = PEEK32(CRT_PLL1_HS);
+	tmp0 &= 0xBFFFFFFF;
+	POKE32(CRT_PLL1_HS, tmp0);
+
+	/* 2. pll_pd=1?inter_bypass=1 */
+	POKE32(CRT_PLL1_HS, 0x21000000);
+
+	/* 3. config pll */
+	POKE32(CRT_PLL1_HS, pll);
+
+	/* 4. delay  */
+	mdelay(1);
+
+	/* 5. pll_pd =0 */
+	tmp1 = pll & ~0x01000000;
+	POKE32(CRT_PLL1_HS, tmp1);
+
+	/* 6. delay  */
+	mdelay(1);
+
+	/* 7. inter_bypass=0 */
+	tmp1 &= ~0x20000000;
+	POKE32(CRT_PLL1_HS, tmp1);
+
+	/* 8. delay  */
+	mdelay(1);
+
+	/* 9. outer_bypass_n=1 */
+	tmp1 |= 0x40000000;
+	POKE32(CRT_PLL1_HS, tmp1);
+}
+
+/* This function takes care the extra registers and bit fields required to
+*setup a mode in board.
+*Explanation about Display Control register:
+*FPGA only supports 7 predefined pixel clocks, and clock select is
+*in bit 4:0 of new register 0x802a8.
+*/
+unsigned int display_ctrl_adjust(struct drm_display_mode *mode,
+				 unsigned int ctrl)
+{
+	unsigned long x, y;
+	unsigned long pll1; /* bit[31:0] of PLL */
+	unsigned long pll2; /* bit[63:32] of PLL */
+
+	x = mode->hdisplay;
+	y = mode->vdisplay;
+
+	/* Hisilicon has to set up a new register for PLL control
+	 *(CRT_PLL1_HS & CRT_PLL2_HS).
+	 */
+	if (x == 800 && y == 600) {
+		pll1 = CRT_PLL1_HS_40MHZ;
+		pll2 = CRT_PLL2_HS_40MHZ;
+	} else if (x == 1024 && y == 768) {
+		pll1 = CRT_PLL1_HS_65MHZ;
+		pll2 = CRT_PLL2_HS_65MHZ;
+	} else if (x == 1152 && y == 864) {
+		pll1 = CRT_PLL1_HS_80MHZ_1152;
+		pll2 = CRT_PLL2_HS_80MHZ;
+	} else if (x == 1280 && y == 768) {
+		pll1 = CRT_PLL1_HS_80MHZ;
+		pll2 = CRT_PLL2_HS_80MHZ;
+	} else if (x == 1280 && y == 720) {
+		pll1 = CRT_PLL1_HS_74MHZ;
+		pll2 = CRT_PLL2_HS_74MHZ;
+	} else if (x == 1280 && y == 960) {
+		pll1 = CRT_PLL1_HS_108MHZ;
+		pll2 = CRT_PLL2_HS_108MHZ;
+	} else if (x == 1280 && y == 1024) {
+		pll1 = CRT_PLL1_HS_108MHZ;
+		pll2 = CRT_PLL2_HS_108MHZ;
+	} else if (x == 1600 && y == 1200) {
+		pll1 = CRT_PLL1_HS_162MHZ;
+		pll2 = CRT_PLL2_HS_162MHZ;
+	} else if (x == 1920 && y == 1080) {
+		pll1 = CRT_PLL1_HS_148MHZ;
+		pll2 = CRT_PLL2_HS_148MHZ;
+	} else if (x == 1920 && y == 1200) {
+		pll1 = CRT_PLL1_HS_193MHZ;
+		pll2 = CRT_PLL2_HS_193MHZ;
+	} else /* default to VGA clock */ {
+		pll1 = CRT_PLL1_HS_25MHZ;
+		pll2 = CRT_PLL2_HS_25MHZ;
+	}
+
+	POKE32(CRT_PLL2_HS, pll2);
+	set_vclock_hisilicon(pll1);
+
+	/* Hisilicon has to set up the top-left and bottom-right
+	 * registers as well.
+	 * Note that normal chip only use those two register for
+	 * auto-centering mode.
+	 */
+	POKE32(CRT_AUTO_CENTERING_TL,
+	       FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0)
+	       | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0));
+
+	POKE32(CRT_AUTO_CENTERING_BR,
+	       FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y - 1)
+	       | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x - 1));
+
+	/* Assume common fields in ctrl have been properly set before
+	 * calling this function.
+	 * This function only sets the extra fields in ctrl.
+	 */
+
+	/* Set bit 25 of display controller: Select CRT or VGA clock */
+	ctrl = FIELD_SET(ctrl, CRT_DISPLAY_CTRL, CRTSELECT, CRT);
+
+	/* Set bit 14 of display controller */
+	ctrl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLOCK_PHASE);
+
+	/* clock_phase_polarity is 0 */
+	ctrl = FIELD_SET(ctrl, CRT_DISPLAY_CTRL,
+			 CLOCK_PHASE, ACTIVE_HIGH);
+
+	POKE32(CRT_DISPLAY_CTRL, ctrl);
+
+	return ctrl;
+}
+
+static void hibmc_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	unsigned int val;
+	struct drm_display_mode *mode = &crtc->state->mode;
+
+	POKE32(CRT_PLL_CTRL, format_pll_reg());
+	POKE32(CRT_HORIZONTAL_TOTAL,
+	       FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL,
+			   TOTAL, mode->htotal - 1) |
+	       FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL,
+			   DISPLAY_END, mode->hdisplay - 1));
+
+	POKE32(CRT_HORIZONTAL_SYNC,
+	       FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH,
+			   mode->hsync_end - mode->hsync_start) |
+	       FIELD_VALUE(0, CRT_HORIZONTAL_SYNC,
+			   START, mode->hsync_start - 1));
+
+	POKE32(CRT_VERTICAL_TOTAL,
+	       FIELD_VALUE(0, CRT_VERTICAL_TOTAL,
+			   TOTAL, mode->vtotal - 1) |
+	       FIELD_VALUE(0, CRT_VERTICAL_TOTAL,
+			   DISPLAY_END, mode->vdisplay - 1));
+
+	POKE32(CRT_VERTICAL_SYNC,
+	       FIELD_VALUE(0, CRT_VERTICAL_SYNC,
+			   HEIGHT, mode->vsync_end - mode->vsync_start) |
+	       FIELD_VALUE(0, CRT_VERTICAL_SYNC,
+			   START, mode->vsync_start - 1));
+
+	val = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, 0) |
+			  FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, 0) |
+			  FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE) |
+			  FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE);
+
+	display_ctrl_adjust(mode, val);
+}
+
+static void hibmc_crtc_atomic_begin(struct drm_crtc *crtc,
+				    struct drm_crtc_state *old_state)
+{
+	unsigned int reg;
+
+	set_power_mode(POWER_MODE_CTRL_MODE_MODE0);
+
+	/* Enable display power gate & LOCALMEM power gate*/
+	reg = PEEK32(CURRENT_GATE);
+	reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, ON);
+	reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, ON);
+	set_current_gate(reg);
+
+	/* We can add more initialization as needed. */
+}
+
+static void hibmc_crtc_atomic_flush(struct drm_crtc *crtc,
+				    struct drm_crtc_state *old_state)
+
+{
+}
+
+/* These provide the minimum set of functions required to handle a CRTC */
+static const struct drm_crtc_funcs hibmc_crtc_funcs = {
+	.page_flip = drm_atomic_helper_page_flip,
+	.set_config = drm_atomic_helper_set_config,
+	.destroy = drm_crtc_cleanup,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state =  drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = {
+	.enable		= hibmc_crtc_enable,
+	.disable	= hibmc_crtc_disable,
+	.mode_set_nofb	= hibmc_crtc_mode_set_nofb,
+	.atomic_check	= hibmc_crtc_atomic_check,
+	.atomic_begin	= hibmc_crtc_atomic_begin,
+	.atomic_flush	= hibmc_crtc_atomic_flush,
+};
+
+int hibmc_crtc_init(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+	struct drm_crtc *crtc = &hiprivate->crtc;
+	struct drm_plane *plane = &hiprivate->plane;
+	int ret;
+
+	ret = drm_crtc_init_with_planes(dev, crtc, plane,
+					NULL, &hibmc_crtc_funcs, NULL);
+	if (ret) {
+		DRM_ERROR("failed to init crtc.\n");
+		return ret;
+	}
+
+	drm_mode_crtc_set_gamma_size(crtc, 256);
+	drm_crtc_helper_add(crtc, &hibmc_crtc_helper_funcs);
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h
new file mode 100644
index 0000000..b7b9d2b
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+ #ifndef HIBMC_DRM_DE_H
+#define HIBMC_DRM_DE_H
+
+struct panel_pll {
+	unsigned long M;
+	unsigned long N;
+	unsigned long OD;
+	unsigned long POD;
+};
+
+#endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index d7e03c5..732836d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -131,6 +131,12 @@ int hibmc_kms_init(struct hibmc_private *hiprivate)
 		return ret;
 	}
 
+	ret = hibmc_crtc_init(hiprivate->dev);
+	if (ret) {
+		DRM_ERROR("failed to init crtc.\n");
+		return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 08c82ae..7b4cb5e 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -47,5 +47,6 @@ struct hibmc_private {
 };
 
 int hibmc_plane_init(struct drm_device *dev);
+int hibmc_crtc_init(struct drm_device *dev);
 
 #endif
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/7] drm/hisilicon:Add encoder for VDAC
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
                   ` (2 preceding siblings ...)
  2016-02-29  0:58 ` [PATCH 3/7] drm/hisilicon:Add crtc " lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  0:58 ` [PATCH 5/7] drm/hisilicon:Add connector " lijianhua
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add encoder funcs and helpers for VDAC.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile         |  2 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  |  6 ++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h  |  1 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 73 ++++++++++++++++++++++++
 4 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index bca651b..6ab59b1 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,5 +1,5 @@
 ccflags-y := -Iinclude/drm
-hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_hw.o
+hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_hw.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC)	+=hibmc-drm.o
 #obj-y	+= hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 732836d..aa7f8415 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -137,6 +137,12 @@ int hibmc_kms_init(struct hibmc_private *hiprivate)
 		return ret;
 	}
 
+	ret = hibmc_encoder_init(hiprivate->dev);
+	if (ret) {
+		DRM_ERROR("failed to init encoder\n");
+		return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 7b4cb5e..7f3c4bb 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -48,5 +48,6 @@ struct hibmc_private {
 
 int hibmc_plane_init(struct drm_device *dev);
 int hibmc_crtc_init(struct drm_device *dev);
+int hibmc_encoder_init(struct drm_device *dev);
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
new file mode 100644
index 0000000..06d9549
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drmP.h>
+
+#include "hibmc_drm_drv.h"
+#include "hibmc_drm_hw.h"
+
+static void hibmc_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static void hibmc_encoder_enable(struct drm_encoder *encoder)
+{
+}
+
+static void hibmc_encoder_mode_set(struct drm_encoder *encoder,
+				   struct drm_display_mode *mode,
+				   struct drm_display_mode *adj_mode)
+{
+	u32 reg;
+
+	/* just open DISPLAY_CONTROL_HISILE register bit 3:0*/
+	reg = PEEK32(DISPLAY_CONTROL_HISILE);
+	reg |= 0xf;
+	POKE32(DISPLAY_CONTROL_HISILE, reg);
+}
+
+static int hibmc_encoder_atomic_check(struct drm_encoder *encoder,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	return 0;
+}
+
+static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {
+	.mode_set = hibmc_encoder_mode_set,
+	.disable = hibmc_encoder_disable,
+	.enable = hibmc_encoder_enable,
+	.atomic_check = hibmc_encoder_atomic_check,
+};
+
+static const struct drm_encoder_funcs hibmc_encoder_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+int hibmc_encoder_init(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+	struct drm_encoder *encoder = &hiprivate->encoder;
+	int ret;
+
+	encoder->possible_crtcs = 0x1;
+	ret = drm_encoder_init(dev, encoder, &hibmc_encoder_encoder_funcs,
+			       DRM_MODE_ENCODER_DAC, NULL);
+	if (ret) {
+		DRM_ERROR("failed to init encoder\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
+	return 0;
+}
+
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/7] drm/hisilicon:Add connector for VDAC
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
                   ` (3 preceding siblings ...)
  2016-02-29  0:58 ` [PATCH 4/7] drm/hisilicon:Add encoder for VDAC lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  0:58 ` [PATCH 6/7] drm/hisilicon:Add fbdev lijianhua
  2016-02-29  0:58 ` [PATCH 7/7] MAINTAINERS:Add maintainer for hibmc DRM driver lijianhua
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add connector funcs and helper funcs for VDAC.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  |  8 +++
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h  |  1 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 89 ++++++++++++++++++++++++
 3 files changed, 98 insertions(+)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index aa7f8415..673a8cd 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -143,6 +143,14 @@ int hibmc_kms_init(struct hibmc_private *hiprivate)
 		return ret;
 	}
 
+	ret = hibmc_connector_init(hiprivate->dev);
+	if (ret) {
+		DRM_ERROR("failed to init connector\n");
+		return ret;
+	}
+
+	drm_mode_connector_attach_encoder(&hiprivate->connector,
+					  &hiprivate->encoder);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 7f3c4bb..1f6b25c 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -49,5 +49,6 @@ struct hibmc_private {
 int hibmc_plane_init(struct drm_device *dev);
 int hibmc_crtc_init(struct drm_device *dev);
 int hibmc_encoder_init(struct drm_device *dev);
+int hibmc_connector_init(struct drm_device *dev);
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 06d9549..e832e22 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -15,6 +15,14 @@
 #include "hibmc_drm_drv.h"
 #include "hibmc_drm_hw.h"
 
+static int defx = 800;
+static int defy = 600;
+
+module_param(defx, int, 0444);
+module_param(defy, int, 0444);
+MODULE_PARM_DESC(defx, "default x resolution");
+MODULE_PARM_DESC(defy, "default y resolution");
+
 static void hibmc_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -71,3 +79,84 @@ int hibmc_encoder_init(struct drm_device *dev)
 	return 0;
 }
 
+int hibmc_connector_get_modes(struct drm_connector *connector)
+{
+	int count;
+
+	count = drm_add_modes_noedid(connector, 800, 600);
+	drm_set_preferred_mode(connector, defx, defy);
+	return count;
+}
+
+static int hibmc_connector_mode_valid(struct drm_connector *connector,
+				      struct drm_display_mode *mode)
+{
+	struct hibmc_private *hiprivate =
+	 container_of(connector, struct hibmc_private, connector);
+	unsigned long size = mode->hdisplay * mode->vdisplay * 4;
+
+	/*
+	* Make sure we can fit two framebuffers into video memory.
+	* This allows up to 1600x1200 with 16 MB (default size).
+	* If you want more try this:
+	* 'qemu -vga std -global VGA.vgamem_mb=32 $otherargs'
+	*/
+	if (size * 2 > hiprivate->fb_size)
+		return MODE_BAD;
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+hibmc_connector_best_encoder(struct drm_connector *connector)
+{
+	int enc_id = connector->encoder_ids[0];
+
+	/* pick the encoder ids */
+	if (enc_id)
+		return drm_encoder_find(connector->dev, enc_id);
+
+	return NULL;
+}
+
+static enum drm_connector_status hibmc_connector_detect(struct drm_connector
+						 *connector, bool force)
+{
+	return connector_status_connected;
+}
+
+struct drm_connector_helper_funcs hibmc_connector_connector_helper_funcs = {
+	.get_modes = hibmc_connector_get_modes,
+	.mode_valid = hibmc_connector_mode_valid,
+	.best_encoder = hibmc_connector_best_encoder,
+};
+
+struct drm_connector_funcs hibmc_connector_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = hibmc_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+int hibmc_connector_init(struct drm_device *dev)
+{
+	struct hibmc_private *hiprivate = dev->dev_private;
+	struct drm_connector *connector = &hiprivate->connector;
+	int ret;
+
+	ret = drm_connector_init(dev, connector,
+				 &hibmc_connector_connector_funcs,
+				 DRM_MODE_CONNECTOR_VIRTUAL);
+	if (ret) {
+		DRM_ERROR("failed to init connector\n");
+		return ret;
+	}
+	drm_connector_helper_add(connector,
+				 &hibmc_connector_connector_helper_funcs);
+	drm_connector_register(connector);
+	return 0;
+}
+
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/7] drm/hisilicon:Add fbdev
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
                   ` (4 preceding siblings ...)
  2016-02-29  0:58 ` [PATCH 5/7] drm/hisilicon:Add connector " lijianhua
@ 2016-02-29  0:58 ` lijianhua
  2016-02-29  0:58 ` [PATCH 7/7] MAINTAINERS:Add maintainer for hibmc DRM driver lijianhua
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add fbdev.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 drivers/gpu/drm/hisilicon/hibmc/Makefile          |   2 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   5 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |   2 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c | 290 ++++++++++++++++++++++
 4 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
index 6ab59b1..1ca1d49 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
+++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
@@ -1,5 +1,5 @@
 ccflags-y := -Iinclude/drm
-hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_hw.o
+hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_fbdev.o hibmc_drm_hw.o
 
 obj-$(CONFIG_DRM_HISI_HIBMC)	+=hibmc-drm.o
 #obj-y	+= hibmc-drm.o
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 673a8cd..7439f62 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -250,6 +250,7 @@ static int hibmc_unload(struct drm_device *dev)
 {
 	struct hibmc_private *hiprivate = dev->dev_private;
 
+	hibmc_fbdev_fini(hiprivate);
 	hibmc_kms_fini(hiprivate);
 	hibmc_hw_fini(dev);
 	dev->dev_private = NULL;
@@ -283,6 +284,10 @@ static int hibmc_load(struct drm_device *dev, unsigned long flags)
 	/* reset all the states of crtc/plane/encoder/connector */
 	drm_mode_config_reset(dev);
 
+	ret = hibmc_fbdev_init(hiprivate);
+	if (ret)
+		goto err;
+
 	return 0;
 
 err:
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 1f6b25c..e863e1a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -50,5 +50,7 @@ int hibmc_plane_init(struct drm_device *dev);
 int hibmc_crtc_init(struct drm_device *dev);
 int hibmc_encoder_init(struct drm_device *dev);
 int hibmc_connector_init(struct drm_device *dev);
+int hibmc_fbdev_init(struct hibmc_private *hiprivate);
+void hibmc_fbdev_fini(struct hibmc_private *hiprivate);
 
 #endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
new file mode 100644
index 0000000..416a6c6
--- /dev/null
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2016 Huawei Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "hibmc_drm_drv.h"
+
+/* ---------------------------------------------------------------------- */
+
+void hibmc_drm_fb_destroy(struct drm_framebuffer *fb)
+{
+	struct hibmc_private *hiprivate =
+		container_of(fb, struct hibmc_private, fbdev.fb.fb);
+	struct drm_gem_object *base = &hiprivate->fbdev.fb.obj->base;
+
+	if (hiprivate->fbdev.fb.obj)
+		drm_gem_object_unreference_unlocked(base);
+	drm_framebuffer_cleanup(fb);
+	kfree(fb);
+}
+
+static struct drm_framebuffer_funcs hibmc_drm_fb_funcs = {
+	.destroy	= hibmc_drm_fb_destroy,
+};
+
+int hibmc_drm_fb_init(struct drm_device *dev,
+		      struct hibmc_framebuffer *gfb,
+		      struct drm_mode_fb_cmd2 *mode_cmd,
+		      struct drm_gem_cma_object *obj)
+{
+	int ret;
+
+	drm_helper_mode_fill_fb_struct(&gfb->fb, mode_cmd);
+	gfb->obj = obj;
+	gfb->is_fbdev_fb = true;
+	ret = drm_framebuffer_init(dev, &gfb->fb, &hibmc_drm_fb_funcs);
+	if (ret) {
+		DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
+struct drm_gem_cma_object *hibmc_drm_gem_create_object(
+						struct hibmc_private *hiprivate,
+						size_t size)
+{
+	struct drm_gem_cma_object *cma_obj;
+	struct drm_gem_object *gem_obj;
+	struct drm_device *drm = hiprivate->dev;
+	int ret;
+
+	cma_obj = devm_kzalloc(drm->dev, sizeof(*cma_obj), GFP_KERNEL);
+	if (!cma_obj)
+		return ERR_PTR(-ENOMEM);
+
+	gem_obj = &cma_obj->base;
+
+	ret = drm_gem_object_init(drm, gem_obj, size);
+	if (ret)
+		return ERR_PTR(ret);
+
+	cma_obj->vaddr = hiprivate->fb_map;
+	cma_obj->paddr = hiprivate->fb_base;
+	return cma_obj;
+}
+
+void hibmc_drm_gem_free_object(struct drm_gem_object *gem_obj)
+{
+	struct drm_gem_cma_object *cma_obj;
+
+	cma_obj = to_drm_gem_cma_obj(gem_obj);
+	drm_gem_object_release(gem_obj);
+}
+
+static struct fb_ops hibmc_drm_fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_fillrect = sys_fillrect,
+	.fb_copyarea = sys_copyarea,
+	.fb_imageblit = sys_imageblit,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static int hibmc_drm_fb_probe(struct drm_fb_helper *helper,
+			      struct drm_fb_helper_surface_size *sizes)
+{
+	struct hibmc_private *hiprivate =
+		container_of(helper, struct hibmc_private, fbdev.helper);
+	struct drm_device *dev = hiprivate->dev;
+	struct fb_info *info;
+	struct drm_framebuffer *fb;
+	struct drm_mode_fb_cmd2 mode_cmd;
+	struct device *device = &dev->pdev->dev;
+	struct drm_gem_cma_object *obj = NULL;
+	int ret = 0;
+	size_t size;
+	unsigned int bytes_per_pixel;
+	unsigned long offset;
+
+	DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n",
+			 sizes->surface_width, sizes->surface_height,
+			 sizes->surface_bpp);
+	sizes->surface_depth = 32;
+
+	bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);
+
+	mode_cmd.width = sizes->surface_width;
+	mode_cmd.height = sizes->surface_height;
+	mode_cmd.pitches[0] = mode_cmd.width * bytes_per_pixel;
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+							  sizes->surface_depth);
+
+	size = roundup(mode_cmd.pitches[0] * mode_cmd.height, PAGE_SIZE);
+
+	obj = hibmc_drm_gem_create_object(hiprivate, size);
+	if (IS_ERR(obj)) {
+		DRM_ERROR("can't allocate gem object\n");
+		return -ENOMEM;
+	}
+
+	/* init fb device */
+	info = framebuffer_alloc(0, device);
+	if (!info) {
+		DRM_ERROR("can't allocate framebuffer\n");
+		goto err_drm_gem_cma_free_object;
+	}
+
+	ret = hibmc_drm_fb_init(hiprivate->dev,
+				&hiprivate->fbdev.fb, &mode_cmd, obj);
+	if (ret) {
+		DRM_ERROR("framebuffer init error\n");
+		goto err_drm_gem_cma_free_object;
+	}
+
+	/* setup helper */
+	fb = &hiprivate->fbdev.fb.fb;
+	hiprivate->fbdev.helper.fb = fb;
+	hiprivate->fbdev.helper.fbdev = info;
+
+	strcpy(info->fix.id, "hibmcdrmfb");
+	info->par = &hiprivate->fbdev.helper;
+	info->flags = FBINFO_DEFAULT;
+	info->fbops = &hibmc_drm_fb_ops;
+
+	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
+	drm_fb_helper_fill_var(info, &hiprivate->fbdev.helper, sizes->fb_width,
+			       sizes->fb_height);
+
+	offset = info->var.xoffset * bytes_per_pixel;
+	offset += info->var.yoffset * fb->pitches[0];
+
+	dev->mode_config.fb_base = (resource_size_t)obj->paddr;
+	info->screen_base = obj->vaddr + offset;
+	info->fix.smem_start = (unsigned long)(obj->paddr + offset);
+	info->screen_size = size;
+	info->fix.smem_len = size;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret) {
+		DRM_ERROR("%s: can't allocate color map\n", info->fix.id);
+		goto err_hisi_drm_fb_destroy;
+	}
+
+	return 0;
+
+err_hisi_drm_fb_destroy:
+	drm_framebuffer_unregister_private(fb);
+err_drm_gem_cma_free_object:
+	hibmc_drm_gem_free_object(&obj->base);
+	return ret;
+}
+
+static int hibmc_fbdev_destroy(struct hibmc_private *hiprivate)
+{
+	struct hibmc_framebuffer *gfb = &hiprivate->fbdev.fb;
+	struct fb_info *info;
+
+	DRM_DEBUG_DRIVER("hibmc_fbdev_destroy\n");
+
+	if (hiprivate->fbdev.helper.fbdev) {
+		info = hiprivate->fbdev.helper.fbdev;
+
+		unregister_framebuffer(info);
+		if (info->cmap.len)
+			fb_dealloc_cmap(&info->cmap);
+		framebuffer_release(info);
+	}
+
+	drm_framebuffer_unregister_private(&gfb->fb);
+	if (gfb->obj) {
+		drm_gem_object_unreference_unlocked(&gfb->obj->base);
+		gfb->obj = NULL;
+	}
+
+	drm_framebuffer_cleanup(&gfb->fb);
+	drm_fb_helper_fini(&hiprivate->fbdev.helper);
+
+	return 0;
+}
+
+static const struct drm_fb_helper_funcs hibmc_fbdev_helper_funcs = {
+	.fb_probe = hibmc_drm_fb_probe,
+};
+
+int hibmc_fbdev_init(struct hibmc_private *hiprivate)
+{
+	int ret;
+	struct fb_var_screeninfo *var;
+	struct fb_fix_screeninfo *fix;
+
+	drm_fb_helper_prepare(hiprivate->dev, &hiprivate->fbdev.helper,
+			      &hibmc_fbdev_helper_funcs);
+
+	/* Now just one crtc and one channel */
+	ret = drm_fb_helper_init(hiprivate->dev,
+				 &hiprivate->fbdev.helper, 1, 1);
+	if (ret)
+		return ret;
+
+	ret = drm_fb_helper_single_add_all_connectors(&hiprivate->fbdev.helper);
+	if (ret)
+		goto fini;
+
+	drm_helper_disable_unused_functions(hiprivate->dev);
+
+	ret = drm_fb_helper_initial_config(&hiprivate->fbdev.helper, 16);
+	if (ret)
+		goto fini;
+
+	hiprivate->fbdev.initialized = true;
+
+	var = &hiprivate->fbdev.helper.fbdev->var;
+	fix = &hiprivate->fbdev.helper.fbdev->fix;
+
+	DRM_DEBUG("Member of info->var is :\n"
+		 "xres=%d\n"
+		 "yres=%d\n"
+		 "xres_virtual=%d\n"
+		 "yres_virtual=%d\n"
+		 "xoffset=%d\n"
+		 "yoffset=%d\n"
+		 "bits_per_pixel=%d\n"
+		 "...\n", var->xres, var->yres, var->xres_virtual,
+		 var->yres_virtual, var->xoffset, var->yoffset,
+		 var->bits_per_pixel);
+	DRM_DEBUG("Member of info->fix is :\n"
+		 "smem_start=%lx\n"
+		 "smem_len=%d\n"
+		 "type=%d\n"
+		 "type_aux=%d\n"
+		 "visual=%d\n"
+		 "xpanstep=%d\n"
+		 "ypanstep=%d\n"
+		 "ywrapstep=%d\n"
+		 "line_length=%d\n"
+		 "accel=%d\n"
+		 "capabilities=%d\n"
+		 "...\n", fix->smem_start, fix->smem_len, fix->type,
+		 fix->type_aux, fix->visual, fix->xpanstep,
+		 fix->ypanstep, fix->ywrapstep, fix->line_length,
+		 fix->accel, fix->capabilities);
+
+	return 0;
+
+fini:
+	drm_fb_helper_fini(&hiprivate->fbdev.helper);
+	return ret;
+}
+
+void hibmc_fbdev_fini(struct hibmc_private *hiprivate)
+{
+	if (!hiprivate->fbdev.initialized)
+		return;
+
+	hibmc_fbdev_destroy(hiprivate);
+	hiprivate->fbdev.initialized = false;
+}
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/7] MAINTAINERS:Add maintainer for hibmc DRM driver
  2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
                   ` (5 preceding siblings ...)
  2016-02-29  0:58 ` [PATCH 6/7] drm/hisilicon:Add fbdev lijianhua
@ 2016-02-29  0:58 ` lijianhua
  6 siblings, 0 replies; 11+ messages in thread
From: lijianhua @ 2016-02-29  0:58 UTC (permalink / raw)
  To: airlied, dri-devel; +Cc: linuxarm, z.liuxinliang, zourongrong

Add maintainer for hibmc DRM driver.

Signed-off-by: lijianhua <jueying0518@gmail.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4978dc1..2bf23eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3774,6 +3774,13 @@ S:	Maintained
 F:	drivers/gpu/drm/gma500
 F:	include/drm/gma500*
 
+DRM DRIVERS FOR HIBMC
+M:	lijianhua <lijianhua@huawei.com>
+M:	Rongrong Zou <zourongrong@huawei.com>
+L:	dri-devel@lists.freedesktop.org
+S:	Maintained
+F:	drivers/gpu/drm/hisilicon/hibmc
+
 DRM DRIVERS FOR NVIDIA TEGRA
 M:	Thierry Reding <thierry.reding@gmail.com>
 M:	Terje Bergström <tbergstrom@nvidia.com>
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver.
  2016-02-29  0:58 ` [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver lijianhua
@ 2016-02-29  9:40   ` Emil Velikov
  2016-03-01  8:07     ` Rongrong Zou
  0 siblings, 1 reply; 11+ messages in thread
From: Emil Velikov @ 2016-02-29  9:40 UTC (permalink / raw)
  To: lijianhua; +Cc: z.liuxinliang, zourongrong, linuxarm, ML dri-devel

On 29 February 2016 at 00:58, lijianhua <jueying0518@gmail.com> wrote:
> Add hibmc DRM master driver for hi1710 which used in arm64 board.
>
Would be nice to give examples of what "arm64 board" this hardware is
presently available. Some information about the device as seen in the
cover letter, and/or a link to the cover letter would be nice to have.

> Signed-off-by: lijianhua <jueying0518@gmail.com>
> ---
>  drivers/gpu/drm/Kconfig                         |   2 +
>  drivers/gpu/drm/Makefile                        |   1 +
>  drivers/gpu/drm/hisilicon/Kconfig               |   4 +
>  drivers/gpu/drm/hisilicon/Makefile              |   4 +
>  drivers/gpu/drm/hisilicon/hibmc/Kconfig         |  13 +
>  drivers/gpu/drm/hisilicon/hibmc/Makefile        |   5 +
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 301 +++++++++++++++
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h |  49 +++
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c  |  83 ++++
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h  | 484 ++++++++++++++++++++++++
>  10 files changed, 946 insertions(+)
>  create mode 100644 drivers/gpu/drm/hisilicon/Kconfig
>  create mode 100644 drivers/gpu/drm/hisilicon/Makefile
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 8ae7ab6..600f94d 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -269,3 +269,5 @@ source "drivers/gpu/drm/imx/Kconfig"
>  source "drivers/gpu/drm/vc4/Kconfig"
>
>  source "drivers/gpu/drm/etnaviv/Kconfig"
> +
> +source "drivers/gpu/drm/hisilicon/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 61766de..6055483 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -74,3 +74,4 @@ obj-y                 += panel/
>  obj-y                  += bridge/
>  obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
>  obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
> +obj-y                  += hisilicon/
> diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig
> new file mode 100644
> index 0000000..1f10e17
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/Kconfig
> @@ -0,0 +1,4 @@
> +# hisilicon drm device configuration.
> +# Please keep this sorted alphabetically.
> +
> +source "drivers/gpu/drm/hisilicon/hibmc/Kconfig"
> diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile
> new file mode 100644
> index 0000000..487d5b0
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/Makefile
> @@ -0,0 +1,4 @@
> +# Makefile for hisilicon drm drivers.
> +# Please keep this list sorted alphabetically
> +
> +obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
> new file mode 100644
> index 0000000..c60ace6
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
> @@ -0,0 +1,13 @@
> +config DRM_HISI_HIBMC
> +       tristate "DRM Support for hisilicon hibmc dispi vga interface"
Use proper capitalisation in the above ? Is the driver copied/derived
from bochs - the above does not sounds right.

> +       depends on DRM && PCI
> +       select DRM_KMS_HELPER
> +       select DRM_KMS_FB_HELPER
> +       select DRM_GEM_CMA_HELPER
> +       select DRM_KMS_CMA_HELPER
> +       select FB_SYS_FILLRECT
> +       select FB_SYS_COPYAREA
> +       select FB_SYS_IMAGEBLIT
> +       help
> +         Choose this option for qemu.
Err what - too much copy/pasta ?

> +         If M is selected the module will be called hibmc-drm.
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> new file mode 100644
> index 0000000..28e59bb
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> @@ -0,0 +1,5 @@
> +ccflags-y := -Iinclude/drm
Based on the includes in hibmc_drm_drv.c the above include isn't needed.

> +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_hw.o
> +
> +obj-$(CONFIG_DRM_HISI_HIBMC)   +=hibmc-drm.o
> +#obj-y += hibmc-drm.o
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> new file mode 100644
> index 0000000..444ced8
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> @@ -0,0 +1,301 @@
> +/*
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/console.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drmP.h>
> +
> +#include "hibmc_drm_drv.h"
> +#include "hibmc_drm_hw.h"
> +
> +unsigned char __iomem *mmio_bmc_vga;
> +
Having globals like this is never a good idea.

> +static const struct file_operations hibmc_fops = {
> +       .owner          = THIS_MODULE,
> +       .open           = drm_open,
> +       .release        = drm_release,
> +       .unlocked_ioctl = drm_ioctl,
> +#ifdef CONFIG_COMPAT
> +       .compat_ioctl   = drm_compat_ioctl,
> +#endif
> +       .poll           = drm_poll,
> +       .read           = drm_read,
> +       .llseek         = no_llseek,
> +};
> +
> +int hibmc_enable_vblank(struct drm_device *dev, unsigned int pipe)
> +{
> +       return 0;
> +}
> +
> +void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
> +{
> +}
> +
> +static struct drm_driver hibmc_driver = {
> +       .driver_features        = DRIVER_GEM | DRIVER_MODESET |
> +                                               DRIVER_ATOMIC,
You do not manage any outputs, let alone in atomic manner, yet. This
should come with the patch that introduces the functionality ?

> +       .fops                   = &hibmc_fops,
> +       .name                   = "hibmc-drm",
> +       .desc                   = "hibmc drm driver",
> +       .date                   = "20151218",
Afaict this date is mostly unused, then again it's quite off :-)

> +       .major                  = 1,
> +       .minor                  = 0,
> +       .get_vblank_counter = drm_vblank_no_hw_counter,
> +       .enable_vblank          = hibmc_enable_vblank,
> +       .disable_vblank = hibmc_disable_vblank,
> +       .gem_free_object        = drm_gem_cma_free_object,
> +       .gem_vm_ops                             = &drm_gem_cma_vm_ops,
> +       .dumb_create            = drm_gem_cma_dumb_create,
> +       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
> +       .dumb_destroy           = drm_gem_dumb_destroy,
> +};
> +
> +static int hibmc_pm_suspend(struct device *dev)
> +{
> +       struct pci_dev *pdev = to_pci_dev(dev);
> +       struct drm_device *drm_dev = pci_get_drvdata(pdev);
> +       struct hibmc_private *hiprivate = drm_dev->dev_private;
> +
> +       drm_kms_helper_poll_disable(drm_dev);
> +
> +       if (hiprivate->fbdev.initialized) {
> +               console_lock();
> +               fb_set_suspend(hiprivate->fbdev.helper.fbdev, 1);
> +               console_unlock();
> +       }
> +
> +       return 0;
> +}
> +
> +static int hibmc_pm_resume(struct device *dev)
> +{
> +       struct pci_dev *pdev = to_pci_dev(dev);
> +       struct drm_device *drm_dev = pci_get_drvdata(pdev);
> +       struct hibmc_private *hiprivate = drm_dev->dev_private;
> +
> +       drm_helper_resume_force_mode(drm_dev);
> +
> +       if (hiprivate->fbdev.initialized) {
> +               console_lock();
> +               fb_set_suspend(hiprivate->fbdev.helper.fbdev, 0);
> +               console_unlock();
> +       }
> +
> +       drm_kms_helper_poll_enable(drm_dev);
> +       return 0;
> +}
> +
> +static const struct dev_pm_ops hibmc_pm_ops = {
> +       SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
> +                               hibmc_pm_resume)
> +};
> +
> +int hibmc_hw_config(void)
> +{
> +       unsigned int reg;
> +
> +       /* On hardware reset, power mode 0 is default. */
> +       set_power_mode(POWER_MODE_CTRL_MODE_MODE0);
> +
> +       /* Enable display power gate & LOCALMEM power gate*/
> +       reg = PEEK32(CURRENT_GATE);
> +       reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, ON);
> +       reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, ON);
> +       set_current_gate(reg);
> +
> +       /* Reset the memory controller. If the memory controller
> +        * is not reset in chip,the system might hang when sw accesses
> +        * the memory.The memory should be resetted after
> +        * changing the MXCLK.
> +        */
> +       reg = PEEK32(MISC_CTRL);
> +       reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, RESET);
> +       POKE32(MISC_CTRL, reg);
> +
> +       reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
> +       POKE32(MISC_CTRL, reg);
> +
> +       /* We can add more initialization as needed. */
> +
> +       return 0;
> +}
> +
> +int hibmc_hw_map(struct drm_device *dev)
> +{
> +       struct hibmc_private *hiprivate = dev->dev_private;
> +       struct pci_dev *pdev = dev->pdev;
> +       resource_size_t addr, size, ioaddr, iosize;
> +
> +       ioaddr = pci_resource_start(pdev, 1);
> +       iosize = MB(2);
> +
> +       hiprivate->mmio = ioremap_nocache(ioaddr, iosize);
> +       if (!hiprivate->mmio) {
> +               DRM_ERROR("Cannot map mmio region\n");
> +               return -ENOMEM;
> +       }
> +
> +       mmio_bmc_vga = hiprivate->mmio;
> +
> +       addr = pci_resource_start(pdev, 0);
> +       size = MB(16);
> +
> +       hiprivate->fb_map = ioremap(addr, size);
> +       if (!hiprivate->fb_map) {
> +               DRM_ERROR("Cannot map framebuffer\n");
> +               return -ENOMEM;
> +       }
> +       hiprivate->fb_base = addr;
> +       hiprivate->fb_size = size;
> +
> +       return 0;
> +}
> +
> +void hibmc_hw_fini(struct drm_device *dev)
> +{
> +       struct hibmc_private *hiprivate = dev->dev_private;
> +
> +       if (hiprivate->mmio)
> +               iounmap(hiprivate->mmio);
> +       if (hiprivate->fb_map)
> +               iounmap(hiprivate->fb_map);
> +}
> +
> +int hibmc_hw_init(struct drm_device *dev)
> +{
> +       int ret;
> +
> +       ret = hibmc_hw_map(dev);
> +       if (ret)
> +               return ret;
> +
> +       hibmc_hw_config();
> +
> +       return 0;
> +}
> +
> +static int hibmc_unload(struct drm_device *dev)
> +{
> +       hibmc_hw_fini(dev);
> +       dev->dev_private = NULL;
> +       return 0;
> +}
> +
> +static int hibmc_load(struct drm_device *dev, unsigned long flags)
> +{
> +       struct hibmc_private *hiprivate;
> +       int ret;
> +
> +       hiprivate = devm_kzalloc(dev->dev, sizeof(*hiprivate), GFP_KERNEL);
> +       if (!hiprivate)
> +               return -ENOMEM;
> +       dev->dev_private = hiprivate;
> +       hiprivate->dev = dev;
> +
> +       ret = hibmc_hw_init(dev);
> +       if (ret)
> +               goto err;
> +       ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
> +       if (ret) {
> +               DRM_ERROR("failed to initialize vblank.\n");
> +               return ret;
> +       }
> +       /* reset all the states of crtc/plane/encoder/connector */
> +       drm_mode_config_reset(dev);
> +
> +       return 0;
> +
> +err:
> +       hibmc_unload(dev);
> +       DRM_ERROR("failed to initialize drm driver.\n");
> +       return ret;
> +}
> +
> +static int hibmc_pci_probe(struct pci_dev *pdev,
> +                          const struct pci_device_id *ent)
> +{
> +       struct drm_device *dev;
> +       int ret;
> +
> +       dev = drm_dev_alloc(&hibmc_driver, &pdev->dev);
> +       if (!dev)
> +               return -ENOMEM;
> +
> +       dev->pdev = pdev;
> +       pci_set_drvdata(pdev, dev);
> +
> +       ret = pci_enable_device(pdev);
> +       if (ret)
> +               goto err_free;
> +
> +       ret = hibmc_load(dev, 0);
> +       if (ret)
> +               goto err_disable;
> +
> +       ret = drm_dev_register(dev, 0);
> +       if (ret)
> +               goto err_unload;
> +
> +       return 0;
> +
> +err_unload:
> +       hibmc_unload(dev);
> +err_disable:
> +       pci_disable_device(pdev);
> +err_free:
> +       drm_dev_unref(dev);
> +
> +       return ret;
> +}
> +
> +static void hibmc_pci_remove(struct pci_dev *pdev)
> +{
> +       struct drm_device *dev = pci_get_drvdata(pdev);
> +
> +       drm_dev_unregister(dev);
> +       hibmc_unload(dev);
> +       drm_dev_unref(dev);
> +}
> +
> +static struct pci_device_id hibmc_pci_table[] = {
> +       {PCI_VENDOR_ID_HIS, PCI_DEVID_HS_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> +       {0,}
> +};
> +
> +static struct pci_driver hibmc_pci_driver = {
> +       .name =         "hibmc-drm",
> +       .id_table =     hibmc_pci_table,
> +       .probe =        hibmc_pci_probe,
> +       .remove =       hibmc_pci_remove,
> +       .driver.pm =    &hibmc_pm_ops,
> +};
> +
> +static int __init hibmc_init(void)
> +{
> +       return drm_pci_init(&hibmc_driver, &hibmc_pci_driver);
The use of drm_pci_init has been deprecated for more than half a year.
Please update and check that the rest of the driver does not use such
(deprecated) functions.

> +}
> +
> +static void __exit hibmc_exit(void)
> +{
> +       drm_pci_exit(&hibmc_driver, &hibmc_pci_driver);
> +}
> +
> +module_init(hibmc_init);
> +module_exit(hibmc_exit);
> +
> +MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
> +MODULE_AUTHOR("lijianhua <lijianhua@huawei.com>");
> +MODULE_DESCRIPTION("DRM Driver for Hisilicon BMC Hi1710");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> new file mode 100644
> index 0000000..5db7902
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +
> +#ifndef HIBMC_DRM_DRV_H
> +#define HIBMC_DRM_DRV_H
> +
> +/* Vendor and Device id for HISILICON Graphics chip*/
> +#define PCI_VENDOR_ID_HIS 0x19e5
> +#define PCI_DEVID_HS_VGA 0x1711
> +
Pretty sure that these don't belong here. Also the device id name
seems quite generic.

> +struct hibmc_framebuffer {
> +       struct drm_framebuffer fb;
> +       struct drm_gem_cma_object *obj;
> +       bool is_fbdev_fb;
> +};
> +
> +struct hibmc_fbdev {
> +       struct hibmc_framebuffer fb;
> +       struct drm_fb_helper helper;
> +       bool initialized;
> +};
> +
> +struct hibmc_private {
> +       /* hw */
> +       void __iomem   *mmio;
> +       void __iomem   *fb_map;
> +       unsigned long  fb_base;
> +       unsigned long  fb_size;
> +
> +       /* drm */
> +       struct drm_device  *dev;
> +       struct drm_plane plane;
> +       struct drm_crtc crtc;
> +       struct drm_encoder encoder;
> +       struct drm_connector connector;
> +       bool mode_config_initialized;
> +
> +       /* fbdev */
> +       struct hibmc_fbdev fbdev;
> +};
> +
hibmc_private looks quite strange. I haven't closely looked at the
driver, but many of the above structs, or their member variables, are
not used yet. They should be introduced by the patch where needed.

> +#endif
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
> new file mode 100644
> index 0000000..8eb7b26
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
> @@ -0,0 +1,83 @@
> +/*
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +#include <linux/io.h>
> +
> +#include "hibmc_drm_hw.h"
> +
> +/*
> + * It can operate in one of three modes: 0, 1 or Sleep.
> + */
> +void set_power_mode(unsigned int power_mode)
> +{
> +       unsigned int control_value = 0;
> +
> +       control_value = PEEK32(POWER_MODE_CTRL);
> +
> +       switch (power_mode) {
> +       case POWER_MODE_CTRL_MODE_MODE0:
> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
> +                                         MODE, MODE0);
> +               break;
> +
> +       case POWER_MODE_CTRL_MODE_MODE1:
> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
> +                                         MODE, MODE1);
> +               break;
> +
> +       case POWER_MODE_CTRL_MODE_SLEEP:
> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
> +                                         MODE, SLEEP);
> +               break;
> +
> +       default:
> +               break;
> +       }
> +
> +    /* Set up other fields in Power Control Register */
> +       if (power_mode == POWER_MODE_CTRL_MODE_SLEEP) {
> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
> +                                         OSC_INPUT,  OFF);
> +       } else {
> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
> +                                         OSC_INPUT,  ON);
> +       }
> +    /* Program new power mode. */
> +       POKE32(POWER_MODE_CTRL, control_value);
> +}
> +
> +unsigned int get_power_mode(void)
> +{
> +       return FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE);
> +}
> +
> +void set_current_gate(unsigned int gate)
> +{
> +       unsigned int gate_reg;
> +       unsigned int mode;
> +
> +       /* Get current power mode. */
> +       mode = get_power_mode();
> +
> +       switch (mode) {
> +       case POWER_MODE_CTRL_MODE_MODE0:
> +               gate_reg = MODE0_GATE;
> +               break;
> +
> +       case POWER_MODE_CTRL_MODE_MODE1:
> +               gate_reg = MODE1_GATE;
> +               break;
> +
> +       default:
> +               gate_reg = MODE0_GATE;
> +               break;
> +       }
> +       POKE32(gate_reg, gate);
> +}
> +
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
> new file mode 100644
> index 0000000..52787d4
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
> @@ -0,0 +1,484 @@
> +/*
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> + #ifndef HIBMC_DRM_HW_H
> +#define HIBMC_DRM_HW_H
> +
> +#define F(v)    v
> +
I wonder why almost every new kernel developer introduces their own
set of bit macros :-(
Please use take a look at include/linux/bitops.h.

> +/* register definition */
> +#define DE_STATE1                                        0x100054
> +#define DE_STATE1_DE_ABORT                               F(0 : 0)
> +#define DE_STATE1_DE_ABORT_OFF                           0
> +#define DE_STATE1_DE_ABORT_ON                            1
> +
> +#define DE_STATE2                                        0x100058
> +#define DE_STATE2_DE_FIFO                                F(3 : 3)
> +#define DE_STATE2_DE_FIFO_NOTEMPTY                       0
> +#define DE_STATE2_DE_FIFO_EMPTY                          1
> +#define DE_STATE2_DE_STATUS                              F(2 : 2)
> +#define DE_STATE2_DE_STATUS_IDLE                         0
> +#define DE_STATE2_DE_STATUS_BUSY                         1
> +#define DE_STATE2_DE_MEM_FIFO                            F(1 : 1)
> +#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY                   0
> +#define DE_STATE2_DE_MEM_FIFO_EMPTY                      1
> +
> +#define MISC_CTRL                                     0x000004
> +#define MISC_CTRL_DAC_POWER                           F(20 : 20)
> +#define MISC_CTRL_DAC_POWER_ON                        0
> +#define MISC_CTRL_DAC_POWER_OFF                       1
> +#define MISC_CTRL_LOCALMEM_RESET                      F(6 : 6)
> +#define MISC_CTRL_LOCALMEM_RESET_RESET                0
> +#define MISC_CTRL_LOCALMEM_RESET_NORMAL               1
> +
> +#define CURRENT_GATE                                  0x000040
> +#define CURRENT_GATE_MCLK                             F(15 : 14)
> +#define CURRENT_GATE_CSC                              F(4 : 4)
> +#define CURRENT_GATE_CSC_OFF                          0
> +#define CURRENT_GATE_CSC_ON                           1
> +#define CURRENT_GATE_DE                               F(3 : 3)
> +#define CURRENT_GATE_DE_OFF                           0
> +#define CURRENT_GATE_DE_ON                            1
> +#define CURRENT_GATE_DISPLAY                          F(2 : 2)
> +#define CURRENT_GATE_DISPLAY_OFF                      0
> +#define CURRENT_GATE_DISPLAY_ON                       1
> +#define CURRENT_GATE_LOCALMEM                         F(1 : 1)
> +#define CURRENT_GATE_LOCALMEM_OFF                     0
> +#define CURRENT_GATE_LOCALMEM_ON                      1
> +#define CURRENT_GATE_DMA                              F(0 : 0)
> +#define CURRENT_GATE_DMA_OFF                          0
> +#define CURRENT_GATE_DMA_ON                           1
> +
> +#define MODE0_GATE                                    0x000044
> +#define MODE1_GATE                                    0x000048
> +#define POWER_MODE_CTRL                               0x00004C
> +
> +#define POWER_MODE_CTRL_OSC_INPUT                     F(3 : 3)
> +#define POWER_MODE_CTRL_OSC_INPUT_OFF                 0
> +#define POWER_MODE_CTRL_OSC_INPUT_ON                  1
> +#define POWER_MODE_CTRL_ACPI                          F(2 : 2)
> +#define POWER_MODE_CTRL_ACPI_OFF                      0
> +#define POWER_MODE_CTRL_ACPI_ON                       1
> +#define POWER_MODE_CTRL_MODE                          F(1 : 0)
> +#define POWER_MODE_CTRL_MODE_MODE0                    0
> +#define POWER_MODE_CTRL_MODE_MODE1                    1
> +#define POWER_MODE_CTRL_MODE_SLEEP                    2
> +
> +#define PANEL_PLL_CTRL                                0x00005C
> +#define PANEL_PLL_CTRL_BYPASS                         F(18 : 18)
> +#define PANEL_PLL_CTRL_BYPASS_OFF                     0
> +#define PANEL_PLL_CTRL_BYPASS_ON                      1
> +#define PANEL_PLL_CTRL_POWER                          F(17 : 17)
> +#define PANEL_PLL_CTRL_POWER_OFF                      0
> +#define PANEL_PLL_CTRL_POWER_ON                       1
> +#define PANEL_PLL_CTRL_INPUT                          F(16 : 16)
> +#define PANEL_PLL_CTRL_INPUT_OSC                      0
> +#define PANEL_PLL_CTRL_INPUT_TESTCLK                  1
> +
> +#define PANEL_PLL_CTRL_POD                        F(15 : 14)
> +#define PANEL_PLL_CTRL_OD                         F(13 : 12)
> +
> +#define PANEL_PLL_CTRL_N                              F(11 : 8)
> +#define PANEL_PLL_CTRL_M                              F(7 : 0)
> +
> +#define CRT_PLL_CTRL                                  0x000060
> +/* Video Control */
> +
> +#define VIDEO_DISPLAY_CTRL                              0x080040
> +#define VIDEO_DISPLAY_CTRL_PLANE                        F(2 : 2)
> +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE                0
> +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE                 1
> +
> +/* Video Alpha Control */
> +
> +#define VIDEO_ALPHA_DISPLAY_CTRL                        0x080080
> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE                  F(2 : 2)
> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE          0
> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE           1
> +
> +/* Panel Cursor Control */
> +#define ALPHA_DISPLAY_CTRL                            0x080100
> +#define ALPHA_DISPLAY_CTRL_PLANE                      F(2 : 2)
> +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE              0
> +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE               1
> +
> +/* CRT Graphics Control */
> +#define CRT_DISPLAY_CTRL                              0x080200
> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK              F(31 : 27)
> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE      0
> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE       0x1F
> +
> +/* register definition */
> +#define CRT_DISPLAY_CTRL_DPMS                         F(31 : 30)
> +#define CRT_DISPLAY_CTRL_DPMS_0                       0
> +#define CRT_DISPLAY_CTRL_DPMS_1                       1
> +#define CRT_DISPLAY_CTRL_DPMS_2                       2
> +#define CRT_DISPLAY_CTRL_DPMS_3                       3
> +
> +/* register definition */
> +#define CRT_DISPLAY_CTRL_CRTSELECT                    F(25 : 25)
> +#define CRT_DISPLAY_CTRL_CRTSELECT_VGA                0
> +#define CRT_DISPLAY_CTRL_CRTSELECT_CRT                1
> +
> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE                  F(14 : 14)
> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH      0
> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW       1
> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE                  F(13 : 13)
> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH      0
> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW       1
> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE                  F(12 : 12)
> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH      0
> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW       1
> +#define CRT_DISPLAY_CTRL_BLANK                        F(10 : 10)
> +#define CRT_DISPLAY_CTRL_BLANK_OFF                    0
> +#define CRT_DISPLAY_CTRL_BLANK_ON                     1
> +#define CRT_DISPLAY_CTRL_TIMING                       F(8 : 8)
> +#define CRT_DISPLAY_CTRL_TIMING_DISABLE               0
> +#define CRT_DISPLAY_CTRL_TIMING_ENABLE                1
> +#define CRT_DISPLAY_CTRL_PLANE                        F(2 : 2)
> +#define CRT_DISPLAY_CTRL_PLANE_DISABLE                0
> +#define CRT_DISPLAY_CTRL_PLANE_ENABLE                 1
> +#define CRT_DISPLAY_CTRL_FORMAT                       F(1 : 0)
> +#define CRT_DISPLAY_CTRL_FORMAT_8                     0
> +#define CRT_DISPLAY_CTRL_FORMAT_16                    1
> +#define CRT_DISPLAY_CTRL_FORMAT_32                    2
> +#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK           0xFF000200
> +
> +#define CRT_FB_ADDRESS                                0x080204
> +#define CRT_FB_ADDRESS_STATUS                         F(31 : 31)
> +#define CRT_FB_ADDRESS_STATUS_CURRENT                 0
> +#define CRT_FB_ADDRESS_STATUS_PENDING                 1
> +#define CRT_FB_ADDRESS_EXT                            F(27 : 27)
> +#define CRT_FB_ADDRESS_EXT_LOCAL                      0
> +#define CRT_FB_ADDRESS_EXT_EXTERNAL                   1
> +#define CRT_FB_ADDRESS_ADDRESS                        F(25 : 0)
> +
> +#define CRT_FB_WIDTH                                  0x080208
> +#define CRT_FB_WIDTH_WIDTH                            F(29 : 16)
> +#define CRT_FB_WIDTH_OFFSET                           F(13 : 0)
> +
> +#define CRT_HORIZONTAL_TOTAL                          0x08020C
> +#define CRT_HORIZONTAL_TOTAL_TOTAL                    F(27 : 16)
> +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END              F(11 : 0)
> +
> +#define CRT_HORIZONTAL_SYNC                           0x080210
> +#define CRT_HORIZONTAL_SYNC_WIDTH                     F(23 : 16)
> +#define CRT_HORIZONTAL_SYNC_START                     F(11 : 0)
> +
> +#define CRT_VERTICAL_TOTAL                            0x080214
> +#define CRT_VERTICAL_TOTAL_TOTAL                      F(26 : 16)
> +#define CRT_VERTICAL_TOTAL_DISPLAY_END                F(10 : 0)
> +
> +#define CRT_VERTICAL_SYNC                             0x080218
> +#define CRT_VERTICAL_SYNC_HEIGHT                      F(21 : 16)
> +#define CRT_VERTICAL_SYNC_START                       F(10 : 0)
> +
> +/* Auto Centering */
> +#define CRT_AUTO_CENTERING_TL                     0x080280
> +#define CRT_AUTO_CENTERING_TL_TOP                 F(26 : 16)
> +#define CRT_AUTO_CENTERING_TL_LEFT                F(10 : 0)
> +
> +#define CRT_AUTO_CENTERING_BR                     0x080284
> +#define CRT_AUTO_CENTERING_BR_BOTTOM              F(26 : 16)
> +#define CRT_AUTO_CENTERING_BR_RIGHT               F(10 : 0)
> +
> +/* register to control panel output */
> +#define DISPLAY_CONTROL_HISILE                    0x80288
> +
> +/* register and values for PLL control */
> +#define CRT_PLL1_HS                            0x802a8
> +#define CRT_PLL1_HS_25MHZ                     0x23d40f02
> +#define CRT_PLL1_HS_40MHZ                     0x23940801
> +#define CRT_PLL1_HS_65MHZ                     0x23940d01
> +#define CRT_PLL1_HS_78MHZ                     0x23540F82
> +#define CRT_PLL1_HS_74MHZ                     0x23941dc2
> +#define CRT_PLL1_HS_80MHZ                     0x23941001
> +#define CRT_PLL1_HS_80MHZ_1152            0x23540fc2
> +#define CRT_PLL1_HS_108MHZ                    0x23b41b01
> +#define CRT_PLL1_HS_162MHZ                    0x23480681
> +#define CRT_PLL1_HS_148MHZ                    0x23541dc2
> +#define CRT_PLL1_HS_193MHZ                    0x234807c1
> +
> +#define CRT_PLL2_HS                         0x802ac
> +#define CRT_PLL2_HS_25MHZ                     0x206B851E
> +#define CRT_PLL2_HS_40MHZ                     0x30000000
> +#define CRT_PLL2_HS_65MHZ                     0x40000000
> +#define CRT_PLL2_HS_78MHZ                     0x50E147AE
> +#define CRT_PLL2_HS_74MHZ                     0x602B6AE7
> +#define CRT_PLL2_HS_80MHZ                     0x70000000
> +#define CRT_PLL2_HS_108MHZ                    0x80000000
> +#define CRT_PLL2_HS_162MHZ                    0xA0000000
> +#define CRT_PLL2_HS_148MHZ                    0xB0CCCCCD
> +#define CRT_PLL2_HS_193MHZ                    0xC0872B02
> +
> +/* Palette RAM */
> +
> +/* Panel Palette register starts at 0x080400 ~ 0x0807FC */
> +#define PANEL_PALETTE_RAM                             0x080400
> +
> +/* Panel Palette register starts at 0x080C00 ~ 0x080FFC */
> +#define CRT_PALETTE_RAM                               0x080C00
> +
> +#define DMA_ABORT_INTERRUPT                             0x0D0020
> +#define DMA_ABORT_INTERRUPT_ABORT_1                     F(5 : 5)
> +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE              0
> +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT               1
> +
> +/* cursor control */
> +#define HWC_ADDRESS                         0x0
> +#define HWC_ADDRESS_ENABLE                  F(31 : 31)
> +#define HWC_ADDRESS_ENABLE_DISABLE          0
> +#define HWC_ADDRESS_ENABLE_ENABLE           1
> +#define HWC_ADDRESS_EXT                     F(27 : 27)
> +#define HWC_ADDRESS_EXT_LOCAL               0
> +#define HWC_ADDRESS_EXT_EXTERNAL            1
> +#define HWC_ADDRESS_CS                      F(26 : 26)
> +#define HWC_ADDRESS_CS_0                    0
> +#define HWC_ADDRESS_CS_1                    1
> +#define HWC_ADDRESS_ADDRESS                 F(25 : 0)
> +
> +#define HWC_LOCATION                        0x4
> +#define HWC_LOCATION_Y                      F(26 : 16)
> +#define HWC_LOCATION_LEFT                   F(11 : 11)
> +#define HWC_LOCATION_LEFT_INSIDE            0
> +#define HWC_LOCATION_LEFT_OUTSIDE           1
> +#define HWC_LOCATION_X                      F(10 : 0)
> +
> +#define HWC_COLOR_12                        0x8
> +
> +#define HWC_COLOR_3                         0xC
> +
> +/* accelate 2d graphic */
> +#define DE_SOURCE                                       0x0
> +#define DE_SOURCE_WRAP                                  F(31 : 31)
> +#define DE_SOURCE_WRAP_DISABLE                          0
> +#define DE_SOURCE_WRAP_ENABLE                           1
> +#define DE_SOURCE_X_K1                                  F(29 : 16)
> +#define DE_SOURCE_Y_K2                                  F(15 : 0)
> +#define DE_SOURCE_X_K1_MONO                             F(20 : 16)
> +
> +#define DE_DESTINATION                                  0x4
> +#define DE_DESTINATION_WRAP                             F(31 : 31)
> +#define DE_DESTINATION_WRAP_DISABLE                     0
> +#define DE_DESTINATION_WRAP_ENABLE                      1
> +#define DE_DESTINATION_X                                F(28 : 16)
> +#define DE_DESTINATION_Y                                F(15 : 0)
> +
> +#define DE_DIMENSION                                    0x8
> +#define DE_DIMENSION_X                                  F(28 : 16)
> +#define DE_DIMENSION_Y_ET                               F(15 : 0)
> +
> +#define DE_CONTROL                                      0xC
> +#define DE_CONTROL_STATUS                               F(31 : 31)
> +#define DE_CONTROL_STATUS_STOP                          0
> +#define DE_CONTROL_STATUS_START                         1
> +#define DE_CONTROL_PATTERN                              F(30 : 30)
> +#define DE_CONTROL_PATTERN_MONO                         0
> +#define DE_CONTROL_PATTERN_COLOR                        1
> +#define DE_CONTROL_UPDATE_DESTINATION_X                 F(29 : 29)
> +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE         0
> +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE          1
> +#define DE_CONTROL_QUICK_START                          F(28 : 28)
> +#define DE_CONTROL_QUICK_START_DISABLE                  0
> +#define DE_CONTROL_QUICK_START_ENABLE                   1
> +#define DE_CONTROL_DIRECTION                            F(27 : 27)
> +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT              0
> +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT              1
> +#define DE_CONTROL_MAJOR                                F(26 : 26)
> +#define DE_CONTROL_MAJOR_X                              0
> +#define DE_CONTROL_MAJOR_Y                              1
> +#define DE_CONTROL_STEP_X                               F(25 : 25)
> +#define DE_CONTROL_STEP_X_POSITIVE                      1
> +#define DE_CONTROL_STEP_X_NEGATIVE                      0
> +#define DE_CONTROL_STEP_Y                               F(24 : 24)
> +#define DE_CONTROL_STEP_Y_POSITIVE                      1
> +#define DE_CONTROL_STEP_Y_NEGATIVE                      0
> +#define DE_CONTROL_STRETCH                              F(23 : 23)
> +#define DE_CONTROL_STRETCH_DISABLE                      0
> +#define DE_CONTROL_STRETCH_ENABLE                       1
> +#define DE_CONTROL_HOST                                 F(22 : 22)
> +#define DE_CONTROL_HOST_COLOR                           0
> +#define DE_CONTROL_HOST_MONO                            1
> +#define DE_CONTROL_LAST_PIXEL                           F(21 : 21)
> +#define DE_CONTROL_LAST_PIXEL_OFF                       0
> +#define DE_CONTROL_LAST_PIXEL_ON                        1
> +#define DE_CONTROL_COMMAND                              F(20 : 16)
> +#define DE_CONTROL_COMMAND_BITBLT                       0
> +#define DE_CONTROL_COMMAND_RECTANGLE_FILL               1
> +#define DE_CONTROL_COMMAND_DE_TILE                      2
> +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL               3
> +#define DE_CONTROL_COMMAND_ALPHA_BLEND                  4
> +#define DE_CONTROL_COMMAND_RLE_STRIP                    5
> +#define DE_CONTROL_COMMAND_SHORT_STROKE                 6
> +#define DE_CONTROL_COMMAND_LINE_DRAW                    7
> +#define DE_CONTROL_COMMAND_HOST_WRITE                   8
> +#define DE_CONTROL_COMMAND_HOST_READ                    9
> +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP         10
> +#define DE_CONTROL_COMMAND_ROTATE                       11
> +#define DE_CONTROL_COMMAND_FONT                         12
> +#define DE_CONTROL_COMMAND_TEXTURE_LOAD                 15
> +#define DE_CONTROL_ROP_SELECT                           F(15 : 15)
> +#define DE_CONTROL_ROP_SELECT_ROP3                      0
> +#define DE_CONTROL_ROP_SELECT_ROP2                      1
> +#define DE_CONTROL_ROP2_SOURCE                          F(14 : 14)
> +#define DE_CONTROL_ROP2_SOURCE_BITMAP                   0
> +#define DE_CONTROL_ROP2_SOURCE_PATTERN                  1
> +#define DE_CONTROL_MONO_DATA                            F(13 : 12)
> +#define DE_CONTROL_MONO_DATA_NOT_PACKED                 0
> +#define DE_CONTROL_MONO_DATA_8_PACKED                   1
> +#define DE_CONTROL_MONO_DATA_16_PACKED                  2
> +#define DE_CONTROL_MONO_DATA_32_PACKED                  3
> +#define DE_CONTROL_REPEAT_ROTATE                        F(11 : 11)
> +#define DE_CONTROL_REPEAT_ROTATE_DISABLE                0
> +#define DE_CONTROL_REPEAT_ROTATE_ENABLE                 1
> +#define DE_CONTROL_TRANSPARENCY_MATCH                   F(10 : 10)
> +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE            0
> +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT       1
> +#define DE_CONTROL_TRANSPARENCY_SELECT                  F(9 : 9)
> +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE           0
> +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION      1
> +#define DE_CONTROL_TRANSPARENCY                         F(8 : 8)
> +#define DE_CONTROL_TRANSPARENCY_DISABLE                 0
> +#define DE_CONTROL_TRANSPARENCY_ENABLE                  1
> +#define DE_CONTROL_ROP                                  F(7 : 0)
> +
> +/* Pseudo fields. */
> +
> +#define DE_CONTROL_SHORT_STROKE_DIR                     F(27 : 24)
> +#define DE_CONTROL_SHORT_STROKE_DIR_225                 0
> +#define DE_CONTROL_SHORT_STROKE_DIR_135                 1
> +#define DE_CONTROL_SHORT_STROKE_DIR_315                 2
> +#define DE_CONTROL_SHORT_STROKE_DIR_45                  3
> +#define DE_CONTROL_SHORT_STROKE_DIR_270                 4
> +#define DE_CONTROL_SHORT_STROKE_DIR_90                  5
> +#define DE_CONTROL_SHORT_STROKE_DIR_180                 8
> +#define DE_CONTROL_SHORT_STROKE_DIR_0                   10
> +#define DE_CONTROL_ROTATION                             F(25 : 24)
> +#define DE_CONTROL_ROTATION_0                           0
> +#define DE_CONTROL_ROTATION_270                         1
> +#define DE_CONTROL_ROTATION_90                          2
> +#define DE_CONTROL_ROTATION_180                         3
> +
> +#define DE_PITCH                                        0x000010
> +#define DE_PITCH_DESTINATION                            F(28 : 16)
> +#define DE_PITCH_SOURCE                                 F(12 : 0)
> +
> +#define DE_FOREGROUND                                   0x000014
> +
> +#define DE_BACKGROUND                                   0x000018
> +
> +#define DE_STRETCH_FORMAT                               0x00001C
> +#define DE_STRETCH_FORMAT_PATTERN_XY                    F(30 : 30)
> +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL             0
> +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE          1
> +#define DE_STRETCH_FORMAT_PATTERN_Y                     F(29 : 27)
> +#define DE_STRETCH_FORMAT_PATTERN_X                     F(25 : 23)
> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT                  F(21 : 20)
> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8                0
> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16               1
> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32               2
> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24               3
> +
> +#define DE_STRETCH_FORMAT_ADDRESSING                    F(19 : 16)
> +#define DE_STRETCH_FORMAT_ADDRESSING_XY                 0
> +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR             15
> +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT                 F(11 : 0)
> +
> +#define DE_COLOR_COMPARE                                0x000020
> +
> +#define DE_COLOR_COMPARE_MASK                           0x000024
> +
> +#define DE_MASKS                                        0x000028
> +
> +#define DE_CLIP_TL                                      0x00002C
> +
> +#define DE_CLIP_BR                                      0x000030
> +
> +#define DE_WINDOW_WIDTH                                 0x00003C
> +#define DE_WINDOW_WIDTH_DESTINATION                     F(28 : 16)
> +#define DE_WINDOW_WIDTH_SOURCE                          F(12 : 0)
> +
> +#define DE_WINDOW_SOURCE_BASE                           0x000040
> +#define DE_WINDOW_SOURCE_BASE_EXT                       F(27 : 27)
> +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL                 0
> +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL              1
> +#define DE_WINDOW_SOURCE_BASE_CS                        F(26 : 26)
> +#define DE_WINDOW_SOURCE_BASE_CS_0                      0
> +#define DE_WINDOW_SOURCE_BASE_CS_1                      1
> +#define DE_WINDOW_SOURCE_BASE_ADDRESS                   F(25 : 0)
> +
> +#define DE_WINDOW_DESTINATION_BASE                      0x000044
> +#define DE_WINDOW_DESTINATION_BASE_EXT                  F(27 : 27)
> +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL            0
> +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL         1
> +#define DE_WINDOW_DESTINATION_BASE_CS                   F(26 : 26)
> +#define DE_WINDOW_DESTINATION_BASE_CS_0                 0
> +#define DE_WINDOW_DESTINATION_BASE_CS_1                 1
> +#define DE_WINDOW_DESTINATION_BASE_ADDRESS              F(25 : 0)
> +
> +/* Internal macros */
> +#define _F_START(f)             (0 ? f)
> +#define _F_END(f)               (1 ? f)
Why do you even need these ?

> +#define _F_SIZE(f)              (1 + _F_END(f) - _F_START(f))
> +#define _F_MASK(f)              (((1 << _F_SIZE(f)) - 1) << _F_START(f))
> +#define _F_NORMALIZE(v, f)      (((v) & _F_MASK(f)) >> _F_START(f))
> +#define _F_DENORMALIZE(v, f)    (((v) << _F_START(f)) & _F_MASK(f))
> +
> +/* Global macros */
> +#define FIELD_GET(x, reg, field) \
> +( \
> +       _F_NORMALIZE((x), reg ## _ ## field) \
> +)
> +
> +#define FIELD_SET(x, reg, field, value) \
> +( \
> +       (x & ~_F_MASK(reg ## _ ## field)) \
> +       | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
> +)
> +
> +#define FIELD_VALUE(x, reg, field, value) \
> +( \
> +       (x & ~_F_MASK(reg ## _ ## field)) \
> +       | _F_DENORMALIZE(value, reg ## _ ## field) \
> +)
> +
> +#define FIELD_CLEAR(reg, field) \
> +( \
> +       ~_F_MASK(reg ## _ ## field) \
> +)
> +
> +/* Field Macros */
> +#define FIELD_START(field)              (0 ? field)
> +#define FIELD_END(field)                (1 ? field)
Same goes here ?

> +#define FIELD_SIZE(field) \
> +       (1 + FIELD_END(field) - FIELD_START(field))
> +#define FIELD_MASK(field) \
> +       (((1 << (FIELD_SIZE(field) - 1)) |\
> +       ((1 << (FIELD_SIZE(field) - 1)) - 1)) << FIELD_START(field))
> +#define FIELD_NORMALIZE(reg, field) \
> +       (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
> +#define FIELD_DENORMALIZE(field, value) \
> +       (((value) << FIELD_START(field)) & FIELD_MASK(field))
> +#define RGB(r, g, b) \
> +( \
> +       (unsigned long)(((r) << 16) | ((g) << 8) | (b)) \
> +)
> +
> +#define PEEK32(addr) readl((addr) + mmio_bmc_vga)
> +#define POKE32(addr, data) writel((data), (addr) + mmio_bmc_vga)
> +extern unsigned char __iomem *mmio_bmc_vga;
> +
> +#define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
> +
> +#define MB(x) ((x) << 20)
> +
> +void set_power_mode(unsigned int power_mode);
> +void set_current_gate(unsigned int gate);
> +
In general you want to have your symbols (be that macros or functions)
prefixed appropriatelly, otherwise they will clash with others in the
kernel.
A handful of the internal/field macros seems like they should not
exist and/or there's an existing kernel equivalent. I would suggest
looking at other DRM drivers and how they deal with the above.

Regards,
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver.
  2016-02-29  9:40   ` Emil Velikov
@ 2016-03-01  8:07     ` Rongrong Zou
  2016-03-09 15:12       ` Emil Velikov
  0 siblings, 1 reply; 11+ messages in thread
From: Rongrong Zou @ 2016-03-01  8:07 UTC (permalink / raw)
  To: Emil Velikov, lijianhua; +Cc: z.liuxinliang, linuxarm, ML dri-devel

Hi, Emil

Thanks for reviewing this path.
在 2016/2/29 17:40, Emil Velikov 写道:
> On 29 February 2016 at 00:58, lijianhua <jueying0518@gmail.com> wrote:
>> Add hibmc DRM master driver for hi1710 which used in arm64 board.
>>
> Would be nice to give examples of what "arm64 board" this hardware is
> presently available. Some information about the device as seen in the
> cover letter, and/or a link to the cover letter would be nice to have.
>
Apply ,Will be fixed in next version.thanks!

>> Signed-off-by: lijianhua <jueying0518@gmail.com>
>> ---
>>   drivers/gpu/drm/Kconfig                         |   2 +
>>   drivers/gpu/drm/Makefile                        |   1 +
>>   drivers/gpu/drm/hisilicon/Kconfig               |   4 +
>>   drivers/gpu/drm/hisilicon/Makefile              |   4 +
>>   drivers/gpu/drm/hisilicon/hibmc/Kconfig         |  13 +
>>   drivers/gpu/drm/hisilicon/hibmc/Makefile        |   5 +
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 301 +++++++++++++++
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h |  49 +++
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c  |  83 ++++
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h  | 484 ++++++++++++++++++++++++
>>   10 files changed, 946 insertions(+)
>>   create mode 100644 drivers/gpu/drm/hisilicon/Kconfig
>>   create mode 100644 drivers/gpu/drm/hisilicon/Makefile
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
>>   create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
>>
>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>> index 8ae7ab6..600f94d 100644
>> --- a/drivers/gpu/drm/Kconfig
>> +++ b/drivers/gpu/drm/Kconfig
>> @@ -269,3 +269,5 @@ source "drivers/gpu/drm/imx/Kconfig"
>>   source "drivers/gpu/drm/vc4/Kconfig"
>>
>>   source "drivers/gpu/drm/etnaviv/Kconfig"
>> +
>> +source "drivers/gpu/drm/hisilicon/Kconfig"
>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
>> index 61766de..6055483 100644
>> --- a/drivers/gpu/drm/Makefile
>> +++ b/drivers/gpu/drm/Makefile
>> @@ -74,3 +74,4 @@ obj-y                 += panel/
>>   obj-y                  += bridge/
>>   obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
>>   obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
>> +obj-y                  += hisilicon/
>> diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig
>> new file mode 100644
>> index 0000000..1f10e17
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/Kconfig
>> @@ -0,0 +1,4 @@
>> +# hisilicon drm device configuration.
>> +# Please keep this sorted alphabetically.
>> +
>> +source "drivers/gpu/drm/hisilicon/hibmc/Kconfig"
>> diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile
>> new file mode 100644
>> index 0000000..487d5b0
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/Makefile
>> @@ -0,0 +1,4 @@
>> +# Makefile for hisilicon drm drivers.
>> +# Please keep this list sorted alphabetically
>> +
>> +obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/
>> \ No newline at end of file
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
>> new file mode 100644
>> index 0000000..c60ace6
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
>> @@ -0,0 +1,13 @@
>> +config DRM_HISI_HIBMC
>> +       tristate "DRM Support for hisilicon hibmc dispi vga interface"
> Use proper capitalisation in the above ? Is the driver copied/derived
> from bochs - the above does not sounds right.

Apply ,Will be fixed in next version.thanks!

>
>> +       depends on DRM && PCI
>> +       select DRM_KMS_HELPER
>> +       select DRM_KMS_FB_HELPER
>> +       select DRM_GEM_CMA_HELPER
>> +       select DRM_KMS_CMA_HELPER
>> +       select FB_SYS_FILLRECT
>> +       select FB_SYS_COPYAREA
>> +       select FB_SYS_IMAGEBLIT
>> +       help
>> +         Choose this option for qemu.
> Err what - too much copy/pasta ?

Apply ,thanks!

>
>> +         If M is selected the module will be called hibmc-drm.
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
>> new file mode 100644
>> index 0000000..28e59bb
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
>> @@ -0,0 +1,5 @@
>> +ccflags-y := -Iinclude/drm
> Based on the includes in hibmc_drm_drv.c the above include isn't needed.

Apply ,thanks!
>
>> +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_hw.o
>> +
>> +obj-$(CONFIG_DRM_HISI_HIBMC)   +=hibmc-drm.o
>> +#obj-y += hibmc-drm.o
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>> new file mode 100644
>> index 0000000..444ced8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>> @@ -0,0 +1,301 @@
>> +/*
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/console.h>
>> +#include <drm/drm_atomic_helper.h>
>> +#include <drm/drm_crtc_helper.h>
>> +#include <drm/drm_fb_helper.h>
>> +#include <drm/drm_gem_cma_helper.h>
>> +#include <drm/drmP.h>
>> +
>> +#include "hibmc_drm_drv.h"
>> +#include "hibmc_drm_hw.h"
>> +
>> +unsigned char __iomem *mmio_bmc_vga;
>> +
> Having globals like this is never a good idea.

Apply , i'll remove it.
>
>> +static const struct file_operations hibmc_fops = {
>> +       .owner          = THIS_MODULE,
>> +       .open           = drm_open,
>> +       .release        = drm_release,
>> +       .unlocked_ioctl = drm_ioctl,
>> +#ifdef CONFIG_COMPAT
>> +       .compat_ioctl   = drm_compat_ioctl,
>> +#endif
>> +       .poll           = drm_poll,
>> +       .read           = drm_read,
>> +       .llseek         = no_llseek,
>> +};
>> +
>> +int hibmc_enable_vblank(struct drm_device *dev, unsigned int pipe)
>> +{
>> +       return 0;
>> +}
>> +
>> +void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
>> +{
>> +}
>> +
>> +static struct drm_driver hibmc_driver = {
>> +       .driver_features        = DRIVER_GEM | DRIVER_MODESET |
>> +                                               DRIVER_ATOMIC,
> You do not manage any outputs, let alone in atomic manner, yet. This
> should come with the patch that introduces the functionality ?

OK, let me consider how to introduce the functionality.

>
>> +       .fops                   = &hibmc_fops,
>> +       .name                   = "hibmc-drm",
>> +       .desc                   = "hibmc drm driver",
>> +       .date                   = "20151218",
> Afaict this date is mostly unused, then again it's quite off :-)
Do you mean i should better remove this property?
>
>> +       .major                  = 1,
>> +       .minor                  = 0,
>> +       .get_vblank_counter = drm_vblank_no_hw_counter,
>> +       .enable_vblank          = hibmc_enable_vblank,
>> +       .disable_vblank = hibmc_disable_vblank,
>> +       .gem_free_object        = drm_gem_cma_free_object,
>> +       .gem_vm_ops                             = &drm_gem_cma_vm_ops,
>> +       .dumb_create            = drm_gem_cma_dumb_create,
>> +       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
>> +       .dumb_destroy           = drm_gem_dumb_destroy,
>> +};
>> +
>> +static int hibmc_pm_suspend(struct device *dev)
>> +{
>> +       struct pci_dev *pdev = to_pci_dev(dev);
>> +       struct drm_device *drm_dev = pci_get_drvdata(pdev);
>> +       struct hibmc_private *hiprivate = drm_dev->dev_private;
>> +
>> +       drm_kms_helper_poll_disable(drm_dev);
>> +
>> +       if (hiprivate->fbdev.initialized) {
>> +               console_lock();
>> +               fb_set_suspend(hiprivate->fbdev.helper.fbdev, 1);
>> +               console_unlock();
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int hibmc_pm_resume(struct device *dev)
>> +{
>> +       struct pci_dev *pdev = to_pci_dev(dev);
>> +       struct drm_device *drm_dev = pci_get_drvdata(pdev);
>> +       struct hibmc_private *hiprivate = drm_dev->dev_private;
>> +
>> +       drm_helper_resume_force_mode(drm_dev);
>> +
>> +       if (hiprivate->fbdev.initialized) {
>> +               console_lock();
>> +               fb_set_suspend(hiprivate->fbdev.helper.fbdev, 0);
>> +               console_unlock();
>> +       }
>> +
>> +       drm_kms_helper_poll_enable(drm_dev);
>> +       return 0;
>> +}
>> +
>> +static const struct dev_pm_ops hibmc_pm_ops = {
>> +       SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
>> +                               hibmc_pm_resume)
>> +};
>> +
>> +int hibmc_hw_config(void)
>> +{
>> +       unsigned int reg;
>> +
>> +       /* On hardware reset, power mode 0 is default. */
>> +       set_power_mode(POWER_MODE_CTRL_MODE_MODE0);
>> +
>> +       /* Enable display power gate & LOCALMEM power gate*/
>> +       reg = PEEK32(CURRENT_GATE);
>> +       reg = FIELD_SET(reg, CURRENT_GATE, DISPLAY, ON);
>> +       reg = FIELD_SET(reg, CURRENT_GATE, LOCALMEM, ON);
>> +       set_current_gate(reg);
>> +
>> +       /* Reset the memory controller. If the memory controller
>> +        * is not reset in chip,the system might hang when sw accesses
>> +        * the memory.The memory should be resetted after
>> +        * changing the MXCLK.
>> +        */
>> +       reg = PEEK32(MISC_CTRL);
>> +       reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, RESET);
>> +       POKE32(MISC_CTRL, reg);
>> +
>> +       reg = FIELD_SET(reg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
>> +       POKE32(MISC_CTRL, reg);
>> +
>> +       /* We can add more initialization as needed. */
>> +
>> +       return 0;
>> +}
>> +
>> +int hibmc_hw_map(struct drm_device *dev)
>> +{
>> +       struct hibmc_private *hiprivate = dev->dev_private;
>> +       struct pci_dev *pdev = dev->pdev;
>> +       resource_size_t addr, size, ioaddr, iosize;
>> +
>> +       ioaddr = pci_resource_start(pdev, 1);
>> +       iosize = MB(2);
>> +
>> +       hiprivate->mmio = ioremap_nocache(ioaddr, iosize);
>> +       if (!hiprivate->mmio) {
>> +               DRM_ERROR("Cannot map mmio region\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       mmio_bmc_vga = hiprivate->mmio;
>> +
>> +       addr = pci_resource_start(pdev, 0);
>> +       size = MB(16);
>> +
>> +       hiprivate->fb_map = ioremap(addr, size);
>> +       if (!hiprivate->fb_map) {
>> +               DRM_ERROR("Cannot map framebuffer\n");
>> +               return -ENOMEM;
>> +       }
>> +       hiprivate->fb_base = addr;
>> +       hiprivate->fb_size = size;
>> +
>> +       return 0;
>> +}
>> +
>> +void hibmc_hw_fini(struct drm_device *dev)
>> +{
>> +       struct hibmc_private *hiprivate = dev->dev_private;
>> +
>> +       if (hiprivate->mmio)
>> +               iounmap(hiprivate->mmio);
>> +       if (hiprivate->fb_map)
>> +               iounmap(hiprivate->fb_map);
>> +}
>> +
>> +int hibmc_hw_init(struct drm_device *dev)
>> +{
>> +       int ret;
>> +
>> +       ret = hibmc_hw_map(dev);
>> +       if (ret)
>> +               return ret;
>> +
>> +       hibmc_hw_config();
>> +
>> +       return 0;
>> +}
>> +
>> +static int hibmc_unload(struct drm_device *dev)
>> +{
>> +       hibmc_hw_fini(dev);
>> +       dev->dev_private = NULL;
>> +       return 0;
>> +}
>> +
>> +static int hibmc_load(struct drm_device *dev, unsigned long flags)
>> +{
>> +       struct hibmc_private *hiprivate;
>> +       int ret;
>> +
>> +       hiprivate = devm_kzalloc(dev->dev, sizeof(*hiprivate), GFP_KERNEL);
>> +       if (!hiprivate)
>> +               return -ENOMEM;
>> +       dev->dev_private = hiprivate;
>> +       hiprivate->dev = dev;
>> +
>> +       ret = hibmc_hw_init(dev);
>> +       if (ret)
>> +               goto err;
>> +       ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
>> +       if (ret) {
>> +               DRM_ERROR("failed to initialize vblank.\n");
>> +               return ret;
>> +       }
>> +       /* reset all the states of crtc/plane/encoder/connector */
>> +       drm_mode_config_reset(dev);
>> +
>> +       return 0;
>> +
>> +err:
>> +       hibmc_unload(dev);
>> +       DRM_ERROR("failed to initialize drm driver.\n");
>> +       return ret;
>> +}
>> +
>> +static int hibmc_pci_probe(struct pci_dev *pdev,
>> +                          const struct pci_device_id *ent)
>> +{
>> +       struct drm_device *dev;
>> +       int ret;
>> +
>> +       dev = drm_dev_alloc(&hibmc_driver, &pdev->dev);
>> +       if (!dev)
>> +               return -ENOMEM;
>> +
>> +       dev->pdev = pdev;
>> +       pci_set_drvdata(pdev, dev);
>> +
>> +       ret = pci_enable_device(pdev);
>> +       if (ret)
>> +               goto err_free;
>> +
>> +       ret = hibmc_load(dev, 0);
>> +       if (ret)
>> +               goto err_disable;
>> +
>> +       ret = drm_dev_register(dev, 0);
>> +       if (ret)
>> +               goto err_unload;
>> +
>> +       return 0;
>> +
>> +err_unload:
>> +       hibmc_unload(dev);
>> +err_disable:
>> +       pci_disable_device(pdev);
>> +err_free:
>> +       drm_dev_unref(dev);
>> +
>> +       return ret;
>> +}
>> +
>> +static void hibmc_pci_remove(struct pci_dev *pdev)
>> +{
>> +       struct drm_device *dev = pci_get_drvdata(pdev);
>> +
>> +       drm_dev_unregister(dev);
>> +       hibmc_unload(dev);
>> +       drm_dev_unref(dev);
>> +}
>> +
>> +static struct pci_device_id hibmc_pci_table[] = {
>> +       {PCI_VENDOR_ID_HIS, PCI_DEVID_HS_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>> +       {0,}
>> +};
>> +
>> +static struct pci_driver hibmc_pci_driver = {
>> +       .name =         "hibmc-drm",
>> +       .id_table =     hibmc_pci_table,
>> +       .probe =        hibmc_pci_probe,
>> +       .remove =       hibmc_pci_remove,
>> +       .driver.pm =    &hibmc_pm_ops,
>> +};
>> +
>> +static int __init hibmc_init(void)
>> +{
>> +       return drm_pci_init(&hibmc_driver, &hibmc_pci_driver);
> The use of drm_pci_init has been deprecated for more than half a year.
> Please update and check that the rest of the driver does not use such
> (deprecated) functions.
>
thanks,i will fix it
>> +}
>> +
>> +static void __exit hibmc_exit(void)
>> +{
>> +       drm_pci_exit(&hibmc_driver, &hibmc_pci_driver);
>> +}
>> +
>> +module_init(hibmc_init);
>> +module_exit(hibmc_exit);
>> +
>> +MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
>> +MODULE_AUTHOR("lijianhua <lijianhua@huawei.com>");
>> +MODULE_DESCRIPTION("DRM Driver for Hisilicon BMC Hi1710");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> new file mode 100644
>> index 0000000..5db7902
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> @@ -0,0 +1,49 @@
>> +/*
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +
>> +#ifndef HIBMC_DRM_DRV_H
>> +#define HIBMC_DRM_DRV_H
>> +
>> +/* Vendor and Device id for HISILICON Graphics chip*/
>> +#define PCI_VENDOR_ID_HIS 0x19e5
>> +#define PCI_DEVID_HS_VGA 0x1711
>> +
I wonder where to place the 2 macros, any suggusetions, thanks.

> Pretty sure that these don't belong here. Also the device id name
> seems quite generic.
>
>> +struct hibmc_framebuffer {
>> +       struct drm_framebuffer fb;
>> +       struct drm_gem_cma_object *obj;
>> +       bool is_fbdev_fb;
>> +};
>> +
>> +struct hibmc_fbdev {
>> +       struct hibmc_framebuffer fb;
>> +       struct drm_fb_helper helper;
>> +       bool initialized;
>> +};
>> +
>> +struct hibmc_private {
>> +       /* hw */
>> +       void __iomem   *mmio;
>> +       void __iomem   *fb_map;
>> +       unsigned long  fb_base;
>> +       unsigned long  fb_size;
>> +
>> +       /* drm */
>> +       struct drm_device  *dev;
>> +       struct drm_plane plane;
>> +       struct drm_crtc crtc;
>> +       struct drm_encoder encoder;
>> +       struct drm_connector connector;
>> +       bool mode_config_initialized;
>> +
>> +       /* fbdev */
>> +       struct hibmc_fbdev fbdev;
>> +};
>> +
> hibmc_private looks quite strange. I haven't closely looked at the
> driver, but many of the above structs, or their member variables, are
> not used yet. They should be introduced by the patch where needed.

OK, i will move the member to the patch where they referred.

>
>> +#endif
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
>> new file mode 100644
>> index 0000000..8eb7b26
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.c
>> @@ -0,0 +1,83 @@
>> +/*
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +#include <linux/io.h>
>> +
>> +#include "hibmc_drm_hw.h"
>> +
>> +/*
>> + * It can operate in one of three modes: 0, 1 or Sleep.
>> + */
>> +void set_power_mode(unsigned int power_mode)
>> +{
>> +       unsigned int control_value = 0;
>> +
>> +       control_value = PEEK32(POWER_MODE_CTRL);
>> +
>> +       switch (power_mode) {
>> +       case POWER_MODE_CTRL_MODE_MODE0:
>> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
>> +                                         MODE, MODE0);
>> +               break;
>> +
>> +       case POWER_MODE_CTRL_MODE_MODE1:
>> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
>> +                                         MODE, MODE1);
>> +               break;
>> +
>> +       case POWER_MODE_CTRL_MODE_SLEEP:
>> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
>> +                                         MODE, SLEEP);
>> +               break;
>> +
>> +       default:
>> +               break;
>> +       }
>> +
>> +    /* Set up other fields in Power Control Register */
>> +       if (power_mode == POWER_MODE_CTRL_MODE_SLEEP) {
>> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
>> +                                         OSC_INPUT,  OFF);
>> +       } else {
>> +               control_value = FIELD_SET(control_value, POWER_MODE_CTRL,
>> +                                         OSC_INPUT,  ON);
>> +       }
>> +    /* Program new power mode. */
>> +       POKE32(POWER_MODE_CTRL, control_value);
>> +}
>> +
>> +unsigned int get_power_mode(void)
>> +{
>> +       return FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE);
>> +}
>> +
>> +void set_current_gate(unsigned int gate)
>> +{
>> +       unsigned int gate_reg;
>> +       unsigned int mode;
>> +
>> +       /* Get current power mode. */
>> +       mode = get_power_mode();
>> +
>> +       switch (mode) {
>> +       case POWER_MODE_CTRL_MODE_MODE0:
>> +               gate_reg = MODE0_GATE;
>> +               break;
>> +
>> +       case POWER_MODE_CTRL_MODE_MODE1:
>> +               gate_reg = MODE1_GATE;
>> +               break;
>> +
>> +       default:
>> +               gate_reg = MODE0_GATE;
>> +               break;
>> +       }
>> +       POKE32(gate_reg, gate);
>> +}
>> +
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
>> new file mode 100644
>> index 0000000..52787d4
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_hw.h
>> @@ -0,0 +1,484 @@
>> +/*
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> + #ifndef HIBMC_DRM_HW_H
>> +#define HIBMC_DRM_HW_H
>> +
>> +#define F(v)    v
>> +
> I wonder why almost every new kernel developer introduces their own
> set of bit macros :-(
> Please use take a look at include/linux/bitops.h.

It is derived from its fb version originally. i will fix it in
next version.
>
>> +/* register definition */
>> +#define DE_STATE1                                        0x100054
>> +#define DE_STATE1_DE_ABORT                               F(0 : 0)
>> +#define DE_STATE1_DE_ABORT_OFF                           0
>> +#define DE_STATE1_DE_ABORT_ON                            1
>> +
>> +#define DE_STATE2                                        0x100058
>> +#define DE_STATE2_DE_FIFO                                F(3 : 3)
>> +#define DE_STATE2_DE_FIFO_NOTEMPTY                       0
>> +#define DE_STATE2_DE_FIFO_EMPTY                          1
>> +#define DE_STATE2_DE_STATUS                              F(2 : 2)
>> +#define DE_STATE2_DE_STATUS_IDLE                         0
>> +#define DE_STATE2_DE_STATUS_BUSY                         1
>> +#define DE_STATE2_DE_MEM_FIFO                            F(1 : 1)
>> +#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY                   0
>> +#define DE_STATE2_DE_MEM_FIFO_EMPTY                      1
>> +
>> +#define MISC_CTRL                                     0x000004
>> +#define MISC_CTRL_DAC_POWER                           F(20 : 20)
>> +#define MISC_CTRL_DAC_POWER_ON                        0
>> +#define MISC_CTRL_DAC_POWER_OFF                       1
>> +#define MISC_CTRL_LOCALMEM_RESET                      F(6 : 6)
>> +#define MISC_CTRL_LOCALMEM_RESET_RESET                0
>> +#define MISC_CTRL_LOCALMEM_RESET_NORMAL               1
>> +
>> +#define CURRENT_GATE                                  0x000040
>> +#define CURRENT_GATE_MCLK                             F(15 : 14)
>> +#define CURRENT_GATE_CSC                              F(4 : 4)
>> +#define CURRENT_GATE_CSC_OFF                          0
>> +#define CURRENT_GATE_CSC_ON                           1
>> +#define CURRENT_GATE_DE                               F(3 : 3)
>> +#define CURRENT_GATE_DE_OFF                           0
>> +#define CURRENT_GATE_DE_ON                            1
>> +#define CURRENT_GATE_DISPLAY                          F(2 : 2)
>> +#define CURRENT_GATE_DISPLAY_OFF                      0
>> +#define CURRENT_GATE_DISPLAY_ON                       1
>> +#define CURRENT_GATE_LOCALMEM                         F(1 : 1)
>> +#define CURRENT_GATE_LOCALMEM_OFF                     0
>> +#define CURRENT_GATE_LOCALMEM_ON                      1
>> +#define CURRENT_GATE_DMA                              F(0 : 0)
>> +#define CURRENT_GATE_DMA_OFF                          0
>> +#define CURRENT_GATE_DMA_ON                           1
>> +
>> +#define MODE0_GATE                                    0x000044
>> +#define MODE1_GATE                                    0x000048
>> +#define POWER_MODE_CTRL                               0x00004C
>> +
>> +#define POWER_MODE_CTRL_OSC_INPUT                     F(3 : 3)
>> +#define POWER_MODE_CTRL_OSC_INPUT_OFF                 0
>> +#define POWER_MODE_CTRL_OSC_INPUT_ON                  1
>> +#define POWER_MODE_CTRL_ACPI                          F(2 : 2)
>> +#define POWER_MODE_CTRL_ACPI_OFF                      0
>> +#define POWER_MODE_CTRL_ACPI_ON                       1
>> +#define POWER_MODE_CTRL_MODE                          F(1 : 0)
>> +#define POWER_MODE_CTRL_MODE_MODE0                    0
>> +#define POWER_MODE_CTRL_MODE_MODE1                    1
>> +#define POWER_MODE_CTRL_MODE_SLEEP                    2
>> +
>> +#define PANEL_PLL_CTRL                                0x00005C
>> +#define PANEL_PLL_CTRL_BYPASS                         F(18 : 18)
>> +#define PANEL_PLL_CTRL_BYPASS_OFF                     0
>> +#define PANEL_PLL_CTRL_BYPASS_ON                      1
>> +#define PANEL_PLL_CTRL_POWER                          F(17 : 17)
>> +#define PANEL_PLL_CTRL_POWER_OFF                      0
>> +#define PANEL_PLL_CTRL_POWER_ON                       1
>> +#define PANEL_PLL_CTRL_INPUT                          F(16 : 16)
>> +#define PANEL_PLL_CTRL_INPUT_OSC                      0
>> +#define PANEL_PLL_CTRL_INPUT_TESTCLK                  1
>> +
>> +#define PANEL_PLL_CTRL_POD                        F(15 : 14)
>> +#define PANEL_PLL_CTRL_OD                         F(13 : 12)
>> +
>> +#define PANEL_PLL_CTRL_N                              F(11 : 8)
>> +#define PANEL_PLL_CTRL_M                              F(7 : 0)
>> +
>> +#define CRT_PLL_CTRL                                  0x000060
>> +/* Video Control */
>> +
>> +#define VIDEO_DISPLAY_CTRL                              0x080040
>> +#define VIDEO_DISPLAY_CTRL_PLANE                        F(2 : 2)
>> +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE                0
>> +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE                 1
>> +
>> +/* Video Alpha Control */
>> +
>> +#define VIDEO_ALPHA_DISPLAY_CTRL                        0x080080
>> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE                  F(2 : 2)
>> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE          0
>> +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE           1
>> +
>> +/* Panel Cursor Control */
>> +#define ALPHA_DISPLAY_CTRL                            0x080100
>> +#define ALPHA_DISPLAY_CTRL_PLANE                      F(2 : 2)
>> +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE              0
>> +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE               1
>> +
>> +/* CRT Graphics Control */
>> +#define CRT_DISPLAY_CTRL                              0x080200
>> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK              F(31 : 27)
>> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE      0
>> +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE       0x1F
>> +
>> +/* register definition */
>> +#define CRT_DISPLAY_CTRL_DPMS                         F(31 : 30)
>> +#define CRT_DISPLAY_CTRL_DPMS_0                       0
>> +#define CRT_DISPLAY_CTRL_DPMS_1                       1
>> +#define CRT_DISPLAY_CTRL_DPMS_2                       2
>> +#define CRT_DISPLAY_CTRL_DPMS_3                       3
>> +
>> +/* register definition */
>> +#define CRT_DISPLAY_CTRL_CRTSELECT                    F(25 : 25)
>> +#define CRT_DISPLAY_CTRL_CRTSELECT_VGA                0
>> +#define CRT_DISPLAY_CTRL_CRTSELECT_CRT                1
>> +
>> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE                  F(14 : 14)
>> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH      0
>> +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW       1
>> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE                  F(13 : 13)
>> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH      0
>> +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW       1
>> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE                  F(12 : 12)
>> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH      0
>> +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW       1
>> +#define CRT_DISPLAY_CTRL_BLANK                        F(10 : 10)
>> +#define CRT_DISPLAY_CTRL_BLANK_OFF                    0
>> +#define CRT_DISPLAY_CTRL_BLANK_ON                     1
>> +#define CRT_DISPLAY_CTRL_TIMING                       F(8 : 8)
>> +#define CRT_DISPLAY_CTRL_TIMING_DISABLE               0
>> +#define CRT_DISPLAY_CTRL_TIMING_ENABLE                1
>> +#define CRT_DISPLAY_CTRL_PLANE                        F(2 : 2)
>> +#define CRT_DISPLAY_CTRL_PLANE_DISABLE                0
>> +#define CRT_DISPLAY_CTRL_PLANE_ENABLE                 1
>> +#define CRT_DISPLAY_CTRL_FORMAT                       F(1 : 0)
>> +#define CRT_DISPLAY_CTRL_FORMAT_8                     0
>> +#define CRT_DISPLAY_CTRL_FORMAT_16                    1
>> +#define CRT_DISPLAY_CTRL_FORMAT_32                    2
>> +#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK           0xFF000200
>> +
>> +#define CRT_FB_ADDRESS                                0x080204
>> +#define CRT_FB_ADDRESS_STATUS                         F(31 : 31)
>> +#define CRT_FB_ADDRESS_STATUS_CURRENT                 0
>> +#define CRT_FB_ADDRESS_STATUS_PENDING                 1
>> +#define CRT_FB_ADDRESS_EXT                            F(27 : 27)
>> +#define CRT_FB_ADDRESS_EXT_LOCAL                      0
>> +#define CRT_FB_ADDRESS_EXT_EXTERNAL                   1
>> +#define CRT_FB_ADDRESS_ADDRESS                        F(25 : 0)
>> +
>> +#define CRT_FB_WIDTH                                  0x080208
>> +#define CRT_FB_WIDTH_WIDTH                            F(29 : 16)
>> +#define CRT_FB_WIDTH_OFFSET                           F(13 : 0)
>> +
>> +#define CRT_HORIZONTAL_TOTAL                          0x08020C
>> +#define CRT_HORIZONTAL_TOTAL_TOTAL                    F(27 : 16)
>> +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END              F(11 : 0)
>> +
>> +#define CRT_HORIZONTAL_SYNC                           0x080210
>> +#define CRT_HORIZONTAL_SYNC_WIDTH                     F(23 : 16)
>> +#define CRT_HORIZONTAL_SYNC_START                     F(11 : 0)
>> +
>> +#define CRT_VERTICAL_TOTAL                            0x080214
>> +#define CRT_VERTICAL_TOTAL_TOTAL                      F(26 : 16)
>> +#define CRT_VERTICAL_TOTAL_DISPLAY_END                F(10 : 0)
>> +
>> +#define CRT_VERTICAL_SYNC                             0x080218
>> +#define CRT_VERTICAL_SYNC_HEIGHT                      F(21 : 16)
>> +#define CRT_VERTICAL_SYNC_START                       F(10 : 0)
>> +
>> +/* Auto Centering */
>> +#define CRT_AUTO_CENTERING_TL                     0x080280
>> +#define CRT_AUTO_CENTERING_TL_TOP                 F(26 : 16)
>> +#define CRT_AUTO_CENTERING_TL_LEFT                F(10 : 0)
>> +
>> +#define CRT_AUTO_CENTERING_BR                     0x080284
>> +#define CRT_AUTO_CENTERING_BR_BOTTOM              F(26 : 16)
>> +#define CRT_AUTO_CENTERING_BR_RIGHT               F(10 : 0)
>> +
>> +/* register to control panel output */
>> +#define DISPLAY_CONTROL_HISILE                    0x80288
>> +
>> +/* register and values for PLL control */
>> +#define CRT_PLL1_HS                            0x802a8
>> +#define CRT_PLL1_HS_25MHZ                     0x23d40f02
>> +#define CRT_PLL1_HS_40MHZ                     0x23940801
>> +#define CRT_PLL1_HS_65MHZ                     0x23940d01
>> +#define CRT_PLL1_HS_78MHZ                     0x23540F82
>> +#define CRT_PLL1_HS_74MHZ                     0x23941dc2
>> +#define CRT_PLL1_HS_80MHZ                     0x23941001
>> +#define CRT_PLL1_HS_80MHZ_1152            0x23540fc2
>> +#define CRT_PLL1_HS_108MHZ                    0x23b41b01
>> +#define CRT_PLL1_HS_162MHZ                    0x23480681
>> +#define CRT_PLL1_HS_148MHZ                    0x23541dc2
>> +#define CRT_PLL1_HS_193MHZ                    0x234807c1
>> +
>> +#define CRT_PLL2_HS                         0x802ac
>> +#define CRT_PLL2_HS_25MHZ                     0x206B851E
>> +#define CRT_PLL2_HS_40MHZ                     0x30000000
>> +#define CRT_PLL2_HS_65MHZ                     0x40000000
>> +#define CRT_PLL2_HS_78MHZ                     0x50E147AE
>> +#define CRT_PLL2_HS_74MHZ                     0x602B6AE7
>> +#define CRT_PLL2_HS_80MHZ                     0x70000000
>> +#define CRT_PLL2_HS_108MHZ                    0x80000000
>> +#define CRT_PLL2_HS_162MHZ                    0xA0000000
>> +#define CRT_PLL2_HS_148MHZ                    0xB0CCCCCD
>> +#define CRT_PLL2_HS_193MHZ                    0xC0872B02
>> +
>> +/* Palette RAM */
>> +
>> +/* Panel Palette register starts at 0x080400 ~ 0x0807FC */
>> +#define PANEL_PALETTE_RAM                             0x080400
>> +
>> +/* Panel Palette register starts at 0x080C00 ~ 0x080FFC */
>> +#define CRT_PALETTE_RAM                               0x080C00
>> +
>> +#define DMA_ABORT_INTERRUPT                             0x0D0020
>> +#define DMA_ABORT_INTERRUPT_ABORT_1                     F(5 : 5)
>> +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE              0
>> +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT               1
>> +
>> +/* cursor control */
>> +#define HWC_ADDRESS                         0x0
>> +#define HWC_ADDRESS_ENABLE                  F(31 : 31)
>> +#define HWC_ADDRESS_ENABLE_DISABLE          0
>> +#define HWC_ADDRESS_ENABLE_ENABLE           1
>> +#define HWC_ADDRESS_EXT                     F(27 : 27)
>> +#define HWC_ADDRESS_EXT_LOCAL               0
>> +#define HWC_ADDRESS_EXT_EXTERNAL            1
>> +#define HWC_ADDRESS_CS                      F(26 : 26)
>> +#define HWC_ADDRESS_CS_0                    0
>> +#define HWC_ADDRESS_CS_1                    1
>> +#define HWC_ADDRESS_ADDRESS                 F(25 : 0)
>> +
>> +#define HWC_LOCATION                        0x4
>> +#define HWC_LOCATION_Y                      F(26 : 16)
>> +#define HWC_LOCATION_LEFT                   F(11 : 11)
>> +#define HWC_LOCATION_LEFT_INSIDE            0
>> +#define HWC_LOCATION_LEFT_OUTSIDE           1
>> +#define HWC_LOCATION_X                      F(10 : 0)
>> +
>> +#define HWC_COLOR_12                        0x8
>> +
>> +#define HWC_COLOR_3                         0xC
>> +
>> +/* accelate 2d graphic */
>> +#define DE_SOURCE                                       0x0
>> +#define DE_SOURCE_WRAP                                  F(31 : 31)
>> +#define DE_SOURCE_WRAP_DISABLE                          0
>> +#define DE_SOURCE_WRAP_ENABLE                           1
>> +#define DE_SOURCE_X_K1                                  F(29 : 16)
>> +#define DE_SOURCE_Y_K2                                  F(15 : 0)
>> +#define DE_SOURCE_X_K1_MONO                             F(20 : 16)
>> +
>> +#define DE_DESTINATION                                  0x4
>> +#define DE_DESTINATION_WRAP                             F(31 : 31)
>> +#define DE_DESTINATION_WRAP_DISABLE                     0
>> +#define DE_DESTINATION_WRAP_ENABLE                      1
>> +#define DE_DESTINATION_X                                F(28 : 16)
>> +#define DE_DESTINATION_Y                                F(15 : 0)
>> +
>> +#define DE_DIMENSION                                    0x8
>> +#define DE_DIMENSION_X                                  F(28 : 16)
>> +#define DE_DIMENSION_Y_ET                               F(15 : 0)
>> +
>> +#define DE_CONTROL                                      0xC
>> +#define DE_CONTROL_STATUS                               F(31 : 31)
>> +#define DE_CONTROL_STATUS_STOP                          0
>> +#define DE_CONTROL_STATUS_START                         1
>> +#define DE_CONTROL_PATTERN                              F(30 : 30)
>> +#define DE_CONTROL_PATTERN_MONO                         0
>> +#define DE_CONTROL_PATTERN_COLOR                        1
>> +#define DE_CONTROL_UPDATE_DESTINATION_X                 F(29 : 29)
>> +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE         0
>> +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE          1
>> +#define DE_CONTROL_QUICK_START                          F(28 : 28)
>> +#define DE_CONTROL_QUICK_START_DISABLE                  0
>> +#define DE_CONTROL_QUICK_START_ENABLE                   1
>> +#define DE_CONTROL_DIRECTION                            F(27 : 27)
>> +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT              0
>> +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT              1
>> +#define DE_CONTROL_MAJOR                                F(26 : 26)
>> +#define DE_CONTROL_MAJOR_X                              0
>> +#define DE_CONTROL_MAJOR_Y                              1
>> +#define DE_CONTROL_STEP_X                               F(25 : 25)
>> +#define DE_CONTROL_STEP_X_POSITIVE                      1
>> +#define DE_CONTROL_STEP_X_NEGATIVE                      0
>> +#define DE_CONTROL_STEP_Y                               F(24 : 24)
>> +#define DE_CONTROL_STEP_Y_POSITIVE                      1
>> +#define DE_CONTROL_STEP_Y_NEGATIVE                      0
>> +#define DE_CONTROL_STRETCH                              F(23 : 23)
>> +#define DE_CONTROL_STRETCH_DISABLE                      0
>> +#define DE_CONTROL_STRETCH_ENABLE                       1
>> +#define DE_CONTROL_HOST                                 F(22 : 22)
>> +#define DE_CONTROL_HOST_COLOR                           0
>> +#define DE_CONTROL_HOST_MONO                            1
>> +#define DE_CONTROL_LAST_PIXEL                           F(21 : 21)
>> +#define DE_CONTROL_LAST_PIXEL_OFF                       0
>> +#define DE_CONTROL_LAST_PIXEL_ON                        1
>> +#define DE_CONTROL_COMMAND                              F(20 : 16)
>> +#define DE_CONTROL_COMMAND_BITBLT                       0
>> +#define DE_CONTROL_COMMAND_RECTANGLE_FILL               1
>> +#define DE_CONTROL_COMMAND_DE_TILE                      2
>> +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL               3
>> +#define DE_CONTROL_COMMAND_ALPHA_BLEND                  4
>> +#define DE_CONTROL_COMMAND_RLE_STRIP                    5
>> +#define DE_CONTROL_COMMAND_SHORT_STROKE                 6
>> +#define DE_CONTROL_COMMAND_LINE_DRAW                    7
>> +#define DE_CONTROL_COMMAND_HOST_WRITE                   8
>> +#define DE_CONTROL_COMMAND_HOST_READ                    9
>> +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP         10
>> +#define DE_CONTROL_COMMAND_ROTATE                       11
>> +#define DE_CONTROL_COMMAND_FONT                         12
>> +#define DE_CONTROL_COMMAND_TEXTURE_LOAD                 15
>> +#define DE_CONTROL_ROP_SELECT                           F(15 : 15)
>> +#define DE_CONTROL_ROP_SELECT_ROP3                      0
>> +#define DE_CONTROL_ROP_SELECT_ROP2                      1
>> +#define DE_CONTROL_ROP2_SOURCE                          F(14 : 14)
>> +#define DE_CONTROL_ROP2_SOURCE_BITMAP                   0
>> +#define DE_CONTROL_ROP2_SOURCE_PATTERN                  1
>> +#define DE_CONTROL_MONO_DATA                            F(13 : 12)
>> +#define DE_CONTROL_MONO_DATA_NOT_PACKED                 0
>> +#define DE_CONTROL_MONO_DATA_8_PACKED                   1
>> +#define DE_CONTROL_MONO_DATA_16_PACKED                  2
>> +#define DE_CONTROL_MONO_DATA_32_PACKED                  3
>> +#define DE_CONTROL_REPEAT_ROTATE                        F(11 : 11)
>> +#define DE_CONTROL_REPEAT_ROTATE_DISABLE                0
>> +#define DE_CONTROL_REPEAT_ROTATE_ENABLE                 1
>> +#define DE_CONTROL_TRANSPARENCY_MATCH                   F(10 : 10)
>> +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE            0
>> +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT       1
>> +#define DE_CONTROL_TRANSPARENCY_SELECT                  F(9 : 9)
>> +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE           0
>> +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION      1
>> +#define DE_CONTROL_TRANSPARENCY                         F(8 : 8)
>> +#define DE_CONTROL_TRANSPARENCY_DISABLE                 0
>> +#define DE_CONTROL_TRANSPARENCY_ENABLE                  1
>> +#define DE_CONTROL_ROP                                  F(7 : 0)
>> +
>> +/* Pseudo fields. */
>> +
>> +#define DE_CONTROL_SHORT_STROKE_DIR                     F(27 : 24)
>> +#define DE_CONTROL_SHORT_STROKE_DIR_225                 0
>> +#define DE_CONTROL_SHORT_STROKE_DIR_135                 1
>> +#define DE_CONTROL_SHORT_STROKE_DIR_315                 2
>> +#define DE_CONTROL_SHORT_STROKE_DIR_45                  3
>> +#define DE_CONTROL_SHORT_STROKE_DIR_270                 4
>> +#define DE_CONTROL_SHORT_STROKE_DIR_90                  5
>> +#define DE_CONTROL_SHORT_STROKE_DIR_180                 8
>> +#define DE_CONTROL_SHORT_STROKE_DIR_0                   10
>> +#define DE_CONTROL_ROTATION                             F(25 : 24)
>> +#define DE_CONTROL_ROTATION_0                           0
>> +#define DE_CONTROL_ROTATION_270                         1
>> +#define DE_CONTROL_ROTATION_90                          2
>> +#define DE_CONTROL_ROTATION_180                         3
>> +
>> +#define DE_PITCH                                        0x000010
>> +#define DE_PITCH_DESTINATION                            F(28 : 16)
>> +#define DE_PITCH_SOURCE                                 F(12 : 0)
>> +
>> +#define DE_FOREGROUND                                   0x000014
>> +
>> +#define DE_BACKGROUND                                   0x000018
>> +
>> +#define DE_STRETCH_FORMAT                               0x00001C
>> +#define DE_STRETCH_FORMAT_PATTERN_XY                    F(30 : 30)
>> +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL             0
>> +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE          1
>> +#define DE_STRETCH_FORMAT_PATTERN_Y                     F(29 : 27)
>> +#define DE_STRETCH_FORMAT_PATTERN_X                     F(25 : 23)
>> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT                  F(21 : 20)
>> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8                0
>> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16               1
>> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32               2
>> +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24               3
>> +
>> +#define DE_STRETCH_FORMAT_ADDRESSING                    F(19 : 16)
>> +#define DE_STRETCH_FORMAT_ADDRESSING_XY                 0
>> +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR             15
>> +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT                 F(11 : 0)
>> +
>> +#define DE_COLOR_COMPARE                                0x000020
>> +
>> +#define DE_COLOR_COMPARE_MASK                           0x000024
>> +
>> +#define DE_MASKS                                        0x000028
>> +
>> +#define DE_CLIP_TL                                      0x00002C
>> +
>> +#define DE_CLIP_BR                                      0x000030
>> +
>> +#define DE_WINDOW_WIDTH                                 0x00003C
>> +#define DE_WINDOW_WIDTH_DESTINATION                     F(28 : 16)
>> +#define DE_WINDOW_WIDTH_SOURCE                          F(12 : 0)
>> +
>> +#define DE_WINDOW_SOURCE_BASE                           0x000040
>> +#define DE_WINDOW_SOURCE_BASE_EXT                       F(27 : 27)
>> +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL                 0
>> +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL              1
>> +#define DE_WINDOW_SOURCE_BASE_CS                        F(26 : 26)
>> +#define DE_WINDOW_SOURCE_BASE_CS_0                      0
>> +#define DE_WINDOW_SOURCE_BASE_CS_1                      1
>> +#define DE_WINDOW_SOURCE_BASE_ADDRESS                   F(25 : 0)
>> +
>> +#define DE_WINDOW_DESTINATION_BASE                      0x000044
>> +#define DE_WINDOW_DESTINATION_BASE_EXT                  F(27 : 27)
>> +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL            0
>> +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL         1
>> +#define DE_WINDOW_DESTINATION_BASE_CS                   F(26 : 26)
>> +#define DE_WINDOW_DESTINATION_BASE_CS_0                 0
>> +#define DE_WINDOW_DESTINATION_BASE_CS_1                 1
>> +#define DE_WINDOW_DESTINATION_BASE_ADDRESS              F(25 : 0)
>> +
>> +/* Internal macros */
>> +#define _F_START(f)             (0 ? f)
>> +#define _F_END(f)               (1 ? f)
> Why do you even need these ?
>
  f is a subfiled of a register,
  eg:  f(18:15) means bit15-18
  so, _F_START(18:15) = 18, _F_END(18:15) = 15


>> +#define _F_SIZE(f)              (1 + _F_END(f) - _F_START(f))
>> +#define _F_MASK(f)              (((1 << _F_SIZE(f)) - 1) << _F_START(f))
>> +#define _F_NORMALIZE(v, f)      (((v) & _F_MASK(f)) >> _F_START(f))
>> +#define _F_DENORMALIZE(v, f)    (((v) << _F_START(f)) & _F_MASK(f))
>> +
>> +/* Global macros */
>> +#define FIELD_GET(x, reg, field) \
>> +( \
>> +       _F_NORMALIZE((x), reg ## _ ## field) \
>> +)
>> +
>> +#define FIELD_SET(x, reg, field, value) \
>> +( \
>> +       (x & ~_F_MASK(reg ## _ ## field)) \
>> +       | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
>> +)
>> +
>> +#define FIELD_VALUE(x, reg, field, value) \
>> +( \
>> +       (x & ~_F_MASK(reg ## _ ## field)) \
>> +       | _F_DENORMALIZE(value, reg ## _ ## field) \
>> +)
>> +
>> +#define FIELD_CLEAR(reg, field) \
>> +( \
>> +       ~_F_MASK(reg ## _ ## field) \
>> +)
>> +
>> +/* Field Macros */
>> +#define FIELD_START(field)              (0 ? field)
>> +#define FIELD_END(field)                (1 ? field)
> Same goes here ?

Looks define twice.

>
>> +#define FIELD_SIZE(field) \
>> +       (1 + FIELD_END(field) - FIELD_START(field))
>> +#define FIELD_MASK(field) \
>> +       (((1 << (FIELD_SIZE(field) - 1)) |\
>> +       ((1 << (FIELD_SIZE(field) - 1)) - 1)) << FIELD_START(field))
>> +#define FIELD_NORMALIZE(reg, field) \
>> +       (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
>> +#define FIELD_DENORMALIZE(field, value) \
>> +       (((value) << FIELD_START(field)) & FIELD_MASK(field))
>> +#define RGB(r, g, b) \
>> +( \
>> +       (unsigned long)(((r) << 16) | ((g) << 8) | (b)) \
>> +)
>> +
>> +#define PEEK32(addr) readl((addr) + mmio_bmc_vga)
>> +#define POKE32(addr, data) writel((data), (addr) + mmio_bmc_vga)
>> +extern unsigned char __iomem *mmio_bmc_vga;
>> +
>> +#define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
>> +
>> +#define MB(x) ((x) << 20)
>> +
>> +void set_power_mode(unsigned int power_mode);
>> +void set_current_gate(unsigned int gate);
>> +
> In general you want to have your symbols (be that macros or functions)
> prefixed appropriatelly, otherwise they will clash with others in the
> kernel.
> A handful of the internal/field macros seems like they should not
> exist and/or there's an existing kernel equivalent. I would suggest
> looking at other DRM drivers and how they deal with the above.

OK, i will check again and then fix it. thanks for your comment.

>
> Regards,
> Emil
>
> .
>


-- 
Regards,
Rongrong
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver.
  2016-03-01  8:07     ` Rongrong Zou
@ 2016-03-09 15:12       ` Emil Velikov
  0 siblings, 0 replies; 11+ messages in thread
From: Emil Velikov @ 2016-03-09 15:12 UTC (permalink / raw)
  To: Rongrong Zou, Archit Taneja
  Cc: z.liuxinliang, linuxarm, ML dri-devel, lijianhua

Hi Rongrong Zou,

With the next revision sent out, I've missed out that you had
questions in here :-)

>> On 29 February 2016 at 00:58, lijianhua <jueying0518@gmail.com> wrote:
>>> +static struct drm_driver hibmc_driver = {

>>> +       .date                   = "20151218",
>>
>> Afaict this date is mostly unused, then again it's quite off :-)
>
> Do you mean i should better remove this property?
>
Just update it ? Then again many other drivers haven't updated theirs,
in a long time so I'm not sure how useful the .date field is to begin
with.
Ah, yes. It serves mostly to be send back to userspace via the
DRM_VERSION ioctl.

If we were to break the ABI, this is one of the things that will go :-)

>>> +static int hibmc_pm_resume(struct device *dev)
>>> +{
>>> +       struct pci_dev *pdev = to_pci_dev(dev);
>>> +       struct drm_device *drm_dev = pci_get_drvdata(pdev);
>>> +       struct hibmc_private *hiprivate = drm_dev->dev_private;
>>> +
>>> +       drm_helper_resume_force_mode(drm_dev);
>>> +
>>> +       if (hiprivate->fbdev.initialized) {
>>> +               console_lock();
>>> +               fb_set_suspend(hiprivate->fbdev.helper.fbdev, 0);
These should be using the drm fb helpers from Archit - see commit
0843010bbd6 "drm/virtio: Use new drm_fb_helper functions" and alike.

Which brings the question:

Archit,
Is it too much to ask to create a cocci script for the fb helper
refactoring ? One that warns/updates cases that are using the fb
functions directly, as opposed to the helper. Otherwise things are
bound to get confused. Like in the radeon driver, which uses both fb
and the helper.

I believe that one should even remove the relevant select statements
from the driver Kconfigs (FB_CFB* and FB_SYS*), correct ?

Just a humble request, thanks.

>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h

>>> +/* Vendor and Device id for HISILICON Graphics chip*/
>>> +#define PCI_VENDOR_ID_HIS 0x19e5
>>> +#define PCI_DEVID_HS_VGA 0x1711
>>> +
>
> I wonder where to place the 2 macros, any suggusetions, thanks.
>
include/linux/pci_ids.h looks like the place ?

Personally, I think that the above can be done with follow up patches.
Then again it's not my call to make.

Thanks
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-03-09 15:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-29  0:58 [PATCH 0/7] Add DRM driver for Hisilicon hi1710 lijianhua
2016-02-29  0:58 ` [PATCH 1/7] drm/hisilicon:Add hisilicon hibmc master driver lijianhua
2016-02-29  9:40   ` Emil Velikov
2016-03-01  8:07     ` Rongrong Zou
2016-03-09 15:12       ` Emil Velikov
2016-02-29  0:58 ` [PATCH 2/7] drm/hisilicon:Add plane for DE lijianhua
2016-02-29  0:58 ` [PATCH 3/7] drm/hisilicon:Add crtc " lijianhua
2016-02-29  0:58 ` [PATCH 4/7] drm/hisilicon:Add encoder for VDAC lijianhua
2016-02-29  0:58 ` [PATCH 5/7] drm/hisilicon:Add connector " lijianhua
2016-02-29  0:58 ` [PATCH 6/7] drm/hisilicon:Add fbdev lijianhua
2016-02-29  0:58 ` [PATCH 7/7] MAINTAINERS:Add maintainer for hibmc DRM driver lijianhua

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.