Index: kernel-source-rx-34-2.6.21.0/drivers/misc/Kconfig =================================================================== --- kernel-source-rx-34-2.6.21.0.orig/drivers/misc/Kconfig 2008-03-03 18:22:12.000000000 +0100 +++ kernel-source-rx-34-2.6.21.0/drivers/misc/Kconfig 2008-03-03 18:22:34.000000000 +0100 @@ -122,4 +122,11 @@ Read for more information. +config POWERVR + tristate "PowerVR MBX test driver for OMAP2420" + depends on ARCH_OMAP2420 + ---help--- + For now this driver only turns on the clocks and power to + the PowerVR MBX peripheral integrated into OMAP2420 CPUs. + endmenu Index: kernel-source-rx-34-2.6.21.0/drivers/misc/Makefile =================================================================== --- kernel-source-rx-34-2.6.21.0.orig/drivers/misc/Makefile 2008-03-03 18:22:12.000000000 +0100 +++ kernel-source-rx-34-2.6.21.0/drivers/misc/Makefile 2008-03-03 18:22:34.000000000 +0100 @@ -12,3 +12,5 @@ obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o +obj-$(CONFIG_POWERVR) += powervr.o + Index: kernel-source-rx-34-2.6.21.0/drivers/misc/powervr.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ kernel-source-rx-34-2.6.21.0/drivers/misc/powervr.c 2008-03-03 19:04:35.000000000 +0100 @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2008 Philipp Zabel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include /* udelay */ + +#include + +#define CM_CLKSEL_GFX 0x340 +#define PRCM_CLKCFG_STATUS 0x84 +#define PRCM_CLKCFG_CTRL 0x80 +#define CM_ICLKEN_GFX 0x310 +#define CM_FCLKEN_GFX 0x300 +#define CM_CLKSTCTRL_GFX 0x348 +#define AUTOSTAT_GFX (1 << 0) +#define RM_RSTST_GFX 0x358 +#define OMAP24XX_GFX_SW_RST 0x10 +#define RM_RSTCTRL_GFX 0x350 +#define OMAP24XX_GFX_RESET 0x1 +#define PM_WKDEP_GFX 0x3c8 +#define EN_WKUP (1 << 4) +#define EN_GFX (1 << 3) +#define EN_DSP (1 << 2) +#define EN_MPU (1 << 1) +#define EN_CORE (1 << 0) +#define PM_PWSTCTRL_GFX 0x3e0 +#define FORCE_STATE 0x40000 +#define POWERSTATE_ON 0 +#define POWERSTATE_OFF 3 +#define PM_PWSTST_GFX 0x3e4 + +#define OMAP24XX_PVR_BASE 0x50000000 /* 0x4000 */ +#define PVR_TASLAVEPORT 0x50008000 /* 0x2000 */ +#define PVR_TACONTROLSLAVEPORT 0x5000c000 /* 0x2000 */ +#define PVR_2DSLAVEPORT 0x5000a000 /* 0x2000 */ +#define PVR_SOCREGS 0x4808a000 + +/* from arch/arm/mach-omap2/pm.c */ +static u32 prcm_base = IO_ADDRESS(OMAP24XX_PRCM_BASE); + +static inline void prcm_write_reg(int idx, u32 val) +{ + __raw_writel(val, prcm_base + idx); +} + +static inline u32 prcm_read_reg(int idx) +{ + return __raw_readl(prcm_base + idx); +} + +static void __iomem *pvr_base; + +static inline void pvr_write_reg(int idx, u32 val) +{ + __raw_writel(val, pvr_base + idx); +} + +static inline u32 pvr_read_reg(int idx) +{ + return __raw_readl(pvr_base + idx); +} + +static struct clk *gfx_3d_fck; +static struct clk *gfx_2d_fck; +static struct clk *gfx_ick; + +int enable_system_clocks(void) +{ + gfx_ick = clk_get(NULL, "gfx_ick"); + if (!gfx_ick) + goto fail_ick; + gfx_3d_fck = clk_get(NULL, "gfx_3d_fck"); + if (!gfx_3d_fck) + goto fail_3d_fck; + gfx_2d_fck = clk_get(NULL, "gfx_2d_fck"); + if (!gfx_2d_fck) + goto fail_2d_fck; + + prcm_write_reg(PM_PWSTCTRL_GFX, POWERSTATE_ON); + prcm_write_reg(PM_WKDEP_GFX, 0x13 /* EN_WKUP|EN_MPU|EN_CORE */); + + pr_info("PM_WKDEP_GFX = %x\n", prcm_read_reg(PM_WKDEP_GFX)); + pr_info("CM_CLKSTCTRL_GFX = %x\n", prcm_read_reg(CM_CLKSTCTRL_GFX)); + pr_info("PM_PWSTST_GFX = %x\n", prcm_read_reg(PM_PWSTST_GFX)); + + //pr_info("CM_CLKSEL_GFX = %x\n", prcm_read_reg(CM_CLKSEL_GFX)); + //prcm_write_reg(CM_CLKSEL_GFX, 0x2); +#if 0 + /* DELAYED_APP flag? */ + r0 = HostReadHWReg(pvClkCtrl, 0x84); // OMAP24XX_PRCM_CLKCFG_STATUS + if unlikely(!(r0 & 1)) + HostWriteHWReg(pvClkCtrl, 0x80, 1); // OMAP24XX_PRCM_CLKCFG_CTRL +#endif + + clk_enable(gfx_ick); + clk_enable(gfx_3d_fck); + clk_enable(gfx_2d_fck); + + prcm_write_reg(RM_RSTST_GFX, OMAP24XX_GFX_SW_RST); + prcm_write_reg(RM_RSTCTRL_GFX, OMAP24XX_GFX_RESET); + prcm_write_reg(RM_RSTCTRL_GFX, 0); + + if (!(prcm_read_reg(RM_RSTST_GFX) & OMAP24XX_GFX_SW_RST)) { + pr_info("waiting 1ms\n"); + udelay(1000); + } + prcm_write_reg(RM_RSTST_GFX, OMAP24XX_GFX_SW_RST); + + return 0; + + clk_put(gfx_2d_fck); + gfx_2d_fck = NULL; +fail_2d_fck: + clk_put(gfx_3d_fck); + gfx_3d_fck = NULL; +fail_3d_fck: + clk_put(gfx_ick); + gfx_ick = NULL; +fail_ick: + return -ENOMEM; +} + +void disable_system_clocks(void) +{ + prcm_write_reg(RM_RSTCTRL_GFX, OMAP24XX_GFX_RESET); + + clk_disable(gfx_2d_fck); + clk_disable(gfx_3d_fck); + clk_disable(gfx_ick); + + prcm_write_reg(PM_WKDEP_GFX, 0); + prcm_write_reg(PM_PWSTCTRL_GFX, FORCE_STATE | POWERSTATE_OFF); + + clk_put(gfx_2d_fck); + gfx_2d_fck = NULL; + clk_put(gfx_3d_fck); + gfx_3d_fck = NULL; + clk_put(gfx_ick); + gfx_ick = NULL; +} + +static int __init powervr_init(void) +{ + int ret; + + pvr_base = ioremap(OMAP24XX_PVR_BASE, 0x4000); + if (!pvr_base) + return -ENOMEM; + + ret = enable_system_clocks(); + if (ret == 0) { + int core_id; + int revision; + int version_minor; + int version_major; + char *name; + + pr_info("F00 = %x\n", pvr_read_reg(0xf00)); + pr_info("F10 = %x\n", pvr_read_reg(0xf10)); + + core_id = (pvr_read_reg(0xf00) >> 16) & 0xff; /* 00ff0000 */ + revision = pvr_read_reg(0xf00) & 0xffff; /* 0000ffff */ + version_minor = (pvr_read_reg(0xf10) >> 8) & 0xff; /* 0000ff00 */ + version_major = (pvr_read_reg(0xf10) >> 16) & 0xff; /* 00ff0000 */ + + switch (core_id) { + case 1: name = ""; break; + case 2: name = " Lite"; break; + default: + return -ENODEV; + } + pr_info("core: PowerVR MBX%s, revision %d, version %d.%d\n", name, revision, version_major, version_minor); + + pr_info("F04 = %x\n", pvr_read_reg(0xf04)); + pr_info("FE0 = %x\n", pvr_read_reg(0xfe0)); + pr_info("FE4 = %x\n", pvr_read_reg(0xfe4)); + pr_info("FF0 = %x\n", pvr_read_reg(0xff0)); + pr_info("FF4 = %x\n", pvr_read_reg(0xff4)); + pr_info("FF8 = %x\n", pvr_read_reg(0xff8)); + pr_info("FFC = %x\n", pvr_read_reg(0xffc)); + + pr_info("80 = %x\n", pvr_read_reg(0x80)); + pr_info("12c = %x\n", pvr_read_reg(0x12c)); + pr_info("130 = %x\n", pvr_read_reg(0x130)); + pr_info("134 = %x\n", pvr_read_reg(0x134)); + + pr_info("powervr: driver loaded.\n"); + } + return ret; +} + +static void __exit powervr_cleanup(void) +{ + disable_system_clocks(); + iounmap(pvr_base); + pr_info("powervr: driver unloaded.\n"); +} + +module_init(powervr_init); +module_exit(powervr_cleanup); + +MODULE_AUTHOR("Philipp Zabel"); +MODULE_DESCRIPTION("PowerVR MBX test driver for OMAP2420"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL");