* RE: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Jenkins, Clive @ 2011-06-22 10:39 UTC (permalink / raw)
To: Anatolij Gustschin, Timur Tabi; +Cc: linuxppc-dev, linux-fbdev, lethal, yorksun
In-Reply-To: <20110622003853.1041385c@wker>
> > The ioctl interface in the Freescale DIU framebuffer driver is just
a
> > collection of miscellaneous functions which were only used in a
one-time
> > demo application that was never distributed. Plus, the ioctls were
spread
> > across two types (both conflicting), and the demo app didn't even
use all
> > of them.
> >
> > Removing the ioctl interface also allows us to clean up the header
file and
> > remove other unusued stuff.
>
> No! We are using ioctl interface of this driver in many video
> rendering applications on overlay planes on huge number of boards.
> So, please don't remove it.
>
> Anatolij
Can you make available your application code by posting a link to it?
Thanks,
Clive
^ permalink raw reply
* RE: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Marek Szyprowski @ 2011-06-22 9:47 UTC (permalink / raw)
To: 'Jingoo Han', 'Kukjin Kim', 'Paul Mundt',
linux-samsung-soc, linux-fbdev
Cc: 'Anand Kumar N', 'Thomas Abraham',
Sylwester Nawrocki, 'Kyungmin Park', 'Inki Dae',
'ARM Linux', 'Ben Dooks', 'Jonghun Han'
In-Reply-To: <1308724904-31521-1-git-send-email-jg1.han@samsung.com>
Hello,
On Wednesday, June 22, 2011 8:42 AM Jingoo Han wrote:
> From: Jonghun Han <jonghun.han@samsung.com>
>
> This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
>
> Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
> arch/arm/mach-exynos4/mach-smdkc210.c | 114
> +++++++++++++++++++++++++++++++++
> arch/arm/mach-exynos4/mach-smdkv310.c | 114
> +++++++++++++++++++++++++++++++++
> 2 files changed, 228 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-
> exynos4/mach-smdkc210.c
> index e645f7a..360a50a 100644
> --- a/arch/arm/mach-exynos4/mach-smdkc210.c
> +++ b/arch/arm/mach-exynos4/mach-smdkc210.c
> @@ -9,26 +9,33 @@
> */
>
> #include <linux/serial_core.h>
> +#include <linux/delay.h>
> #include <linux/gpio.h>
> +#include <linux/lcd.h>
> #include <linux/mmc/host.h>
> #include <linux/platform_device.h>
> #include <linux/smsc911x.h>
> #include <linux/io.h>
> #include <linux/i2c.h>
> +#include <linux/clk.h>
>
> #include <asm/mach/arch.h>
> #include <asm/mach-types.h>
>
> +#include <video/platform_lcd.h>
> +
> #include <plat/regs-serial.h>
> #include <plat/regs-srom.h>
> #include <plat/exynos4.h>
> #include <plat/cpu.h>
> #include <plat/devs.h>
> +#include <plat/fb.h>
> #include <plat/sdhci.h>
> #include <plat/iic.h>
> #include <plat/pd.h>
>
> #include <mach/map.h>
> +#include <mach/regs-fb.h>
>
> /* Following are default values for UCON, ULCON and UFCON UART registers
> */
> #define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
> @@ -111,6 +118,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata
> __initdata = {
> .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
> };
>
> +static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
> + unsigned int power)
> +{
> + if (power) {
> +#if !defined(CONFIG_BACKLIGHT_PWM)
> + gpio_request(EXYNOS4_GPD0(1), "GPD0");
> + gpio_direction_output(EXYNOS4_GPD0(1), 1);
> + gpio_free(EXYNOS4_GPD0(1));
> +#endif
> + /* fire nRESET on power up */
> + gpio_request(EXYNOS4_GPX0(6), "GPX0");
> +
> + gpio_direction_output(EXYNOS4_GPX0(6), 1);
> + mdelay(100);
> +
> + gpio_set_value(EXYNOS4_GPX0(6), 0);
> + mdelay(10);
> +
> + gpio_set_value(EXYNOS4_GPX0(6), 1);
> + mdelay(10);
> +
> + gpio_free(EXYNOS4_GPX0(6));
> + } else {
> +#if !defined(CONFIG_BACKLIGHT_PWM)
> + gpio_request(EXYNOS4_GPD0(1), "GPD0");
> + gpio_direction_output(EXYNOS4_GPD0(1), 0);
> + gpio_free(EXYNOS4_GPD0(1));
> +#endif
> + }
> +}
> +
> +static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
> + .set_power = lcd_lte480wv_set_power,
> +};
> +
> +static struct platform_device smdkc210_lcd_lte480wv = {
> + .name = "platform-lcd",
> + .dev.parent = &s5p_device_fimd0.dev,
> + .dev.platform_data = &smdkc210_lcd_lte480wv_data,
> +};
> +
> +static struct s3c_fb_pd_win smdkc210_fb_win0 = {
> + .win_mode = {
> + .left_margin = 13,
> + .right_margin = 8,
> + .upper_margin = 7,
> + .lower_margin = 5,
> + .hsync_len = 3,
> + .vsync_len = 1,
> + .xres = 800,
> + .yres = 480,
> + },
> + .max_bpp = 32,
> + .default_bpp = 24,
> +};
> +
> +static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
> + .win[0] = &smdkc210_fb_win0,
> + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
> + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
> + .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
> +};
> +
> static struct resource smdkc210_smsc911x_resources[] = {
> [0] = {
> .start = EXYNOS4_PA_SROM_BANK(1),
> @@ -165,6 +235,8 @@ static struct platform_device *smdkc210_devices[]
> __initdata = {
> &exynos4_device_pd[PD_GPS],
> &exynos4_device_sysmmu,
> &samsung_asoc_dma,
> + &s5p_device_fimd0,
> + &smdkc210_lcd_lte480wv,
> &smdkc210_smsc911x,
> };
>
> @@ -191,6 +263,44 @@ static void __init smdkc210_smsc911x_init(void)
> (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
> }
>
> +static int __init smdkc210_fimd0_setup_clock(void)
> +{
> + struct clk *sclk = NULL;
> + struct clk *mout_mpll = NULL;
> +
> + u32 rate = 0;
> +
> + sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
> + if (IS_ERR(sclk)) {
> + printk(KERN_ERR "failed to get sclk for fimd\n");
> + goto err_clk2;
> + }
> +
> + mout_mpll = clk_get(NULL, "mout_mpll");
> + if (IS_ERR(mout_mpll)) {
> + printk(KERN_ERR "failed to get mout_mpll\n");
> + goto err_clk1;
> + }
> +
> + clk_set_parent(sclk, mout_mpll);
> + if (!rate)
> + rate = 134000000;
> +
> + clk_set_rate(sclk, rate);
> +
> + clk_put(sclk);
> + clk_put(mout_mpll);
> +
> + return 0;
> +
> +err_clk1:
> + clk_put(mout_mpll);
> +err_clk2:
> + clk_put(sclk);
> +
> + return -EINVAL;
> +}
> +
I'm not sure if mach-smdk*.c is the right place for the above code.
IMHO all the code that configures very low level, board specific parameters
(like clocks and their relations) should be performed in boot loarder.
(snipped)
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply
* Re: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Sylwester Nawrocki @ 2011-06-22 8:56 UTC (permalink / raw)
To: Jingoo Han
Cc: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
Jonghun Han, Anand Kumar N, Thomas Abraham, Marek Szyprowski,
Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks
In-Reply-To: <1308724904-31521-1-git-send-email-jg1.han@samsung.com>
Hello,
On 06/22/2011 08:41 AM, Jingoo Han wrote:
> From: Jonghun Han <jonghun.han@samsung.com>
>
> This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
>
> Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
> arch/arm/mach-exynos4/mach-smdkc210.c | 114 +++++++++++++++++++++++++++++++++
> arch/arm/mach-exynos4/mach-smdkv310.c | 114 +++++++++++++++++++++++++++++++++
> 2 files changed, 228 insertions(+), 0 deletions(-)
...
> +static int __init smdkc210_fimd0_setup_clock(void)
> +{
> + struct clk *sclk = NULL;
> + struct clk *mout_mpll = NULL;
You don't need initialize to NULL here.
> +
> + u32 rate = 0;
Other than this variable is not really needed I would make it unsigned long.
> +
> + sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
> + if (IS_ERR(sclk)) {
> + printk(KERN_ERR "failed to get sclk for fimd\n");
> + goto err_clk2;
You could just do:
return PTR_ERR(sclk);
> + }
> +
> + mout_mpll = clk_get(NULL, "mout_mpll");
> + if (IS_ERR(mout_mpll)) {
> + printk(KERN_ERR "failed to get mout_mpll\n");
> + goto err_clk1;
> + }
> +
> + clk_set_parent(sclk, mout_mpll);
> + if (!rate)
> + rate = 134000000;
134000000UL
> +
> + clk_set_rate(sclk, rate);
> +
> + clk_put(sclk);
> + clk_put(mout_mpll);
> +
> + return 0;
> +
> +err_clk1:
> + clk_put(mout_mpll);
clk_put is supposed to be used only for clocks that were successfully acquired.
> +err_clk2:
> + clk_put(sclk);
Ditto.
> +
> + return -EINVAL;
> +}
...
> +static int __init smdkv310_fimd0_setup_clock(void)
> +{
> + struct clk *sclk = NULL;
> + struct clk *mout_mpll = NULL;
> +
> + u32 rate = 0;
> +
> + sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
> + if (IS_ERR(sclk)) {
> + printk(KERN_ERR "failed to get sclk for fimd\n");
> + goto err_clk2;
> + }
> +
> + mout_mpll = clk_get(NULL, "mout_mpll");
> + if (IS_ERR(mout_mpll)) {
> + printk(KERN_ERR "failed to get mout_mpll\n");
> + goto err_clk1;
> + }
> +
> + clk_set_parent(sclk, mout_mpll);
> + if (!rate)
> + rate = 134000000;
> +
> + clk_set_rate(sclk, rate);
> +
> + clk_put(sclk);
> + clk_put(mout_mpll);
> +
> + return 0;
> +
> +err_clk1:
> + clk_put(mout_mpll);
> +err_clk2:
> + clk_put(sclk);
> +
> + return -EINVAL;
> +}
We have multiple copies of same function and I suspect other boards will try
to repeat this pattern which is not that good.
It would be worth to create common function for all boards if we really
must have that, e.g.
int __init exynos4_fimd_setup_clock(struct device *dev, const char *parent,
unsigned long clk_rate);
{
struct clk *clk_parent;
struct clk *sclk;
sclk = clk_get(dev, "sclk_fimd");
if (IS_ERR(sclk))
return PTR_ERR(sclk);
clk_parent = clk_get(NULL, parent);
if (IS_ERR(parent_clk)) {
clk_put(sclk);
return PTR_ERR(clk_parent);
}
clk_set_parent(sclk, clk_parent);
if (!rate)
rate = 134000000UL;
clk_set_rate(sclk, rate);
clk_put(sclk);
clk_put(clk_parent);
return 0;
}
But I have no idea where to put that...
Perhaps we should create common mach-exynos4/setup-fimd.c file for FIMD0, FIMD1.
But then it would contain ugly #ifdef for unused FIMD1 setup functions
("#ifdef CONFIG_DEV_FIMD0 ..") if only FIMD0 is used. Maybe someone else has
better idea.
Regards,
--
Sylwester Nawrocki
Samsung Poland R&D Center
^ permalink raw reply
* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-06-22 8:50 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: Geert Uytterhoeven, linux-fbdev, linux-media, dri-devel
In-Reply-To: <4E018189.3020305@gmx.de>
Hi Florian,
On Wednesday 22 June 2011 07:45:45 Florian Tobias Schandinat wrote:
> On 06/21/2011 10:31 PM, Laurent Pinchart wrote:
> > On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
> >> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
> >>> +The FOURCC-based API replaces format descriptions by four character
> >>> codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define
> >>> a format +without explicitly describing it. This is the only API that
> >>> supports YUV +formats. Drivers are also encouraged to implement the
> >>> FOURCC-based API for RGB +and grayscale formats.
> >>> +
> >>> +Drivers that support the FOURCC-based API report this capability by
> >>> setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
> >>> field. +
> >>> +FOURCC definitions are located in the linux/videodev2.h header.
> >>> However, and +despite starting with the V4L2_PIX_FMT_prefix, they are
> >>> not restricted to V4L2 +and don't require usage of the V4L2 subsystem.
> >>> FOURCC documentation is +available in
> >>> Documentation/DocBook/v4l/pixfmt.xml.
> >>> +
> >>> +To select a format, applications set the FB_VMODE_FOURCC bit in the
> >>> +fb_var_screeninfo vmode field, and set the fourcc field to the desired
> >>> FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
> >>> must be set to +0 by applications and ignored by drivers. Note that the
> >>> grayscale and fourcc +fields share the same memory location.
> >>> Application must thus not set the +grayscale field to 0.
> >>
> >> These are the only parts I don't like: (ab)using the vmode field (this
> >> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
> >> unions where possible).
> >
> > I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a
> > FOURCC mode indicator in my initial RFC. Florian Tobias Schandinat
> > wasn't very happy with that, and proposed using the vmode field instead.
> >
> > Given that there's virtually no fbdev documentation, whether the vmode
> > field and/or nonstd field are good fit for a FOURCC mode indicator is
> > subject to interpretation.
>
> The reason for my suggestion is that the vmode field is accepted to contain
> only flags and at least to me there is no hard line what is part of the
> video mode and what is not.
Lacks of documentation indeed makes that line fuzzy. I really hope that
api.txt will be extended to cover the full fbdev API :-)
> In contrast the nonstd field is already used in a lot of different
> (incompatible) ways. I think if we only use the nonstd field for handling
> FOURCC it is likely that some problems will appear.
>
> >> What about storing the FOURCC value in nonstd instead?
> >
> > Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format
> > setting will be a standard fbdev API, I'm not very keen on storing it in
> > the nonstd field without a union.
> >
> >> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
> >> be non-zero), I don't think there are any conflicts with existing values
> >> of nonstd. To make it even safer and easier to parse, you could set bit
> >> 31 of nonstd as a FOURCC indicator.
> >
> > I would then create a union between nonstd and fourcc, and document
> > nonstd as being used for the legacy API only. Most existing drivers use
> > a couple of nonstd bits only. The driver that (ab)uses nonstd the most
> > is pxafb and uses bits 22:0. Bits 31:24 are never used as far as I can
> > tell, so nonstd& 0xff000000 != 0 could be used as a FOURCC mode test.
> >
> > This assumes that FOURCCs will never have their last character set to
> > '\0'. Is that a safe assumption for the future ?
>
> Yes, I think. The information I found indicates that space should be used
> for padding, so a \0 shouldn't exist.
> I think using only the nonstd field and requiring applications to check the
> capabilities would be possible, although not fool proof ;)
>
> Great work, Laurent, do you have plans to modify fbset to allow using this
> format API from the command line?
Once we agree on an API, I will implement it in a driver and update fbset.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 4/4] OMAP: DSS2: Fix FIFO threshold and burst size for OMAP4
From: Tomi Valkeinen @ 2011-06-22 8:45 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1308732326-17278-1-git-send-email-tomi.valkeinen@ti.com>
The DMA FIFO threshold registers and burst size registers have changed
for OMAP4. The current code only handles OMAP2/3 case, and so the
values are a bit off for OMAP4. A summary of the differences between
OMAP2/3 and OMAP4:
Burst size:
OMAP2/3: 4 x 32 bits / 8 x 32 bits / 16 x 32 bits
OMAP4: 2 x 128 bits / 4 x 128 bits / 8 x 128 bits
Threshold size:
OMAP2/3: in bytes (8 bit units)
OMAP4: in 128bit units
This patch fixes the issue by creating two new helper functions in
dss_features: dss_feat_get_buffer_size_unit() and
dss_feat_get_burst_size_unit(). These return (in bytes) the unit size
for threshold registers and unit size for burst size register,
respectively, and are used to calculate correct values.
For the threshold size the usage is straightforward. However, the burst
size register has different multipliers for OMAP2/3 and OMAP4. This
patch solves the problem by defining the multipliers for the burst size
as 2x, 4x and 8x, which fit fine for the OMAP4 burst size definition
(i.e. burst size unit for OMAP4 is 128bits), but requires a slight twist
on OMAP2/3 by defining the burst size unit as 64bit.
As the driver in practice always uses the maximum burst size, and no use
case currently exists where we would want to use a smaller burst size,
this patch changes the driver to hardcode the burst size when
initializing DISPC. This makes the threshold configuration code somewhat
simpler.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 50 ++++++++++++++++++++++++++-----
drivers/video/omap2/dss/display.c | 12 +++----
drivers/video/omap2/dss/dsi.c | 11 ++-----
drivers/video/omap2/dss/dss.h | 15 ++-------
drivers/video/omap2/dss/dss_features.c | 23 ++++++++++++++
drivers/video/omap2/dss/dss_features.h | 3 ++
drivers/video/omap2/dss/manager.c | 12 ++++----
7 files changed, 86 insertions(+), 40 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0151f16..2fcb73b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -79,6 +79,12 @@ struct dispc_v_coef {
s8 vc00;
};
+enum omap_burst_size {
+ BURST_SIZE_X2 = 0,
+ BURST_SIZE_X4 = 1,
+ BURST_SIZE_X8 = 2,
+};
+
#define REG_GET(idx, start, end) \
FLD_GET(dispc_read_reg(idx), start, end)
@@ -1044,11 +1050,10 @@ void dispc_set_channel_out(enum omap_plane plane,
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
-void dispc_set_burst_size(enum omap_plane plane,
+static void dispc_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
int shift;
- u32 val;
switch (plane) {
case OMAP_DSS_GFX:
@@ -1063,9 +1068,24 @@ void dispc_set_burst_size(enum omap_plane plane,
return;
}
- val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
- val = FLD_MOD(val, burst_size, shift+1, shift);
- dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);
+}
+
+static void dispc_configure_burst_sizes(void)
+{
+ int i;
+ const int burst_size = BURST_SIZE_X8;
+
+ /* Configure burst size always to maximum size */
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i)
+ dispc_set_burst_size(i, burst_size);
+}
+
+u32 dispc_get_burst_size(enum omap_plane plane)
+{
+ unsigned unit = dss_feat_get_burst_size_unit();
+ /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
+ return unit * 8;
}
void dispc_enable_gamma_table(bool enable)
@@ -1160,12 +1180,15 @@ static void dispc_read_plane_fifo_sizes(void)
u32 size;
int plane;
u8 start, end;
+ u32 unit;
+
+ unit = dss_feat_get_buffer_size_unit();
dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
- size = FLD_GET(dispc_read_reg(DISPC_OVL_FIFO_SIZE_STATUS(plane)),
- start, end);
+ size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
+ size *= unit;
dispc.fifo_size[plane] = size;
}
}
@@ -1175,9 +1198,18 @@ u32 dispc_get_plane_fifo_size(enum omap_plane plane)
return dispc.fifo_size[plane];
}
-void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
+void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
{
u8 hi_start, hi_end, lo_start, lo_end;
+ u32 unit;
+
+ unit = dss_feat_get_buffer_size_unit();
+
+ WARN_ON(low % unit != 0);
+ WARN_ON(high % unit != 0);
+
+ low /= unit;
+ high /= unit;
dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
@@ -3601,6 +3633,8 @@ static void _omap_dispc_initial_config(void)
dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
dispc_read_plane_fifo_sizes();
+
+ dispc_configure_burst_sizes();
}
/* DISPC HW IP initialisation */
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index a0bbdf6..94495e4 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -29,6 +29,7 @@
#include <video/omapdss.h>
#include "dss.h"
+#include "dss_features.h"
static ssize_t display_enabled_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -282,16 +283,13 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
EXPORT_SYMBOL(omapdss_default_get_resolution);
void default_get_overlay_fifo_thresholds(enum omap_plane plane,
- u32 fifo_size, enum omap_burst_size *burst_size,
+ u32 fifo_size, u32 burst_size,
u32 *fifo_low, u32 *fifo_high)
{
- unsigned burst_size_bytes;
+ unsigned buf_unit = dss_feat_get_buffer_size_unit();
- *burst_size = OMAP_DSS_BURST_16x32;
- burst_size_bytes = 16 * 32 / 8;
-
- *fifo_high = fifo_size - 1;
- *fifo_low = fifo_size - burst_size_bytes;
+ *fifo_high = fifo_size - buf_unit;
+ *fifo_low = fifo_size - burst_size;
}
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 62b11c5..12bc2e7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4292,16 +4292,11 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
EXPORT_SYMBOL(omapdss_dsi_enable_te);
void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
- u32 fifo_size, enum omap_burst_size *burst_size,
+ u32 fifo_size, u32 burst_size,
u32 *fifo_low, u32 *fifo_high)
{
- unsigned burst_size_bytes;
-
- *burst_size = OMAP_DSS_BURST_16x32;
- burst_size_bytes = 16 * 32 / 8;
-
- *fifo_high = fifo_size - burst_size_bytes;
- *fifo_low = fifo_size - burst_size_bytes * 2;
+ *fifo_high = fifo_size - burst_size;
+ *fifo_low = fifo_size - burst_size * 2;
}
int dsi_init_display(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 9dc5c00..adeff04 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,12 +97,6 @@ extern unsigned int dss_debug;
#define FLD_MOD(orig, val, start, end) \
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
-enum omap_burst_size {
- OMAP_DSS_BURST_4x32 = 0,
- OMAP_DSS_BURST_8x32 = 1,
- OMAP_DSS_BURST_16x32 = 2,
-};
-
enum omap_parallel_interface_mode {
OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
@@ -186,7 +180,7 @@ void dss_uninit_device(struct platform_device *pdev,
bool dss_use_replication(struct omap_dss_device *dssdev,
enum omap_color_mode mode);
void default_get_overlay_fifo_thresholds(enum omap_plane plane,
- u32 fifo_size, enum omap_burst_size *burst_size,
+ u32 fifo_size, u32 burst_size,
u32 *fifo_low, u32 *fifo_high);
/* manager */
@@ -293,7 +287,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
bool enable_hsdiv);
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
- u32 fifo_size, enum omap_burst_size *burst_size,
+ u32 fifo_size, u32 burst_size,
u32 *fifo_low, u32 *fifo_high);
void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
@@ -394,10 +388,9 @@ void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
void dispc_set_digit_size(u16 width, u16 height);
u32 dispc_get_plane_fifo_size(enum omap_plane plane);
-void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
+void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
void dispc_enable_fifomerge(bool enable);
-void dispc_set_burst_size(enum omap_plane plane,
- enum omap_burst_size burst_size);
+u32 dispc_get_burst_size(enum omap_plane plane);
void dispc_enable_cpr(enum omap_channel channel, bool enable);
void dispc_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index bd420f9..b415c4e 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -49,6 +49,9 @@ struct omap_dss_features {
const enum omap_color_mode *supported_color_modes;
const char * const *clksrc_names;
const struct dss_param_range *dss_params;
+
+ const u32 buffer_size_unit;
+ const u32 burst_size_unit;
};
/* This struct is assigned to one of the below during initialization */
@@ -274,6 +277,8 @@ static const struct omap_dss_features omap2_dss_features = {
.supported_color_modes = omap2_dss_supported_color_modes,
.clksrc_names = omap2_dss_clk_source_names,
.dss_params = omap2_dss_param_range,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
/* OMAP3 DSS Features */
@@ -296,6 +301,8 @@ static const struct omap_dss_features omap3430_dss_features = {
.supported_color_modes = omap3_dss_supported_color_modes,
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
static const struct omap_dss_features omap3630_dss_features = {
@@ -317,6 +324,8 @@ static const struct omap_dss_features omap3630_dss_features = {
.supported_color_modes = omap3_dss_supported_color_modes,
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
/* OMAP4 DSS Features */
@@ -339,6 +348,8 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
};
/* For all the other OMAP4 versions */
@@ -361,6 +372,8 @@ static const struct omap_dss_features omap4_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
};
/* Functions returning values related to a DSS feature */
@@ -406,6 +419,16 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
return omap_current_dss_features->clksrc_names[id];
}
+u32 dss_feat_get_buffer_size_unit(void)
+{
+ return omap_current_dss_features->buffer_size_unit;
+}
+
+u32 dss_feat_get_burst_size_unit(void)
+{
+ return omap_current_dss_features->burst_size_unit;
+}
+
/* DSS has_feature check */
bool dss_has_feature(enum dss_feat_id id)
{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 5be8103..b7398cb 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -94,6 +94,9 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
enum omap_color_mode color_mode);
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
+u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
+u32 dss_feat_get_burst_size_unit(void); /* in bytes */
+
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);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index ad76c5b..13d72d5 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -507,7 +507,6 @@ struct overlay_cache_data {
bool replication;
bool ilace;
- enum omap_burst_size burst_size;
u32 fifo_low;
u32 fifo_high;
};
@@ -947,8 +946,7 @@ static int configure_overlay(enum omap_plane plane)
dispc_enable_replication(plane, c->replication);
- dispc_set_burst_size(plane, c->burst_size);
- dispc_setup_plane_fifo(plane, c->fifo_low, c->fifo_high);
+ dispc_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
dispc_enable_plane(plane, 1);
@@ -1421,7 +1419,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
/* Configure overlay fifos */
for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
struct omap_dss_device *dssdev;
- u32 size;
+ u32 size, burst_size;
ovl = omap_dss_get_overlay(i);
@@ -1439,6 +1437,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
if (use_fifomerge)
size *= 3;
+ burst_size = dispc_get_burst_size(ovl->id);
+
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
case OMAP_DISPLAY_TYPE_DBI:
@@ -1446,13 +1446,13 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
case OMAP_DISPLAY_TYPE_VENC:
case OMAP_DISPLAY_TYPE_HDMI:
default_get_overlay_fifo_thresholds(ovl->id, size,
- &oc->burst_size, &oc->fifo_low,
+ burst_size, &oc->fifo_low,
&oc->fifo_high);
break;
#ifdef CONFIG_OMAP2_DSS_DSI
case OMAP_DISPLAY_TYPE_DSI:
dsi_get_overlay_fifo_thresholds(ovl->id, size,
- &oc->burst_size, &oc->fifo_low,
+ burst_size, &oc->fifo_low,
&oc->fifo_high);
break;
#endif
--
1.7.4.1
^ permalink raw reply related
* [PATCH 3/4] OMAP: DSS2: DSI: sync when disabling a display
From: Tomi Valkeinen @ 2011-06-22 8:45 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1308732326-17278-1-git-send-email-tomi.valkeinen@ti.com>
When the panel driver calls omapdss_dsi_display_disable() it is possible
that there are still some unsent packets in the TX fifo.
Add dsi_sync_vc() calls in the beginning of
omapdss_dsi_display_disable() to make sure the TX fifos are empty.
This allows us to remove the msleep(10) hack from panel-taal.c
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays/panel-taal.c | 5 +----
drivers/video/omap2/dss/dsi.c | 5 +++++
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 4cb0449..4e888ac 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1247,11 +1247,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
int r;
r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
- if (!r) {
+ if (!r)
r = taal_sleep_in(td);
- /* HACK: wait a bit so that the message goes through */
- msleep(10);
- }
if (r) {
dev_err(&dssdev->dev,
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index b6a57bb..62b11c5 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4263,6 +4263,11 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
mutex_lock(&dsi->lock);
+ dsi_sync_vc(dsidev, 0);
+ dsi_sync_vc(dsidev, 1);
+ dsi_sync_vc(dsidev, 2);
+ dsi_sync_vc(dsidev, 3);
+
dsi_display_uninit_dispc(dssdev);
dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 2/4] OMAP: DSS2: Add Color Phase Rotation support
From: Tomi Valkeinen @ 2011-06-22 8:45 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1308732326-17278-1-git-send-email-tomi.valkeinen@ti.com>
Add Color Phase Rotation (CPR) support and sysfs files to enable CPR and
to set the CPR coefficient matrix.
CPR is enabled via manager?/cpr_enable file, and the coefficient matrix
is set via manager?/cpr_coef file. The values in cpr_coef are in the
following order:
RR RG RB GR GG GB BR BG BB
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 34 +++++++++++
drivers/video/omap2/dss/dss.h | 3 +
drivers/video/omap2/dss/manager.c | 114 +++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 9 +++
4 files changed, 160 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index eac768f..0151f16 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1082,6 +1082,40 @@ void dispc_enable_gamma_table(bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
}
+void dispc_enable_cpr(enum omap_channel channel, bool enable)
+{
+ u16 reg;
+
+ if (channel = OMAP_DSS_CHANNEL_LCD)
+ reg = DISPC_CONFIG;
+ else if (channel = OMAP_DSS_CHANNEL_LCD2)
+ reg = DISPC_CONFIG2;
+ else
+ return;
+
+ REG_FLD_MOD(reg, enable, 15, 15);
+}
+
+void dispc_set_cpr_coef(enum omap_channel channel,
+ struct omap_dss_cpr_coefs *coefs)
+{
+ u32 coef_r, coef_g, coef_b;
+
+ if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2)
+ return;
+
+ coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
+ FLD_VAL(coefs->rb, 9, 0);
+ coef_g = FLD_VAL(coefs->gr, 31, 22) | FLD_VAL(coefs->gg, 20, 11) |
+ FLD_VAL(coefs->gb, 9, 0);
+ coef_b = FLD_VAL(coefs->br, 31, 22) | FLD_VAL(coefs->bg, 20, 11) |
+ FLD_VAL(coefs->bb, 9, 0);
+
+ dispc_write_reg(DISPC_CPR_COEF_R(channel), coef_r);
+ dispc_write_reg(DISPC_CPR_COEF_G(channel), coef_g);
+ dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b);
+}
+
static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
{
u32 val;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index ce17a61..9dc5c00 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -398,6 +398,9 @@ void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
void dispc_enable_fifomerge(bool enable);
void dispc_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size);
+void dispc_enable_cpr(enum omap_channel channel, bool enable);
+void dispc_set_cpr_coef(enum omap_channel channel,
+ struct omap_dss_cpr_coefs *coefs);
void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 4691b81..ad76c5b 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -275,6 +275,108 @@ static ssize_t manager_alpha_blending_enabled_store(
return size;
}
+static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable);
+}
+
+static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ int v;
+ int r;
+ bool enable;
+
+ if (!dss_has_feature(FEAT_CPR))
+ return -ENODEV;
+
+ r = kstrtoint(buf, 0, &v);
+ if (r)
+ return r;
+
+ enable = !!v;
+
+ mgr->get_manager_info(mgr, &info);
+
+ if (info.cpr_enable = enable)
+ return size;
+
+ info.cpr_enable = enable;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE,
+ "%d %d %d %d %d %d %d %d %d\n",
+ info.cpr_coefs.rr,
+ info.cpr_coefs.rg,
+ info.cpr_coefs.rb,
+ info.cpr_coefs.gr,
+ info.cpr_coefs.gg,
+ info.cpr_coefs.gb,
+ info.cpr_coefs.br,
+ info.cpr_coefs.bg,
+ info.cpr_coefs.bb);
+}
+
+static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ struct omap_dss_cpr_coefs coefs;
+ int r, i;
+ s16 *arr;
+
+ if (!dss_has_feature(FEAT_CPR))
+ return -ENODEV;
+
+ if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
+ &coefs.rr, &coefs.rg, &coefs.rb,
+ &coefs.gr, &coefs.gg, &coefs.gb,
+ &coefs.br, &coefs.bg, &coefs.bb) != 9)
+ return -EINVAL;
+
+ arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
+ coefs.gr, coefs.gg, coefs.gb,
+ coefs.br, coefs.bg, coefs.bb };
+
+ for (i = 0; i < 9; ++i) {
+ if (arr[i] < -512 || arr[i] > 511)
+ return -EINVAL;
+ }
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.cpr_coefs = coefs;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
struct manager_attribute {
struct attribute attr;
ssize_t (*show)(struct omap_overlay_manager *, char *);
@@ -300,6 +402,12 @@ static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
manager_alpha_blending_enabled_show,
manager_alpha_blending_enabled_store);
+static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
+ manager_cpr_enable_show,
+ manager_cpr_enable_store);
+static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
+ manager_cpr_coef_show,
+ manager_cpr_coef_store);
static struct attribute *manager_sysfs_attrs[] = {
@@ -310,6 +418,8 @@ static struct attribute *manager_sysfs_attrs[] = {
&manager_attr_trans_key_value.attr,
&manager_attr_trans_key_enabled.attr,
&manager_attr_alpha_blending_enabled.attr,
+ &manager_attr_cpr_enable.attr,
+ &manager_attr_cpr_coef.attr,
NULL
};
@@ -858,6 +968,10 @@ static void configure_manager(enum omap_channel channel)
dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
dispc_enable_trans_key(channel, mi->trans_enabled);
dispc_enable_alpha_blending(channel, mi->alpha_enabled);
+ if (dss_has_feature(FEAT_CPR)) {
+ dispc_enable_cpr(channel, mi->cpr_enable);
+ dispc_set_cpr_coef(channel, &mi->cpr_coefs);
+ }
}
/* configure_dispc() tries to write values from cache to shadow registers.
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index e02823e..3b55ef2 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -290,6 +290,12 @@ extern const struct omap_video_timings omap_dss_pal_timings;
extern const struct omap_video_timings omap_dss_ntsc_timings;
#endif
+struct omap_dss_cpr_coefs {
+ s16 rr, rg, rb;
+ s16 gr, gg, gb;
+ s16 br, bg, bb;
+};
+
struct omap_overlay_info {
bool enabled;
@@ -349,6 +355,9 @@ struct omap_overlay_manager_info {
bool trans_enabled;
bool alpha_enabled;
+
+ bool cpr_enable;
+ struct omap_dss_cpr_coefs cpr_coefs;
};
struct omap_overlay_manager {
--
1.7.4.1
^ permalink raw reply related
* [PATCH 1/4] OMAP: DSS: Minor cleanup in ovl and mgr cache structs
From: Tomi Valkeinen @ 2011-06-22 8:45 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Nishant Kamat, Tomi Valkeinen
In-Reply-To: <1308732326-17278-1-git-send-email-tomi.valkeinen@ti.com>
From: Nishant Kamat <nskamat@ti.com>
The overlay_cache_data and manager_cache_data structs include
the elements of omap_overlay_info and omap_overlay_manager_info
structs respectively. Include the structs instead of the individual
elements to reduce code.
Signed-off-by: Nishant Kamat <nskamat@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/manager.c | 158 ++++++++++++++----------------------
1 files changed, 62 insertions(+), 96 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index c6d26c6..4691b81 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -391,23 +391,7 @@ struct overlay_cache_data {
bool enabled;
- u32 paddr;
- void __iomem *vaddr;
- u32 p_uv_addr; /* relevant for NV12 format only */
- u16 screen_width;
- u16 width;
- u16 height;
- enum omap_color_mode color_mode;
- u8 rotation;
- enum omap_dss_rotation_type rotation_type;
- bool mirror;
-
- u16 pos_x;
- u16 pos_y;
- u16 out_width; /* if 0, out_width = width */
- u16 out_height; /* if 0, out_height = height */
- u8 global_alpha;
- u8 pre_mult_alpha;
+ struct omap_overlay_info info;
enum omap_channel channel;
bool replication;
@@ -427,13 +411,7 @@ struct manager_cache_data {
* VSYNC/EVSYNC */
bool shadow_dirty;
- u32 default_color;
-
- enum omap_dss_trans_key_type trans_key_type;
- u32 trans_key;
- bool trans_enabled;
-
- bool alpha_enabled;
+ struct omap_overlay_manager_info info;
bool manual_update;
bool do_manual_update;
@@ -699,10 +677,12 @@ static bool rectangle_intersects(int x1, int y1, int w1, int h1,
static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
{
- if (oc->out_width != 0 && oc->width != oc->out_width)
+ struct omap_overlay_info *oi = &oc->info;
+
+ if (oi->out_width != 0 && oi->width != oi->out_width)
return true;
- if (oc->out_height != 0 && oc->height != oc->out_height)
+ if (oi->out_height != 0 && oi->height != oi->out_height)
return true;
return false;
@@ -712,6 +692,8 @@ static int configure_overlay(enum omap_plane plane)
{
struct overlay_cache_data *c;
struct manager_cache_data *mc;
+ struct omap_overlay_info *oi;
+ struct omap_overlay_manager_info *mi;
u16 outw, outh;
u16 x, y, w, h;
u32 paddr;
@@ -721,6 +703,7 @@ static int configure_overlay(enum omap_plane plane)
DSSDBGF("%d", plane);
c = &dss_cache.overlay_cache[plane];
+ oi = &c->info;
if (!c->enabled) {
dispc_enable_plane(plane, 0);
@@ -728,14 +711,15 @@ static int configure_overlay(enum omap_plane plane)
}
mc = &dss_cache.manager_cache[c->channel];
+ mi = &mc->info;
- x = c->pos_x;
- y = c->pos_y;
- w = c->width;
- h = c->height;
- outw = c->out_width = 0 ? c->width : c->out_width;
- outh = c->out_height = 0 ? c->height : c->out_height;
- paddr = c->paddr;
+ x = oi->pos_x;
+ y = oi->pos_y;
+ w = oi->width;
+ h = oi->height;
+ outw = oi->out_width = 0 ? oi->width : oi->out_width;
+ outh = oi->out_height = 0 ? oi->height : oi->out_height;
+ paddr = oi->paddr;
orig_w = w;
orig_h = h;
@@ -754,7 +738,7 @@ static int configure_overlay(enum omap_plane plane)
return 0;
}
- switch (c->color_mode) {
+ switch (oi->color_mode) {
case OMAP_DSS_COLOR_NV12:
bpp = 8;
break;
@@ -784,23 +768,23 @@ static int configure_overlay(enum omap_plane plane)
BUG();
}
- if (mc->x > c->pos_x) {
+ if (mc->x > oi->pos_x) {
x = 0;
- outw -= (mc->x - c->pos_x);
- paddr += (mc->x - c->pos_x) *
+ outw -= (mc->x - oi->pos_x);
+ paddr += (mc->x - oi->pos_x) *
scale_x_m / scale_x_d * bpp / 8;
} else {
- x = c->pos_x - mc->x;
+ x = oi->pos_x - mc->x;
}
- if (mc->y > c->pos_y) {
+ if (mc->y > oi->pos_y) {
y = 0;
- outh -= (mc->y - c->pos_y);
- paddr += (mc->y - c->pos_y) *
+ outh -= (mc->y - oi->pos_y);
+ paddr += (mc->y - oi->pos_y) *
scale_y_m / scale_y_d *
- c->screen_width * bpp / 8;
+ oi->screen_width * bpp / 8;
} else {
- y = c->pos_y - mc->y;
+ y = oi->pos_y - mc->y;
}
if (mc->w < (x + outw))
@@ -819,8 +803,8 @@ static int configure_overlay(enum omap_plane plane)
* the width if the original width was bigger.
*/
if ((w & 1) &&
- (c->color_mode = OMAP_DSS_COLOR_YUV2 ||
- c->color_mode = OMAP_DSS_COLOR_UYVY)) {
+ (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
+ oi->color_mode = OMAP_DSS_COLOR_UYVY)) {
if (orig_w > w)
w += 1;
else
@@ -830,19 +814,19 @@ static int configure_overlay(enum omap_plane plane)
r = dispc_setup_plane(plane,
paddr,
- c->screen_width,
+ oi->screen_width,
x, y,
w, h,
outw, outh,
- c->color_mode,
+ oi->color_mode,
c->ilace,
- c->rotation_type,
- c->rotation,
- c->mirror,
- c->global_alpha,
- c->pre_mult_alpha,
+ oi->rotation_type,
+ oi->rotation,
+ oi->mirror,
+ oi->global_alpha,
+ oi->pre_mult_alpha,
c->channel,
- c->p_uv_addr);
+ oi->p_uv_addr);
if (r) {
/* this shouldn't happen */
@@ -863,16 +847,17 @@ static int configure_overlay(enum omap_plane plane)
static void configure_manager(enum omap_channel channel)
{
- struct manager_cache_data *c;
+ struct omap_overlay_manager_info *mi;
DSSDBGF("%d", channel);
- c = &dss_cache.manager_cache[channel];
+ /* picking info from the cache */
+ mi = &dss_cache.manager_cache[channel].info;
- dispc_set_default_color(channel, c->default_color);
- dispc_set_trans_key(channel, c->trans_key_type, c->trans_key);
- dispc_enable_trans_key(channel, c->trans_enabled);
- dispc_enable_alpha_blending(channel, c->alpha_enabled);
+ dispc_set_default_color(channel, mi->default_color);
+ dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
+ dispc_enable_trans_key(channel, mi->trans_enabled);
+ dispc_enable_alpha_blending(channel, mi->alpha_enabled);
}
/* configure_dispc() tries to write values from cache to shadow registers.
@@ -990,6 +975,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
{
struct overlay_cache_data *oc;
struct manager_cache_data *mc;
+ struct omap_overlay_info *oi;
const int num_ovls = dss_feat_get_num_ovls();
struct omap_overlay_manager *mgr;
int i;
@@ -1032,6 +1018,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
unsigned outw, outh;
oc = &dss_cache.overlay_cache[i];
+ oi = &oc->info;
if (oc->channel != mgr->id)
continue;
@@ -1047,39 +1034,39 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
if (!dispc_is_overlay_scaled(oc))
continue;
- outw = oc->out_width = 0 ?
- oc->width : oc->out_width;
- outh = oc->out_height = 0 ?
- oc->height : oc->out_height;
+ outw = oi->out_width = 0 ?
+ oi->width : oi->out_width;
+ outh = oi->out_height = 0 ?
+ oi->height : oi->out_height;
/* is the overlay outside the update region? */
if (!rectangle_intersects(x, y, w, h,
- oc->pos_x, oc->pos_y,
+ oi->pos_x, oi->pos_y,
outw, outh))
continue;
/* if the overlay totally inside the update region? */
- if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh,
+ if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh,
x, y, w, h))
continue;
- if (x > oc->pos_x)
- x1 = oc->pos_x;
+ if (x > oi->pos_x)
+ x1 = oi->pos_x;
else
x1 = x;
- if (y > oc->pos_y)
- y1 = oc->pos_y;
+ if (y > oi->pos_y)
+ y1 = oi->pos_y;
else
y1 = y;
- if ((x + w) < (oc->pos_x + outw))
- x2 = oc->pos_x + outw;
+ if ((x + w) < (oi->pos_x + outw))
+ x2 = oi->pos_x + outw;
else
x2 = x + w;
- if ((y + h) < (oc->pos_y + outh))
- y2 = oc->pos_y + outh;
+ if ((y + h) < (oi->pos_y + outh))
+ y2 = oi->pos_y + outh;
else
y2 = y + h;
@@ -1258,23 +1245,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
ovl->info_dirty = false;
oc->dirty = true;
-
- oc->paddr = ovl->info.paddr;
- oc->vaddr = ovl->info.vaddr;
- oc->p_uv_addr = ovl->info.p_uv_addr;
- oc->screen_width = ovl->info.screen_width;
- oc->width = ovl->info.width;
- oc->height = ovl->info.height;
- oc->color_mode = ovl->info.color_mode;
- oc->rotation = ovl->info.rotation;
- oc->rotation_type = ovl->info.rotation_type;
- oc->mirror = ovl->info.mirror;
- oc->pos_x = ovl->info.pos_x;
- oc->pos_y = ovl->info.pos_y;
- oc->out_width = ovl->info.out_width;
- oc->out_height = ovl->info.out_height;
- oc->global_alpha = ovl->info.global_alpha;
- oc->pre_mult_alpha = ovl->info.pre_mult_alpha;
+ oc->info = ovl->info;
oc->replication dss_use_replication(dssdev, ovl->info.color_mode);
@@ -1312,12 +1283,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
mgr->info_dirty = false;
mc->dirty = true;
-
- mc->default_color = mgr->info.default_color;
- mc->trans_key_type = mgr->info.trans_key_type;
- mc->trans_key = mgr->info.trans_key;
- mc->trans_enabled = mgr->info.trans_enabled;
- mc->alpha_enabled = mgr->info.alpha_enabled;
+ mc->info = mgr->info;
mc->manual_update dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 0/4] OMAP: DSS2: misc patches
From: Tomi Valkeinen @ 2011-06-22 8:45 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
Here are few miscellaneous patches for DSS. A pure cleanup patch from Nishant,
patch adding Color Phase Rotation support, and two minor fixes.
Tomi
Nishant Kamat (1):
OMAP: DSS: Minor cleanup in ovl and mgr cache structs
Tomi Valkeinen (3):
OMAP: DSS2: Add Color Phase Rotation support
OMAP: DSS2: DSI: sync when disabling a display
OMAP: DSS2: Fix FIFO threshold and burst size for OMAP4
drivers/video/omap2/displays/panel-taal.c | 5 +-
drivers/video/omap2/dss/dispc.c | 84 ++++++++-
drivers/video/omap2/dss/display.c | 12 +-
drivers/video/omap2/dss/dsi.c | 16 +-
drivers/video/omap2/dss/dss.h | 18 +-
drivers/video/omap2/dss/dss_features.c | 23 +++
drivers/video/omap2/dss/dss_features.h | 3 +
drivers/video/omap2/dss/manager.c | 284 ++++++++++++++++++----------
include/video/omapdss.h | 9 +
9 files changed, 314 insertions(+), 140 deletions(-)
--
1.7.4.1
^ permalink raw reply
* Re: Some questions about DRM(Direct Rendering Manager)
From: InKi Dae @ 2011-06-22 7:50 UTC (permalink / raw)
To: daeinki, dri-devel
Cc: linux-fbdev, Kukjin Kim, Kyungmin Park, airlied, Paul Mundt,
jesse.barnes, linux-arm-kernel
In-Reply-To: <4E0185E7.8020708@samsung.com>
It adds dri-devel@lists.freedesktop.org to this mail thread.
Thank you.
2011년 6월 22일 오후 3:04, daeinki <inki.dae@samsung.com>님의 말:
> below is additional comments.
>
> daeinki 쓴 글:
>> Hi all,
>>
>> I'm writing Samsung SoC based DRM framework and this one includes FIMD
>> and HDMI driver as hardware dependent modules. and for now, encoder,
>> connector, crtc and fb module has been materialized almost. but I'm
>> contending with framebuffer setting issue(created fb_info should be
>> registered to linux framebuffer through register_framebuffer() or not)as
>> default framebuffer at booting time.
>>
>> at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
>> fb_probe callback is called and this one creates new framebuffer and
>> returns a value more then 0 if true. internally, this process creates an
>> fb_info object and drm_framebuffer and then drm_framebuffer would be
>> added to mode_config.fb_list of the drm_device.
>>
> it's my mistake. return value is 0 if true, nonzero otherwise.
>
>> a value returned, new_fb is used to decide that it calls
>> register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
>> confused it's a good way to call register_framebuffer() otherwise
>> drm_fb_helper_set_par(). if register_framebuffer() is called then I
>> guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
>> called somewhere subsequently to apply this one to real hardware because
>> previous process is just for maintaining data logically.(not set up data
>> to h/w)
>>
>> it's a right way to call register_framebuffer() and then
>> drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
>> only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
>> register_framebuffer()? and what is the purpose of using
>> register_framebuffer()?
>>
> I understood that if fb_probe() callback is fail then fb_info object is
> registered to linux framebuffer through register_framebuffer()
> otherwise(if true) hardware configuration would be completed by
> drm_fb_helper_set_par() so the reason of using register_framebuffer() is
> that the case of failing fb_probe() callback, it is for drawing on only
> linux framebuffer. is it right?
>
>> In my case, first, register_framebuffer() is called and then if desired
>> default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
>> it gets mode_set of drm_fb_helper->crtc_info[n] and then it calls
>> drm_crtc_helper_set_config(mode_set). at this time, all the hardware
>> configurations would be completed.
>>
>> thank you in advance.
>>
>> Best Regards
>> Inki Dae.
>>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 5/5] fbdev: sh_mobile_meram: Assign meram to the SH7372_A4LC power domain
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
Register the MERAM device as a part of the A4LC power domain for
power management.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
arch/arm/mach-shmobile/board-mackerel.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index f556b2a..53f2b93 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1585,6 +1585,7 @@ static void __init mackerel_init(void)
sh7372_init_pm_domain(&sh7372_a4lc_domain);
sh7372_add_device_to_domain(SH7372_A4LC, &lcdc_device);
sh7372_add_device_to_domain(SH7372_A4LC, &hdmi_lcdc_device);
+ sh7372_add_device_to_domain(SH7372_A4LC, &meram_device);
hdmi_init_pm_clock();
sh7372_pm_init();
--
1.7.1
^ permalink raw reply related
* [PATCH 4/5 v3] fbdev: sh_mobile_meram: Backup/restore device registers on shutdown/resume
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
Save and reconfigure the MERAM registers when the MERAM is powered down
and restored
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* The private data structure definition was moved from sh_mobile_meram.h to
sh_mobile_meram.c. This has been moved into a separate patch
drivers/video/sh_mobile_meram.c | 71 +++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index cc71cbf..7afd77a 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -37,12 +37,31 @@
#define MEQSEL1 0x40
#define MEQSEL2 0x44
+static unsigned long common_regs[] = {
+ MEVCR1,
+ MEQSEL1,
+ MEQSEL2,
+};
+#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)
+
+static unsigned long icb_regs[] = {
+ MExxCTL,
+ MExxBSIZE,
+ MExxMNCF,
+ MExxSARA,
+ MExxSARB,
+ MExxSBSIZE,
+};
+#define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)
+
struct sh_mobile_meram_priv {
void __iomem *base;
struct mutex lock;
unsigned long used_icb;
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];
};
/* settings */
@@ -489,6 +508,57 @@ int sh_mobile_meram_pm_put_sync(struct sh_mobile_meram_info *pdata)
return 0;
}
+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;
+
+ for (k = 0; k < CMN_REGS_SIZE; k++)
+ priv->cmn_saved_regs[k] = meram_read_reg(priv->base,
+ common_regs[k]);
+
+ for (j = 0; j < 32; j++) {
+ if (!test_bit(j, &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]);
+ /* Reset ICB on resume */
+ if (icb_regs[k] = MExxCTL)
+ priv->icb_saved_regs[j * ICB_REGS_SIZE + k] + 0x70;
+ }
+ }
+ return 0;
+}
+
+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;
+
+ for (j = 0; j < 32; j++) {
+ if (!test_bit(j, &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 (k = 0; k < CMN_REGS_SIZE; k++)
+ meram_write_reg(priv->base, common_regs[k],
+ priv->cmn_saved_regs[k]);
+ return 0;
+}
+
+static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
+ .runtime_suspend = sh_mobile_meram_runtime_suspend,
+ .runtime_resume = sh_mobile_meram_runtime_resume,
+};
+
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
.module = THIS_MODULE,
.meram_register = sh_mobile_meram_register,
@@ -579,6 +649,7 @@ static struct platform_driver sh_mobile_meram_driver = {
.driver = {
.name = "sh_mobile_meram",
.owner = THIS_MODULE,
+ .pm = &sh_mobile_meram_dev_pm_ops,
},
.probe = sh_mobile_meram_probe,
.remove = sh_mobile_meram_remove,
--
1.7.1
^ permalink raw reply related
* [PATCH 3/5] fbdev: sh_mobile_meram: Move private data from .h to .c
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
There is no reason for sh_mobile_meram_priv to be in the .h file
since it should be private to sh_mobile_meram.c
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
drivers/video/sh_mobile_meram.c | 8 ++++++++
drivers/video/sh_mobile_meram.h | 8 --------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 371f129..cc71cbf 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -37,6 +37,14 @@
#define MEQSEL1 0x40
#define MEQSEL2 0x44
+struct sh_mobile_meram_priv {
+ void __iomem *base;
+ struct mutex lock;
+ unsigned long used_icb;
+ int used_meram_cache_regions;
+ unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
+};
+
/* settings */
#define MERAM_SEC_LINE 15
#define MERAM_LINE_WIDTH 2048
diff --git a/drivers/video/sh_mobile_meram.h b/drivers/video/sh_mobile_meram.h
index 82c54fb..1615204 100644
--- a/drivers/video/sh_mobile_meram.h
+++ b/drivers/video/sh_mobile_meram.h
@@ -17,14 +17,6 @@
#define SH_MOBILE_MERAM_CACHE_OFFSET(p) ((p) >> 16)
#define SH_MOBILE_MERAM_CACHE_SIZE(p) ((p) & 0xffff)
-struct sh_mobile_meram_priv {
- void __iomem *base;
- struct mutex lock;
- unsigned long used_icb;
- int used_meram_cache_regions;
- unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
-};
-
int sh_mobile_meram_alloc_icb(const struct sh_mobile_meram_cfg *cfg,
int xres,
int yres,
--
1.7.1
^ permalink raw reply related
* [PATCH 2/5 v3] fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
The MERAM reference counts should be tied to the two LCDC devices (LCD/HDMI)
so that when they are enable/disabled, the MERAM is as well.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
to better reflect their actual functionality
drivers/video/sh_mobile_lcdcfb.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 019dbd3..78cc828 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -259,6 +259,11 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
pm_runtime_get_sync(priv->dev);
if (priv->dot_clk)
clk_enable(priv->dot_clk);
+ if (priv->meram_dev && priv->meram_dev->ops) {
+ struct sh_mobile_meram_info *mdev;
+ mdev = priv->meram_dev;
+ mdev->ops->meram_pm_get_sync(mdev);
+ }
}
}
@@ -267,6 +272,11 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
if (priv->dot_clk)
clk_disable(priv->dot_clk);
+ if (priv->meram_dev && priv->meram_dev->ops) {
+ struct sh_mobile_meram_info *mdev;
+ mdev = priv->meram_dev;
+ mdev->ops->meram_pm_put_sync(mdev);
+ }
pm_runtime_put(priv->dev);
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH 1/5 v3] fbdev: sh_mobile_meram: Add enable/disble hooks for LCDC
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
Add hooks to allow the LCDC to increase/decrease the MERAM PM reference
counts
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
to better reflect their actual functionality
* Make these callback functions static
drivers/video/sh_mobile_meram.c | 27 +++++++++++++++++++++++++++
include/video/sh_mobile_meram.h | 6 ++++++
2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 9170c82..371f129 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
@@ -460,11 +461,33 @@ static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
return 0;
}
+static int sh_mobile_meram_pm_get_sync(struct sh_mobile_meram_info *pdata)
+{
+ if (!pdata || !pdata->pdev)
+ return -EINVAL;
+
+ dev_dbg(&pdata->pdev->dev, "Enabling sh_mobile_meram clock.");
+ pm_runtime_get_sync(&pdata->pdev->dev);
+ return 0;
+}
+
+static int sh_mobile_meram_pm_put_sync(struct sh_mobile_meram_info *pdata)
+{
+ if (!pdata || !pdata->pdev)
+ return -EINVAL;
+
+ dev_dbg(&pdata->pdev->dev, "Disabling sh_mobile_meram clock.");
+ pm_runtime_put_sync(&pdata->pdev->dev);
+ return 0;
+}
+
static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
.module = THIS_MODULE,
.meram_register = sh_mobile_meram_register,
.meram_unregister = sh_mobile_meram_unregister,
.meram_update = sh_mobile_meram_update,
+ .meram_pm_put_sync = sh_mobile_meram_pm_put_sync,
+ .meram_pm_get_sync = sh_mobile_meram_pm_get_sync,
};
/*
@@ -515,6 +538,8 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
if (pdata->addr_mode = SH_MOBILE_MERAM_MODE1)
meram_write_reg(priv->base, MEVCR1, 1 << 29);
+ pm_runtime_enable(&pdev->dev);
+
dev_info(&pdev->dev, "sh_mobile_meram initialized.");
return 0;
@@ -530,6 +555,8 @@ static int sh_mobile_meram_remove(struct platform_device *pdev)
{
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+ pm_runtime_disable(&pdev->dev);
+
if (priv->base)
iounmap(priv->base);
diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
index af602d6..f213b6d 100644
--- a/include/video/sh_mobile_meram.h
+++ b/include/video/sh_mobile_meram.h
@@ -63,6 +63,12 @@ struct sh_mobile_meram_ops {
unsigned long base_addr_c,
unsigned long *icb_addr_y,
unsigned long *icb_addr_c);
+
+ /* enable meram clock */
+ int (*meram_pm_get_sync)(struct sh_mobile_meram_info *meram_dev);
+
+ /* disable meram clock */
+ int (*meram_pm_put_sync)(struct sh_mobile_meram_info *meram_dev);
};
#endif /* __VIDEO_SH_MOBILE_MERAM_H__ */
--
1.7.1
^ permalink raw reply related
* [PATCH 0/5 v3] LCDC MERAM runtime PM support
From: Damian Hobson-Garcia @ 2011-06-22 7:49 UTC (permalink / raw)
To: linux-fbdev
This patch series is a provides PM runtime support for the LCDC MERAM.
The runtime_pm_get/put calls are made at the same time as the LCDC calls, so
that the LCDC MERAM is enabled with the first LCDC device and disabled
with the last LCDC device.
The first 4 patches will apply to rmobile-latest or common/fbdev-meram as-is,
but the final patch needs to have the "PM / Domains: Support for generic I/O PM
domains" patch series.
Changes from V2
* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
to better reflect their actual functionality
* Make these callback functions static
* The private data structure definition was moved from sh_mobile_meram.h to
sh_mobile_meram.c. This has been moved into a separate patch
* Use the sh7372_add_device_to_domain() function to register the MERAM in
the SH7372_A4LC domain.
Damian Hobson-Garcia (5):
fbdev: sh_mobile_meram: Add enable/disble hooks for LCDC
fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC
fbdev: sh_mobile_meram: Move private data from .h to .c
fbdev: sh_mobile_meram: Backup/restore device registers on
shutdown/resume
fbdev: sh_mobile_meram: Assign meram to the SH7372_A4LC power domain
arch/arm/mach-shmobile/board-mackerel.c | 1 +
drivers/video/sh_mobile_lcdcfb.c | 10 +++
drivers/video/sh_mobile_meram.c | 106 +++++++++++++++++++++++++++++++
drivers/video/sh_mobile_meram.h | 8 ---
include/video/sh_mobile_meram.h | 6 ++
5 files changed, 123 insertions(+), 8 deletions(-)
^ permalink raw reply
* [PATCH] fbdev: sh_mobile_meram: Correct pointer check for YCbCr chroma plane
From: Damian Hobson-Garcia @ 2011-06-22 7:46 UTC (permalink / raw)
To: linux-fbdev
The check was intended to test if we have a valid pointer to write into,
but it mistakenly checks the pointer contents instead.
Since a valid pointer is mandatory for the chroma data if a YCbCr format
is used, the pointer check has been removed.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Sorry, forgot to sign off the previous version. Resend
drivers/video/sh_mobile_meram.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 216f7f7..a6f28b9 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -246,7 +246,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
icb_offset = 0xc0000000 | (cfg->current_reg << 23);
*icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
- if ((*icb_addr_c) && is_nvcolor(cfg->pixelformat))
+ if (is_nvcolor(cfg->pixelformat))
*icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
}
--
1.7.1
^ permalink raw reply related
* [PATCH V5 0/5] ARM: EXYNOS4: Add support EXYNOS4 FIMD
From: JinGoo Han @ 2011-06-22 6:45 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
"linux-fbdev@vger.kernel.org" <linux-f>
Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
JinGoo Han
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 1319 bytes --]
This patch series is based on the latest
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
This was originally submitted by Jonghun Han <jonghun.han@samsung.com>
http://www.spinics.net/lists/arm-kernel/msg101781.html
This patch adds support FIMD(Fully Interactive Mobile Display) on Exynos4.
The 4th patch is update for s3c-fb and others are for platform data.
v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
use 'has_clksel' variable in order to distinguish FIMD version
add 'lcd_clk' that can be used for only lcd pixel clock
add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement
v5: add clk_enable/disable(sfb->lcd_clk) to s3c_fb_runtime_suspend/resume().
o To Kukjin Kim
[PATCH V5 1/5] ARM: EXYNOS4: Change clock name for FIMD
[PATCH V5 2/5] ARM: EXYNOS4: Add FIMD resource definition
[PATCH V5 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
[PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd
o To Paul Mundt
[PATCH V5 4/5] video: s3c-fb: Add support EXYNOS4 FIMDÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±ýöÝzÿâØ^nr¡ö¦zË\x1aëh¨èÚ&£ûàz¿äz¹Þú+Ê+zf£¢·h§~Ûiÿÿïêÿêçz_è®\x0fæj:+v¨þ)ߣøm
^ permalink raw reply
* [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd
From: Jingoo Han @ 2011-06-22 6:41 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jonghun Han, Jingoo Han
From: Jonghun Han <jonghun.han@samsung.com>
This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/mach-smdkc210.c | 114 +++++++++++++++++++++++++++++++++
arch/arm/mach-exynos4/mach-smdkv310.c | 114 +++++++++++++++++++++++++++++++++
2 files changed, 228 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..360a50a 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,26 +9,33 @@
*/
#include <linux/serial_core.h>
+#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/lcd.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
#include <linux/i2c.h>
+#include <linux/clk.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
#include <plat/exynos4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/fb.h>
#include <plat/sdhci.h>
#include <plat/iic.h>
#include <plat/pd.h>
#include <mach/map.h>
+#include <mach/regs-fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -111,6 +118,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+ .win[0] = &smdkc210_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+
static struct resource smdkc210_smsc911x_resources[] = {
[0] = {
.start = EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +235,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
&exynos4_device_pd[PD_GPS],
&exynos4_device_sysmmu,
&samsung_asoc_dma,
+ &s5p_device_fimd0,
+ &smdkc210_lcd_lte480wv,
&smdkc210_smsc911x,
};
@@ -191,6 +263,44 @@ static void __init smdkc210_smsc911x_init(void)
(0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
}
+static int __init smdkc210_fimd0_setup_clock(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_mpll = NULL;
+
+ u32 rate = 0;
+
+ sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+ if (IS_ERR(sclk)) {
+ printk(KERN_ERR "failed to get sclk for fimd\n");
+ goto err_clk2;
+ }
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk1;
+ }
+
+ clk_set_parent(sclk, mout_mpll);
+ if (!rate)
+ rate = 134000000;
+
+ clk_set_rate(sclk, rate);
+
+ clk_put(sclk);
+ clk_put(mout_mpll);
+
+ return 0;
+
+err_clk1:
+ clk_put(mout_mpll);
+err_clk2:
+ clk_put(sclk);
+
+ return -EINVAL;
+}
+
static void __init smdkc210_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -210,7 +320,11 @@ static void __init smdkc210_machine_init(void)
s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
+ s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+ smdkc210_fimd0_setup_clock();
}
MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..7bc12b5 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,28 +9,35 @@
*/
#include <linux/serial_core.h>
+#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/lcd.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/input.h>
+#include <linux/clk.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
#include <plat/exynos4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/fb.h>
#include <plat/keypad.h>
#include <plat/sdhci.h>
#include <plat/iic.h>
#include <plat/pd.h>
#include <mach/map.h>
+#include <mach/regs-fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -113,6 +120,69 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+ .win[0] = &smdkv310_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+
static struct resource smdkv310_smsc911x_resources[] = {
[0] = {
.start = EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +257,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
&exynos4_device_pd[PD_GPS],
&exynos4_device_sysmmu,
&samsung_asoc_dma,
+ &s5p_device_fimd0,
+ &smdkv310_lcd_lte480wv,
&smdkv310_smsc911x,
};
@@ -213,6 +285,44 @@ static void __init smdkv310_smsc911x_init(void)
(0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
}
+static int __init smdkv310_fimd0_setup_clock(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_mpll = NULL;
+
+ u32 rate = 0;
+
+ sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+ if (IS_ERR(sclk)) {
+ printk(KERN_ERR "failed to get sclk for fimd\n");
+ goto err_clk2;
+ }
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk1;
+ }
+
+ clk_set_parent(sclk, mout_mpll);
+ if (!rate)
+ rate = 134000000;
+
+ clk_set_rate(sclk, rate);
+
+ clk_put(sclk);
+ clk_put(mout_mpll);
+
+ return 0;
+
+err_clk1:
+ clk_put(mout_mpll);
+err_clk2:
+ clk_put(sclk);
+
+ return -EINVAL;
+}
+
static void __init smdkv310_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -232,9 +342,13 @@ static void __init smdkv310_machine_init(void)
s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+ s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
samsung_keypad_set_platdata(&smdkv310_keypad_data);
platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+ smdkv310_fimd0_setup_clock();
}
MACHINE_START(SMDKV310, "SMDKV310")
--
1.7.1
^ permalink raw reply related
* [PATCH V5 4/5] video: s3c-fb: Add support EXYNOS4 FIMD
From: Jingoo Han @ 2011-06-22 6:41 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
Jonghun Han
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jingoo Han
This patch adds struct s3c_fb_driverdata s3c_fb_data_exynos4 for EXYNOS4
and adds lcd clock gating support.
FIMD driver needs two clocks for FIMD IP and LCD pixel clock. Previously,
both clocks are provided by using bus clock such as HCLK. However, EXYNOS4
can not select HCLK for LCD pixel clock because the EXYNOS4 FIMD IP does not
have the CLKSEL bit of VIDCON0. So, FIMD driver should provide the lcd clock
using SCLK_FIMD as LCD pixel clock for EXYNOS4.
The driver selects enabling lcd clock according to has_clksel which means
the CLKSEL bit of VIDCON0. If there is has_clksel, the driver will not
enable the lcd clock using SCLK_FIMD because bus clock using HCLK is used
a LCD pixel clock.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/Kconfig | 2 +-
drivers/video/s3c-fb.c | 88 +++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..963b8b7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2027,7 +2027,7 @@ config FB_TMIO_ACCELL
config FB_S3C
tristate "Samsung S3C framebuffer support"
- depends on FB && S3C_DEV_FB
+ depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 4aecf21..cb0d3ea 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -81,6 +81,7 @@ struct s3c_fb;
* @palette: Address of palette memory, or 0 if none.
* @has_prtcon: Set if has PRTCON register.
* @has_shadowcon: Set if has SHADOWCON register.
+ * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
*/
struct s3c_fb_variant {
unsigned int is_2443:1;
@@ -98,6 +99,7 @@ struct s3c_fb_variant {
unsigned int has_prtcon:1;
unsigned int has_shadowcon:1;
+ unsigned int has_clksel:1;
};
/**
@@ -186,6 +188,7 @@ struct s3c_fb_vsync {
* @dev: The device that we bound to, for printing, etc.
* @regs_res: The resource we claimed for the IO registers.
* @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @lcd_clk: The clk (sclk) feeding pixclk.
* @regs: The mapped hardware registers.
* @variant: Variant information for this hardware.
* @enabled: A bitmask of enabled hardware windows.
@@ -200,6 +203,7 @@ struct s3c_fb {
struct device *dev;
struct resource *regs_res;
struct clk *bus_clk;
+ struct clk *lcd_clk;
void __iomem *regs;
struct s3c_fb_variant variant;
@@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
*/
static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
{
- unsigned long clk = clk_get_rate(sfb->bus_clk);
+ unsigned long clk;
unsigned long long tmp;
unsigned int result;
+ if (sfb->variant.has_clksel)
+ clk = clk_get_rate(sfb->bus_clk);
+ else
+ clk = clk_get_rate(sfb->lcd_clk);
+
tmp = (unsigned long long)clk;
tmp *= pixclk;
@@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel) {
+ sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+ if (IS_ERR(sfb->lcd_clk)) {
+ dev_err(dev, "failed to get lcd clock\n");
+ ret = PTR_ERR(sfb->lcd_clk);
+ goto err_bus_clk;
+ }
+
+ clk_enable(sfb->lcd_clk);
+ }
+
pm_runtime_enable(sfb->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "failed to find registers\n");
ret = -ENOENT;
- goto err_clk;
+ goto err_lcd_clk;
}
sfb->regs_res = request_mem_region(res->start, resource_size(res),
@@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
if (!sfb->regs_res) {
dev_err(dev, "failed to claim register region\n");
ret = -ENOENT;
- goto err_clk;
+ goto err_lcd_clk;
}
sfb->regs = ioremap(res->start, resource_size(res));
@@ -1450,7 +1470,13 @@ err_ioremap:
err_req_region:
release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-err_clk:
+err_lcd_clk:
+ if (!sfb->variant.has_clksel) {
+ clk_disable(sfb->lcd_clk);
+ clk_put(sfb->lcd_clk);
+ }
+
+err_bus_clk:
clk_disable(sfb->bus_clk);
clk_put(sfb->bus_clk);
@@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
iounmap(sfb->regs);
+ if (!sfb->variant.has_clksel) {
+ clk_disable(sfb->lcd_clk);
+ clk_put(sfb->lcd_clk);
+ }
+
clk_disable(sfb->bus_clk);
clk_put(sfb->bus_clk);
@@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
}
+ if (!sfb->variant.has_clksel)
+ clk_disable(sfb->lcd_clk);
+
clk_disable(sfb->bus_clk);
return 0;
}
@@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel)
+ clk_enable(sfb->lcd_clk);
+
/* setup gpio and output polarity controls */
pd->setup_gpio();
writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1569,6 +1606,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
}
+ if (!sfb->variant.has_clksel)
+ clk_disable(sfb->lcd_clk);
+
clk_disable(sfb->bus_clk);
return 0;
}
@@ -1583,6 +1623,9 @@ static int s3c_fb_runtime_resume(struct device *dev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel)
+ clk_enable(sfb->lcd_clk);
+
/* setup gpio and output polarity controls */
pd->setup_gpio();
writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1755,6 +1798,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
},
.has_prtcon = 1,
+ .has_clksel = 1,
},
.win[0] = &s3c_fb_data_64xx_wins[0],
.win[1] = &s3c_fb_data_64xx_wins[1],
@@ -1785,6 +1829,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
},
.has_prtcon = 1,
+ .has_clksel = 1,
},
.win[0] = &s3c_fb_data_s5p_wins[0],
.win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1815,6 +1860,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
},
.has_shadowcon = 1,
+ .has_clksel = 1,
+ },
+ .win[0] = &s3c_fb_data_s5p_wins[0],
+ .win[1] = &s3c_fb_data_s5p_wins[1],
+ .win[2] = &s3c_fb_data_s5p_wins[2],
+ .win[3] = &s3c_fb_data_s5p_wins[3],
+ .win[4] = &s3c_fb_data_s5p_wins[4],
+};
+
+static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
+ .variant = {
+ .nr_windows = 5,
+ .vidtcon = VIDTCON0,
+ .wincon = WINCON(0),
+ .winmap = WINxMAP(0),
+ .keycon = WKEYCON,
+ .osd = VIDOSD_BASE,
+ .osd_stride = 16,
+ .buf_start = VIDW_BUF_START(0),
+ .buf_size = VIDW_BUF_SIZE(0),
+ .buf_end = VIDW_BUF_END(0),
+
+ .palette = {
+ [0] = 0x2400,
+ [1] = 0x2800,
+ [2] = 0x2c00,
+ [3] = 0x3000,
+ [4] = 0x3400,
+ },
+
+ .has_shadowcon = 1,
},
.win[0] = &s3c_fb_data_s5p_wins[0],
.win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1843,6 +1919,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
[0] = 0x400,
[1] = 0x800,
},
+ .has_clksel = 1,
},
.win[0] = &(struct s3c_fb_win_variant) {
.palette_sz = 256,
@@ -1870,6 +1947,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
.name = "s5pv210-fb",
.driver_data = (unsigned long)&s3c_fb_data_s5pv210,
}, {
+ .name = "exynos4-fb",
+ .driver_data = (unsigned long)&s3c_fb_data_exynos4,
+ }, {
.name = "s3c2443-fb",
.driver_data = (unsigned long)&s3c_fb_data_s3c2443,
},
--
1.7.1
^ permalink raw reply related
* [PATCH V5 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
From: Jingoo Han @ 2011-06-22 6:41 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jonghun Han, Jingoo Han
From: Jonghun Han <jonghun.han@samsung.com>
This patch adds platform device s5p_device_fimd0 for EXYNOS4 FIMD0.
EXYNOS4 has two FIMDs(FIMD0, FIMD1). FIMD1 will be added later.
Some definitions used to enable EXYNOS4 FIMD0 are added.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/Kconfig | 9 ++++
arch/arm/mach-exynos4/Makefile | 1 +
arch/arm/mach-exynos4/cpu.c | 4 +-
arch/arm/mach-exynos4/include/mach/regs-fb.h | 21 ++++++++
arch/arm/mach-exynos4/setup-fimd0-24bpp.c | 47 ++++++++++++++++++
arch/arm/plat-s5p/Kconfig | 5 ++
arch/arm/plat-s5p/Makefile | 1 +
arch/arm/plat-s5p/dev-fimd0.c | 67 ++++++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/fb-core.h | 15 ++++++
arch/arm/plat-samsung/include/plat/fb.h | 15 ++++++
11 files changed, 185 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-exynos4/include/mach/regs-fb.h
create mode 100644 arch/arm/mach-exynos4/setup-fimd0-24bpp.c
create mode 100644 arch/arm/plat-s5p/dev-fimd0.c
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..8428ac7 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -25,6 +25,11 @@ config EXYNOS4_DEV_AHCI
help
Compile in platform device definitions for AHCI
+config EXYNOS4_SETUP_FIMD0_24BPP
+ bool
+ help
+ Common setup code for FIMD0 with a 24bpp RGB display helper.
+
config EXYNOS4_DEV_PD
bool
help
@@ -103,6 +108,7 @@ menu "EXYNOS4 Machines"
config MACH_SMDKC210
bool "SMDKC210"
select CPU_EXYNOS4210
+ select S5P_DEV_FIMD0
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
@@ -112,6 +118,7 @@ config MACH_SMDKC210
select S3C_DEV_HSMMC3
select EXYNOS4_DEV_PD
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_SETUP_FIMD0_24BPP
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_SDHCI
help
@@ -120,6 +127,7 @@ config MACH_SMDKC210
config MACH_SMDKV310
bool "SMDKV310"
select CPU_EXYNOS4210
+ select S5P_DEV_FIMD0
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
@@ -130,6 +138,7 @@ config MACH_SMDKV310
select SAMSUNG_DEV_KEYPAD
select EXYNOS4_DEV_PD
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_SETUP_FIMD0_24BPP
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_KEYPAD
select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..aa4d1f4 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0_24BPP) += setup-fimd0-24bpp.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 9babe44..778a5b0 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -19,9 +19,10 @@
#include <plat/cpu.h>
#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
#include <plat/exynos4.h>
#include <plat/sdhci.h>
-#include <plat/devs.h>
#include <plat/fimc-core.h>
#include <mach/regs-irq.h>
@@ -132,6 +133,7 @@ void __init exynos4_map_io(void)
s3c_fimc_setname(1, "exynos4-fimc");
s3c_fimc_setname(2, "exynos4-fimc");
s3c_fimc_setname(3, "exynos4-fimc");
+ s5p_fb_setname(0, "exynos4-fb"); /* FIMD0 */
}
void __init exynos4_init_clocks(int xtal)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-fb.h b/arch/arm/mach-exynos4/include/mach/regs-fb.h
new file mode 100644
index 0000000..f320105
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Dummy framebuffer to allow build for the moment.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+ return 0x2400 + (window * 256 * 4) + reg;
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-exynos4/setup-fimd0-24bpp.c b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
new file mode 100644
index 0000000..3ca8555
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
@@ -0,0 +1,47 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+ /*
+ * Set DISPLAY_CONTROL register for Display path selection.
+ *
+ * DISPLAY_CONTROL[1:0]
+ * ---------------------
+ * 00 | MIE
+ * 01 | MDINE
+ * 10 | FIMD : selected
+ * 11 | FIMD
+ */
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1 << 1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..46de16e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -70,6 +70,11 @@ config S5P_DEV_FIMC3
help
Compile in platform device definitions for FIMC controller 3
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
config S5P_DEV_ONENAND
bool
help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..eec7e24 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMD0,
+ .end = S5P_PA_FIMD0 + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMD0_VSYNC,
+ .end = IRQ_FIMD0_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMD0_FIFO,
+ .end = IRQ_FIMD0_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_FIMD0_SYSTEM,
+ .end = IRQ_FIMD0_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+ .name = "s5p-fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
+ .resource = s5p_fimd0_resource,
+ .dev = {
+ .dma_mask = &fimd0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4af108f..370bd2b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -45,6 +45,7 @@ extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
extern struct platform_device s3c_device_fb;
+extern struct platform_device s5p_device_fimd0;
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..6abcbf1 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name)
#endif
}
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+ case 0:
+ s5p_device_fimd0.name = name;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+ break;
+ }
+}
+
#endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..01f10e4 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -74,6 +74,14 @@ struct s3c_fb_platdata {
extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
/**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
* s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
*
* Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +102,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
*/
extern void s5pv210_fb_gpio_setup_24bpp(void);
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
#endif /* __PLAT_S3C_FB_H */
--
1.7.1
^ permalink raw reply related
* [PATCH V5 2/5] ARM: EXYNOS4: Add FIMD resource definition
From: Jingoo Han @ 2011-06-22 6:41 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jonghun Han, Jingoo Han
From: Jonghun Han <jonghun.han@samsung.com>
This patch adds resource definitions for EXYNOS4 FIMD.
IRQ and SFR definitions are added.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/include/mach/irqs.h | 8 ++++++++
arch/arm/mach-exynos4/include/mach/map.h | 5 +++++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..2cd2090 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -73,6 +73,14 @@
#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
+#define IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM COMBINER_IRQ(12, 2)
+
#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..94006f7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -93,6 +93,9 @@
#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
+#define EXYNOS4_PA_FIMD0 0x11C00000
+#define EXYNOS4_PA_FIMD1 0x12000000
+
#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define EXYNOS4_PA_SATA 0x12560000
@@ -140,6 +143,8 @@
#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1 EXYNOS4_PA_FIMD1
#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
--
1.7.1
^ permalink raw reply related
* [PATCH V5 1/5] ARM: EXYNOS4: Change clock name for FIMD
From: Jingoo Han @ 2011-06-22 6:41 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
Jonghun Han
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jingoo Han
This patch changes clock name for FIMD from "fimd" to "lcd".
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/clock.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..12e6853 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -433,12 +433,12 @@ static struct clk init_clocks_off[] = {
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 3),
}, {
- .name = "fimd",
+ .name = "lcd",
.id = 0,
.enable = exynos4_clk_ip_lcd0_ctrl,
.ctrlbit = (1 << 0),
}, {
- .name = "fimd",
+ .name = "lcd",
.id = 1,
.enable = exynos4_clk_ip_lcd1_ctrl,
.ctrlbit = (1 << 0),
--
1.7.1
^ permalink raw reply related
* Re: Some questions about DRM(Direct Rendering Manager)
From: daeinki @ 2011-06-22 6:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E016EDC.30200@samsung.com>
below is additional comments.
daeinki ¾´ ±Û:
> Hi all,
>
> I'm writing Samsung SoC based DRM framework and this one includes FIMD
> and HDMI driver as hardware dependent modules. and for now, encoder,
> connector, crtc and fb module has been materialized almost. but I'm
> contending with framebuffer setting issue(created fb_info should be
> registered to linux framebuffer through register_framebuffer() or not)as
> default framebuffer at booting time.
>
> at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
> fb_probe callback is called and this one creates new framebuffer and
> returns a value more then 0 if true. internally, this process creates an
> fb_info object and drm_framebuffer and then drm_framebuffer would be
> added to mode_config.fb_list of the drm_device.
>
it's my mistake. return value is 0 if true, nonzero otherwise.
> a value returned, new_fb is used to decide that it calls
> register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
> confused it's a good way to call register_framebuffer() otherwise
> drm_fb_helper_set_par(). if register_framebuffer() is called then I
> guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
> called somewhere subsequently to apply this one to real hardware because
> previous process is just for maintaining data logically.(not set up data
> to h/w)
>
> it's a right way to call register_framebuffer() and then
> drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
> only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
> register_framebuffer()? and what is the purpose of using
> register_framebuffer()?
>
I understood that if fb_probe() callback is fail then fb_info object is
registered to linux framebuffer through register_framebuffer()
otherwise(if true) hardware configuration would be completed by
drm_fb_helper_set_par() so the reason of using register_framebuffer() is
that the case of failing fb_probe() callback, it is for drawing on only
linux framebuffer. is it right?
> In my case, first, register_framebuffer() is called and then if desired
> default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
> it gets mode_set of drm_fb_helper->crtc_info[n] and then it calls
> drm_crtc_helper_set_config(mode_set). at this time, all the hardware
> configurations would be completed.
>
> thank you in advance.
>
> Best Regards
> Inki Dae.
>
^ permalink raw reply
* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Florian Tobias Schandinat @ 2011-06-22 5:45 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: Geert Uytterhoeven, linux-fbdev, linux-media, dri-devel
In-Reply-To: <201106220031.57972.laurent.pinchart@ideasonboard.com>
Hi Geert, Laurent,
On 06/21/2011 10:31 PM, Laurent Pinchart wrote:
> Hi Geert,
>
> On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
>> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
>>> +The FOURCC-based API replaces format descriptions by four character
>>> codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define a
>>> format +without explicitly describing it. This is the only API that
>>> supports YUV +formats. Drivers are also encouraged to implement the
>>> FOURCC-based API for RGB +and grayscale formats.
>>> +
>>> +Drivers that support the FOURCC-based API report this capability by
>>> setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
>>> field. +
>>> +FOURCC definitions are located in the linux/videodev2.h header. However,
>>> and +despite starting with the V4L2_PIX_FMT_prefix, they are not
>>> restricted to V4L2 +and don't require usage of the V4L2 subsystem.
>>> FOURCC documentation is +available in
>>> Documentation/DocBook/v4l/pixfmt.xml.
>>> +
>>> +To select a format, applications set the FB_VMODE_FOURCC bit in the
>>> +fb_var_screeninfo vmode field, and set the fourcc field to the desired
>>> FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
>>> must be set to +0 by applications and ignored by drivers. Note that the
>>> grayscale and fourcc +fields share the same memory location. Application
>>> must thus not set the +grayscale field to 0.
>>
>> These are the only parts I don't like: (ab)using the vmode field (this
>> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
>> unions where possible).
>
> I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a FOURCC
> mode indicator in my initial RFC. Florian Tobias Schandinat wasn't very happy
> with that, and proposed using the vmode field instead.
>
> Given that there's virtually no fbdev documentation, whether the vmode field
> and/or nonstd field are good fit for a FOURCC mode indicator is subject to
> interpretation.
The reason for my suggestion is that the vmode field is accepted to contain only
flags and at least to me there is no hard line what is part of the video mode
and what is not. In contrast the nonstd field is already used in a lot of
different (incompatible) ways. I think if we only use the nonstd field for
handling FOURCC it is likely that some problems will appear.
>> What about storing the FOURCC value in nonstd instead?
>
> Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format
> setting will be a standard fbdev API, I'm not very keen on storing it in the
> nonstd field without a union.
>
>> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
>> be non-zero), I don't think there are any conflicts with existing values of
>> nonstd. To make it even safer and easier to parse, you could set bit 31 of
>> nonstd as a FOURCC indicator.
>
> I would then create a union between nonstd and fourcc, and document nonstd as
> being used for the legacy API only. Most existing drivers use a couple of
> nonstd bits only. The driver that (ab)uses nonstd the most is pxafb and uses
> bits 22:0. Bits 31:24 are never used as far as I can tell, so nonstd&
> 0xff000000 != 0 could be used as a FOURCC mode test.
>
> This assumes that FOURCCs will never have their last character set to '\0'. Is
> that a safe assumption for the future ?
Yes, I think. The information I found indicates that space should be used for
padding, so a \0 shouldn't exist.
I think using only the nonstd field and requiring applications to check the
capabilities would be possible, although not fool proof ;)
Great work, Laurent, do you have plans to modify fbset to allow using this
format API from the command line?
Regards,
Florian Tobias Schandinat
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox