From e1d1144eb92e69394958e59ff2a0fd22d58094d4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Request memory regions for memory resources Make sure the registers and MERAM spaces are reserved before using them. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 53 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index f45d83ecfd21..dbf5c43852bb 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -596,13 +596,12 @@ static struct sh_mobile_meram_ops sh_mobile_meram_ops = { * initialize MERAM */ -static int sh_mobile_meram_remove(struct platform_device *pdev); - static int __devinit sh_mobile_meram_probe(struct platform_device *pdev) { struct sh_mobile_meram_priv *priv; struct sh_mobile_meram_info *pdata = pdev->dev.platform_data; - struct resource *res; + struct resource *regs; + struct resource *meram; int error; if (!pdata) { @@ -610,8 +609,9 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + meram = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (regs == NULL || meram == NULL) { dev_err(&pdev->dev, "cannot get platform resources\n"); return -ENOENT; } @@ -622,32 +622,50 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev) return -ENOMEM; } - platform_set_drvdata(pdev, priv); - /* initialize private data */ mutex_init(&priv->lock); - priv->base = ioremap_nocache(res->start, resource_size(res)); + pdata->ops = &sh_mobile_meram_ops; + pdata->priv = priv; + pdata->pdev = pdev; + + if (!request_mem_region(regs->start, resource_size(regs), pdev->name)) { + dev_err(&pdev->dev, "MERAM registers region already claimed\n"); + error = -EBUSY; + goto err_req_regs; + } + + if (!request_mem_region(meram->start, resource_size(meram), + pdev->name)) { + dev_err(&pdev->dev, "MERAM memory region already claimed\n"); + error = -EBUSY; + goto err_req_meram; + } + + priv->base = ioremap_nocache(regs->start, resource_size(regs)); if (!priv->base) { dev_err(&pdev->dev, "ioremap failed\n"); error = -EFAULT; - goto err; + goto err_ioremap; } - pdata->ops = &sh_mobile_meram_ops; - pdata->priv = priv; - pdata->pdev = pdev; /* initialize ICB addressing mode */ if (pdata->addr_mode == SH_MOBILE_MERAM_MODE1) meram_write_reg(priv->base, MEVCR1, MEVCR1_AMD1); + platform_set_drvdata(pdev, priv); pm_runtime_enable(&pdev->dev); dev_info(&pdev->dev, "sh_mobile_meram initialized."); return 0; -err: - sh_mobile_meram_remove(pdev); +err_ioremap: + release_mem_region(meram->start, resource_size(meram)); +err_req_meram: + release_mem_region(regs->start, resource_size(regs)); +err_req_regs: + mutex_destroy(&priv->lock); + kfree(priv); return error; } @@ -656,11 +674,14 @@ err: static int sh_mobile_meram_remove(struct platform_device *pdev) { struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev); + struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct resource *meram = platform_get_resource(pdev, IORESOURCE_MEM, 1); pm_runtime_disable(&pdev->dev); - if (priv->base) - iounmap(priv->base); + iounmap(priv->base); + release_mem_region(meram->start, resource_size(meram)); + release_mem_region(regs->start, resource_size(regs)); mutex_destroy(&priv->lock); -- cgit v1.2.1 From d272f428fac77ec57049a3293583ab3353928b1c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Add _cfg suffix to struct sh_mobile_meram_icb The structure describe ICB configuration, no ICB objects themselves. Rename it to sh_mobile_meram_icb_cfg in preparation for the addition of an ICB structure. All the structure fields are unsigned integers, make them so. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index dbf5c43852bb..2ad5a454fa2e 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -156,7 +156,7 @@ static inline unsigned long meram_read_reg(void __iomem *base, int off) */ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb *new) + struct sh_mobile_meram_icb_cfg *new) { int i; int used_start, used_end, meram_start, meram_end; @@ -188,7 +188,7 @@ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, */ static inline void meram_mark(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb *new) + struct sh_mobile_meram_icb_cfg *new) { int n; @@ -211,7 +211,7 @@ static inline void meram_mark(struct sh_mobile_meram_priv *priv, */ static inline void meram_unmark(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb *icb) + struct sh_mobile_meram_icb_cfg *icb) { int i; unsigned long pattern; @@ -303,7 +303,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, */ static int meram_init(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb *icb, + struct sh_mobile_meram_icb_cfg *icb, int xres, int yres, int *out_pitch) { unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres); @@ -370,7 +370,7 @@ static int meram_init(struct sh_mobile_meram_priv *priv, } static void meram_deinit(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb *icb) + struct sh_mobile_meram_icb_cfg *icb) { /* disable ICB */ meram_write_icb(priv->base, icb->cache_icb, MExxCTL, -- cgit v1.2.1 From 05432837ae0dfc6c7de93d081b1377ced4eb866b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Make variables unsigned where applicable Many variables, such as loop counters, sizes and offsets, should be unsigned integers. Make them so. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 80 ++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 37 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index 2ad5a454fa2e..548f70096124 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -104,7 +104,7 @@ struct sh_mobile_meram_priv { void __iomem *base; struct mutex lock; unsigned long used_icb; - int used_meram_cache_regions; + unsigned int used_meram_cache_regions; unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM]; unsigned long cmn_saved_regs[CMN_REGS_SIZE]; unsigned long icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM]; @@ -120,24 +120,25 @@ struct sh_mobile_meram_priv { #define MERAM_ICB_OFFSET(base, idx, off) ((base) + (off) + (idx) * 0x20) -static inline void meram_write_icb(void __iomem *base, int idx, int off, - unsigned long val) +static inline void meram_write_icb(void __iomem *base, unsigned int idx, + unsigned int off, unsigned long val) { iowrite32(val, MERAM_ICB_OFFSET(base, idx, off)); } -static inline unsigned long meram_read_icb(void __iomem *base, int idx, int off) +static inline unsigned long meram_read_icb(void __iomem *base, unsigned int idx, + unsigned int off) { return ioread32(MERAM_ICB_OFFSET(base, idx, off)); } -static inline void meram_write_reg(void __iomem *base, int off, - unsigned long val) +static inline void meram_write_reg(void __iomem *base, unsigned int off, + unsigned long val) { iowrite32(val, base + off); } -static inline unsigned long meram_read_reg(void __iomem *base, int off) +static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off) { return ioread32(base + off); } @@ -158,8 +159,8 @@ static inline unsigned long meram_read_reg(void __iomem *base, int off) static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, struct sh_mobile_meram_icb_cfg *new) { - int i; - int used_start, used_end, meram_start, meram_end; + unsigned int used_start, used_end, meram_start, meram_end; + unsigned int i; /* valid ICB? */ if (new->marker_icb & ~0x1f || new->cache_icb & ~0x1f) @@ -190,7 +191,7 @@ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, static inline void meram_mark(struct sh_mobile_meram_priv *priv, struct sh_mobile_meram_icb_cfg *new) { - int n; + unsigned int n; if (new->marker_icb < 0 || new->cache_icb < 0) return; @@ -213,8 +214,8 @@ static inline void meram_mark(struct sh_mobile_meram_priv *priv, static inline void meram_unmark(struct sh_mobile_meram_priv *priv, struct sh_mobile_meram_icb_cfg *icb) { - int i; unsigned long pattern; + unsigned int i; if (icb->marker_icb < 0 || icb->cache_icb < 0) return; @@ -304,12 +305,15 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, static int meram_init(struct sh_mobile_meram_priv *priv, struct sh_mobile_meram_icb_cfg *icb, - int xres, int yres, int *out_pitch) + unsigned int xres, unsigned int yres, + unsigned int *out_pitch) { unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres); unsigned long bnm; - int lcdc_pitch, xpitch, line_cnt; - int save_lines; + unsigned int lcdc_pitch; + unsigned int xpitch; + unsigned int line_cnt; + unsigned int save_lines; /* adjust pitch to 1024, 2048, 4096 or 8192 */ lcdc_pitch = (xres - 1) | 1023; @@ -386,16 +390,18 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv, static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, struct sh_mobile_meram_cfg *cfg, - int xres, int yres, int pixelformat, + unsigned int xres, unsigned int yres, + unsigned int pixelformat, unsigned long base_addr_y, unsigned long base_addr_c, unsigned long *icb_addr_y, unsigned long *icb_addr_c, - int *pitch) + unsigned int *pitch) { struct platform_device *pdev; struct sh_mobile_meram_priv *priv; - int n, out_pitch; + unsigned int out_pitch; + unsigned int n; int error = 0; if (!pdata || !pdata->priv || !pdata->pdev || !cfg) @@ -538,21 +544,21 @@ static int sh_mobile_meram_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev); - int k, j; + unsigned int i, j; - for (k = 0; k < CMN_REGS_SIZE; k++) - priv->cmn_saved_regs[k] = meram_read_reg(priv->base, - common_regs[k]); + for (i = 0; i < CMN_REGS_SIZE; i++) + priv->cmn_saved_regs[i] = meram_read_reg(priv->base, + common_regs[i]); - for (j = 0; j < 32; j++) { - if (!test_bit(j, &priv->used_icb)) + for (i = 0; i < 32; i++) { + if (!test_bit(i, &priv->used_icb)) continue; - for (k = 0; k < ICB_REGS_SIZE; k++) { - priv->icb_saved_regs[j * ICB_REGS_SIZE + k] = - meram_read_icb(priv->base, j, icb_regs[k]); + for (j = 0; j < ICB_REGS_SIZE; j++) { + priv->icb_saved_regs[i * ICB_REGS_SIZE + j] = + meram_read_icb(priv->base, i, icb_regs[j]); /* Reset ICB on resume */ - if (icb_regs[k] == MExxCTL) - priv->icb_saved_regs[j * ICB_REGS_SIZE + k] |= + if (icb_regs[j] == MExxCTL) + priv->icb_saved_regs[i * ICB_REGS_SIZE + j] |= MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF; } } @@ -563,20 +569,20 @@ static int sh_mobile_meram_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev); - int k, j; + unsigned int i, j; - for (j = 0; j < 32; j++) { - if (!test_bit(j, &priv->used_icb)) + for (i = 0; i < 32; i++) { + if (!test_bit(i, &priv->used_icb)) continue; - for (k = 0; k < ICB_REGS_SIZE; k++) { - meram_write_icb(priv->base, j, icb_regs[k], - priv->icb_saved_regs[j * ICB_REGS_SIZE + k]); + for (j = 0; j < ICB_REGS_SIZE; j++) { + meram_write_icb(priv->base, i, icb_regs[j], + priv->icb_saved_regs[i * ICB_REGS_SIZE + j]); } } - for (k = 0; k < CMN_REGS_SIZE; k++) - meram_write_reg(priv->base, common_regs[k], - priv->cmn_saved_regs[k]); + for (i = 0; i < CMN_REGS_SIZE; i++) + meram_write_reg(priv->base, common_regs[i], + priv->cmn_saved_regs[i]); return 0; } -- cgit v1.2.1 From eb4f2304ba029f78516c2fe23213d7e2d0f8d58f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Make current_reg field store the current reg set Make sure current_reg == 0/1 always mean register set A/B through all the code. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index 548f70096124..7af2ffe475d4 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -259,8 +259,8 @@ static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv, { unsigned long target; - target = (cfg->current_reg) ? MExxSARA : MExxSARB; cfg->current_reg ^= 1; + target = cfg->current_reg ? MExxSARB : MExxSARA; /* set the next address to fetch */ meram_write_icb(priv->base, cfg->icb[0].cache_icb, target, -- cgit v1.2.1 From 2a618e0333f5d1d27bbd4d90d70f07e0a8dc0ba7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Add struct sh_mobile_meram_icb The new structure stores ICB parameters for ICBs. Instead of modifying the struct sh_mobile_meram_cfg instances passed by callers, store the ICB parameters internally and make the public API take const pointers to sh_mobile_meram_cfg. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 178 ++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 88 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index 7af2ffe475d4..cddb180f8267 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -100,14 +100,38 @@ static unsigned long icb_regs[] = { }; #define ICB_REGS_SIZE ARRAY_SIZE(icb_regs) +/* + * sh_mobile_meram_icb - MERAM ICB information + * @regs: Registers cache + * @region: Start and end addresses of the MERAM region + * @cache_unit: Bytes to cache per ICB + * @pixelformat: Video pixel format of the data stored in the ICB + * @current_reg: Which of Start Address Register A (0) or B (1) is in use + */ +struct sh_mobile_meram_icb { + unsigned long regs[ICB_REGS_SIZE]; + + unsigned long region; + unsigned int cache_unit; + unsigned int pixelformat; + unsigned int current_reg; +}; + +/* + * sh_mobile_meram_priv - MERAM device + * @base: Registers base address + * @regs: Registers cache + * @lock: Protects used_icb and icbs + * @used_icb: Bitmask of used ICBs + * @icbs: ICBs + */ struct sh_mobile_meram_priv { - void __iomem *base; - struct mutex lock; - unsigned long used_icb; - unsigned int used_meram_cache_regions; - unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM]; - unsigned long cmn_saved_regs[CMN_REGS_SIZE]; - unsigned long icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM]; + void __iomem *base; + unsigned long regs[CMN_REGS_SIZE]; + + struct mutex lock; + unsigned long used_icb; + struct sh_mobile_meram_icb icbs[SH_MOBILE_MERAM_ICB_NUM]; }; /* settings */ @@ -157,7 +181,7 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off) */ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb_cfg *new) + const struct sh_mobile_meram_icb_cfg *new) { unsigned int used_start, used_end, meram_start, meram_end; unsigned int i; @@ -167,17 +191,20 @@ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, return 1; if (test_bit(new->marker_icb, &priv->used_icb) || - test_bit(new->cache_icb, &priv->used_icb)) + test_bit(new->cache_icb, &priv->used_icb)) return 1; - for (i = 0; i < priv->used_meram_cache_regions; i++) { - used_start = MERAM_CACHE_START(priv->used_meram_cache[i]); - used_end = MERAM_CACHE_END(priv->used_meram_cache[i]); + for (i = 0; i < SH_MOBILE_MERAM_ICB_NUM; i++) { + if (!test_bit(i, &priv->used_icb)) + continue; + + used_start = MERAM_CACHE_START(priv->icbs[i].region); + used_end = MERAM_CACHE_END(priv->icbs[i].region); meram_start = new->meram_offset; meram_end = new->meram_offset + new->meram_size; if ((meram_start >= used_start && meram_start < used_end) || - (meram_end > used_start && meram_end < used_end)) + (meram_end > used_start && meram_end < used_end)) return 1; } @@ -189,22 +216,18 @@ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, */ static inline void meram_mark(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb_cfg *new) + const struct sh_mobile_meram_icb_cfg *new, + int pixelformat) { - unsigned int n; - - if (new->marker_icb < 0 || new->cache_icb < 0) - return; - __set_bit(new->marker_icb, &priv->used_icb); __set_bit(new->cache_icb, &priv->used_icb); - n = priv->used_meram_cache_regions; - - priv->used_meram_cache[n] = MERAM_CACHE_SET(new->meram_offset, - new->meram_size); - - priv->used_meram_cache_regions++; + priv->icbs[new->marker_icb].region = MERAM_CACHE_SET(new->meram_offset, + new->meram_size); + priv->icbs[new->cache_icb].region = MERAM_CACHE_SET(new->meram_offset, + new->meram_size); + priv->icbs[new->marker_icb].current_reg = 1; + priv->icbs[new->marker_icb].pixelformat = pixelformat; } /* @@ -212,30 +235,10 @@ static inline void meram_mark(struct sh_mobile_meram_priv *priv, */ static inline void meram_unmark(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb_cfg *icb) + const struct sh_mobile_meram_icb_cfg *icb) { - unsigned long pattern; - unsigned int i; - - if (icb->marker_icb < 0 || icb->cache_icb < 0) - return; - __clear_bit(icb->marker_icb, &priv->used_icb); __clear_bit(icb->cache_icb, &priv->used_icb); - - pattern = MERAM_CACHE_SET(icb->meram_offset, icb->meram_size); - for (i = 0; i < priv->used_meram_cache_regions; i++) { - if (priv->used_meram_cache[i] == pattern) { - while (i < priv->used_meram_cache_regions - 1) { - priv->used_meram_cache[i] = - priv->used_meram_cache[i + 1] ; - i++; - } - priv->used_meram_cache[i] = 0; - priv->used_meram_cache_regions--; - break; - } - } } /* @@ -244,7 +247,7 @@ static inline void meram_unmark(struct sh_mobile_meram_priv *priv, static inline int is_nvcolor(int cspace) { if (cspace == SH_MOBILE_MERAM_PF_NV || - cspace == SH_MOBILE_MERAM_PF_NV24) + cspace == SH_MOBILE_MERAM_PF_NV24) return 1; return 0; } @@ -253,46 +256,51 @@ static inline int is_nvcolor(int cspace) * set the next address to fetch */ static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_cfg *cfg, + const struct sh_mobile_meram_cfg *cfg, unsigned long base_addr_y, unsigned long base_addr_c) { + struct sh_mobile_meram_icb *icb = &priv->icbs[cfg->icb[0].marker_icb]; unsigned long target; - cfg->current_reg ^= 1; - target = cfg->current_reg ? MExxSARB : MExxSARA; + icb->current_reg ^= 1; + target = icb->current_reg ? MExxSARB : MExxSARA; /* set the next address to fetch */ - meram_write_icb(priv->base, cfg->icb[0].cache_icb, target, + meram_write_icb(priv->base, cfg->icb[0].cache_icb, target, base_addr_y); meram_write_icb(priv->base, cfg->icb[0].marker_icb, target, - base_addr_y + cfg->icb[0].cache_unit); + base_addr_y + + priv->icbs[cfg->icb[0].marker_icb].cache_unit); - if (is_nvcolor(cfg->pixelformat)) { + if (is_nvcolor(icb->pixelformat)) { meram_write_icb(priv->base, cfg->icb[1].cache_icb, target, base_addr_c); meram_write_icb(priv->base, cfg->icb[1].marker_icb, target, - base_addr_c + cfg->icb[1].cache_unit); + base_addr_c + + priv->icbs[cfg->icb[1].marker_icb].cache_unit); } } /* * get the next ICB address */ -static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, - struct sh_mobile_meram_cfg *cfg, - unsigned long *icb_addr_y, - unsigned long *icb_addr_c) +static inline void +meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, + const struct sh_mobile_meram_cfg *cfg, + unsigned long *icb_addr_y, unsigned long *icb_addr_c) { + struct sh_mobile_meram_priv *priv = pdata->priv; + struct sh_mobile_meram_icb *icb = &priv->icbs[cfg->icb[0].marker_icb]; unsigned long icb_offset; if (pdata->addr_mode == SH_MOBILE_MERAM_MODE0) - icb_offset = 0x80000000 | (cfg->current_reg << 29); + icb_offset = 0x80000000 | (icb->current_reg << 29); else - icb_offset = 0xc0000000 | (cfg->current_reg << 23); + icb_offset = 0xc0000000 | (icb->current_reg << 23); *icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24); - if (is_nvcolor(cfg->pixelformat)) + if (is_nvcolor(icb->pixelformat)) *icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24); } @@ -304,7 +312,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, */ static int meram_init(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb_cfg *icb, + const struct sh_mobile_meram_icb_cfg *icb, unsigned int xres, unsigned int yres, unsigned int *out_pitch) { @@ -352,7 +360,8 @@ static int meram_init(struct sh_mobile_meram_priv *priv, meram_write_icb(priv->base, icb->marker_icb, MExxSBSIZE, xpitch); /* save a cache unit size */ - icb->cache_unit = xres * save_lines; + priv->icbs[icb->cache_icb].cache_unit = xres * save_lines; + priv->icbs[icb->marker_icb].cache_unit = xres * save_lines; /* * Set MERAM for framebuffer @@ -374,14 +383,16 @@ static int meram_init(struct sh_mobile_meram_priv *priv, } static void meram_deinit(struct sh_mobile_meram_priv *priv, - struct sh_mobile_meram_icb_cfg *icb) + const struct sh_mobile_meram_icb_cfg *icb) { /* disable ICB */ meram_write_icb(priv->base, icb->cache_icb, MExxCTL, MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF); meram_write_icb(priv->base, icb->marker_icb, MExxCTL, MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF); - icb->cache_unit = 0; + + priv->icbs[icb->cache_icb].cache_unit = 0; + priv->icbs[icb->marker_icb].cache_unit = 0; } /* @@ -389,7 +400,7 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv, */ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, - struct sh_mobile_meram_cfg *cfg, + const struct sh_mobile_meram_cfg *cfg, unsigned int xres, unsigned int yres, unsigned int pixelformat, unsigned long base_addr_y, @@ -433,12 +444,6 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, mutex_lock(&priv->lock); - if (priv->used_meram_cache_regions + 2 > SH_MOBILE_MERAM_ICB_NUM) { - dev_err(&pdev->dev, "no more ICB available."); - error = -EINVAL; - goto err; - } - /* make sure that there's no overlaps */ if (meram_check_overlap(priv, &cfg->icb[0])) { dev_err(&pdev->dev, "conflicting config detected."); @@ -464,10 +469,9 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, } /* we now register the ICB */ - cfg->pixelformat = pixelformat; - meram_mark(priv, &cfg->icb[0]); + meram_mark(priv, &cfg->icb[0], pixelformat); if (is_nvcolor(pixelformat)) - meram_mark(priv, &cfg->icb[1]); + meram_mark(priv, &cfg->icb[1], pixelformat); /* initialize MERAM */ meram_init(priv, &cfg->icb[0], xres, yres, &out_pitch); @@ -479,7 +483,6 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, meram_init(priv, &cfg->icb[1], 2 * xres, (yres + 1) / 2, &out_pitch); - cfg->current_reg = 1; meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c); meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c); @@ -492,19 +495,21 @@ err: } static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, - struct sh_mobile_meram_cfg *cfg) + const struct sh_mobile_meram_cfg *cfg) { struct sh_mobile_meram_priv *priv; + struct sh_mobile_meram_icb *icb; if (!pdata || !pdata->priv || !cfg) return -EINVAL; priv = pdata->priv; + icb = &priv->icbs[cfg->icb[0].marker_icb]; mutex_lock(&priv->lock); /* deinit & unmark */ - if (is_nvcolor(cfg->pixelformat)) { + if (is_nvcolor(icb->pixelformat)) { meram_deinit(priv, &cfg->icb[1]); meram_unmark(priv, &cfg->icb[1]); } @@ -517,7 +522,7 @@ static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, } static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, - struct sh_mobile_meram_cfg *cfg, + const struct sh_mobile_meram_cfg *cfg, unsigned long base_addr_y, unsigned long base_addr_c, unsigned long *icb_addr_y, @@ -547,18 +552,17 @@ static int sh_mobile_meram_runtime_suspend(struct device *dev) unsigned int i, j; for (i = 0; i < CMN_REGS_SIZE; i++) - priv->cmn_saved_regs[i] = meram_read_reg(priv->base, - common_regs[i]); + priv->regs[i] = meram_read_reg(priv->base, common_regs[i]); for (i = 0; i < 32; i++) { if (!test_bit(i, &priv->used_icb)) continue; for (j = 0; j < ICB_REGS_SIZE; j++) { - priv->icb_saved_regs[i * ICB_REGS_SIZE + j] = + priv->icbs[i].regs[j] = meram_read_icb(priv->base, i, icb_regs[j]); /* Reset ICB on resume */ if (icb_regs[j] == MExxCTL) - priv->icb_saved_regs[i * ICB_REGS_SIZE + j] |= + priv->icbs[i].regs[j] |= MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF; } } @@ -574,15 +578,13 @@ static int sh_mobile_meram_runtime_resume(struct device *dev) for (i = 0; i < 32; i++) { if (!test_bit(i, &priv->used_icb)) continue; - for (j = 0; j < ICB_REGS_SIZE; j++) { + for (j = 0; j < ICB_REGS_SIZE; j++) meram_write_icb(priv->base, i, icb_regs[j], - priv->icb_saved_regs[i * ICB_REGS_SIZE + j]); - } + priv->icbs[i].regs[j]); } for (i = 0; i < CMN_REGS_SIZE; i++) - meram_write_reg(priv->base, common_regs[i], - priv->cmn_saved_regs[i]); + meram_write_reg(priv->base, common_regs[i], priv->regs[i]); return 0; } -- cgit v1.2.1 From 762f7cc94bc5c5c8c54f9d0073a07a275b106d89 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Don't inline everything Let the compiler decide which complex functions to inline, and constify constant static arrays. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index cddb180f8267..0c5b301697e1 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -83,14 +83,14 @@ #define SH_MOBILE_MERAM_ICB_NUM 32 -static unsigned long common_regs[] = { +static const unsigned long common_regs[] = { MEVCR1, MEQSEL1, MEQSEL2, }; #define CMN_REGS_SIZE ARRAY_SIZE(common_regs) -static unsigned long icb_regs[] = { +static const unsigned long icb_regs[] = { MExxCTL, MExxBSIZE, MExxMNCF, @@ -180,8 +180,8 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off) * check if there's no overlaps in MERAM allocation. */ -static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, - const struct sh_mobile_meram_icb_cfg *new) +static int meram_check_overlap(struct sh_mobile_meram_priv *priv, + const struct sh_mobile_meram_icb_cfg *new) { unsigned int used_start, used_end, meram_start, meram_end; unsigned int i; @@ -215,9 +215,9 @@ static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv, * mark the specified ICB as used */ -static inline void meram_mark(struct sh_mobile_meram_priv *priv, - const struct sh_mobile_meram_icb_cfg *new, - int pixelformat) +static void meram_mark(struct sh_mobile_meram_priv *priv, + const struct sh_mobile_meram_icb_cfg *new, + int pixelformat) { __set_bit(new->marker_icb, &priv->used_icb); __set_bit(new->cache_icb, &priv->used_icb); @@ -234,8 +234,8 @@ static inline void meram_mark(struct sh_mobile_meram_priv *priv, * unmark the specified ICB as used */ -static inline void meram_unmark(struct sh_mobile_meram_priv *priv, - const struct sh_mobile_meram_icb_cfg *icb) +static void meram_unmark(struct sh_mobile_meram_priv *priv, + const struct sh_mobile_meram_icb_cfg *icb) { __clear_bit(icb->marker_icb, &priv->used_icb); __clear_bit(icb->cache_icb, &priv->used_icb); @@ -244,7 +244,7 @@ static inline void meram_unmark(struct sh_mobile_meram_priv *priv, /* * is this a YCbCr(NV12, NV16 or NV24) colorspace */ -static inline int is_nvcolor(int cspace) +static int is_nvcolor(int cspace) { if (cspace == SH_MOBILE_MERAM_PF_NV || cspace == SH_MOBILE_MERAM_PF_NV24) @@ -255,10 +255,10 @@ static inline int is_nvcolor(int cspace) /* * set the next address to fetch */ -static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv, - const struct sh_mobile_meram_cfg *cfg, - unsigned long base_addr_y, - unsigned long base_addr_c) +static void meram_set_next_addr(struct sh_mobile_meram_priv *priv, + const struct sh_mobile_meram_cfg *cfg, + unsigned long base_addr_y, + unsigned long base_addr_c) { struct sh_mobile_meram_icb *icb = &priv->icbs[cfg->icb[0].marker_icb]; unsigned long target; @@ -285,7 +285,7 @@ static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv, /* * get the next ICB address */ -static inline void +static void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, const struct sh_mobile_meram_cfg *cfg, unsigned long *icb_addr_y, unsigned long *icb_addr_c) -- cgit v1.2.1 From 7554340c7acae4a719b1b70b0defa3c67149610b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 19 Sep 2011 11:40:31 +0200 Subject: fbdev: sh_mobile_meram: Divide the code into sections And rename a couple of constants to make prefixes more uniform. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_meram.c | 98 ++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 54 deletions(-) (limited to 'drivers/video/sh_mobile_meram.c') diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index 0c5b301697e1..30a3305ba366 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c @@ -9,16 +9,20 @@ * for more details. */ +#include +#include #include #include -#include +#include #include -#include #include -#include + #include