#define DISPC_MAX_NR_ISRS 8
+#define TABLE_SIZE (256 * 4)
+
struct omap_dispc_isr_data {
omap_dispc_isr_t isr;
void *arg;
bool ctx_valid;
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
+ /* palette/gamma table */
+ void *table_virt;
+ dma_addr_t table_phys;
+
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
spinlock_t irq_stats_lock;
struct dispc_irq_stats irq_stats;
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
}
+void dispc_set_gamma_table(void *table, u32 size)
+{
+ if (table == NULL || size == 0 || size > TABLE_SIZE) {
+ REG_FLD_MOD(DISPC_CONFIG, 0, 3, 3);
+ return;
+ }
+
+ memcpy(dispc.table_virt, table, size);
+
+ dispc_write_reg(DISPC_OVL_TABLE_BA(0), dispc.table_phys);
+ dispc_set_loadmode(OMAP_DSS_LOAD_CLUT_ONCE_FRAME);
+ REG_FLD_MOD(DISPC_CONFIG, 1, 3, 3);
+}
+
void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
{
u16 reg;
goto err_irq;
}
+ pdev->dev.coherent_dma_mask = ~0;
+ dispc.table_virt = dma_alloc_writecombine(&pdev->dev,
+ TABLE_SIZE, &dispc.table_phys, GFP_KERNEL);
+ if (dispc.table_virt == NULL) {
+ dev_err(&pdev->dev, "failed to alloc palette memory\n");
+ goto err_palette;
+ }
+ memset(dispc.table_virt, 0, TABLE_SIZE);
+
pm_runtime_enable(&pdev->dev);
r = dispc_runtime_get();
err_runtime_get:
pm_runtime_disable(&pdev->dev);
+ dma_free_writecombine(&pdev->dev, TABLE_SIZE,
+ dispc.table_virt, dispc.table_phys);
+err_palette:
free_irq(dispc.irq, dispc.pdev);
err_irq:
iounmap(dispc.base);
{
pm_runtime_disable(&pdev->dev);
+ dma_free_writecombine(&pdev->dev, TABLE_SIZE,
+ dispc.table_virt, dispc.table_phys);
+
clk_put(dispc.dss_clk);
free_irq(dispc.irq, dispc.pdev);
return size;
}
+#include <linux/ctype.h>
+
+static ssize_t display_dss_gamma_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned int table[256];
+ char *end = NULL;
+ int i;
+
+ for (i = 0; i < 256; ) {
+ table[i++] = simple_strtoul(buf, &end, 0);
+ while (isspace(*end))
+ end++;
+ if (*end == 0)
+ break;
+ buf = end;
+ }
+
+ if (i == 1 && table[0] == 0)
+ dispc_set_gamma_table(NULL, 0);
+ else if (i < 256) {
+ dev_err(dev, "not enough gamma values supplied (%d)\n", i);
+ dispc_set_gamma_table(NULL, 0);
+ } else
+ dispc_set_gamma_table(table, 256 * 4);
+
+ dispc_mgr_go(dssdev->manager->id);
+
+ return size;
+}
+
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store);
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
display_mirror_show, display_mirror_store);
static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store);
+static DEVICE_ATTR(dss_gamma, S_IRUGO|S_IWUSR,
+ NULL, display_dss_gamma_store);
static struct device_attribute *display_sysfs_attrs[] = {
&dev_attr_enabled,
DSSERR("failed to create sysfs file\n");
}
+ if (dssdev->channel == OMAP_DSS_CHANNEL_LCD) {
+ r = device_create_file(&dssdev->dev, &dev_attr_dss_gamma);
+ if (r)
+ DSSERR("failed to create sysfs file\n");
+ }
+
/* create display? sysfs links */
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
dev_name(&dssdev->dev));
void dispc_set_digit_size(u16 width, u16 height);
void dispc_enable_fifomerge(bool enable);
void dispc_enable_gamma_table(bool enable);
+void dispc_set_gamma_table(void *table, u32 size);
void dispc_set_loadmode(enum omap_dss_load_mode mode);
bool dispc_lcd_timings_ok(struct omap_video_timings *timings);