diff options
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/core.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 43 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 13 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 53 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 64 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 7 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-ioctl.c | 4 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 8 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-sysfs.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/vrfb.c | 142 |
11 files changed, 254 insertions, 89 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index b2af72dc20bd..d94ef9e31a35 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -237,7 +237,7 @@ static int __init omap_dss_probe(struct platform_device *pdev) core.pdev = pdev; - dss_features_init(); + dss_features_init(pdata->version); dss_apply_init(); diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b43477a5fae8..a5ab354f267a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -37,8 +37,6 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <plat/cpu.h> - #include <video/omapdss.h> #include "dss.h" @@ -4042,29 +4040,44 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = { .gfx_fifo_workaround = true, }; -static int __init dispc_init_features(struct device *dev) +static int __init dispc_init_features(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; const struct dispc_features *src; struct dispc_features *dst; - dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL); + dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); if (!dst) { - dev_err(dev, "Failed to allocate DISPC Features\n"); + dev_err(&pdev->dev, "Failed to allocate DISPC Features\n"); return -ENOMEM; } - if (cpu_is_omap24xx()) { + switch (pdata->version) { + case OMAPDSS_VER_OMAP24xx: src = &omap24xx_dispc_feats; - } else if (cpu_is_omap34xx()) { - if (omap_rev() < OMAP3430_REV_ES3_0) - src = &omap34xx_rev1_0_dispc_feats; - else - src = &omap34xx_rev3_0_dispc_feats; - } else if (cpu_is_omap44xx()) { + break; + + case OMAPDSS_VER_OMAP34xx_ES1: + src = &omap34xx_rev1_0_dispc_feats; + break; + + case OMAPDSS_VER_OMAP34xx_ES3: + case OMAPDSS_VER_OMAP3630: + case OMAPDSS_VER_AM35xx: + src = &omap34xx_rev3_0_dispc_feats; + break; + + case OMAPDSS_VER_OMAP4430_ES1: + case OMAPDSS_VER_OMAP4430_ES2: + case OMAPDSS_VER_OMAP4: src = &omap44xx_dispc_feats; - } else if (soc_is_omap54xx()) { + break; + + case OMAPDSS_VER_OMAP5: src = &omap44xx_dispc_feats; - } else { + break; + + default: return -ENODEV; } @@ -4084,7 +4097,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) dispc.pdev = pdev; - r = dispc_init_features(&dispc.pdev->dev); + r = dispc_init_features(dispc.pdev); if (r) return r; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d64ac3842884..bee92846cfab 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module) struct omap_dss_output *out; enum omap_dss_output_id id; - id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; + switch (module) { + case 0: + id = OMAP_DSS_OUTPUT_DSI1; + break; + case 1: + id = OMAP_DSS_OUTPUT_DSI2; + break; + default: + return NULL; + } out = omap_dss_get_output(id); - return out->pdev; + return out ? out->pdev : NULL; } static inline void dsi_write_reg(struct platform_device *dsidev, diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2ab1c3e96553..602102cebcbf 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -35,8 +35,6 @@ #include <video/omapdss.h> -#include <plat/cpu.h> - #include "dss.h" #include "dss_features.h" @@ -697,11 +695,15 @@ static int dss_get_clocks(void) dss.dss_clk = clk; - clk = clk_get(NULL, dss.feat->clk_name); - if (IS_ERR(clk)) { - DSSERR("Failed to get %s\n", dss.feat->clk_name); - r = PTR_ERR(clk); - goto err; + if (dss.feat->clk_name) { + clk = clk_get(NULL, dss.feat->clk_name); + if (IS_ERR(clk)) { + DSSERR("Failed to get %s\n", dss.feat->clk_name); + r = PTR_ERR(clk); + goto err; + } + } else { + clk = NULL; } dss.dpll4_m4_ck = clk; @@ -792,29 +794,46 @@ static const struct dss_features omap54xx_dss_feats __initconst = { .dpi_select_source = &dss_dpi_select_source_omap5, }; -static int __init dss_init_features(struct device *dev) +static int __init dss_init_features(struct platform_device *pdev) { + struct omap_dss_board_info *pdata = pdev->dev.platform_data; const struct dss_features *src; struct dss_features *dst; - dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL); + dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); if (!dst) { - dev_err(dev, "Failed to allocate local DSS Features\n"); + dev_err(&pdev->dev, "Failed to allocate local DSS Features\n"); return -ENOMEM; } - if (cpu_is_omap24xx()) + switch (pdata->version) { + case OMAPDSS_VER_OMAP24xx: src = &omap24xx_dss_feats; - else if (cpu_is_omap34xx()) + break; + + case OMAPDSS_VER_OMAP34xx_ES1: + case OMAPDSS_VER_OMAP34xx_ES3: + case OMAPDSS_VER_AM35xx: src = &omap34xx_dss_feats; - else if (cpu_is_omap3630()) + break; + + case OMAPDSS_VER_OMAP3630: src = &omap3630_dss_feats; - else if (cpu_is_omap44xx()) + break; + + case OMAPDSS_VER_OMAP4430_ES1: + case OMAPDSS_VER_OMAP4430_ES2: + case OMAPDSS_VER_OMAP4: src = &omap44xx_dss_feats; - else if (soc_is_omap54xx()) + break; + + case OMAPDSS_VER_OMAP5: src = &omap54xx_dss_feats; - else + break; + + default: return -ENODEV; + } memcpy(dst, src, sizeof(*dst)); dss.feat = dst; @@ -831,7 +850,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) dss.pdev = pdev; - r = dss_init_features(&dss.pdev->dev); + r = dss_init_features(dss.pdev); if (r) return r; diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index acbc1e1efba3..3e8287c8709d 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -23,7 +23,6 @@ #include <linux/slab.h> #include <video/omapdss.h> -#include <plat/cpu.h> #include "dss.h" #include "dss_features.h" @@ -825,10 +824,20 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { }; -void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data) +void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, + enum omapdss_version version) { - if (cpu_is_omap44xx()) + switch (version) { + case OMAPDSS_VER_OMAP4430_ES1: + case OMAPDSS_VER_OMAP4430_ES2: + case OMAPDSS_VER_OMAP4: ip_data->ops = &omap4_hdmi_functions; + break; + default: + ip_data->ops = NULL; + } + + WARN_ON(ip_data->ops == NULL); } #endif @@ -929,29 +938,44 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type) return omap_current_dss_features->supported_rotation_types & rot_type; } -void dss_features_init(void) +void dss_features_init(enum omapdss_version version) { - if (cpu_is_omap24xx()) + switch (version) { + case OMAPDSS_VER_OMAP24xx: omap_current_dss_features = &omap2_dss_features; - else if (cpu_is_omap3630()) + break; + + case OMAPDSS_VER_OMAP34xx_ES1: + case OMAPDSS_VER_OMAP34xx_ES3: + omap_current_dss_features = &omap3430_dss_features; + break; + + case OMAPDSS_VER_OMAP3630: omap_current_dss_features = &omap3630_dss_features; - else if (cpu_is_omap34xx()) { - if (soc_is_am35xx()) { - omap_current_dss_features = &am35xx_dss_features; - } else { - omap_current_dss_features = &omap3430_dss_features; - } - } - else if (omap_rev() == OMAP4430_REV_ES1_0) + break; + + case OMAPDSS_VER_OMAP4430_ES1: omap_current_dss_features = &omap4430_es1_0_dss_features; - else if (omap_rev() == OMAP4430_REV_ES2_0 || - omap_rev() == OMAP4430_REV_ES2_1 || - omap_rev() == OMAP4430_REV_ES2_2) + break; + + case OMAPDSS_VER_OMAP4430_ES2: omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; - else if (cpu_is_omap44xx()) + break; + + case OMAPDSS_VER_OMAP4: omap_current_dss_features = &omap4_dss_features; - else if (soc_is_omap54xx()) + break; + + case OMAPDSS_VER_OMAP5: omap_current_dss_features = &omap5_dss_features; - else + break; + + case OMAPDSS_VER_AM35xx: + omap_current_dss_features = &am35xx_dss_features; + break; + + default: DSSWARN("Unsupported OMAP version"); + break; + } } diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 9218113b5e88..fc492ef72a51 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -123,8 +123,9 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type); bool dss_has_feature(enum dss_feat_id id); void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); -void dss_features_init(void); +void dss_features_init(enum omapdss_version version); #if defined(CONFIG_OMAP4_DSS_HDMI) -void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data); +void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, + enum omapdss_version version); #endif #endif diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a48a7dd75b33..0d6d7213a858 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -323,6 +323,7 @@ static void hdmi_runtime_put(void) static int __init hdmi_init_display(struct omap_dss_device *dssdev) { + struct omap_dss_board_info *pdata = hdmi.pdev->dev.platform_data; int r; struct gpio gpios[] = { @@ -333,7 +334,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev) DSSDBG("init_display\n"); - dss_init_hdmi_ip_ops(&hdmi.ip_data); + dss_init_hdmi_ip_ops(&hdmi.ip_data, pdata->version); if (hdmi.vdda_hdmi_dac_reg == NULL) { struct regulator *reg; @@ -644,8 +645,10 @@ static void hdmi_dump_regs(struct seq_file *s) { mutex_lock(&hdmi.lock); - if (hdmi_runtime_get()) + if (hdmi_runtime_get()) { + mutex_unlock(&hdmi.lock); return; + } hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 606b89f12351..532a31b3d96b 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -30,7 +30,7 @@ #include <linux/export.h> #include <video/omapdss.h> -#include <plat/vrfb.h> +#include <video/omapvrfb.h> #include <plat/vram.h> #include "omapfb.h" @@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); - if (!display && !display->output && !display->output->manager) { + if (!display || !display->output || !display->output->manager) { r = -EINVAL; break; } diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 16db1589bd91..bc225e46fdd2 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -31,9 +31,8 @@ #include <linux/omapfb.h> #include <video/omapdss.h> -#include <plat/cpu.h> #include <plat/vram.h> -#include <plat/vrfb.h> +#include <video/omapvrfb.h> #include "omapfb.h" @@ -2396,10 +2395,7 @@ static int __init omapfb_probe(struct platform_device *pdev) goto err0; } - /* TODO : Replace cpu check with omap_has_vrfb once HAS_FEATURE - * available for OMAP2 and OMAP3 - */ - if (def_vrfb && !cpu_is_omap24xx() && !cpu_is_omap34xx()) { + if (def_vrfb && !omap_vrfb_supported()) { def_vrfb = 0; dev_warn(&pdev->dev, "VRFB is not supported on this hardware, " "ignoring the module parameter vrfb=y\n"); diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index e8d8cc76a435..17aa174e187c 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c @@ -30,7 +30,7 @@ #include <linux/omapfb.h> #include <video/omapdss.h> -#include <plat/vrfb.h> +#include <video/omapvrfb.h> #include "omapfb.h" diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c index 7e990220ad2a..5d8fdac3b800 100644 --- a/drivers/video/omap2/vrfb.c +++ b/drivers/video/omap2/vrfb.c @@ -26,9 +26,9 @@ #include <linux/io.h> #include <linux/bitops.h> #include <linux/mutex.h> +#include <linux/platform_device.h> -#include <plat/vrfb.h> -#include <plat/sdrc.h> +#include <video/omapvrfb.h> #ifdef DEBUG #define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__) @@ -36,10 +36,10 @@ #define DBG(format, ...) #endif -#define SMS_ROT_VIRT_BASE(context, rot) \ - (((context >= 4) ? 0xD0000000 : 0x70000000) \ - + (0x4000000 * (context)) \ - + (0x1000000 * (rot))) +#define SMS_ROT_CONTROL(context) (0x0 + 0x10 * context) +#define SMS_ROT_SIZE(context) (0x4 + 0x10 * context) +#define SMS_ROT_PHYSICAL_BA(context) (0x8 + 0x10 * context) +#define SMS_ROT_VIRT_BASE(rot) (0x1000000 * (rot)) #define OMAP_VRFB_SIZE (2048 * 2048 * 4) @@ -53,10 +53,16 @@ #define SMS_PW_OFFSET 4 #define SMS_PS_OFFSET 0 -#define VRFB_NUM_CTXS 12 /* bitmap of reserved contexts */ static unsigned long ctx_map; +struct vrfb_ctx { + u32 base; + u32 physical_ba; + u32 control; + u32 size; +}; + static DEFINE_MUTEX(ctx_lock); /* @@ -65,17 +71,34 @@ static DEFINE_MUTEX(ctx_lock); * we don't need locking, since no drivers will run until after the wake-up * has finished. */ -static struct { - u32 physical_ba; - u32 control; - u32 size; -} vrfb_hw_context[VRFB_NUM_CTXS]; + +static void __iomem *vrfb_base; + +static int num_ctxs; +static struct vrfb_ctx *ctxs; + +static bool vrfb_loaded; + +static void omap2_sms_write_rot_control(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx)); +} + +static void omap2_sms_write_rot_size(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_SIZE(ctx)); +} + +static void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_PHYSICAL_BA(ctx)); +} static inline void restore_hw_context(int ctx) { - omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx); - omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx); - omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx); + omap2_sms_write_rot_control(ctxs[ctx].control, ctx); + omap2_sms_write_rot_size(ctxs[ctx].size, ctx); + omap2_sms_write_rot_physical_ba(ctxs[ctx].physical_ba, ctx); } static u32 get_image_width_roundup(u16 width, u8 bytespp) @@ -196,9 +219,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, control |= VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET; control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET; - vrfb_hw_context[ctx].physical_ba = paddr; - vrfb_hw_context[ctx].size = size; - vrfb_hw_context[ctx].control = control; + ctxs[ctx].physical_ba = paddr; + ctxs[ctx].size = size; + ctxs[ctx].control = control; omap2_sms_write_rot_physical_ba(paddr, ctx); omap2_sms_write_rot_size(size, ctx); @@ -274,11 +297,11 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) mutex_lock(&ctx_lock); - for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx) + for (ctx = 0; ctx < num_ctxs; ++ctx) if ((ctx_map & (1 << ctx)) == 0) break; - if (ctx == VRFB_NUM_CTXS) { + if (ctx == num_ctxs) { pr_err("vrfb: no free contexts\n"); r = -EBUSY; goto out; @@ -293,7 +316,7 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) vrfb->context = ctx; for (rot = 0; rot < 4; ++rot) { - paddr = SMS_ROT_VIRT_BASE(ctx, rot); + paddr = ctxs[ctx].base + SMS_ROT_VIRT_BASE(rot); if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) { pr_err("vrfb: failed to reserve VRFB " "area for ctx %d, rotation %d\n", @@ -314,3 +337,80 @@ out: return r; } EXPORT_SYMBOL(omap_vrfb_request_ctx); + +bool omap_vrfb_supported(void) +{ + return vrfb_loaded; +} +EXPORT_SYMBOL(omap_vrfb_supported); + +static int __init vrfb_probe(struct platform_device *pdev) +{ + struct resource *mem; + int i; + + /* first resource is the register res, the rest are vrfb contexts */ + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "can't get vrfb base address\n"); + return -EINVAL; + } + + vrfb_base = devm_request_and_ioremap(&pdev->dev, mem); + if (!vrfb_base) { + dev_err(&pdev->dev, "can't ioremap vrfb memory\n"); + return -ENOMEM; + } + + num_ctxs = pdev->num_resources - 1; + + ctxs = devm_kzalloc(&pdev->dev, + sizeof(struct vrfb_ctx) * num_ctxs, + GFP_KERNEL); + + if (!ctxs) + return -ENOMEM; + + for (i = 0; i < num_ctxs; ++i) { + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); + if (!mem) { + dev_err(&pdev->dev, "can't get vrfb ctx %d address\n", + i); + return -EINVAL; + } + + ctxs[i].base = mem->start; + } + + vrfb_loaded = true; + + return 0; +} + +static void __exit vrfb_remove(struct platform_device *pdev) +{ + vrfb_loaded = false; +} + +static struct platform_driver vrfb_driver = { + .driver.name = "omapvrfb", + .remove = __exit_p(vrfb_remove), +}; + +static int __init vrfb_init(void) +{ + return platform_driver_probe(&vrfb_driver, &vrfb_probe); +} + +static void __exit vrfb_exit(void) +{ + platform_driver_unregister(&vrfb_driver); +} + +module_init(vrfb_init); +module_exit(vrfb_exit); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); +MODULE_DESCRIPTION("OMAP VRFB"); +MODULE_LICENSE("GPL v2"); |