From patchwork Fri Dec 8 22:47:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 751844 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="DAJfHjTL" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0121D173B; Fri, 8 Dec 2023 14:47:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:Content-Type: MIME-Version:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:In-Reply-To:References; bh=sGKsMAqcLrMi2+MD9Kw80Ts0+gDj12Z83+vCZ7+eX8I=; b=DAJfHjTLEHAE3GJSyYmE0u4V0G MJ663+vq+hr6RSEuFyZkpofRhYdrgSNkqlwPinbf0oHd7KAxe8CgmunpJRnPYHoNle2WuKGjfHwzs 3ngyy/U4+t1RNWY/QCABXIFu3S2CDXD6DWrEvdh5eE8ZTcU6zESS7OM9+bZ198gawljgaCXxUm1DS N42ZjZcijs6w9Dw0wGvfocom7f+UHmi/w5i/SNy4YgZ/UpqgLCT3Do9/bLzGqvcDkk6zNHf6ttTql ZKabdRhjl3BkjnHuvVguDV86Nvdh5WF5eO06apuOBS1/ITvFpFVTwKvjEvbUDjFPnifcanU5KFmbW l5IYX96A==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1rBjcf-006j5T-Ji; Fri, 08 Dec 2023 22:47:05 +0000 From: "Matthew Wilcox (Oracle)" To: linux-fbdev@vger.kernel.org, linux-mtd@lists.infradead.org Cc: "Matthew Wilcox (Oracle)" , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Richard Weinberger , Lee Jones , Andy Lowe , Thomas Hellstrom , Alan Hourihane Subject: [PATCH 1/2] fbdev: Remove support for Carillo Ranch driver Date: Fri, 8 Dec 2023 22:47:02 +0000 Message-Id: <20231208224703.1603264-1-willy@infradead.org> X-Mailer: git-send-email 2.37.1 Precedence: bulk X-Mailing-List: linux-fbdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 As far as anybody can tell, this product never shipped. If it did, it shipped in 2007 and nobody has access to one any more. Remove the fbdev driver and the backlight driver. Signed-off-by: Matthew Wilcox (Oracle) --- drivers/video/backlight/Kconfig | 7 - drivers/video/backlight/Makefile | 1 - drivers/video/backlight/cr_bllcd.c | 264 ----- drivers/video/fbdev/Kconfig | 15 - drivers/video/fbdev/Makefile | 1 - drivers/video/fbdev/vermilion/Makefile | 6 - drivers/video/fbdev/vermilion/cr_pll.c | 195 ---- drivers/video/fbdev/vermilion/vermilion.c | 1175 --------------------- drivers/video/fbdev/vermilion/vermilion.h | 245 ----- 9 files changed, 1909 deletions(-) delete mode 100644 drivers/video/backlight/cr_bllcd.c delete mode 100644 drivers/video/fbdev/vermilion/Makefile delete mode 100644 drivers/video/fbdev/vermilion/cr_pll.c delete mode 100644 drivers/video/fbdev/vermilion/vermilion.c delete mode 100644 drivers/video/fbdev/vermilion/vermilion.h diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 1144a54a35c0..ea2d0d69bd8c 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -235,13 +235,6 @@ config BACKLIGHT_HP700 If you have an HP Jornada 700 series, say Y to include backlight control driver. -config BACKLIGHT_CARILLO_RANCH - tristate "Intel Carillo Ranch Backlight Driver" - depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 - help - If you have a Intel LE80578 (Carillo Ranch) say Y to enable the - backlight driver. - config BACKLIGHT_PWM tristate "Generic PWM based Backlight Driver" depends on PWM diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 1af583de665b..06966cb20459 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o -obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c deleted file mode 100644 index 781aeecc451d..000000000000 --- a/drivers/video/backlight/cr_bllcd.c +++ /dev/null @@ -1,264 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) Intel Corp. 2007. - * All Rights Reserved. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - * This file is part of the Carillo Ranch video subsystem driver. - * - * Authors: - * Thomas Hellstrom - * Alan Hourihane - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* The LVDS- and panel power controls sits on the - * GPIO port of the ISA bridge. - */ - -#define CRVML_DEVICE_LPC 0x27B8 -#define CRVML_REG_GPIOBAR 0x48 -#define CRVML_REG_GPIOEN 0x4C -#define CRVML_GPIOEN_BIT (1 << 4) -#define CRVML_PANEL_PORT 0x38 -#define CRVML_LVDS_ON 0x00000001 -#define CRVML_PANEL_ON 0x00000002 -#define CRVML_BACKLIGHT_OFF 0x00000004 - -/* The PLL Clock register sits on Host bridge */ -#define CRVML_DEVICE_MCH 0x5001 -#define CRVML_REG_MCHBAR 0x44 -#define CRVML_REG_MCHEN 0x54 -#define CRVML_MCHEN_BIT (1 << 28) -#define CRVML_MCHMAP_SIZE 4096 -#define CRVML_REG_CLOCK 0xc3c -#define CRVML_CLOCK_SHIFT 8 -#define CRVML_CLOCK_MASK 0x00000f00 - -static struct pci_dev *lpc_dev; -static u32 gpio_bar; - -struct cr_panel { - struct backlight_device *cr_backlight_device; - struct lcd_device *cr_lcd_device; -}; - -static int cr_backlight_set_intensity(struct backlight_device *bd) -{ - u32 addr = gpio_bar + CRVML_PANEL_PORT; - u32 cur = inl(addr); - - if (backlight_get_brightness(bd) == 0) { - /* OFF */ - cur |= CRVML_BACKLIGHT_OFF; - outl(cur, addr); - } else { - /* FULL ON */ - cur &= ~CRVML_BACKLIGHT_OFF; - outl(cur, addr); - } - - return 0; -} - -static int cr_backlight_get_intensity(struct backlight_device *bd) -{ - u32 addr = gpio_bar + CRVML_PANEL_PORT; - u32 cur = inl(addr); - u8 intensity; - - if (cur & CRVML_BACKLIGHT_OFF) - intensity = 0; - else - intensity = 1; - - return intensity; -} - -static const struct backlight_ops cr_backlight_ops = { - .get_brightness = cr_backlight_get_intensity, - .update_status = cr_backlight_set_intensity, -}; - -static void cr_panel_on(void) -{ - u32 addr = gpio_bar + CRVML_PANEL_PORT; - u32 cur = inl(addr); - - if (!(cur & CRVML_PANEL_ON)) { - /* Make sure LVDS controller is down. */ - if (cur & 0x00000001) { - cur &= ~CRVML_LVDS_ON; - outl(cur, addr); - } - /* Power up Panel */ - schedule_timeout(HZ / 10); - cur |= CRVML_PANEL_ON; - outl(cur, addr); - } - - /* Power up LVDS controller */ - - if (!(cur & CRVML_LVDS_ON)) { - schedule_timeout(HZ / 10); - outl(cur | CRVML_LVDS_ON, addr); - } -} - -static void cr_panel_off(void) -{ - u32 addr = gpio_bar + CRVML_PANEL_PORT; - u32 cur = inl(addr); - - /* Power down LVDS controller first to avoid high currents */ - if (cur & CRVML_LVDS_ON) { - cur &= ~CRVML_LVDS_ON; - outl(cur, addr); - } - if (cur & CRVML_PANEL_ON) { - schedule_timeout(HZ / 10); - outl(cur & ~CRVML_PANEL_ON, addr); - } -} - -static int cr_lcd_set_power(struct lcd_device *ld, int power) -{ - if (power == FB_BLANK_UNBLANK) - cr_panel_on(); - if (power == FB_BLANK_POWERDOWN) - cr_panel_off(); - - return 0; -} - -static struct lcd_ops cr_lcd_ops = { - .set_power = cr_lcd_set_power, -}; - -static int cr_backlight_probe(struct platform_device *pdev) -{ - struct backlight_properties props; - struct backlight_device *bdp; - struct lcd_device *ldp; - struct cr_panel *crp; - u8 dev_en; - - lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, - CRVML_DEVICE_LPC, NULL); - if (!lpc_dev) { - pr_err("INTEL CARILLO RANCH LPC not found.\n"); - return -ENODEV; - } - - pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en); - if (!(dev_en & CRVML_GPIOEN_BIT)) { - pr_err("Carillo Ranch GPIO device was not enabled.\n"); - pci_dev_put(lpc_dev); - return -ENODEV; - } - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - bdp = devm_backlight_device_register(&pdev->dev, "cr-backlight", - &pdev->dev, NULL, &cr_backlight_ops, - &props); - if (IS_ERR(bdp)) { - pci_dev_put(lpc_dev); - return PTR_ERR(bdp); - } - - ldp = devm_lcd_device_register(&pdev->dev, "cr-lcd", &pdev->dev, NULL, - &cr_lcd_ops); - if (IS_ERR(ldp)) { - pci_dev_put(lpc_dev); - return PTR_ERR(ldp); - } - - pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, - &gpio_bar); - gpio_bar &= ~0x3F; - - crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL); - if (!crp) { - pci_dev_put(lpc_dev); - return -ENOMEM; - } - - crp->cr_backlight_device = bdp; - crp->cr_lcd_device = ldp; - crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; - crp->cr_backlight_device->props.brightness = 0; - cr_backlight_set_intensity(crp->cr_backlight_device); - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); - - platform_set_drvdata(pdev, crp); - - return 0; -} - -static void cr_backlight_remove(struct platform_device *pdev) -{ - struct cr_panel *crp = platform_get_drvdata(pdev); - - crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN; - crp->cr_backlight_device->props.brightness = 0; - crp->cr_backlight_device->props.max_brightness = 0; - cr_backlight_set_intensity(crp->cr_backlight_device); - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN); - pci_dev_put(lpc_dev); -} - -static struct platform_driver cr_backlight_driver = { - .probe = cr_backlight_probe, - .remove_new = cr_backlight_remove, - .driver = { - .name = "cr_backlight", - }, -}; - -static struct platform_device *crp; - -static int __init cr_backlight_init(void) -{ - int ret = platform_driver_register(&cr_backlight_driver); - - if (ret) - return ret; - - crp = platform_device_register_simple("cr_backlight", -1, NULL, 0); - if (IS_ERR(crp)) { - platform_driver_unregister(&cr_backlight_driver); - return PTR_ERR(crp); - } - - pr_info("Carillo Ranch Backlight Driver Initialized.\n"); - - return 0; -} - -static void __exit cr_backlight_exit(void) -{ - platform_device_unregister(crp); - platform_driver_unregister(&cr_backlight_driver); -} - -module_init(cr_backlight_init); -module_exit(cr_backlight_exit); - -MODULE_AUTHOR("Tungsten Graphics Inc."); -MODULE_DESCRIPTION("Carillo Ranch Backlight Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index d5909a9206ff..f3a59557db1a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -839,21 +839,6 @@ config FB_I810_I2C If unsure, say Y. -config FB_LE80578 - tristate "Intel LE80578 (Vermilion) support" - depends on FB && PCI && X86 - select FB_IOMEM_HELPERS - select FB_MODE_HELPERS - select VIDEO_NOMODESET - help - This driver supports the LE80578 (Vermilion Range) chipset - -config FB_CARILLO_RANCH - tristate "Intel Carillo Ranch support" - depends on FB_LE80578 && FB && PCI && X86 - help - This driver supports the LE80578 (Carillo Ranch) board - config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" depends on FB && PCI && X86 && AGP_INTEL && EXPERT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 8e15220152bd..7cf7b0af1465 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o obj-$(CONFIG_FB_FM2) += fm2fb.o obj-$(CONFIG_FB_VT8623) += vt8623fb.o obj-$(CONFIG_FB_TRIDENT) += tridentfb.o -obj-$(CONFIG_FB_LE80578) += vermilion/ obj-$(CONFIG_FB_S3) += s3fb.o obj-$(CONFIG_FB_ARK) += arkfb.o obj-$(CONFIG_FB_STI) += stifb.o diff --git a/drivers/video/fbdev/vermilion/Makefile b/drivers/video/fbdev/vermilion/Makefile deleted file mode 100644 index 22e9e4635a00..000000000000 --- a/drivers/video/fbdev/vermilion/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_FB_LE80578) += vmlfb.o -obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o - -vmlfb-objs := vermilion.o -crvml-objs := cr_pll.o diff --git a/drivers/video/fbdev/vermilion/cr_pll.c b/drivers/video/fbdev/vermilion/cr_pll.c deleted file mode 100644 index 79d42b23d850..000000000000 --- a/drivers/video/fbdev/vermilion/cr_pll.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) Intel Corp. 2007. - * All Rights Reserved. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - * This file is part of the Carillo Ranch video subsystem driver. - * - * Authors: - * Thomas Hellstrom - * Alan Hourihane - */ - -#include -#include -#include -#include -#include -#include "vermilion.h" - -/* The PLL Clock register sits on Host bridge */ -#define CRVML_DEVICE_MCH 0x5001 -#define CRVML_REG_MCHBAR 0x44 -#define CRVML_REG_MCHEN 0x54 -#define CRVML_MCHEN_BIT (1 << 28) -#define CRVML_MCHMAP_SIZE 4096 -#define CRVML_REG_CLOCK 0xc3c -#define CRVML_CLOCK_SHIFT 8 -#define CRVML_CLOCK_MASK 0x00000f00 - -static struct pci_dev *mch_dev; -static u32 mch_bar; -static void __iomem *mch_regs_base; -static u32 saved_clock; - -static const unsigned crvml_clocks[] = { - 6750, - 13500, - 27000, - 29700, - 37125, - 54000, - 59400, - 74250, - 120000 - /* - * There are more clocks, but they are disabled on the CR board. - */ -}; - -static const u32 crvml_clock_bits[] = { - 0x0a, - 0x09, - 0x08, - 0x07, - 0x06, - 0x05, - 0x04, - 0x03, - 0x0b -}; - -static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks); - -static int crvml_sys_restore(struct vml_sys *sys) -{ - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; - - iowrite32(saved_clock, clock_reg); - ioread32(clock_reg); - - return 0; -} - -static int crvml_sys_save(struct vml_sys *sys) -{ - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; - - saved_clock = ioread32(clock_reg); - - return 0; -} - -static int crvml_nearest_index(const struct vml_sys *sys, int clock) -{ - int i; - int cur_index = 0; - int cur_diff; - int diff; - - cur_diff = clock - crvml_clocks[0]; - cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; - for (i = 1; i < crvml_num_clocks; ++i) { - diff = clock - crvml_clocks[i]; - diff = (diff < 0) ? -diff : diff; - if (diff < cur_diff) { - cur_index = i; - cur_diff = diff; - } - } - return cur_index; -} - -static int crvml_nearest_clock(const struct vml_sys *sys, int clock) -{ - return crvml_clocks[crvml_nearest_index(sys, clock)]; -} - -static int crvml_set_clock(struct vml_sys *sys, int clock) -{ - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; - int index; - u32 clock_val; - - index = crvml_nearest_index(sys, clock); - - if (crvml_clocks[index] != clock) - return -EINVAL; - - clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK; - clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT; - iowrite32(clock_val, clock_reg); - ioread32(clock_reg); - - return 0; -} - -static struct vml_sys cr_pll_ops = { - .name = "Carillo Ranch", - .save = crvml_sys_save, - .restore = crvml_sys_restore, - .set_clock = crvml_set_clock, - .nearest_clock = crvml_nearest_clock, -}; - -static int __init cr_pll_init(void) -{ - int err; - u32 dev_en; - - mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL, - CRVML_DEVICE_MCH, NULL); - if (!mch_dev) { - printk(KERN_ERR - "Could not find Carillo Ranch MCH device.\n"); - return -ENODEV; - } - - pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en); - if (!(dev_en & CRVML_MCHEN_BIT)) { - printk(KERN_ERR - "Carillo Ranch MCH device was not enabled.\n"); - pci_dev_put(mch_dev); - return -ENODEV; - } - - pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR, - &mch_bar); - mch_regs_base = - ioremap(mch_bar, CRVML_MCHMAP_SIZE); - if (!mch_regs_base) { - printk(KERN_ERR - "Carillo Ranch MCH device was not enabled.\n"); - pci_dev_put(mch_dev); - return -ENODEV; - } - - err = vmlfb_register_subsys(&cr_pll_ops); - if (err) { - printk(KERN_ERR - "Carillo Ranch failed to initialize vml_sys.\n"); - iounmap(mch_regs_base); - pci_dev_put(mch_dev); - return err; - } - - return 0; -} - -static void __exit cr_pll_exit(void) -{ - vmlfb_unregister_subsys(&cr_pll_ops); - - iounmap(mch_regs_base); - pci_dev_put(mch_dev); -} - -module_init(cr_pll_init); -module_exit(cr_pll_exit); - -MODULE_AUTHOR("Tungsten Graphics Inc."); -MODULE_DESCRIPTION("Carillo Ranch PLL Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c deleted file mode 100644 index a087b42ca652..000000000000 --- a/drivers/video/fbdev/vermilion/vermilion.c +++ /dev/null @@ -1,1175 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) Intel Corp. 2007. - * All Rights Reserved. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - * This file is part of the Vermilion Range fb driver. - * - * Authors: - * Thomas Hellström - * Michel Dänzer - * Alan Hourihane - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define VERMILION_DEBUG */ - -#include "vermilion.h" - -#define MODULE_NAME "vmlfb" - -#define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) - -static struct mutex vml_mutex; -static struct list_head global_no_mode; -static struct list_head global_has_mode; -static struct fb_ops vmlfb_ops; -static struct vml_sys *subsys = NULL; -static char *vml_default_mode = "1024x768@60"; -static const struct fb_videomode defaultmode = { - NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED -}; - -static u32 vml_mem_requested = (10 * 1024 * 1024); -static u32 vml_mem_contig = (4 * 1024 * 1024); -static u32 vml_mem_min = (4 * 1024 * 1024); - -static u32 vml_clocks[] = { - 6750, - 13500, - 27000, - 29700, - 37125, - 54000, - 59400, - 74250, - 120000, - 148500 -}; - -static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks); - -/* - * Allocate a contiguous vram area and make its linear kernel map - * uncached. - */ - -static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order, - unsigned min_order) -{ - gfp_t flags; - unsigned long i; - - max_order++; - do { - /* - * Really try hard to get the needed memory. - * We need memory below the first 32MB, so we - * add the __GFP_DMA flag that guarantees that we are - * below the first 16MB. - */ - - flags = __GFP_DMA | __GFP_HIGH | __GFP_KSWAPD_RECLAIM; - va->logical = - __get_free_pages(flags, --max_order); - } while (va->logical == 0 && max_order > min_order); - - if (!va->logical) - return -ENOMEM; - - va->phys = virt_to_phys((void *)va->logical); - va->size = PAGE_SIZE << max_order; - va->order = max_order; - - /* - * It seems like __get_free_pages only ups the usage count - * of the first page. This doesn't work with fault mapping, so - * up the usage count once more (XXX: should use split_page or - * compound page). - */ - - memset((void *)va->logical, 0x00, va->size); - for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) { - get_page(virt_to_page(i)); - } - - /* - * Change caching policy of the linear kernel map to avoid - * mapping type conflicts with user-space mappings. - */ - set_pages_uc(virt_to_page(va->logical), va->size >> PAGE_SHIFT); - - printk(KERN_DEBUG MODULE_NAME - ": Allocated %ld bytes vram area at 0x%08lx\n", - va->size, va->phys); - - return 0; -} - -/* - * Free a contiguous vram area and reset its linear kernel map - * mapping type. - */ - -static void vmlfb_free_vram_area(struct vram_area *va) -{ - unsigned long j; - - if (va->logical) { - - /* - * Reset the linear kernel map caching policy. - */ - - set_pages_wb(virt_to_page(va->logical), - va->size >> PAGE_SHIFT); - - /* - * Decrease the usage count on the pages we've used - * to compensate for upping when allocating. - */ - - for (j = va->logical; j < va->logical + va->size; - j += PAGE_SIZE) { - (void)put_page_testzero(virt_to_page(j)); - } - - printk(KERN_DEBUG MODULE_NAME - ": Freeing %ld bytes vram area at 0x%08lx\n", - va->size, va->phys); - free_pages(va->logical, va->order); - - va->logical = 0; - } -} - -/* - * Free allocated vram. - */ - -static void vmlfb_free_vram(struct vml_info *vinfo) -{ - int i; - - for (i = 0; i < vinfo->num_areas; ++i) { - vmlfb_free_vram_area(&vinfo->vram[i]); - } - vinfo->num_areas = 0; -} - -/* - * Allocate vram. Currently we try to allocate contiguous areas from the - * __GFP_DMA zone and puzzle them together. A better approach would be to - * allocate one contiguous area for scanout and use one-page allocations for - * offscreen areas. This requires user-space and GPU virtual mappings. - */ - -static int vmlfb_alloc_vram(struct vml_info *vinfo, - size_t requested, - size_t min_total, size_t min_contig) -{ - int i, j; - int order; - int contiguous; - int err; - struct vram_area *va; - struct vram_area *va2; - - vinfo->num_areas = 0; - for (i = 0; i < VML_VRAM_AREAS; ++i) { - va = &vinfo->vram[i]; - order = 0; - - while (requested > (PAGE_SIZE << order) && order <= MAX_ORDER) - order++; - - err = vmlfb_alloc_vram_area(va, order, 0); - - if (err) - break; - - if (i == 0) { - vinfo->vram_start = va->phys; - vinfo->vram_logical = (void __iomem *) va->logical; - vinfo->vram_contig_size = va->size; - vinfo->num_areas = 1; - } else { - contiguous = 0; - - for (j = 0; j < i; ++j) { - va2 = &vinfo->vram[j]; - if (va->phys + va->size == va2->phys || - va2->phys + va2->size == va->phys) { - contiguous = 1; - break; - } - } - - if (contiguous) { - vinfo->num_areas++; - if (va->phys < vinfo->vram_start) { - vinfo->vram_start = va->phys; - vinfo->vram_logical = - (void __iomem *)va->logical; - } - vinfo->vram_contig_size += va->size; - } else { - vmlfb_free_vram_area(va); - break; - } - } - - if (requested < va->size) - break; - else - requested -= va->size; - } - - if (vinfo->vram_contig_size > min_total && - vinfo->vram_contig_size > min_contig) { - - printk(KERN_DEBUG MODULE_NAME - ": Contiguous vram: %ld bytes at physical 0x%08lx.\n", - (unsigned long)vinfo->vram_contig_size, - (unsigned long)vinfo->vram_start); - - return 0; - } - - printk(KERN_ERR MODULE_NAME - ": Could not allocate requested minimal amount of vram.\n"); - - vmlfb_free_vram(vinfo); - - return -ENOMEM; -} - -/* - * Find the GPU to use with our display controller. - */ - -static int vmlfb_get_gpu(struct vml_par *par) -{ - mutex_lock(&vml_mutex); - - par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL); - - if (!par->gpu) { - mutex_unlock(&vml_mutex); - return -ENODEV; - } - - mutex_unlock(&vml_mutex); - - if (pci_enable_device(par->gpu) < 0) { - pci_dev_put(par->gpu); - return -ENODEV; - } - - return 0; -} - -/* - * Find a contiguous vram area that contains a given offset from vram start. - */ -static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset) -{ - unsigned long aoffset; - unsigned i; - - for (i = 0; i < vinfo->num_areas; ++i) { - aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start); - - if (aoffset < vinfo->vram[i].size) { - return 0; - } - } - - return -EINVAL; -} - -/* - * Remap the MMIO register spaces of the VDC and the GPU. - */ - -static int vmlfb_enable_mmio(struct vml_par *par) -{ - int err; - - par->vdc_mem_base = pci_resource_start(par->vdc, 0); - par->vdc_mem_size = pci_resource_len(par->vdc, 0); - if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) { - printk(KERN_ERR MODULE_NAME - ": Could not claim display controller MMIO.\n"); - return -EBUSY; - } - par->vdc_mem = ioremap(par->vdc_mem_base, par->vdc_mem_size); - if (par->vdc_mem == NULL) { - printk(KERN_ERR MODULE_NAME - ": Could not map display controller MMIO.\n"); - err = -ENOMEM; - goto out_err_0; - } - - par->gpu_mem_base = pci_resource_start(par->gpu, 0); - par->gpu_mem_size = pci_resource_len(par->gpu, 0); - if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) { - printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n"); - err = -EBUSY; - goto out_err_1; - } - par->gpu_mem = ioremap(par->gpu_mem_base, par->gpu_mem_size); - if (par->gpu_mem == NULL) { - printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n"); - err = -ENOMEM; - goto out_err_2; - } - - return 0; - -out_err_2: - release_mem_region(par->gpu_mem_base, par->gpu_mem_size); -out_err_1: - iounmap(par->vdc_mem); -out_err_0: - release_mem_region(par->vdc_mem_base, par->vdc_mem_size); - return err; -} - -/* - * Unmap the VDC and GPU register spaces. - */ - -static void vmlfb_disable_mmio(struct vml_par *par) -{ - iounmap(par->gpu_mem); - release_mem_region(par->gpu_mem_base, par->gpu_mem_size); - iounmap(par->vdc_mem); - release_mem_region(par->vdc_mem_base, par->vdc_mem_size); -} - -/* - * Release and uninit the VDC and GPU. - */ - -static void vmlfb_release_devices(struct vml_par *par) -{ - if (atomic_dec_and_test(&par->refcount)) { - pci_disable_device(par->gpu); - pci_disable_device(par->vdc); - } -} - -/* - * Free up allocated resources for a device. - */ - -static void vml_pci_remove(struct pci_dev *dev) -{ - struct fb_info *info; - struct vml_info *vinfo; - struct vml_par *par; - - info = pci_get_drvdata(dev); - if (info) { - vinfo = container_of(info, struct vml_info, info); - par = vinfo->par; - mutex_lock(&vml_mutex); - unregister_framebuffer(info); - fb_dealloc_cmap(&info->cmap); - vmlfb_free_vram(vinfo); - vmlfb_disable_mmio(par); - vmlfb_release_devices(par); - kfree(vinfo); - kfree(par); - mutex_unlock(&vml_mutex); - } -} - -static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var) -{ - switch (var->bits_per_pixel) { - case 16: - var->blue.offset = 0; - var->blue.length = 5; - var->green.offset = 5; - var->green.length = 5; - var->red.offset = 10; - var->red.length = 5; - var->transp.offset = 15; - var->transp.length = 1; - break; - case 32: - var->blue.offset = 0; - var->blue.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->red.offset = 16; - var->red.length = 8; - var->transp.offset = 24; - var->transp.length = 0; - break; - default: - break; - } - - var->blue.msb_right = var->green.msb_right = - var->red.msb_right = var->transp.msb_right = 0; -} - -/* - * Device initialization. - * We initialize one vml_par struct per device and one vml_info - * struct per pipe. Currently we have only one pipe. - */ - -static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - struct vml_info *vinfo; - struct fb_info *info; - struct vml_par *par; - int err; - - err = aperture_remove_conflicting_pci_devices(dev, "vmlfb"); - if (err) - return err; - - par = kzalloc(sizeof(*par), GFP_KERNEL); - if (par == NULL) - return -ENOMEM; - - vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL); - if (vinfo == NULL) { - err = -ENOMEM; - goto out_err_0; - } - - vinfo->par = par; - par->vdc = dev; - atomic_set(&par->refcount, 1); - - switch (id->device) { - case VML_DEVICE_VDC: - if ((err = vmlfb_get_gpu(par))) - goto out_err_1; - pci_set_drvdata(dev, &vinfo->info); - break; - default: - err = -ENODEV; - goto out_err_1; - } - - info = &vinfo->info; - info->flags = FBINFO_PARTIAL_PAN_OK; - - err = vmlfb_enable_mmio(par); - if (err) - goto out_err_2; - - err = vmlfb_alloc_vram(vinfo, vml_mem_requested, - vml_mem_contig, vml_mem_min); - if (err) - goto out_err_3; - - strcpy(info->fix.id, "Vermilion Range"); - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; - info->fix.smem_start = vinfo->vram_start; - info->fix.smem_len = vinfo->vram_contig_size; - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.ypanstep = 1; - info->fix.xpanstep = 1; - info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; - info->screen_base = vinfo->vram_logical; - info->pseudo_palette = vinfo->pseudo_palette; - info->par = par; - info->fbops = &vmlfb_ops; - info->device = &dev->dev; - - INIT_LIST_HEAD(&vinfo->head); - vinfo->pipe_disabled = 1; - vinfo->cur_blank_mode = FB_BLANK_UNBLANK; - - info->var.grayscale = 0; - info->var.bits_per_pixel = 16; - vmlfb_set_pref_pixel_format(&info->var); - - if (!fb_find_mode - (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) { - printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n"); - } - - if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { - err = -ENOMEM; - goto out_err_4; - } - - err = register_framebuffer(info); - if (err) { - printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n"); - goto out_err_5; - } - - printk("Initialized vmlfb\n"); - - return 0; - -out_err_5: - fb_dealloc_cmap(&info->cmap); -out_err_4: - vmlfb_free_vram(vinfo); -out_err_3: - vmlfb_disable_mmio(par); -out_err_2: - vmlfb_release_devices(par); -out_err_1: - kfree(vinfo); -out_err_0: - kfree(par); - return err; -} - -static int vmlfb_open(struct fb_info *info, int user) -{ - /* - * Save registers here? - */ - return 0; -} - -static int vmlfb_release(struct fb_info *info, int user) -{ - /* - * Restore registers here. - */ - - return 0; -} - -static int vml_nearest_clock(int clock) -{ - - int i; - int cur_index; - int cur_diff; - int diff; - - cur_index = 0; - cur_diff = clock - vml_clocks[0]; - cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; - for (i = 1; i < vml_num_clocks; ++i) { - diff = clock - vml_clocks[i]; - diff = (diff < 0) ? -diff : diff; - if (diff < cur_diff) { - cur_index = i; - cur_diff = diff; - } - } - return vml_clocks[cur_index]; -} - -static int vmlfb_check_var_locked(struct fb_var_screeninfo *var, - struct vml_info *vinfo) -{ - u32 pitch; - u64 mem; - int nearest_clock; - int clock; - int clock_diff; - struct fb_var_screeninfo v; - - v = *var; - clock = PICOS2KHZ(var->pixclock); - - if (subsys && subsys->nearest_clock) { - nearest_clock = subsys->nearest_clock(subsys, clock); - } else { - nearest_clock = vml_nearest_clock(clock); - } - - /* - * Accept a 20% diff. - */ - - clock_diff = nearest_clock - clock; - clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff; - if (clock_diff > clock / 5) { -#if 0 - printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock); -#endif - return -EINVAL; - } - - v.pixclock = KHZ2PICOS(nearest_clock); - - if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) { - printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n"); - return -EINVAL; - } - if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) { - printk(KERN_DEBUG MODULE_NAME - ": Virtual resolution failure.\n"); - return -EINVAL; - } - switch (v.bits_per_pixel) { - case 0 ... 16: - v.bits_per_pixel = 16; - break; - case 17 ... 32: - v.bits_per_pixel = 32; - break; - default: - printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n", - var->bits_per_pixel); - return -EINVAL; - } - - pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40); - mem = (u64)pitch * var->yres_virtual; - if (mem > vinfo->vram_contig_size) { - return -ENOMEM; - } - - switch (v.bits_per_pixel) { - case 16: - if (var->blue.offset != 0 || - var->blue.length != 5 || - var->green.offset != 5 || - var->green.length != 5 || - var->red.offset != 10 || - var->red.length != 5 || - var->transp.offset != 15 || var->transp.length != 1) { - vmlfb_set_pref_pixel_format(&v); - } - break; - case 32: - if (var->blue.offset != 0 || - var->blue.length != 8 || - var->green.offset != 8 || - var->green.length != 8 || - var->red.offset != 16 || - var->red.length != 8 || - (var->transp.length != 0 && var->transp.length != 8) || - (var->transp.length == 8 && var->transp.offset != 24)) { - vmlfb_set_pref_pixel_format(&v); - } - break; - default: - return -EINVAL; - } - - *var = v; - - return 0; -} - -static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct vml_info *vinfo = container_of(info, struct vml_info, info); - int ret; - - mutex_lock(&vml_mutex); - ret = vmlfb_check_var_locked(var, vinfo); - mutex_unlock(&vml_mutex); - - return ret; -} - -static void vml_wait_vblank(struct vml_info *vinfo) -{ - /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ - mdelay(20); -} - -static void vmlfb_disable_pipe(struct vml_info *vinfo) -{ - struct vml_par *par = vinfo->par; - - /* Disable the MDVO pad */ - VML_WRITE32(par, VML_RCOMPSTAT, 0); - while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ; - - /* Disable display planes */ - VML_WRITE32(par, VML_DSPCCNTR, - VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE); - (void)VML_READ32(par, VML_DSPCCNTR); - /* Wait for vblank for the disable to take effect */ - vml_wait_vblank(vinfo); - - /* Next, disable display pipes */ - VML_WRITE32(par, VML_PIPEACONF, 0); - (void)VML_READ32(par, VML_PIPEACONF); - - vinfo->pipe_disabled = 1; -} - -#ifdef VERMILION_DEBUG -static void vml_dump_regs(struct vml_info *vinfo) -{ - struct vml_par *par = vinfo->par; - - printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n"); - printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_HTOTAL_A)); - printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_HBLANK_A)); - printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_HSYNC_A)); - printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_VTOTAL_A)); - printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_VBLANK_A)); - printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_VSYNC_A)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPCSTRIDE)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPCSIZE)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPCPOS)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPARB)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPCADDR)); - printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_BCLRPAT_A)); - printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n", - (unsigned)VML_READ32(par, VML_CANVSCLR_A)); - printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n", - (unsigned)VML_READ32(par, VML_PIPEASRC)); - printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n", - (unsigned)VML_READ32(par, VML_PIPEACONF)); - printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n", - (unsigned)VML_READ32(par, VML_DSPCCNTR)); - printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n", - (unsigned)VML_READ32(par, VML_RCOMPSTAT)); - printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n"); -} -#endif - -static int vmlfb_set_par_locked(struct vml_info *vinfo) -{ - struct vml_par *par = vinfo->par; - struct fb_info *info = &vinfo->info; - struct fb_var_screeninfo *var = &info->var; - u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end; - u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end; - u32 dspcntr; - int clock; - - vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; - vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40); - info->fix.line_length = vinfo->stride; - - if (!subsys) - return 0; - - htotal = - var->xres + var->right_margin + var->hsync_len + var->left_margin; - hactive = var->xres; - hblank_start = var->xres; - hblank_end = htotal; - hsync_start = hactive + var->right_margin; - hsync_end = hsync_start + var->hsync_len; - - vtotal = - var->yres + var->lower_margin + var->vsync_len + var->upper_margin; - vactive = var->yres; - vblank_start = var->yres; - vblank_end = vtotal; - vsync_start = vactive + var->lower_margin; - vsync_end = vsync_start + var->vsync_len; - - dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS; - clock = PICOS2KHZ(var->pixclock); - - if (subsys->nearest_clock) { - clock = subsys->nearest_clock(subsys, clock); - } else { - clock = vml_nearest_clock(clock); - } - printk(KERN_DEBUG MODULE_NAME - ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal, - ((clock / htotal) * 1000) / vtotal); - - switch (var->bits_per_pixel) { - case 16: - dspcntr |= VML_GFX_ARGB1555; - break; - case 32: - if (var->transp.length == 8) - dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT; - else - dspcntr |= VML_GFX_RGB0888; - break; - default: - return -EINVAL; - } - - vmlfb_disable_pipe(vinfo); - mb(); - - if (subsys->set_clock) - subsys->set_clock(subsys, clock); - else - return -EINVAL; - - VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1)); - VML_WRITE32(par, VML_HBLANK_A, - ((hblank_end - 1) << 16) | (hblank_start - 1)); - VML_WRITE32(par, VML_HSYNC_A, - ((hsync_end - 1) << 16) | (hsync_start - 1)); - VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1)); - VML_WRITE32(par, VML_VBLANK_A, - ((vblank_end - 1) << 16) | (vblank_start - 1)); - VML_WRITE32(par, VML_VSYNC_A, - ((vsync_end - 1) << 16) | (vsync_start - 1)); - VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride); - VML_WRITE32(par, VML_DSPCSIZE, - ((var->yres - 1) << 16) | (var->xres - 1)); - VML_WRITE32(par, VML_DSPCPOS, 0x00000000); - VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT); - VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000); - VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000); - VML_WRITE32(par, VML_PIPEASRC, - ((var->xres - 1) << 16) | (var->yres - 1)); - - wmb(); - VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE); - wmb(); - VML_WRITE32(par, VML_DSPCCNTR, dspcntr); - wmb(); - VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + - var->yoffset * vinfo->stride + - var->xoffset * vinfo->bytes_per_pixel); - - VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE); - - while (!(VML_READ32(par, VML_RCOMPSTAT) & - (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ; - - vinfo->pipe_disabled = 0; -#ifdef VERMILION_DEBUG - vml_dump_regs(vinfo); -#endif - - return 0; -} - -static int vmlfb_set_par(struct fb_info *info) -{ - struct vml_info *vinfo = container_of(info, struct vml_info, info); - int ret; - - mutex_lock(&vml_mutex); - list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode); - ret = vmlfb_set_par_locked(vinfo); - - mutex_unlock(&vml_mutex); - return ret; -} - -static int vmlfb_blank_locked(struct vml_info *vinfo) -{ - struct vml_par *par = vinfo->par; - u32 cur = VML_READ32(par, VML_PIPEACONF); - - switch (vinfo->cur_blank_mode) { - case FB_BLANK_UNBLANK: - if (vinfo->pipe_disabled) { - vmlfb_set_par_locked(vinfo); - } - VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER); - (void)VML_READ32(par, VML_PIPEACONF); - break; - case FB_BLANK_NORMAL: - if (vinfo->pipe_disabled) { - vmlfb_set_par_locked(vinfo); - } - VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER); - (void)VML_READ32(par, VML_PIPEACONF); - break; - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - if (!vinfo->pipe_disabled) { - vmlfb_disable_pipe(vinfo); - } - break; - case FB_BLANK_POWERDOWN: - if (!vinfo->pipe_disabled) { - vmlfb_disable_pipe(vinfo); - } - break; - default: - return -EINVAL; - } - - return 0; -} - -static int vmlfb_blank(int blank_mode, struct fb_info *info) -{ - struct vml_info *vinfo = container_of(info, struct vml_info, info); - int ret; - - mutex_lock(&vml_mutex); - vinfo->cur_blank_mode = blank_mode; - ret = vmlfb_blank_locked(vinfo); - mutex_unlock(&vml_mutex); - return ret; -} - -static int vmlfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct vml_info *vinfo = container_of(info, struct vml_info, info); - struct vml_par *par = vinfo->par; - - mutex_lock(&vml_mutex); - VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + - var->yoffset * vinfo->stride + - var->xoffset * vinfo->bytes_per_pixel); - (void)VML_READ32(par, VML_DSPCADDR); - mutex_unlock(&vml_mutex); - - return 0; -} - -static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) -{ - u32 v; - - if (regno >= 16) - return -EINVAL; - - if (info->var.grayscale) { - red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; - } - - if (info->fix.visual != FB_VISUAL_TRUECOLOR) - return -EINVAL; - - red = VML_TOHW(red, info->var.red.length); - blue = VML_TOHW(blue, info->var.blue.length); - green = VML_TOHW(green, info->var.green.length); - transp = VML_TOHW(transp, info->var.transp.length); - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - - switch (info->var.bits_per_pixel) { - case 16: - ((u32 *) info->pseudo_palette)[regno] = v; - break; - case 24: - case 32: - ((u32 *) info->pseudo_palette)[regno] = v; - break; - } - return 0; -} - -static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct vml_info *vinfo = container_of(info, struct vml_info, info); - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - int ret; - unsigned long prot; - - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); - - ret = vmlfb_vram_offset(vinfo, offset); - if (ret) - return -EINVAL; - - prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK; - pgprot_val(vma->vm_page_prot) = - prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS); - - return vm_iomap_memory(vma, vinfo->vram_start, - vinfo->vram_contig_size); -} - -static int vmlfb_sync(struct fb_info *info) -{ - return 0; -} - -static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor) -{ - return -EINVAL; /* just to force soft_cursor() call */ -} - -static struct fb_ops vmlfb_ops = { - .owner = THIS_MODULE, - .fb_open = vmlfb_open, - .fb_release = vmlfb_release, - __FB_DEFAULT_IOMEM_OPS_RDWR, - .fb_check_var = vmlfb_check_var, - .fb_set_par = vmlfb_set_par, - .fb_blank = vmlfb_blank, - .fb_pan_display = vmlfb_pan_display, - __FB_DEFAULT_IOMEM_OPS_DRAW, - .fb_cursor = vmlfb_cursor, - .fb_sync = vmlfb_sync, - .fb_mmap = vmlfb_mmap, - .fb_setcolreg = vmlfb_setcolreg -}; - -static const struct pci_device_id vml_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)}, - {0} -}; - -static struct pci_driver vmlfb_pci_driver = { - .name = "vmlfb", - .id_table = vml_ids, - .probe = vml_pci_probe, - .remove = vml_pci_remove, -}; - -static void __exit vmlfb_cleanup(void) -{ - pci_unregister_driver(&vmlfb_pci_driver); -} - -static int __init vmlfb_init(void) -{ - -#ifndef MODULE - char *option = NULL; -#endif - - if (fb_modesetting_disabled("vmlfb")) - return -ENODEV; - -#ifndef MODULE - if (fb_get_options(MODULE_NAME, &option)) - return -ENODEV; -#endif - - printk(KERN_DEBUG MODULE_NAME ": initializing\n"); - mutex_init(&vml_mutex); - INIT_LIST_HEAD(&global_no_mode); - INIT_LIST_HEAD(&global_has_mode); - - return pci_register_driver(&vmlfb_pci_driver); -} - -int vmlfb_register_subsys(struct vml_sys *sys) -{ - struct vml_info *entry; - struct list_head *list; - u32 save_activate; - - mutex_lock(&vml_mutex); - if (subsys != NULL) { - subsys->restore(subsys); - } - subsys = sys; - subsys->save(subsys); - - /* - * We need to restart list traversal for each item, since we - * release the list mutex in the loop. - */ - - list = global_no_mode.next; - while (list != &global_no_mode) { - list_del_init(list); - entry = list_entry(list, struct vml_info, head); - - /* - * First, try the current mode which might not be - * completely validated with respect to the pixel clock. - */ - - if (!vmlfb_check_var_locked(&entry->info.var, entry)) { - vmlfb_set_par_locked(entry); - list_add_tail(list, &global_has_mode); - } else { - - /* - * Didn't work. Try to find another mode, - * that matches this subsys. - */ - - mutex_unlock(&vml_mutex); - save_activate = entry->info.var.activate; - entry->info.var.bits_per_pixel = 16; - vmlfb_set_pref_pixel_format(&entry->info.var); - if (fb_find_mode(&entry->info.var, - &entry->info, - vml_default_mode, NULL, 0, NULL, 16)) { - entry->info.var.activate |= - FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; - fb_set_var(&entry->info, &entry->info.var); - } else { - printk(KERN_ERR MODULE_NAME - ": Sorry. no mode found for this subsys.\n"); - } - entry->info.var.activate = save_activate; - mutex_lock(&vml_mutex); - } - vmlfb_blank_locked(entry); - list = global_no_mode.next; - } - mutex_unlock(&vml_mutex); - - printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n", - subsys->name ? subsys->name : "unknown"); - return 0; -} - -EXPORT_SYMBOL_GPL(vmlfb_register_subsys); - -void vmlfb_unregister_subsys(struct vml_sys *sys) -{ - struct vml_info *entry, *next; - - mutex_lock(&vml_mutex); - if (subsys != sys) { - mutex_unlock(&vml_mutex); - return; - } - subsys->restore(subsys); - subsys = NULL; - list_for_each_entry_safe(entry, next, &global_has_mode, head) { - printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n"); - vmlfb_disable_pipe(entry); - list_move_tail(&entry->head, &global_no_mode); - } - mutex_unlock(&vml_mutex); -} - -EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys); - -module_init(vmlfb_init); -module_exit(vmlfb_cleanup); - -MODULE_AUTHOR("Tungsten Graphics"); -MODULE_DESCRIPTION("Initialization of the Vermilion display devices"); -MODULE_VERSION("1.0.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/vermilion/vermilion.h b/drivers/video/fbdev/vermilion/vermilion.h deleted file mode 100644 index 19cbbe76aba7..000000000000 --- a/drivers/video/fbdev/vermilion/vermilion.h +++ /dev/null @@ -1,245 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (c) Intel Corp. 2007. - * All Rights Reserved. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - * This file is part of the Vermilion Range fb driver. - * - * Authors: - * Thomas Hellström - */ - -#ifndef _VERMILION_H_ -#define _VERMILION_H_ - -#include -#include -#include -#include - -#define VML_DEVICE_GPU 0x5002 -#define VML_DEVICE_VDC 0x5009 - -#define VML_VRAM_AREAS 3 -#define VML_MAX_XRES 1024 -#define VML_MAX_YRES 768 -#define VML_MAX_XRES_VIRTUAL 1040 - -/* - * Display controller registers: - */ - -/* Display controller 10-bit color representation */ - -#define VML_R_MASK 0x3FF00000 -#define VML_R_SHIFT 20 -#define VML_G_MASK 0x000FFC00 -#define VML_G_SHIFT 10 -#define VML_B_MASK 0x000003FF -#define VML_B_SHIFT 0 - -/* Graphics plane control */ -#define VML_DSPCCNTR 0x00072180 -#define VML_GFX_ENABLE 0x80000000 -#define VML_GFX_GAMMABYPASS 0x40000000 -#define VML_GFX_ARGB1555 0x0C000000 -#define VML_GFX_RGB0888 0x18000000 -#define VML_GFX_ARGB8888 0x1C000000 -#define VML_GFX_ALPHACONST 0x02000000 -#define VML_GFX_ALPHAMULT 0x01000000 -#define VML_GFX_CONST_ALPHA 0x000000FF - -/* Graphics plane start address. Pixel aligned. */ -#define VML_DSPCADDR 0x00072184 - -/* Graphics plane stride register. */ -#define VML_DSPCSTRIDE 0x00072188 - -/* Graphics plane position register. */ -#define VML_DSPCPOS 0x0007218C -#define VML_POS_YMASK 0x0FFF0000 -#define VML_POS_YSHIFT 16 -#define VML_POS_XMASK 0x00000FFF -#define VML_POS_XSHIFT 0 - -/* Graphics plane height and width */ -#define VML_DSPCSIZE 0x00072190 -#define VML_SIZE_HMASK 0x0FFF0000 -#define VML_SIZE_HSHIFT 16 -#define VML_SISE_WMASK 0x00000FFF -#define VML_SIZE_WSHIFT 0 - -/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */ -#define VML_DSPCGAMLUT 0x00072200 - -/* Pixel video output configuration register */ -#define VML_PVOCONFIG 0x00061140 -#define VML_CONFIG_BASE 0x80000000 -#define VML_CONFIG_PIXEL_SWAP 0x04000000 -#define VML_CONFIG_DE_INV 0x01000000 -#define VML_CONFIG_HREF_INV 0x00400000 -#define VML_CONFIG_VREF_INV 0x00100000 -#define VML_CONFIG_CLK_INV 0x00040000 -#define VML_CONFIG_CLK_DIV2 0x00010000 -#define VML_CONFIG_ESTRB_INV 0x00008000 - -/* Pipe A Horizontal total register */ -#define VML_HTOTAL_A 0x00060000 -#define VML_HTOTAL_MASK 0x1FFF0000 -#define VML_HTOTAL_SHIFT 16 -#define VML_HTOTAL_VAL 8192 -#define VML_HACTIVE_MASK 0x000007FF -#define VML_HACTIVE_SHIFT 0 -#define VML_HACTIVE_VAL 4096 - -/* Pipe A Horizontal Blank register */ -#define VML_HBLANK_A 0x00060004 -#define VML_HBLANK_END_MASK 0x1FFF0000 -#define VML_HBLANK_END_SHIFT 16 -#define VML_HBLANK_END_VAL 8192 -#define VML_HBLANK_START_MASK 0x00001FFF -#define VML_HBLANK_START_SHIFT 0 -#define VML_HBLANK_START_VAL 8192 - -/* Pipe A Horizontal Sync register */ -#define VML_HSYNC_A 0x00060008 -#define VML_HSYNC_END_MASK 0x1FFF0000 -#define VML_HSYNC_END_SHIFT 16 -#define VML_HSYNC_END_VAL 8192 -#define VML_HSYNC_START_MASK 0x00001FFF -#define VML_HSYNC_START_SHIFT 0 -#define VML_HSYNC_START_VAL 8192 - -/* Pipe A Vertical total register */ -#define VML_VTOTAL_A 0x0006000C -#define VML_VTOTAL_MASK 0x1FFF0000 -#define VML_VTOTAL_SHIFT 16 -#define VML_VTOTAL_VAL 8192 -#define VML_VACTIVE_MASK 0x000007FF -#define VML_VACTIVE_SHIFT 0 -#define VML_VACTIVE_VAL 4096 - -/* Pipe A Vertical Blank register */ -#define VML_VBLANK_A 0x00060010 -#define VML_VBLANK_END_MASK 0x1FFF0000 -#define VML_VBLANK_END_SHIFT 16 -#define VML_VBLANK_END_VAL 8192 -#define VML_VBLANK_START_MASK 0x00001FFF -#define VML_VBLANK_START_SHIFT 0 -#define VML_VBLANK_START_VAL 8192 - -/* Pipe A Vertical Sync register */ -#define VML_VSYNC_A 0x00060014 -#define VML_VSYNC_END_MASK 0x1FFF0000 -#define VML_VSYNC_END_SHIFT 16 -#define VML_VSYNC_END_VAL 8192 -#define VML_VSYNC_START_MASK 0x00001FFF -#define VML_VSYNC_START_SHIFT 0 -#define VML_VSYNC_START_VAL 8192 - -/* Pipe A Source Image size (minus one - equal to active size) - * Programmable while pipe is enabled. - */ -#define VML_PIPEASRC 0x0006001C -#define VML_PIPEASRC_HMASK 0x0FFF0000 -#define VML_PIPEASRC_HSHIFT 16 -#define VML_PIPEASRC_VMASK 0x00000FFF -#define VML_PIPEASRC_VSHIFT 0 - -/* Pipe A Border Color Pattern register (10 bit color) */ -#define VML_BCLRPAT_A 0x00060020 - -/* Pipe A Canvas Color register (10 bit color) */ -#define VML_CANVSCLR_A 0x00060024 - -/* Pipe A Configuration register */ -#define VML_PIPEACONF 0x00070008 -#define VML_PIPE_BASE 0x00000000 -#define VML_PIPE_ENABLE 0x80000000 -#define VML_PIPE_FORCE_BORDER 0x02000000 -#define VML_PIPE_PLANES_OFF 0x00080000 -#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000 - -/* Pipe A FIFO setting */ -#define VML_DSPARB 0x00070030 -#define VML_FIFO_DEFAULT 0x00001D9C - -/* MDVO rcomp status & pads control register */ -#define VML_RCOMPSTAT 0x00070048 -#define VML_MDVO_VDC_I_RCOMP 0x80000000 -#define VML_MDVO_POWERSAVE_OFF 0x00000008 -#define VML_MDVO_PAD_ENABLE 0x00000004 -#define VML_MDVO_PULLDOWN_ENABLE 0x00000001 - -struct vml_par { - struct pci_dev *vdc; - u64 vdc_mem_base; - u64 vdc_mem_size; - char __iomem *vdc_mem; - - struct pci_dev *gpu; - u64 gpu_mem_base; - u64 gpu_mem_size; - char __iomem *gpu_mem; - - atomic_t refcount; -}; - -struct vram_area { - unsigned long logical; - unsigned long phys; - unsigned long size; - unsigned order; -}; - -struct vml_info { - struct fb_info info; - struct vml_par *par; - struct list_head head; - struct vram_area vram[VML_VRAM_AREAS]; - u64 vram_start; - u64 vram_contig_size; - u32 num_areas; - void __iomem *vram_logical; - u32 pseudo_palette[16]; - u32 stride; - u32 bytes_per_pixel; - atomic_t vmas; - int cur_blank_mode; - int pipe_disabled; -}; - -/* - * Subsystem - */ - -struct vml_sys { - char *name; - - /* - * Save / Restore; - */ - - int (*save) (struct vml_sys * sys); - int (*restore) (struct vml_sys * sys); - - /* - * PLL programming; - */ - - int (*set_clock) (struct vml_sys * sys, int clock); - int (*nearest_clock) (const struct vml_sys * sys, int clock); -}; - -extern int vmlfb_register_subsys(struct vml_sys *sys); -extern void vmlfb_unregister_subsys(struct vml_sys *sys); - -#define VML_READ32(_par, _offset) \ - (ioread32((_par)->vdc_mem + (_offset))) -#define VML_WRITE32(_par, _offset, _value) \ - iowrite32(_value, (_par)->vdc_mem + (_offset)) - -#endif From patchwork Fri Dec 8 22:47:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 752127 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="gza9M9EO" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6FF6D1; Fri, 8 Dec 2023 14:47:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=iTwSrBS/psQWYmq0oJLKHMv2C9G6WtXP3GgAfwSGatU=; b=gza9M9EOhH7pw0bTgrrtTAVF96 HovQnSj+0EpRHJ88ltnURTrwdHXobInuzWt9mgX4F8qiikHRaPFLbrvse+JwL9aVzxj+bR5EJ7nHJ d9eApY4/zCcwldLY3K06rJN6yPok8gFWR/ZjzgjSQMrwfYc68mIBvoMVXUdJizmuwrphQNTf9cIyc yR8qVQ43SI5cQK30TUgnodfGJbKh3tx3yxhbcD7VDMZdCVp7x+YWhRG7+0Fq8sYDdfYjSRK/ODAxp b6zoYSDvgeb2fCfIGFkwmFGDehdsQejg6bXOxICqlh3jsNN1AkEB1Em7XgmpXeBFjDn9BhZGS4Z2M r+14LTmQ==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1rBjcf-006j5V-Ox; Fri, 08 Dec 2023 22:47:05 +0000 From: "Matthew Wilcox (Oracle)" To: linux-fbdev@vger.kernel.org, linux-mtd@lists.infradead.org Cc: "Matthew Wilcox (Oracle)" , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Richard Weinberger , Lee Jones , Andy Lowe , Thomas Hellstrom , Alan Hourihane Subject: [PATCH 2/2] mtd: Remove support for Carillo Ranch driver Date: Fri, 8 Dec 2023 22:47:03 +0000 Message-Id: <20231208224703.1603264-2-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231208224703.1603264-1-willy@infradead.org> References: <20231208224703.1603264-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fbdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 As far as anybody can tell, this product never shipped. If it did, it shipped in 2007 and nobody has access to one any more. Remove the mtd NOR driver. Signed-off-by: Matthew Wilcox (Oracle) --- drivers/mtd/maps/Kconfig | 7 - drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/intel_vr_nor.c | 265 -------------------------------- 3 files changed, 273 deletions(-) delete mode 100644 drivers/mtd/maps/intel_vr_nor.c diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index e098ae937ce8..8a8b19874e23 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -341,13 +341,6 @@ config MTD_UCLINUX help Map driver to support image based filesystems for uClinux. -config MTD_INTEL_VR_NOR - tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0" - depends on PCI - help - Map driver for a NOR flash bank located on the Expansion Bus of the - Intel Vermilion Range chipset. - config MTD_PLATRAM tristate "Map driver for platform device RAM (mtd-ram)" select MTD_RAM diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 094cfb244086..a9083c888e3b 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -40,6 +40,5 @@ obj-$(CONFIG_MTD_UCLINUX) += uclinux.o obj-$(CONFIG_MTD_NETtel) += nettel.o obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o -obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o obj-$(CONFIG_MTD_VMU) += vmu-flash.o obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c deleted file mode 100644 index d67b845b0e89..000000000000 --- a/drivers/mtd/maps/intel_vr_nor.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * drivers/mtd/maps/intel_vr_nor.c - * - * An MTD map driver for a NOR flash bank on the Expansion Bus of the Intel - * Vermilion Range chipset. - * - * The Vermilion Range Expansion Bus supports four chip selects, each of which - * has 64MiB of address space. The 2nd BAR of the Expansion Bus PCI Device - * is a 256MiB memory region containing the address spaces for all four of the - * chip selects, with start addresses hardcoded on 64MiB boundaries. - * - * This map driver only supports NOR flash on chip select 0. The buswidth - * (either 8 bits or 16 bits) is determined by reading the Expansion Bus Timing - * and Control Register for Chip Select 0 (EXP_TIMING_CS0). This driver does - * not modify the value in the EXP_TIMING_CS0 register except to enable writing - * and disable boot acceleration. The timing parameters in the register are - * assumed to have been properly initialized by the BIOS. The reset default - * timing parameters are maximally conservative (slow), so access to the flash - * will be slower than it should be if the BIOS has not initialized the timing - * parameters. - * - * Author: Andy Lowe - * - * 2006 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "vr_nor" - -struct vr_nor_mtd { - void __iomem *csr_base; - struct map_info map; - struct mtd_info *info; - struct pci_dev *dev; -}; - -/* Expansion Bus Configuration and Status Registers are in BAR 0 */ -#define EXP_CSR_MBAR 0 -/* Expansion Bus Memory Window is BAR 1 */ -#define EXP_WIN_MBAR 1 -/* Maximum address space for Chip Select 0 is 64MiB */ -#define CS0_SIZE 0x04000000 -/* Chip Select 0 is at offset 0 in the Memory Window */ -#define CS0_START 0x0 -/* Chip Select 0 Timing Register is at offset 0 in CSR */ -#define EXP_TIMING_CS0 0x00 -#define TIMING_CS_EN (1 << 31) /* Chip Select Enable */ -#define TIMING_BOOT_ACCEL_DIS (1 << 8) /* Boot Acceleration Disable */ -#define TIMING_WR_EN (1 << 1) /* Write Enable */ -#define TIMING_BYTE_EN (1 << 0) /* 8-bit vs 16-bit bus */ -#define TIMING_MASK 0x3FFF0000 - -static void vr_nor_destroy_partitions(struct vr_nor_mtd *p) -{ - mtd_device_unregister(p->info); -} - -static int vr_nor_init_partitions(struct vr_nor_mtd *p) -{ - /* register the flash bank */ - /* partition the flash bank */ - return mtd_device_register(p->info, NULL, 0); -} - -static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) -{ - map_destroy(p->info); -} - -static int vr_nor_mtd_setup(struct vr_nor_mtd *p) -{ - static const char * const probe_types[] = - { "cfi_probe", "jedec_probe", NULL }; - const char * const *type; - - for (type = probe_types; !p->info && *type; type++) - p->info = do_map_probe(*type, &p->map); - if (!p->info) - return -ENODEV; - - p->info->dev.parent = &p->dev->dev; - - return 0; -} - -static void vr_nor_destroy_maps(struct vr_nor_mtd *p) -{ - unsigned int exp_timing_cs0; - - /* write-protect the flash bank */ - exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0); - exp_timing_cs0 &= ~TIMING_WR_EN; - writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0); - - /* unmap the flash window */ - iounmap(p->map.virt); - - /* unmap the csr window */ - iounmap(p->csr_base); -} - -/* - * Initialize the map_info structure and map the flash. - * Returns 0 on success, nonzero otherwise. - */ -static int vr_nor_init_maps(struct vr_nor_mtd *p) -{ - unsigned long csr_phys, csr_len; - unsigned long win_phys, win_len; - unsigned int exp_timing_cs0; - int err; - - csr_phys = pci_resource_start(p->dev, EXP_CSR_MBAR); - csr_len = pci_resource_len(p->dev, EXP_CSR_MBAR); - win_phys = pci_resource_start(p->dev, EXP_WIN_MBAR); - win_len = pci_resource_len(p->dev, EXP_WIN_MBAR); - - if (!csr_phys || !csr_len || !win_phys || !win_len) - return -ENODEV; - - if (win_len < (CS0_START + CS0_SIZE)) - return -ENXIO; - - p->csr_base = ioremap(csr_phys, csr_len); - if (!p->csr_base) - return -ENOMEM; - - exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0); - if (!(exp_timing_cs0 & TIMING_CS_EN)) { - dev_warn(&p->dev->dev, "Expansion Bus Chip Select 0 " - "is disabled.\n"); - err = -ENODEV; - goto release; - } - if ((exp_timing_cs0 & TIMING_MASK) == TIMING_MASK) { - dev_warn(&p->dev->dev, "Expansion Bus Chip Select 0 " - "is configured for maximally slow access times.\n"); - } - p->map.name = DRV_NAME; - p->map.bankwidth = (exp_timing_cs0 & TIMING_BYTE_EN) ? 1 : 2; - p->map.phys = win_phys + CS0_START; - p->map.size = CS0_SIZE; - p->map.virt = ioremap(p->map.phys, p->map.size); - if (!p->map.virt) { - err = -ENOMEM; - goto release; - } - simple_map_init(&p->map); - - /* Enable writes to flash bank */ - exp_timing_cs0 |= TIMING_BOOT_ACCEL_DIS | TIMING_WR_EN; - writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0); - - return 0; - - release: - iounmap(p->csr_base); - return err; -} - -static const struct pci_device_id vr_nor_pci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x500D)}, - {0,} -}; - -static void vr_nor_pci_remove(struct pci_dev *dev) -{ - struct vr_nor_mtd *p = pci_get_drvdata(dev); - - vr_nor_destroy_partitions(p); - vr_nor_destroy_mtd_setup(p); - vr_nor_destroy_maps(p); - kfree(p); - pci_release_regions(dev); - pci_disable_device(dev); -} - -static int vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - struct vr_nor_mtd *p = NULL; - unsigned int exp_timing_cs0; - int err; - - err = pci_enable_device(dev); - if (err) - goto out; - - err = pci_request_regions(dev, DRV_NAME); - if (err) - goto disable_dev; - - p = kzalloc(sizeof(*p), GFP_KERNEL); - err = -ENOMEM; - if (!p) - goto release; - - p->dev = dev; - - err = vr_nor_init_maps(p); - if (err) - goto release; - - err = vr_nor_mtd_setup(p); - if (err) - goto destroy_maps; - - err = vr_nor_init_partitions(p); - if (err) - goto destroy_mtd_setup; - - pci_set_drvdata(dev, p); - - return 0; - - destroy_mtd_setup: - map_destroy(p->info); - - destroy_maps: - /* write-protect the flash bank */ - exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0); - exp_timing_cs0 &= ~TIMING_WR_EN; - writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0); - - /* unmap the flash window */ - iounmap(p->map.virt); - - /* unmap the csr window */ - iounmap(p->csr_base); - - release: - kfree(p); - pci_release_regions(dev); - - disable_dev: - pci_disable_device(dev); - - out: - return err; -} - -static struct pci_driver vr_nor_pci_driver = { - .name = DRV_NAME, - .probe = vr_nor_pci_probe, - .remove = vr_nor_pci_remove, - .id_table = vr_nor_pci_ids, -}; - -module_pci_driver(vr_nor_pci_driver); - -MODULE_AUTHOR("Andy Lowe"); -MODULE_DESCRIPTION("MTD map driver for NOR flash on Intel Vermilion Range"); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(pci, vr_nor_pci_ids);