diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 17:29:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 17:29:08 -0700 |
commit | 73154383f02998fdd6a1f26c7ef33bfc3785a101 (patch) | |
tree | 85a4c10cf32172b99aed01e95ded7269afcc9d7d /drivers | |
parent | 362ed48dee509abe24cf84b7e137c7a29a8f4d2d (diff) | |
parent | ca0dde97178e75ed1370b8616326f5496a803d65 (diff) | |
download | linux-73154383f02998fdd6a1f26c7ef33bfc3785a101.tar.bz2 |
Merge branch 'akpm' (incoming from Andrew)
Merge first batch of fixes from Andrew Morton:
- A couple of kthread changes
- A few minor audit patches
- A number of fbdev patches. Florian remains AWOL so I'm picking up
some of these.
- A few kbuild things
- ocfs2 updates
- Almost all of the MM queue
(And in the meantime, I already have the second big batch from Andrew
pending in my mailbox ;^)
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (149 commits)
memcg: take reference before releasing rcu_read_lock
mem hotunplug: fix kfree() of bootmem memory
mmKconfig: add an option to disable bounce
mm, nobootmem: do memset() after memblock_reserve()
mm, nobootmem: clean-up of free_low_memory_core_early()
fs/buffer.c: remove unnecessary init operation after allocating buffer_head.
numa, cpu hotplug: change links of CPU and node when changing node number by onlining CPU
mm: fix memory_hotplug.c printk format warning
mm: swap: mark swap pages writeback before queueing for direct IO
swap: redirty page if page write fails on swap file
mm, memcg: give exiting processes access to memory reserves
thp: fix huge zero page logic for page with pfn == 0
memcg: avoid accessing memcg after releasing reference
fs: fix fsync() error reporting
memblock: fix missing comment of memblock_insert_region()
mm: Remove unused parameter of pages_correctly_reserved()
firmware, memmap: fix firmware_map_entry leak
mm/vmstat: add note on safety of drain_zonestat
mm: thp: add split tail pages to shrink page list in page reclaim
mm: allow for outstanding swap writeback accounting
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/cpu.c | 25 | ||||
-rw-r--r-- | drivers/base/memory.c | 49 | ||||
-rw-r--r-- | drivers/base/node.c | 8 | ||||
-rw-r--r-- | drivers/firmware/memmap.c | 9 | ||||
-rw-r--r-- | drivers/video/Kconfig | 9 | ||||
-rw-r--r-- | drivers/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/console/fbcon_cw.c | 3 | ||||
-rw-r--r-- | drivers/video/ep93xx-fb.c | 18 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_mipi_dsi.c | 8 | ||||
-rw-r--r-- | drivers/video/hyperv_fb.c | 829 | ||||
-rw-r--r-- | drivers/video/matrox/matroxfb_maven.c | 16 | ||||
-rw-r--r-- | drivers/video/mmp/hw/mmp_ctrl.h | 479 |
12 files changed, 919 insertions, 535 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index d8c7f3ee6e19..3d48fc887ef4 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -25,6 +25,15 @@ EXPORT_SYMBOL_GPL(cpu_subsys); static DEFINE_PER_CPU(struct device *, cpu_sys_devices); #ifdef CONFIG_HOTPLUG_CPU +static void change_cpu_under_node(struct cpu *cpu, + unsigned int from_nid, unsigned int to_nid) +{ + int cpuid = cpu->dev.id; + unregister_cpu_under_node(cpuid, from_nid); + register_cpu_under_node(cpuid, to_nid); + cpu->node_id = to_nid; +} + static ssize_t show_online(struct device *dev, struct device_attribute *attr, char *buf) @@ -39,17 +48,29 @@ static ssize_t __ref store_online(struct device *dev, const char *buf, size_t count) { struct cpu *cpu = container_of(dev, struct cpu, dev); + int cpuid = cpu->dev.id; + int from_nid, to_nid; ssize_t ret; cpu_hotplug_driver_lock(); switch (buf[0]) { case '0': - ret = cpu_down(cpu->dev.id); + ret = cpu_down(cpuid); if (!ret) kobject_uevent(&dev->kobj, KOBJ_OFFLINE); break; case '1': - ret = cpu_up(cpu->dev.id); + from_nid = cpu_to_node(cpuid); + ret = cpu_up(cpuid); + + /* + * When hot adding memory to memoryless node and enabling a cpu + * on the node, node number of the cpu may internally change. + */ + to_nid = cpu_to_node(cpuid); + if (from_nid != to_nid) + change_cpu_under_node(cpu, from_nid, to_nid); + if (!ret) kobject_uevent(&dev->kobj, KOBJ_ONLINE); break; diff --git a/drivers/base/memory.c b/drivers/base/memory.c index a51007b79032..14f8a6954da0 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -93,16 +93,6 @@ int register_memory(struct memory_block *memory) return error; } -static void -unregister_memory(struct memory_block *memory) -{ - BUG_ON(memory->dev.bus != &memory_subsys); - - /* drop the ref. we got in remove_memory_block() */ - kobject_put(&memory->dev.kobj); - device_unregister(&memory->dev); -} - unsigned long __weak memory_block_size_bytes(void) { return MIN_MEMORY_BLOCK_SIZE; @@ -217,8 +207,7 @@ int memory_isolate_notify(unsigned long val, void *v) * The probe routines leave the pages reserved, just as the bootmem code does. * Make sure they're still that way. */ -static bool pages_correctly_reserved(unsigned long start_pfn, - unsigned long nr_pages) +static bool pages_correctly_reserved(unsigned long start_pfn) { int i, j; struct page *page; @@ -266,7 +255,7 @@ memory_block_action(unsigned long phys_index, unsigned long action, int online_t switch (action) { case MEM_ONLINE: - if (!pages_correctly_reserved(start_pfn, nr_pages)) + if (!pages_correctly_reserved(start_pfn)) return -EBUSY; ret = online_pages(start_pfn, nr_pages, online_type); @@ -637,8 +626,28 @@ static int add_memory_section(int nid, struct mem_section *section, return ret; } -int remove_memory_block(unsigned long node_id, struct mem_section *section, - int phys_device) +/* + * need an interface for the VM to add new memory regions, + * but without onlining it. + */ +int register_new_memory(int nid, struct mem_section *section) +{ + return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); +} + +#ifdef CONFIG_MEMORY_HOTREMOVE +static void +unregister_memory(struct memory_block *memory) +{ + BUG_ON(memory->dev.bus != &memory_subsys); + + /* drop the ref. we got in remove_memory_block() */ + kobject_put(&memory->dev.kobj); + device_unregister(&memory->dev); +} + +static int remove_memory_block(unsigned long node_id, + struct mem_section *section, int phys_device) { struct memory_block *mem; @@ -661,15 +670,6 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, return 0; } -/* - * need an interface for the VM to add new memory regions, - * but without onlining it. - */ -int register_new_memory(int nid, struct mem_section *section) -{ - return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); -} - int unregister_memory_section(struct mem_section *section) { if (!present_section(section)) @@ -677,6 +677,7 @@ int unregister_memory_section(struct mem_section *section) return remove_memory_block(0, section, 0); } +#endif /* CONFIG_MEMORY_HOTREMOVE */ /* * offline one memory block. If the memory block has been offlined, do nothing. diff --git a/drivers/base/node.c b/drivers/base/node.c index fac124a7e1c5..7616a77ca322 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -7,6 +7,7 @@ #include <linux/mm.h> #include <linux/memory.h> #include <linux/vmstat.h> +#include <linux/notifier.h> #include <linux/node.h> #include <linux/hugetlb.h> #include <linux/compaction.h> @@ -683,8 +684,11 @@ static int __init register_node_type(void) ret = subsys_system_register(&node_subsys, cpu_root_attr_groups); if (!ret) { - hotplug_memory_notifier(node_memory_callback, - NODE_CALLBACK_PRI); + static struct notifier_block node_memory_callback_nb = { + .notifier_call = node_memory_callback, + .priority = NODE_CALLBACK_PRI, + }; + register_hotmemory_notifier(&node_memory_callback_nb); } /* diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 0b5b5f619c75..e2e04b007e15 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -114,12 +114,9 @@ static void __meminit release_firmware_map_entry(struct kobject *kobj) * map_entries_bootmem here, and deleted from &map_entries in * firmware_map_remove_entry(). */ - if (firmware_map_find_entry(entry->start, entry->end, - entry->type)) { - spin_lock(&map_entries_bootmem_lock); - list_add(&entry->list, &map_entries_bootmem); - spin_unlock(&map_entries_bootmem_lock); - } + spin_lock(&map_entries_bootmem_lock); + list_add(&entry->list, &map_entries_bootmem); + spin_unlock(&map_entries_bootmem_lock); return; } diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 981c1c08c727..76be61701c97 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2440,6 +2440,15 @@ config FB_PUV3_UNIGFX Choose this option if you want to use the Unigfx device as a framebuffer device. Without the support of PCI & AGP. +config FB_HYPERV + tristate "Microsoft Hyper-V Synthetic Video support" + depends on FB && HYPERV + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This framebuffer driver supports Microsoft Hyper-V Synthetic Video. + source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e414378d6a51..7234e4a959e8 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -149,6 +149,7 @@ obj-$(CONFIG_FB_MSM) += msm/ obj-$(CONFIG_FB_NUC900) += nuc900fb.o obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o +obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 6a737827beb1..a93670ef7f89 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -27,7 +27,7 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute, { int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2; int width = (vc->vc_font.height + 7) >> 3; - u8 c, t = 0, msk = ~(0xff >> offset); + u8 c, msk = ~(0xff >> offset); for (i = 0; i < vc->vc_font.width; i++) { for (j = 0; j < width; j++) { @@ -40,7 +40,6 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute, c = ~c; src++; *dst++ = c; - t = c; } } } diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c index e06cd5d90c97..ee1ee5401544 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/ep93xx-fb.c @@ -419,7 +419,7 @@ static struct fb_ops ep93xxfb_ops = { .fb_mmap = ep93xxfb_mmap, }; -static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info) +static int ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info) { int i, fb_size = 0; @@ -441,7 +441,7 @@ static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info) return fb_size; } -static int __init ep93xxfb_alloc_videomem(struct fb_info *info) +static int ep93xxfb_alloc_videomem(struct fb_info *info) { struct ep93xx_fbi *fbi = info->par; char __iomem *virt_addr; @@ -627,19 +627,7 @@ static struct platform_driver ep93xxfb_driver = { .owner = THIS_MODULE, }, }; - -static int ep93xxfb_init(void) -{ - return platform_driver_register(&ep93xxfb_driver); -} - -static void __exit ep93xxfb_exit(void) -{ - platform_driver_unregister(&ep93xxfb_driver); -} - -module_init(ep93xxfb_init); -module_exit(ep93xxfb_exit); +module_platform_driver(ep93xxfb_driver); MODULE_DESCRIPTION("EP93XX Framebuffer Driver"); MODULE_ALIAS("platform:ep93xx-fb"); diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c index 3dd43ca2b95f..32e540600f99 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/exynos/exynos_mipi_dsi.c @@ -32,6 +32,7 @@ #include <linux/notifier.h> #include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> +#include <linux/err.h> #include <video/exynos_mipi_dsim.h> @@ -382,10 +383,9 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dsim->reg_base = devm_request_and_ioremap(&pdev->dev, res); - if (!dsim->reg_base) { - dev_err(&pdev->dev, "failed to remap io region\n"); - ret = -ENOMEM; + dsim->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dsim->reg_base)) { + ret = PTR_ERR(dsim->reg_base); goto error; } diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c new file mode 100644 index 000000000000..d4d2c5fe2488 --- /dev/null +++ b/drivers/video/hyperv_fb.c @@ -0,0 +1,829 @@ +/* + * Copyright (c) 2012, Microsoft Corporation. + * + * Author: + * Haiyang Zhang <haiyangz@microsoft.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + +/* + * Hyper-V Synthetic Video Frame Buffer Driver + * + * This is the driver for the Hyper-V Synthetic Video, which supports + * screen resolution up to Full HD 1920x1080 with 32 bit color on Windows + * Server 2012, and 1600x1200 with 16 bit color on Windows Server 2008 R2 + * or earlier. + * + * It also solves the double mouse cursor issue of the emulated video mode. + * + * The default screen resolution is 1152x864, which may be changed by a + * kernel parameter: + * video=hyperv_fb:<width>x<height> + * For example: video=hyperv_fb:1280x1024 + * + * Portrait orientation is also supported: + * For example: video=hyperv_fb:864x1152 + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/completion.h> +#include <linux/fb.h> +#include <linux/pci.h> + +#include <linux/hyperv.h> + + +/* Hyper-V Synthetic Video Protocol definitions and structures */ +#define MAX_VMBUS_PKT_SIZE 0x4000 + +#define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major)) +#define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0) +#define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2) + +#define SYNTHVID_DEPTH_WIN7 16 +#define SYNTHVID_DEPTH_WIN8 32 + +#define SYNTHVID_FB_SIZE_WIN7 (4 * 1024 * 1024) +#define SYNTHVID_WIDTH_MAX_WIN7 1600 +#define SYNTHVID_HEIGHT_MAX_WIN7 1200 + +#define SYNTHVID_FB_SIZE_WIN8 (8 * 1024 * 1024) + +#define PCI_VENDOR_ID_MICROSOFT 0x1414 +#define PCI_DEVICE_ID_HYPERV_VIDEO 0x5353 + + +enum pipe_msg_type { + PIPE_MSG_INVALID, + PIPE_MSG_DATA, + PIPE_MSG_MAX +}; + +struct pipe_msg_hdr { + u32 type; + u32 size; /* size of message after this field */ +} __packed; + + +enum synthvid_msg_type { + SYNTHVID_ERROR = 0, + SYNTHVID_VERSION_REQUEST = 1, + SYNTHVID_VERSION_RESPONSE = 2, + SYNTHVID_VRAM_LOCATION = 3, + SYNTHVID_VRAM_LOCATION_ACK = 4, + SYNTHVID_SITUATION_UPDATE = 5, + SYNTHVID_SITUATION_UPDATE_ACK = 6, + SYNTHVID_POINTER_POSITION = 7, + SYNTHVID_POINTER_SHAPE = 8, + SYNTHVID_FEATURE_CHANGE = 9, + SYNTHVID_DIRT = 10, + + SYNTHVID_MAX = 11 +}; + +struct synthvid_msg_hdr { + u32 type; + u32 size; /* size of this header + payload after this field*/ +} __packed; + + +struct synthvid_version_req { + u32 version; +} __packed; + +struct synthvid_version_resp { + u32 version; + u8 is_accepted; + u8 max_video_outputs; +} __packed; + +struct synthvid_vram_location { + u64 user_ctx; + u8 is_vram_gpa_specified; + u64 vram_gpa; +} __packed; + +struct synthvid_vram_location_ack { + u64 user_ctx; +} __packed; + +struct video_output_situation { + u8 active; + u32 vram_offset; + u8 depth_bits; + u32 width_pixels; + u32 height_pixels; + u32 pitch_bytes; +} __packed; + +struct synthvid_situation_update { + u64 user_ctx; + u8 video_output_count; + struct video_output_situation video_output[1]; +} __packed; + +struct synthvid_situation_update_ack { + u64 user_ctx; +} __packed; + +struct synthvid_pointer_position { + u8 is_visible; + u8 video_output; + s32 image_x; + s32 image_y; +} __packed; + + +#define CURSOR_MAX_X 96 +#define CURSOR_MAX_Y 96 +#define CURSOR_ARGB_PIXEL_SIZE 4 +#define CURSOR_MAX_SIZE (CURSOR_MAX_X * CURSOR_MAX_Y * CURSOR_ARGB_PIXEL_SIZE) +#define CURSOR_COMPLETE (-1) + +struct synthvid_pointer_shape { + u8 part_idx; + u8 is_argb; + u32 width; /* CURSOR_MAX_X at most */ + u32 height; /* CURSOR_MAX_Y at most */ + u32 hot_x; /* hotspot relative to upper-left of pointer image */ + u32 hot_y; + u8 data[4]; +} __packed; + +struct synthvid_feature_change { + u8 is_dirt_needed; + u8 is_ptr_pos_needed; + u8 is_ptr_shape_needed; + u8 is_situ_needed; +} __packed; + +struct rect { + s32 x1, y1; /* top left corner */ + s32 x2, y2; /* bottom right corner, exclusive */ +} __packed; + +struct synthvid_dirt { + u8 video_output; + u8 dirt_count; + struct rect rect[1]; +} __packed; + +struct synthvid_msg { + struct pipe_msg_hdr pipe_hdr; + struct synthvid_msg_hdr vid_hdr; + union { + struct synthvid_version_req ver_req; + struct synthvid_version_resp ver_resp; + struct synthvid_vram_location vram; + struct synthvid_vram_location_ack vram_ack; + struct synthvid_situation_update situ; + struct synthvid_situation_update_ack situ_ack; + struct synthvid_pointer_position ptr_pos; + struct synthvid_pointer_shape ptr_shape; + struct synthvid_feature_change feature_chg; + struct synthvid_dirt dirt; + }; +} __packed; + + + +/* FB driver definitions and structures */ +#define HVFB_WIDTH 1152 /* default screen width */ +#define HVFB_HEIGHT 864 /* default screen height */ +#define HVFB_WIDTH_MIN 640 +#define HVFB_HEIGHT_MIN 480 + +#define RING_BUFSIZE (256 * 1024) +#define VSP_TIMEOUT (10 * HZ) +#define HVFB_UPDATE_DELAY (HZ / 20) + +struct hvfb_par { + struct fb_info *info; + bool fb_ready; /* fb device is ready */ + struct completion wait; + u32 synthvid_version; + + struct delayed_work dwork; + bool update; + + u32 pseudo_palette[16]; + u8 init_buf[MAX_VMBUS_PKT_SIZE]; + u8 recv_buf[MAX_VMBUS_PKT_SIZE]; +}; + +static uint screen_width = HVFB_WIDTH; +static uint screen_height = HVFB_HEIGHT; +static uint screen_depth; +static uint screen_fb_size; + +/* Send message to Hyper-V host */ +static inline int synthvid_send(struct hv_device *hdev, + struct synthvid_msg *msg) +{ + static atomic64_t request_id = ATOMIC64_INIT(0); + int ret; + + msg->pipe_hdr.type = PIPE_MSG_DATA; + msg->pipe_hdr.size = msg->vid_hdr.size; + + ret = vmbus_sendpacket(hdev->channel, msg, + msg->vid_hdr.size + sizeof(struct pipe_msg_hdr), + atomic64_inc_return(&request_id), + VM_PKT_DATA_INBAND, 0); + + if (ret) + pr_err("Unable to send packet via vmbus\n"); + + return ret; +} + + +/* Send screen resolution info to host */ +static int synthvid_send_situ(struct hv_device *hdev) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct synthvid_msg msg; + + if (!info) + return -ENODEV; + + memset(&msg, 0, sizeof(struct synthvid_msg)); + + msg.vid_hdr.type = SYNTHVID_SITUATION_UPDATE; + msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_situation_update); + msg.situ.user_ctx = 0; + msg.situ.video_output_count = 1; + msg.situ.video_output[0].active = 1; + msg.situ.video_output[0].vram_offset = 0; + msg.situ.video_output[0].depth_bits = info->var.bits_per_pixel; + msg.situ.video_output[0].width_pixels = info->var.xres; + msg.situ.video_output[0].height_pixels = info->var.yres; + msg.situ.video_output[0].pitch_bytes = info->fix.line_length; + + synthvid_send(hdev, &msg); + + return 0; +} + +/* Send mouse pointer info to host */ +static int synthvid_send_ptr(struct hv_device *hdev) +{ + struct synthvid_msg msg; + + memset(&msg, 0, sizeof(struct synthvid_msg)); + msg.vid_hdr.type = SYNTHVID_POINTER_POSITION; + msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_pointer_position); + msg.ptr_pos.is_visible = 1; + msg.ptr_pos.video_output = 0; + msg.ptr_pos.image_x = 0; + msg.ptr_pos.image_y = 0; + synthvid_send(hdev, &msg); + + memset(&msg, 0, sizeof(struct synthvid_msg)); + msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE; + msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_pointer_shape); + msg.ptr_shape.part_idx = CURSOR_COMPLETE; + msg.ptr_shape.is_argb = 1; + msg.ptr_shape.width = 1; + msg.ptr_shape.height = 1; + msg.ptr_shape.hot_x = 0; + msg.ptr_shape.hot_y = 0; + msg.ptr_shape.data[0] = 0; + msg.ptr_shape.data[1] = 1; + msg.ptr_shape.data[2] = 1; + msg.ptr_shape.data[3] = 1; + synthvid_send(hdev, &msg); + + return 0; +} + +/* Send updated screen area (dirty rectangle) location to host */ +static int synthvid_update(struct fb_info *info) +{ + struct hv_device *hdev = device_to_hv_device(info->device); + struct synthvid_msg msg; + + memset(&msg, 0, sizeof(struct synthvid_msg)); + + msg.vid_hdr.type = SYNTHVID_DIRT; + msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_dirt); + msg.dirt.video_output = 0; + msg.dirt.dirt_count = 1; + msg.dirt.rect[0].x1 = 0; + msg.dirt.rect[0].y1 = 0; + msg.dirt.rect[0].x2 = info->var.xres; + msg.dirt.rect[0].y2 = info->var.yres; + + synthvid_send(hdev, &msg); + + return 0; +} + + +/* + * Actions on received messages from host: + * Complete the wait event. + * Or, reply with screen and cursor info. + */ +static void synthvid_recv_sub(struct hv_device *hdev) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par; + struct synthvid_msg *msg; + + if (!info) + return; + + par = info->par; + msg = (struct synthvid_msg *)par->recv_buf; + + /* Complete the wait event */ + if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE || + msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) { + memcpy(par->init_buf, msg, MAX_VMBUS_PKT_SIZE); + complete(&par->wait); + return; + } + + /* Reply with screen and cursor info */ + if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) { + if (par->fb_ready) { + synthvid_send_ptr(hdev); + synthvid_send_situ(hdev); + } + + par->update = msg->feature_chg.is_dirt_needed; + if (par->update) + schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); + } +} + +/* Receive callback for messages from the host */ +static void synthvid_receive(void *ctx) +{ + struct hv_device *hdev = ctx; + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par; + struct synthvid_msg *recv_buf; + u32 bytes_recvd; + u64 req_id; + int ret; + + if (!info) + return; + + par = info->par; + recv_buf = (struct synthvid_msg *)par->recv_buf; + + do { + ret = vmbus_recvpacket(hdev->channel, recv_buf, + MAX_VMBUS_PKT_SIZE, + &bytes_recvd, &req_id); + if (bytes_recvd > 0 && + recv_buf->pipe_hdr.type == PIPE_MSG_DATA) + synthvid_recv_sub(hdev); + } while (bytes_recvd > 0 && ret == 0); +} + +/* Check synthetic video protocol version with the host */ +static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par = info->par; + struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; + int t, ret = 0; + + memset(msg, 0, sizeof(struct synthvid_msg)); + msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST; + msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_version_req); + msg->ver_req.version = ver; + synthvid_send(hdev, msg); + + t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); + if (!t) { + pr_err("Time out on waiting version response\n"); + ret = -ETIMEDOUT; + goto out; + } + if (!msg->ver_resp.is_accepted) { + ret = -ENODEV; + goto out; + } + + par->synthvid_version = ver; + +out: + return ret; +} + +/* Connect to VSP (Virtual Service Provider) on host */ +static int synthvid_connect_vsp(struct hv_device *hdev) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par = info->par; + int ret; + + ret = vmbus_open(hdev->channel, RING_BUFSIZE, RING_BUFSIZE, + NULL, 0, synthvid_receive, hdev); + if (ret) { + pr_err("Unable to open vmbus channel\n"); + return ret; + } + + /* Negotiate the protocol version with host */ + if (vmbus_proto_version == VERSION_WS2008 || + vmbus_proto_version == VERSION_WIN7) + ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN7); + else + ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN8); + + if (ret) { + pr_err("Synthetic video device version not accepted\n"); + goto error; + } + + if (par->synthvid_version == SYNTHVID_VERSION_WIN7) { + screen_depth = SYNTHVID_DEPTH_WIN7; + screen_fb_size = SYNTHVID_FB_SIZE_WIN7; + } else { + screen_depth = SYNTHVID_DEPTH_WIN8; + screen_fb_size = SYNTHVID_FB_SIZE_WIN8; + } + + return 0; + +error: + vmbus_close(hdev->channel); + return ret; +} + +/* Send VRAM and Situation messages to the host */ +static int synthvid_send_config(struct hv_device *hdev) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par = info->par; + struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; + int t, ret = 0; + + /* Send VRAM location */ + memset(msg, 0, sizeof(struct synthvid_msg)); + msg->vid_hdr.type = SYNTHVID_VRAM_LOCATION; + msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) + + sizeof(struct synthvid_vram_location); + msg->vram.user_ctx = msg->vram.vram_gpa = info->fix.smem_start; + msg->vram.is_vram_gpa_specified = 1; + synthvid_send(hdev, msg); + + t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); + if (!t) { + pr_err("Time out on waiting vram location ack\n"); + ret = -ETIMEDOUT; + goto out; + } + if (msg->vram_ack.user_ctx != info->fix.smem_start) { + pr_err("Unable to set VRAM location\n"); + ret = -ENODEV; + goto out; + } + + /* Send pointer and situation update */ + synthvid_send_ptr(hdev); + synthvid_send_situ(hdev); + +out: + return ret; +} + + +/* + * Delayed work callback: + * It is called at HVFB_UPDATE_DELAY or longer time interval to process + * screen updates. It is re-scheduled if further update is necessary. + */ +static void hvfb_update_work(struct work_struct *w) +{ + struct hvfb_par *par = container_of(w, struct hvfb_par, dwork.work); + struct fb_info *info = par->info; + + if (par->fb_ready) + synthvid_update(info); + + if (par->update) + schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); +} + + +/* Framebuffer operation handlers */ + +static int hvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + if (var->xres < HVFB_WIDTH_MIN || var->yres < HVFB_HEIGHT_MIN || + var->xres > screen_width || var->yres > screen_height || + var->bits_per_pixel != screen_depth) + return -EINVAL; + + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + + return 0; +} + +static int hvfb_set_par(struct fb_info *info) +{ + struct hv_device *hdev = device_to_hv_device(info->device); + + return synthvid_send_situ(hdev); +} + + +static inline u32 chan_to_field(u32 chan, struct fb_bitfield *bf) +{ + return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset; +} + +static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) +{ + u32 *pal = info->pseudo_palette; + + if (regno > 15) + return -EINVAL; + + pal[regno] = chan_to_field(red, &info->var.red) + | chan_to_field(green, &info->var.green) + | chan_to_field(blue, &info->var.blue) + | chan_to_field(transp, &info->var.transp); + + return 0; +} + + +static struct fb_ops hvfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = hvfb_check_var, + .fb_set_par = hvfb_set_par, + .fb_setcolreg = hvfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + + +/* Get options from kernel paramenter "video=" */ +static void hvfb_get_option(struct fb_info *info) +{ + struct hvfb_par *par = info->par; + char *opt = NULL, *p; + uint x = 0, y = 0; + + if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt) + return; + + p = strsep(&opt, "x"); + if (!*p || kstrtouint(p, 0, &x) || + !opt || !*opt || kstrtouint(opt, 0, &y)) { + pr_err("Screen option is invalid: skipped\n"); + return; + } + + if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN || + (par->synthvid_version == SYNTHVID_VERSION_WIN8 && + x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8) || + (par->synthvid_version == SYNTHVID_VERSION_WIN7 && + (x > SYNTHVID_WIDTH_MAX_WIN7 || y > SYNTHVID_HEIGHT_MAX_WIN7))) { + pr_err("Screen resolution option is out of range: skipped\n"); + return; + } + + screen_width = x; + screen_height = y; + return; +} + + +/* Get framebuffer memory from Hyper-V video pci space */ +static int hvfb_getmem(struct fb_info *info) +{ + struct pci_dev *pdev; + ulong fb_phys; + void __iomem *fb_virt; + + pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, + PCI_DEVICE_ID_HYPERV_VIDEO, NULL); + if (!pdev) { + pr_err("Unable to find PCI Hyper-V video\n"); + return -ENODEV; + } + + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || + pci_resource_len(pdev, 0) < screen_fb_size) + goto err1; + + fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1; + if (!request_mem_region(fb_phys, screen_fb_size, KBUILD_MODNAME)) + goto err1; + + fb_virt = ioremap(fb_phys, screen_fb_size); + if (!fb_virt) + goto err2; + + info->apertures = alloc_apertures(1); + if (!info->apertures) + goto err3; + + info->apertures->ranges[0].base = pci_resource_start(pdev, 0); + info->apertures->ranges[0].size = pci_resource_len(pdev, 0); + info->fix.smem_start = fb_phys; + info->fix.smem_len = screen_fb_size; + info->screen_base = fb_virt; + info->screen_size = screen_fb_size; + + pci_dev_put(pdev); + return 0; + +err3: + iounmap(fb_virt); +err2: + release_mem_region(fb_phys, screen_fb_size); +err1: + pci_dev_put(pdev); + return -ENOMEM; +} + +/* Release the framebuffer */ +static void hvfb_putmem(struct fb_info *info) +{ + iounmap(info->screen_base); + release_mem_region(info->fix.smem_start, screen_fb_size); +} + + +static int hvfb_probe(struct hv_device *hdev, + const struct hv_vmbus_device_id *dev_id) +{ + struct fb_info *info; + struct hvfb_par *par; + int ret; + + info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device); + if (!info) { + pr_err("No memory for framebuffer info\n"); + return -ENOMEM; + } + + par = info->par; + par->info = info; + par->fb_ready = false; + init_completion(&par->wait); + INIT_DELAYED_WORK(&par->dwork, hvfb_update_work); + + /* Connect to VSP */ + hv_set_drvdata(hdev, info); + ret = synthvid_connect_vsp(hdev); + if (ret) { + pr_err("Unable to connect to VSP\n"); + goto error1; + } + + ret = hvfb_getmem(info); + if (ret) { + pr_err("No memory for framebuffer\n"); + goto error2; + } + + hvfb_get_option(info); + pr_info("Screen resolution: %dx%d, Color depth: %d\n", + screen_width, screen_height, screen_depth); + + + /* Set up fb_info */ + info->flags = FBINFO_DEFAULT; + + info->var.xres_virtual = info->var.xres = screen_width; + info->var.yres_virtual = info->var.yres = screen_height; + info->var.bits_per_pixel = screen_depth; + + if (info->var.bits_per_pixel == 16) { + info->var.red = (struct fb_bitfield){11, 5, 0}; + info->var.green = (struct fb_bitfield){5, 6, 0}; + info->var.blue = (struct fb_bitfield){0, 5, 0}; + info->var.transp = (struct fb_bitfield){0, 0, 0}; + } else { + info->var.red = (struct fb_bitfield){16, 8, 0}; + info->var.green = (struct fb_bitfield){8, 8, 0}; + info->var.blue = (struct fb_bitfield){0, 8, 0}; + info->var.transp = (struct fb_bitfield){24, 8, 0}; + } + + info->var.activate = FB_ACTIVATE_NOW; + info->var.height = -1; + info->var.width = -1; + info->var.vmode = FB_VMODE_NONINTERLACED; + + strcpy(info->fix.id, KBUILD_MODNAME); + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.line_length = screen_width * screen_depth / 8; + info->fix.accel = FB_ACCEL_NONE; + + info->fbops = &hvfb_ops; + info->pseudo_palette = par->pseudo_palette; + + /* Send config to host */ + ret = synthvid_send_config(hdev); + if (ret) + goto error; + + ret = register_framebuffer(info); + if (ret) { + pr_err("Unable to register framebuffer\n"); + goto error; + } + + par->fb_ready = true; + + return 0; + +error: + hvfb_putmem(info); +error2: + vmbus_close(hdev->channel); +error1: + cancel_delayed_work_sync(&par->dwork); + hv_set_drvdata(hdev, NULL); + framebuffer_release(info); + return ret; +} + + +static int hvfb_remove(struct hv_device *hdev) +{ + struct fb_info *info = hv_get_drvdata(hdev); + struct hvfb_par *par = info->par; + + par->update = false; + par->fb_ready = false; + + unregister_framebuffer(info); + cancel_delayed_work_sync(&par->dwork); + + vmbus_close(hdev->channel); + hv_set_drvdata(hdev, NULL); + + hvfb_putmem(info); + framebuffer_release(info); + + return 0; +} + + +static const struct hv_vmbus_device_id id_table[] = { + /* Synthetic Video Device GUID */ + {HV_SYNTHVID_GUID}, + {} +}; + +MODULE_DEVICE_TABLE(vmbus, id_table); + +static struct hv_driver hvfb_drv = { + .name = KBUILD_MODNAME, + .id_table = id_table, + .probe = hvfb_probe, + .remove = hvfb_remove, +}; + + +static int __init hvfb_drv_init(void) +{ + return vmbus_driver_register(&hvfb_drv); +} + +static void __exit hvfb_drv_exit(void) +{ + vmbus_driver_unregister(&hvfb_drv); +} + +module_init(hvfb_drv_init); +module_exit(hvfb_drv_exit); + +MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver"); diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 217678e0b983..fd2897455696 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c @@ -137,8 +137,20 @@ static int* get_ctrl_ptr(struct maven_data* md, int idx) { static int maven_get_reg(struct i2c_client* c, char reg) { char dst; - struct i2c_msg msgs[] = {{ c->addr, I2C_M_REV_DIR_ADDR, sizeof(reg), ® }, - { c->addr, I2C_M_RD | I2C_M_NOSTART, sizeof(dst), &dst }}; + struct i2c_msg msgs[] = { + { + .addr = c->addr, + .flags = I2C_M_REV_DIR_ADDR, + .len = sizeof(reg), + .buf = ® + }, + { + .addr = c->addr, + .flags = I2C_M_RD | I2C_M_NOSTART, + .len = sizeof(dst), + .buf = &dst + } + }; s32 err; err = i2c_transfer(c->adapter, msgs, 2); diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/mmp/hw/mmp_ctrl.h index 6408d8ef3abb..edd2002b0e99 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.h +++ b/drivers/video/mmp/hw/mmp_ctrl.h @@ -961,56 +961,7 @@ struct lcd_regs { LCD_TVG_CUTVLN : PN2_LCD_GRA_CUTVLN) : LCD_GRA_CUTVLN) /* - * defined Video Memory Color format for DMA control 0 register - * DMA0 bit[23:20] - */ -#define VMODE_RGB565 0x0 -#define VMODE_RGB1555 0x1 -#define VMODE_RGB888PACKED 0x2 -#define VMODE_RGB888UNPACKED 0x3 -#define VMODE_RGBA888 0x4 -#define VMODE_YUV422PACKED 0x5 -#define VMODE_YUV422PLANAR 0x6 -#define VMODE_YUV420PLANAR 0x7 -#define VMODE_SMPNCMD 0x8 -#define VMODE_PALETTE4BIT 0x9 -#define VMODE_PALETTE8BIT 0xa -#define VMODE_RESERVED 0xb - -/* - * defined Graphic Memory Color format for DMA control 0 register - * DMA0 bit[19:16] - */ -#define GMODE_RGB565 0x0 -#define GMODE_RGB1555 0x1 -#define GMODE_RGB888PACKED 0x2 -#define GMODE_RGB888UNPACKED 0x3 -#define GMODE_RGBA888 0x4 -#define GMODE_YUV422PACKED 0x5 -#define GMODE_YUV422PLANAR 0x6 -#define GMODE_YUV420PLANAR 0x7 -#define GMODE_SMPNCMD 0x8 -#define GMODE_PALETTE4BIT 0x9 -#define GMODE_PALETTE8BIT 0xa -#define GMODE_RESERVED 0xb - -/* - * define for DMA control 1 register - */ -#define DMA1_FRAME_TRIG 31 /* bit location */ -#define DMA1_VSYNC_MODE 28 -#define DMA1_VSYNC_INV 27 -#define DMA1_CKEY 24 -#define DMA1_CARRY 23 -#define DMA1_LNBUF_ENA 22 -#define DMA1_GATED_ENA 21 -#define DMA1_PWRDN_ENA 20 -#define DMA1_DSCALE 18 -#define DMA1_ALPHA_MODE 16 -#define DMA1_ALPHA 08 -#define DMA1_PXLCMD 00 - -/* + * defined for Configure Dumb Mode * defined for Configure Dumb Mode * DUMB LCD Panel bit[31:28] */ @@ -1050,18 +1001,6 @@ struct lcd_regs { #define CFG_CYC_BURST_LEN16 (1<<4) #define CFG_CYC_BURST_LEN8 (0<<4) -/* - * defined Dumb Panel Clock Divider register - * SCLK_Source bit[31] - */ - /* 0: PLL clock select*/ -#define AXI_BUS_SEL 0x80000000 -#define CCD_CLK_SEL 0x40000000 -#define DCON_CLK_SEL 0x20000000 -#define ENA_CLK_INT_DIV CONFIG_FB_DOVE_CLCD_SCLK_DIV -#define IDLE_CLK_INT_DIV 0x1 /* idle Integer Divider */ -#define DIS_CLK_INT_DIV 0x0 /* Disable Integer Divider */ - /* SRAM ID */ #define SRAMID_GAMMA_YR 0x0 #define SRAMID_GAMMA_UG 0x1 @@ -1471,422 +1410,6 @@ struct dsi_regs { #define LVDS_FREQ_OFFSET_MODE_CK_DIV4_OUT (0x1 << 1) #define LVDS_FREQ_OFFSET_MODE_EN (0x1 << 0) -/* VDMA */ -struct vdma_ch_regs { -#define VDMA_DC_SADDR_1 0x320 -#define VDMA_DC_SADDR_2 0x3A0 -#define VDMA_DC_SZ_1 0x324 -#define VDMA_DC_SZ_2 0x3A4 -#define VDMA_CTRL_1 0x328 -#define VDMA_CTRL_2 0x3A8 -#define VDMA_SRC_SZ_1 0x32C -#define VDMA_SRC_SZ_2 0x3AC -#define VDMA_SA_1 0x330 -#define VDMA_SA_2 0x3B0 -#define VDMA_DA_1 0x334 -#define VDMA_DA_2 0x3B4 -#define VDMA_SZ_1 0x338 -#define VDMA_SZ_2 0x3B8 - u32 dc_saddr; - u32 dc_size; - u32 ctrl; - u32 src_size; - u32 src_addr; - u32 dst_addr; - u32 dst_size; -#define VDMA_PITCH_1 0x33C -#define VDMA_PITCH_2 0x3BC -#define VDMA_ROT_CTRL_1 0x340 -#define VDMA_ROT_CTRL_2 0x3C0 -#define VDMA_RAM_CTRL0_1 0x344 -#define VDMA_RAM_CTRL0_2 0x3C4 -#define VDMA_RAM_CTRL1_1 0x348 -#define VDMA_RAM_CTRL1_2 0x3C8 - u32 pitch; - u32 rot_ctrl; - u32 ram_ctrl0; - u32 ram_ctrl1; - -}; -struct vdma_regs { -#define VDMA_ARBR_CTRL 0x300 -#define VDMA_IRQR 0x304 -#define VDMA_IRQM 0x308 -#define VDMA_IRQS 0x30C -#define VDMA_MDMA_ARBR_CTRL 0x310 - u32 arbr_ctr; - u32 irq_raw; - u32 irq_mask; - u32 irq_status; - u32 mdma_arbr_ctrl; - u32 reserved[3]; - - struct vdma_ch_regs ch1; - u32 reserved2[21]; - struct vdma_ch_regs ch2; -}; - -/* CMU */ -#define CMU_PIP_DE_H_CFG 0x0008 -#define CMU_PRI1_H_CFG 0x000C -#define CMU_PRI2_H_CFG 0x0010 -#define CMU_ACE_MAIN_DE1_H_CFG 0x0014 -#define CMU_ACE_MAIN_DE2_H_CFG 0x0018 -#define CMU_ACE_PIP_DE1_H_CFG 0x001C -#define CMU_ACE_PIP_DE2_H_CFG 0x0020 -#define CMU_PIP_DE_V_CFG 0x0024 -#define CMU_PRI_V_CFG 0x0028 -#define CMU_ACE_MAIN_DE_V_CFG 0x002C -#define CMU_ACE_PIP_DE_V_CFG 0x0030 -#define CMU_BAR_0_CFG 0x0034 -#define CMU_BAR_1_CFG 0x0038 -#define CMU_BAR_2_CFG 0x003C -#define CMU_BAR_3_CFG 0x0040 -#define CMU_BAR_4_CFG 0x0044 -#define CMU_BAR_5_CFG 0x0048 -#define CMU_BAR_6_CFG 0x004C -#define CMU_BAR_7_CFG 0x0050 -#define CMU_BAR_8_CFG 0x0054 -#define CMU_BAR_9_CFG 0x0058 -#define CMU_BAR_10_CFG 0x005C -#define CMU_BAR_11_CFG 0x0060 -#define CMU_BAR_12_CFG 0x0064 -#define CMU_BAR_13_CFG 0x0068 -#define CMU_BAR_14_CFG 0x006C -#define CMU_BAR_15_CFG 0x0070 -#define CMU_BAR_CTRL 0x0074 -#define PATTERN_TOTAL 0x0078 -#define PATTERN_ACTIVE 0x007C -#define PATTERN_FRONT_PORCH 0x0080 -#define PATTERN_BACK_PORCH 0x0084 -#define CMU_CLK_CTRL 0x0088 - -#define CMU_ICSC_M_C0_L 0x0900 -#define CMU_ICSC_M_C0_H 0x0901 -#define CMU_ICSC_M_C1_L 0x0902 -#define CMU_ICSC_M_C1_H 0x0903 -#define CMU_ICSC_M_C2_L 0x0904 -#define CMU_ICSC_M_C2_H 0x0905 -#define CMU_ICSC_M_C3_L 0x0906 -#define CMU_ICSC_M_C3_H 0x0907 -#define CMU_ICSC_M_C4_L 0x0908 -#define CMU_ICSC_M_C4_H 0x0909 -#define CMU_ICSC_M_C5_L 0x090A -#define CMU_ICSC_M_C5_H 0x090B -#define CMU_ICSC_M_C6_L 0x090C -#define CMU_ICSC_M_C6_H 0x090D -#define CMU_ICSC_M_C7_L 0x090E -#define CMU_ICSC_M_C7_H 0x090F -#define CMU_ICSC_M_C8_L 0x0910 -#define CMU_ICSC_M_C8_H 0x0911 -#define CMU_ICSC_M_O1_0 0x0914 -#define CMU_ICSC_M_O1_1 0x0915 -#define CMU_ICSC_M_O1_2 0x0916 -#define CMU_ICSC_M_O2_0 0x0918 -#define CMU_ICSC_M_O2_1 0x0919 -#define CMU_ICSC_M_O2_2 0x091A -#define CMU_ICSC_M_O3_0 0x091C -#define CMU_ICSC_M_O3_1 0x091D -#define CMU_ICSC_M_O3_2 0x091E -#define CMU_ICSC_P_C0_L 0x0920 -#define CMU_ICSC_P_C0_H 0x0921 -#define CMU_ICSC_P_C1_L 0x0922 -#define CMU_ICSC_P_C1_H 0x0923 -#define CMU_ICSC_P_C2_L 0x0924 -#define CMU_ICSC_P_C2_H 0x0925 -#define CMU_ICSC_P_C3_L 0x0926 -#define CMU_ICSC_P_C3_H 0x0927 -#define CMU_ICSC_P_C4_L 0x0928 -#define CMU_ICSC_P_C4_H 0x0929 -#define CMU_ICSC_P_C5_L 0x092A -#define CMU_ICSC_P_C5_H 0x092B -#define CMU_ICSC_P_C6_L 0x092C -#define CMU_ICSC_P_C6_H 0x092D -#define CMU_ICSC_P_C7_L 0x092E -#define CMU_ICSC_P_C7_H 0x092F -#define CMU_ICSC_P_C8_L 0x0930 -#define CMU_ICSC_P_C8_H 0x0931 -#define CMU_ICSC_P_O1_0 0x0934 -#define CMU_ICSC_P_O1_1 0x0935 -#define CMU_ICSC_P_O1_2 0x0936 -#define CMU_ICSC_P_O2_0 0x0938 -#define CMU_ICSC_P_O2_1 0x0939 -#define CMU_ICSC_P_O2_2 0x093A -#define CMU_ICSC_P_O3_0 0x093C -#define CMU_ICSC_P_O3_1 0x093D -#define CMU_ICSC_P_O3_2 0x093E -#define CMU_BR_M_EN 0x0940 -#define CMU_BR_M_TH1_L 0x0942 -#define CMU_BR_M_TH1_H 0x0943 -#define CMU_BR_M_TH2_L 0x0944 -#define CMU_BR_M_TH2_H 0x0945 -#define CMU_ACE_M_EN 0x0950 -#define CMU_ACE_M_WFG1 0x0951 -#define CMU_ACE_M_WFG2 0x0952 -#define CMU_ACE_M_WFG3 0x0953 -#define CMU_ACE_M_TH0 0x0954 -#define CMU_ACE_M_TH1 0x0955 -#define CMU_ACE_M_TH2 0x0956 -#define CMU_ACE_M_TH3 0x0957 -#define CMU_ACE_M_TH4 0x0958 -#define CMU_ACE_M_TH5 0x0959 -#define CMU_ACE_M_OP0_L 0x095A -#define CMU_ACE_M_OP0_H 0x095B -#define CMU_ACE_M_OP5_L 0x095C -#define CMU_ACE_M_OP5_H 0x095D -#define CMU_ACE_M_GB2 0x095E -#define CMU_ACE_M_GB3 0x095F -#define CMU_ACE_M_MS1 0x0960 -#define CMU_ACE_M_MS2 0x0961 -#define CMU_ACE_M_MS3 0x0962 -#define CMU_BR_P_EN 0x0970 -#define CMU_BR_P_TH1_L 0x0972 -#define CMU_BR_P_TH1_H 0x0973 -#define CMU_BR_P_TH2_L 0x0974 -#define CMU_BR_P_TH2_H 0x0975 -#define CMU_ACE_P_EN 0x0980 -#define CMU_ACE_P_WFG1 0x0981 -#define CMU_ACE_P_WFG2 0x0982 -#define CMU_ACE_P_WFG3 0x0983 -#define CMU_ACE_P_TH0 0x0984 -#define CMU_ACE_P_TH1 0x0985 -#define CMU_ACE_P_TH2 0x0986 -#define CMU_ACE_P_TH3 0x0987 -#define CMU_ACE_P_TH4 0x0988 -#define CMU_ACE_P_TH5 0x0989 -#define CMU_ACE_P_OP0_L 0x098A -#define CMU_ACE_P_OP0_H 0x098B -#define CMU_ACE_P_OP5_L 0x098C -#define CMU_ACE_P_OP5_H 0x098D -#define CMU_ACE_P_GB2 0x098E -#define CMU_ACE_P_GB3 0x098F -#define CMU_ACE_P_MS1 0x0990 -#define CMU_ACE_P_MS2 0x0991 -#define CMU_ACE_P_MS3 0x0992 -#define CMU_FTDC_M_EN 0x09A0 -#define CMU_FTDC_P_EN 0x09A1 -#define CMU_FTDC_INLOW_L 0x09A2 -#define CMU_FTDC_INLOW_H 0x09A3 -#define CMU_FTDC_INHIGH_L 0x09A4 -#define CMU_FTDC_INHIGH_H 0x09A5 -#define CMU_FTDC_OUTLOW_L 0x09A6 -#define CMU_FTDC_OUTLOW_H 0x09A7 -#define CMU_FTDC_OUTHIGH_L 0x09A8 -#define CMU_FTDC_OUTHIGH_H 0x09A9 -#define CMU_FTDC_YLOW 0x09AA -#define CMU_FTDC_YHIGH 0x09AB -#define CMU_FTDC_CH1 0x09AC -#define CMU_FTDC_CH2_L 0x09AE -#define CMU_FTDC_CH2_H 0x09AF -#define CMU_FTDC_CH3_L 0x09B0 -#define CMU_FTDC_CH3_H 0x09B1 -#define CMU_FTDC_1_C00_6 0x09B2 -#define CMU_FTDC_1_C01_6 0x09B8 -#define CMU_FTDC_1_C11_6 0x09BE -#define CMU_FTDC_1_C10_6 0x09C4 -#define CMU_FTDC_1_OFF00_6 0x09CA -#define CMU_FTDC_1_OFF10_6 0x09D0 -#define CMU_HS_M_EN 0x0A00 -#define CMU_HS_M_AX1_L 0x0A02 -#define CMU_HS_M_AX1_H 0x0A03 -#define CMU_HS_M_AX2_L 0x0A04 -#define CMU_HS_M_AX2_H 0x0A05 -#define CMU_HS_M_AX3_L 0x0A06 -#define CMU_HS_M_AX3_H 0x0A07 -#define CMU_HS_M_AX4_L 0x0A08 -#define CMU_HS_M_AX4_H 0x0A09 -#define CMU_HS_M_AX5_L 0x0A0A -#define CMU_HS_M_AX5_H 0x0A0B -#define CMU_HS_M_AX6_L 0x0A0C -#define CMU_HS_M_AX6_H 0x0A0D -#define CMU_HS_M_AX7_L 0x0A0E -#define CMU_HS_M_AX7_H 0x0A0F -#define CMU_HS_M_AX8_L 0x0A10 -#define CMU_HS_M_AX8_H 0x0A11 -#define CMU_HS_M_AX9_L 0x0A12 -#define CMU_HS_M_AX9_H 0x0A13 -#define CMU_HS_M_AX10_L 0x0A14 -#define CMU_HS_M_AX10_H 0x0A15 -#define CMU_HS_M_AX11_L 0x0A16 -#define CMU_HS_M_AX11_H 0x0A17 -#define CMU_HS_M_AX12_L 0x0A18 -#define CMU_HS_M_AX12_H 0x0A19 -#define CMU_HS_M_AX13_L 0x0A1A -#define CMU_HS_M_AX13_H 0x0A1B -#define CMU_HS_M_AX14_L 0x0A1C -#define CMU_HS_M_AX14_H 0x0A1D -#define CMU_HS_M_H1_H14 0x0A1E -#define CMU_HS_M_S1_S14 0x0A2C -#define CMU_HS_M_GL 0x0A3A -#define CMU_HS_M_MAXSAT_RGB_Y_L 0x0A3C -#define CMU_HS_M_MAXSAT_RGB_Y_H 0x0A3D -#define CMU_HS_M_MAXSAT_RCR_L 0x0A3E -#define CMU_HS_M_MAXSAT_RCR_H 0x0A3F -#define CMU_HS_M_MAXSAT_RCB_L 0x0A40 -#define CMU_HS_M_MAXSAT_RCB_H 0x0A41 -#define CMU_HS_M_MAXSAT_GCR_L 0x0A42 -#define CMU_HS_M_MAXSAT_GCR_H 0x0A43 -#define CMU_HS_M_MAXSAT_GCB_L 0x0A44 -#define CMU_HS_M_MAXSAT_GCB_H 0x0A45 -#define CMU_HS_M_MAXSAT_BCR_L 0x0A46 -#define CMU_HS_M_MAXSAT_BCR_H 0x0A47 -#define CMU_HS_M_MAXSAT_BCB_L 0x0A48 -#define CMU_HS_M_MAXSAT_BCB_H 0x0A49 -#define CMU_HS_M_ROFF_L 0x0A4A -#define CMU_HS_M_ROFF_H 0x0A4B -#define CMU_HS_M_GOFF_L 0x0A4C -#define CMU_HS_M_GOFF_H 0x0A4D -#define CMU_HS_M_BOFF_L 0x0A4E -#define CMU_HS_M_BOFF_H 0x0A4F -#define CMU_HS_P_EN 0x0A50 -#define CMU_HS_P_AX1_L 0x0A52 -#define CMU_HS_P_AX1_H 0x0A53 -#define CMU_HS_P_AX2_L 0x0A54 -#define CMU_HS_P_AX2_H 0x0A55 -#define CMU_HS_P_AX3_L 0x0A56 -#define CMU_HS_P_AX3_H 0x0A57 -#define CMU_HS_P_AX4_L 0x0A58 -#define CMU_HS_P_AX4_H 0x0A59 -#define CMU_HS_P_AX5_L 0x0A5A -#define CMU_HS_P_AX5_H 0x0A5B -#define CMU_HS_P_AX6_L 0x0A5C -#define CMU_HS_P_AX6_H 0x0A5D -#define CMU_HS_P_AX7_L 0x0A5E -#define CMU_HS_P_AX7_H 0x0A5F -#define CMU_HS_P_AX8_L 0x0A60 -#define CMU_HS_P_AX8_H 0x0A61 -#define CMU_HS_P_AX9_L 0x0A62 -#define CMU_HS_P_AX9_H 0x0A63 -#define CMU_HS_P_AX10_L 0x0A64 -#define CMU_HS_P_AX10_H 0x0A65 -#define CMU_HS_P_AX11_L 0x0A66 -#define CMU_HS_P_AX11_H 0x0A67 -#define CMU_HS_P_AX12_L 0x0A68 -#define CMU_HS_P_AX12_H 0x0A69 -#define CMU_HS_P_AX13_L 0x0A6A -#define CMU_HS_P_AX13_H 0x0A6B -#define CMU_HS_P_AX14_L 0x0A6C -#define CMU_HS_P_AX14_H 0x0A6D -#define CMU_HS_P_H1_H14 0x0A6E -#define CMU_HS_P_S1_S14 0x0A7C -#define CMU_HS_P_GL 0x0A8A -#define CMU_HS_P_MAXSAT_RGB_Y_L 0x0A8C -#define CMU_HS_P_MAXSAT_RGB_Y_H 0x0A8D -#define CMU_HS_P_MAXSAT_RCR_L 0x0A8E -#define CMU_HS_P_MAXSAT_RCR_H 0x0A8F -#define CMU_HS_P_MAXSAT_RCB_L 0x0A90 -#define CMU_HS_P_MAXSAT_RCB_H 0x0A91 -#define CMU_HS_P_MAXSAT_GCR_L 0x0A92 -#define CMU_HS_P_MAXSAT_GCR_H 0x0A93 -#define CMU_HS_P_MAXSAT_GCB_L 0x0A94 -#define CMU_HS_P_MAXSAT_GCB_H 0x0A95 -#define CMU_HS_P_MAXSAT_BCR_L 0x0A96 -#define CMU_HS_P_MAXSAT_BCR_H 0x0A97 -#define CMU_HS_P_MAXSAT_BCB_L 0x0A98 -#define CMU_HS_P_MAXSAT_BCB_H 0x0A99 -#define CMU_HS_P_ROFF_L 0x0A9A -#define CMU_HS_P_ROFF_H 0x0A9B -#define CMU_HS_P_GOFF_L 0x0A9C -#define CMU_HS_P_GOFF_H 0x0A9D -#define CMU_HS_P_BOFF_L 0x0A9E -#define CMU_HS_P_BOFF_H 0x0A9F -#define CMU_GLCSC_M_C0_L 0x0AA0 -#define CMU_GLCSC_M_C0_H 0x0AA1 -#define CMU_GLCSC_M_C1_L 0x0AA2 -#define CMU_GLCSC_M_C1_H 0x0AA3 -#define CMU_GLCSC_M_C2_L 0x0AA4 -#define CMU_GLCSC_M_C2_H 0x0AA5 -#define CMU_GLCSC_M_C3_L 0x0AA6 -#define CMU_GLCSC_M_C3_H 0x0AA7 -#define CMU_GLCSC_M_C4_L 0x0AA8 -#define CMU_GLCSC_M_C4_H 0x0AA9 -#define CMU_GLCSC_M_C5_L 0x0AAA -#define CMU_GLCSC_M_C5_H 0x0AAB -#define CMU_GLCSC_M_C6_L 0x0AAC -#define CMU_GLCSC_M_C6_H 0x0AAD -#define CMU_GLCSC_M_C7_L 0x0AAE -#define CMU_GLCSC_M_C7_H 0x0AAF -#define CMU_GLCSC_M_C8_L 0x0AB0 -#define CMU_GLCSC_M_C8_H 0x0AB1 -#define CMU_GLCSC_M_O1_1 0x0AB4 -#define CMU_GLCSC_M_O1_2 0x0AB5 -#define CMU_GLCSC_M_O1_3 0x0AB6 -#define CMU_GLCSC_M_O2_1 0x0AB8 -#define CMU_GLCSC_M_O2_2 0x0AB9 -#define CMU_GLCSC_M_O2_3 0x0ABA -#define CMU_GLCSC_M_O3_1 0x0ABC -#define CMU_GLCSC_M_O3_2 0x0ABD -#define CMU_GLCSC_M_O3_3 0x0ABE -#define CMU_GLCSC_P_C0_L 0x0AC0 -#define CMU_GLCSC_P_C0_H 0x0AC1 -#define CMU_GLCSC_P_C1_L 0x0AC2 -#define CMU_GLCSC_P_C1_H 0x0AC3 -#define CMU_GLCSC_P_C2_L 0x0AC4 -#define CMU_GLCSC_P_C2_H 0x0AC5 -#define CMU_GLCSC_P_C3_L 0x0AC6 -#define CMU_GLCSC_P_C3_H 0x0AC7 -#define CMU_GLCSC_P_C4_L 0x0AC8 -#define CMU_GLCSC_P_C4_H 0x0AC9 -#define CMU_GLCSC_P_C5_L 0x0ACA -#define CMU_GLCSC_P_C5_H 0x0ACB -#define CMU_GLCSC_P_C6_L 0x0ACC -#define CMU_GLCSC_P_C6_H 0x0ACD -#define CMU_GLCSC_P_C7_L 0x0ACE -#define CMU_GLCSC_P_C7_H 0x0ACF -#define CMU_GLCSC_P_C8_L 0x0AD0 -#define CMU_GLCSC_P_C8_H 0x0AD1 -#define CMU_GLCSC_P_O1_1 0x0AD4 -#define CMU_GLCSC_P_O1_2 0x0AD5 -#define CMU_GLCSC_P_O1_3 0x0AD6 -#define CMU_GLCSC_P_O2_1 0x0AD8 -#define CMU_GLCSC_P_O2_2 0x0AD9 -#define CMU_GLCSC_P_O2_3 0x0ADA -#define CMU_GLCSC_P_O3_1 0x0ADC -#define CMU_GLCSC_P_O3_2 0x0ADD -#define CMU_GLCSC_P_O3_3 0x0ADE -#define CMU_PIXVAL_M_EN 0x0AE0 -#define CMU_PIXVAL_P_EN 0x0AE1 - -#define CMU_CLK_CTRL_TCLK 0x0 -#define CMU_CLK_CTRL_SCLK 0x2 -#define CMU_CLK_CTRL_MSK 0x2 -#define CMU_CLK_CTRL_ENABLE 0x1 - -#define LCD_TOP_CTRL_TV 0x2 -#define LCD_TOP_CTRL_PN 0x0 -#define LCD_TOP_CTRL_SEL_MSK 0x2 -#define LCD_IO_CMU_IN_SEL_MSK (0x3 << 20) -#define LCD_IO_CMU_IN_SEL_TV 0 -#define LCD_IO_CMU_IN_SEL_PN 1 -#define LCD_IO_CMU_IN_SEL_PN2 2 -#define LCD_IO_TV_OUT_SEL_MSK (0x3 << 26) -#define LCD_IO_PN_OUT_SEL_MSK (0x3 << 24) -#define LCD_IO_PN2_OUT_SEL_MSK (0x3 << 28) -#define LCD_IO_TV_OUT_SEL_NON 3 -#define LCD_IO_PN_OUT_SEL_NON 3 -#define LCD_IO_PN2_OUT_SEL_NON 3 -#define LCD_TOP_CTRL_CMU_ENABLE 0x1 -#define LCD_IO_OVERL_MSK 0xC00000 -#define LCD_IO_OVERL_TV 0x0 -#define LCD_IO_OVERL_LCD1 0x400000 -#define LCD_IO_OVERL_LCD2 0xC00000 -#define HINVERT_MSK 0x4 -#define VINVERT_MSK 0x8 -#define HINVERT_LEN 0x2 -#define VINVERT_LEN 0x3 - -#define CMU_CTRL 0x88 -#define CMU_CTRL_A0_MSK 0x6 -#define CMU_CTRL_A0_TV 0x0 -#define CMU_CTRL_A0_LCD1 0x1 -#define CMU_CTRL_A0_LCD2 0x2 -#define CMU_CTRL_A0_HDMI 0x3 - -#define ICR_DRV_ROUTE_OFF 0x0 -#define ICR_DRV_ROUTE_TV 0x1 -#define ICR_DRV_ROUTE_LCD1 0x2 -#define ICR_DRV_ROUTE_LCD2 0x3 - enum { PATH_PN = 0, PATH_TV, |