Add hibmc DRM master driver for hi1710 which used in arm64 board. Signed-off-by: lijianhua <jueying0518 at 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 at 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