aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Diaz Prado <x0083741@ti.com>2011-01-21 15:11:24 -0600
committerColin Cross <ccross@android.com>2011-06-14 09:06:47 -0700
commitc69212a5c715349f5969da79c161810a2ec884d8 (patch)
tree05edc2e6dd51e5ade3f87466af18cf9ac4001d59
parent7d430f7c7ca91a24ee6601419828e2a2cb31762f (diff)
downloadkernel_samsung_tuna-c69212a5c715349f5969da79c161810a2ec884d8.zip
kernel_samsung_tuna-c69212a5c715349f5969da79c161810a2ec884d8.tar.gz
kernel_samsung_tuna-c69212a5c715349f5969da79c161810a2ec884d8.tar.bz2
SGX: UDD: Create sysfs entry to allow ignoring the display sync
This patch creates a sysfs entry that allows to tell the UDD to ignore the synchronization with a specific display. The change can be made on the fly without rebooting the kernel. This feature makes sense only if flipping is enabled on the display. The sysfs entry can be found in the directory /sys/devices/platform/omaplfb/displayX/ignore_sync By echoing a 1 to the ignore_sync entry the frames per second will go beyond 60fps since the synchronization with the display will be ignored. Setting it to 0 will return it to normal. Signed-off-by: Gustavo Diaz Prado <x0083741@ti.com> Change-Id: I242d88a9be202a7079c0ff7901751d4d996ef5be
-rw-r--r--drivers/gpu/pvr/Makefile1
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c130
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb.h12
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c7
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_linux.c75
5 files changed, 201 insertions, 24 deletions
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile
index 05b3bf6..0dc058d 100644
--- a/drivers/gpu/pvr/Makefile
+++ b/drivers/gpu/pvr/Makefile
@@ -141,6 +141,7 @@ sgx_displayclass-y := \
omaplfb-y := \
omaplfb/omaplfb_displayclass.o \
+ omaplfb/omaplfb-sysfs.o \
omaplfb/omaplfb_linux.o
dbgdrv-$(CONFIG_SGX_PDUMP) := \
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c b/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c
new file mode 100644
index 0000000..2e04583
--- /dev/null
+++ b/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c
@@ -0,0 +1,130 @@
+/*
+ * omaplfb-sysfs.c
+ *
+ * Copyright (C) 2011 Texas Instruments.
+ *
+ * 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.
+ *
+ * Author: Gustavo Diaz (gusdp@ti.com)
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "omaplfb.h"
+
+static ssize_t show_ignore_sync(OMAPLFB_DEVINFO *display_info, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", display_info->ignore_sync);
+}
+
+static ssize_t store_ignore_sync(OMAPLFB_DEVINFO *display_info,
+ const char *buf, size_t count)
+{
+ unsigned long new_value;
+
+ if (strict_strtoul(buf, 10, &new_value))
+ return -EINVAL;
+
+ if (new_value == 0 || new_value == 1) {
+ display_info->ignore_sync = new_value;
+ return count;
+ }
+
+ return -EINVAL;
+}
+
+struct omaplfb_attribute {
+ struct attribute attr;
+ ssize_t (*show)(OMAPLFB_DEVINFO *, char *);
+ ssize_t (*store)(OMAPLFB_DEVINFO *, const char *, size_t);
+};
+
+static ssize_t omaplfb_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ OMAPLFB_DEVINFO *display_info;
+ struct omaplfb_attribute *omaplfb_attr;
+
+ display_info = container_of(kobj, OMAPLFB_DEVINFO, kobj);
+ omaplfb_attr = container_of(attr, struct omaplfb_attribute, attr);
+
+ if (!omaplfb_attr->show)
+ return -ENOENT;
+
+ return omaplfb_attr->show(display_info, buf);
+}
+
+static ssize_t omaplfb_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t size)
+{
+ OMAPLFB_DEVINFO *display_info;
+ struct omaplfb_attribute *omaplfb_attr;
+
+ display_info = container_of(kobj, OMAPLFB_DEVINFO, kobj);
+ omaplfb_attr = container_of(attr, struct omaplfb_attribute, attr);
+
+ if (!omaplfb_attr->store)
+ return -ENOENT;
+
+ return omaplfb_attr->store(display_info, buf, size);
+}
+
+#define OMAPLFB_ATTR(_name, _mode, _show, _store) \
+ struct omaplfb_attribute omaplfb_attr_##_name = \
+ __ATTR(_name, _mode, _show, _store)
+
+static OMAPLFB_ATTR(ignore_sync, S_IRUGO|S_IWUSR, show_ignore_sync,
+ store_ignore_sync);
+
+#undef OMAPLFB_ATTR
+
+static struct attribute *omaplfb_sysfs_attrs[] = {
+ &omaplfb_attr_ignore_sync.attr,
+ NULL
+};
+
+static const struct sysfs_ops omaplfb_sysfs_ops = {
+ .show = omaplfb_attr_show,
+ .store = omaplfb_attr_store,
+};
+
+static struct kobj_type omaplfb_ktype = {
+ .sysfs_ops = &omaplfb_sysfs_ops,
+ .default_attrs = omaplfb_sysfs_attrs,
+};
+
+void omaplfb_create_sysfs(struct omaplfb_device *odev)
+{
+ int i, r;
+
+ /* Create a sysfs entry for every display */
+ for (i = 0; i < odev->display_count; i++) {
+ OMAPLFB_DEVINFO *display_info = &odev->display_info_list[i];
+ r = kobject_init_and_add(&display_info->kobj, &omaplfb_ktype,
+ &odev->dev->kobj, "display%d",
+ display_info->uDeviceID);
+ if (r)
+ ERROR_PRINTK("failed to create sysfs file\n");
+ }
+}
+
+void omaplfb_remove_sysfs(struct omaplfb_device *odev)
+{
+ int i;
+ for (i = 0; i < odev->display_count; i++) {
+ OMAPLFB_DEVINFO *display_info = &odev->display_info_list[i];
+ kobject_del(&display_info->kobj);
+ kobject_put(&display_info->kobj);
+ }
+}
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb.h b/drivers/gpu/pvr/omaplfb/omaplfb.h
index 7e46c90..57620ab 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb.h
+++ b/drivers/gpu/pvr/omaplfb/omaplfb.h
@@ -107,6 +107,8 @@ typedef struct OMAPLFB_DEVINFO_TAG
DISPLAY_DIMS sDisplayDim;
struct workqueue_struct* sync_display_wq;
struct work_struct sync_display_work;
+ struct kobject kobj;
+ OMAP_BOOL ignore_sync;
} OMAPLFB_DEVINFO;
@@ -124,6 +126,12 @@ typedef enum _OMAP_ERROR_
} OMAP_ERROR;
+struct omaplfb_device {
+ struct device *dev;
+ OMAPLFB_DEVINFO *display_info_list;
+ int display_count;
+};
+
#define OMAPLFB_PAGE_SIZE 4096
#define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1)
#define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK)
@@ -149,7 +157,7 @@ typedef enum _OMAP_ERROR_
#define ERROR_PRINTK(format, ...) printk("ERROR " DRIVER_PREFIX \
" (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
-OMAP_ERROR OMAPLFBInit(void);
+OMAP_ERROR OMAPLFBInit(struct omaplfb_device *omaplfb_dev);
OMAP_ERROR OMAPLFBDeinit(void);
void *OMAPLFBAllocKernelMem(unsigned long ulSize);
void OMAPLFBFreeKernelMem(void *pvMem);
@@ -158,6 +166,8 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName,
PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr);
+void omaplfb_create_sysfs(struct omaplfb_device *odev);
+void omaplfb_remove_sysfs(struct omaplfb_device *odev);
#ifdef LDM_PLATFORM
void OMAPLFBDriverSuspend(void);
void OMAPLFBDriverResume(void);
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
index cc07824..425059c 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
@@ -1135,6 +1135,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
#if defined(SYS_USING_INTERRUPTS)
if( psFlipCmd->ui32SwapInterval == 0 ||
+ psDevInfo->ignore_sync ||
psSwapChain->bFlushCommands == OMAP_TRUE)
{
#endif
@@ -1533,7 +1534,7 @@ static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo, int fb_idx)
/*
* Initialization routine for the 3rd party display driver
*/
-OMAP_ERROR OMAPLFBInit(void)
+OMAP_ERROR OMAPLFBInit(struct omaplfb_device *omaplfb_dev)
{
OMAPLFB_DEVINFO *psDevInfo;
PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
@@ -1573,12 +1574,13 @@ OMAP_ERROR OMAPLFBInit(void)
sizeof(OMAPLFB_DEVINFO) * FRAMEBUFFER_COUNT);
if(!pDisplayDevices)
{
- pDisplayDevices = NULL;
ERROR_PRINTK("Out of memory");
return OMAP_ERROR_OUT_OF_MEMORY;
}
memset(pDisplayDevices, 0, sizeof(OMAPLFB_DEVINFO) *
FRAMEBUFFER_COUNT);
+ omaplfb_dev->display_info_list = pDisplayDevices;
+ omaplfb_dev->display_count = FRAMEBUFFER_COUNT;
/*
* Initialize each display device
@@ -1617,6 +1619,7 @@ OMAP_ERROR OMAPLFBInit(void)
psDevInfo->psSwapChain = 0;
psDevInfo->bFlushCommands = OMAP_FALSE;
psDevInfo->bDeviceSuspended = OMAP_FALSE;
+ psDevInfo->ignore_sync = OMAP_FALSE;
if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 1)
{
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
index 10805d6..7629c6f 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
@@ -296,6 +296,44 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
static volatile OMAP_BOOL bDeviceSuspended;
+static int omaplfb_probe(struct platform_device *pdev)
+{
+ struct omaplfb_device *odev;
+
+ odev = kzalloc(sizeof(*odev), GFP_KERNEL);
+
+ if (!odev)
+ return -ENOMEM;
+
+ if (OMAPLFBInit(odev) != OMAP_OK) {
+ dev_err(&pdev->dev, "failed to setup omaplfb\n");
+ kfree(odev);
+ return -ENODEV;
+ }
+
+ odev->dev = &pdev->dev;
+ platform_set_drvdata(pdev, odev);
+ omaplfb_create_sysfs(odev);
+
+ return 0;
+}
+
+static int omaplfb_remove(struct platform_device *pdev)
+{
+ struct omaplfb_device *odev;
+
+ odev = platform_get_drvdata(pdev);
+
+ omaplfb_remove_sysfs(odev);
+
+ if (OMAPLFBDeinit() != OMAP_OK)
+ WARNING_PRINTK("Driver cleanup failed");
+
+ kfree(odev);
+
+ return 0;
+}
+
/*
* Common suspend driver function
* in: psSwapChain, aPhyAddr
@@ -334,8 +372,6 @@ static struct platform_device omaplfb_device = {
#if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND)
-static struct early_suspend omaplfb_early_suspend;
-
/*
* Android specific, driver is requested to be suspended
* in: ea_event
@@ -360,7 +396,16 @@ static void OMAPLFBDriverResume_Entry(struct early_suspend *ea_event)
static struct platform_driver omaplfb_driver = {
.driver = {
.name = DRVNAME,
- }
+ .owner = THIS_MODULE,
+ },
+ .probe = omaplfb_probe,
+ .remove = omaplfb_remove,
+};
+
+static struct early_suspend omaplfb_early_suspend = {
+ .suspend = OMAPLFBDriverSuspend_Entry,
+ .resume = OMAPLFBDriverResume_Entry,
+ .level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
};
#else /* defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND) */
@@ -403,7 +448,10 @@ static IMG_VOID OMAPLFBDriverShutdown_Entry(
static struct platform_driver omaplfb_driver = {
.driver = {
.name = DRVNAME,
+ .owner = THIS_MODULE,
},
+ .probe = omaplfb_probe,
+ .remove = omaplfb_remove,
.suspend = OMAPLFBDriverSuspend_Entry,
.resume = OMAPLFBDriverResume_Entry,
.shutdown = OMAPLFBDriverShutdown_Entry,
@@ -418,21 +466,10 @@ static struct platform_driver omaplfb_driver = {
*/
static int __init OMAPLFB_Init(void)
{
- if(OMAPLFBInit() != OMAP_OK)
- {
- WARNING_PRINTK("Driver init failed");
- return -ENODEV;
- }
-
#if defined(LDM_PLATFORM)
DEBUG_PRINTK("Registering platform driver");
if (platform_driver_register(&omaplfb_driver))
- {
- WARNING_PRINTK("Unable to register platform driver");
- if(OMAPLFBDeinit() != OMAP_OK)
- WARNING_PRINTK("Driver cleanup failed\n");
return -ENODEV;
- }
#if 0
DEBUG_PRINTK("Registering device driver");
if (platform_device_register(&omaplfb_device))
@@ -446,10 +483,7 @@ static int __init OMAPLFB_Init(void)
#endif
#if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND)
- omaplfb_early_suspend.suspend = OMAPLFBDriverSuspend_Entry;
- omaplfb_early_suspend.resume = OMAPLFBDriverResume_Entry;
- omaplfb_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
- register_early_suspend(&omaplfb_early_suspend);
+ register_early_suspend(&omaplfb_early_suspend);
DEBUG_PRINTK("Registered early suspend support");
#endif
@@ -470,11 +504,10 @@ static IMG_VOID __exit OMAPLFB_Cleanup(IMG_VOID)
DEBUG_PRINTK("Removing platform driver");
platform_driver_unregister(&omaplfb_driver);
#if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND)
- unregister_early_suspend(&omaplfb_early_suspend);
+ DEBUG_PRINTK("Removed early suspend support");
+ unregister_early_suspend(&omaplfb_early_suspend);
#endif
#endif
- if(OMAPLFBDeinit() != OMAP_OK)
- WARNING_PRINTK("Driver cleanup failed");
}
late_initcall(OMAPLFB_Init);