* Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
From: Jerome Glisse @ 2013-06-25 14:49 UTC (permalink / raw)
To: Inki Dae
Cc: Rob Clark, linux-fbdev, Russell King - ARM Linux,
DRI mailing list, Kyungmin Park, myungjoo.ham, YoungJun Cho,
linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAAQKjZNjjgG3hoKU2RLsG7w+B-2v7CpTT5hfnnTTJ2DgTEk0vA@mail.gmail.com>
On Tue, Jun 25, 2013 at 10:17 AM, Inki Dae <daeinki@gmail.com> wrote:
> 2013/6/25 Rob Clark <robdclark@gmail.com>:
>> On Tue, Jun 25, 2013 at 5:09 AM, Inki Dae <daeinki@gmail.com> wrote:
>>>> that
>>>> should be the role of kernel memory management which of course needs
>>>> synchronization btw A and B. But in no case this should be done using
>>>> dma-buf. dma-buf is for sharing content btw different devices not
>>>> sharing resources.
>>>>
>>>
>>> hmm, is that true? And are you sure? Then how do you think about
>>> reservation? the reservation also uses dma-buf with same reason as long as I
>>> know: actually, we use reservation to use dma-buf. As you may know, a
>>> reservation object is allocated and initialized when a buffer object is
>>> exported to a dma buf.
>>
>> no, this is why the reservation object can be passed in when you
>> construction the dmabuf.
>
> Right, that way, we could use dma buf for buffer synchronization. I
> just wanted to ask for why Jerome said that "dma-buf is for sharing
> content btw different devices not sharing resources".
From memory, the motivation of dma-buf was to done for few use case,
among them webcam capturing frame into a buffer and having gpu using
it directly without memcpy, or one big gpu rendering a scene into a
buffer that is then use by low power gpu for display ie it was done to
allow different device to operate on same data using same backing
memory.
AFAICT you seem to want to use dma-buf to create scratch buffer, ie a
process needs to use X amount of memory for an operation, it can
release|free this memory once its done and a process B can the use
this X memory for its own operation discarding content of process A. I
presume that next frame would have the sequence repeat, process A do
something, then process B does its thing. So to me it sounds like you
want to implement global scratch buffer using the dmabuf API and that
sounds bad to me.
I know most closed driver have several pool of memory, long lived
object, short lived object and scratch space, then user space allocate
from one of this pool and there is synchronization done by driver
using driver specific API to reclaim memory. Of course this work
nicely if you only talking about one logic block or at very least hw
that have one memory controller.
Now if you are thinking of doing scratch buffer for several different
device and share the memory among then you need to be aware of
security implication, most obvious being that you don't want process B
being able to read process A scratch memory. I know the argument about
it being graphic but one day this might become gpu code and it might
be able to insert jump to malicious gpu code.
Cheers,
Jerome
^ permalink raw reply
* Re: [V2 1/7] video: mmp: rb swap setting update for new LCD driver
From: Daniel Drake @ 2013-06-25 14:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACDDiy_CpKuZkevm4jQud1DKBEDa-ZhtrWb+rFpTXvK3zm6aHw@mail.gmail.com>
On Mon, Jun 24, 2013 at 8:23 PM, jett zhou <jett.zhou@gmail.com> wrote:
>> What if I'm working with a display that doesn't need or want RB
>> swapping? Lets say I am working with format PIXFMT_RGB565, and running
>> your patch. dmafetch_set_fmt() gets called, and fmt_to_reg() sets
>> rbswap to 1.
>> This means that dmafetch_set_fmt() writes a '1' into the appropriate
>> RB-swapping bit in the LCD_PN_CTRL0 register, and this triggers the
>> "DMA input" swapping that you mentioned. But I never asked for RB
>> swapping...
>
> Yes, if you configure it as PIXFMT_RGB565, it will set rbswap in "DMA
> input" part.
> So, for your case, you need to use PIXFMT_BGR565 instead of PIXFMT_RGB565.
So let me get this straight. I have a display that wants RGB565
format, no RB swapping. I don't do anything special in link_config to
affect any swapping.
After your patch, I must request BGR565 format in order to get RGB565?
That sounds backwards to me.
>> Your comment above suggests that this RB-swapping behaviour is
>> something that is imposed by the output device. In which case, this
>> should be a configuration parameter on the panel, not on the path
>> structure.
>>
>>> TTC_dkb does not support dsi, the link_config is no used anymore.
>>
>> Then you should fix up ttc_dkb before submitting this patch.
>
> After we add one new field for this output rbswap setting based on dsi
> interface, it can be used by new stepping of mmp display controller,
> ttc_dkb platform just leave and not touch it, it will be tranparent
> for ttc_dkb, does not need to nothing for platform configuration for
> ttc_dkb usage.
> It means , ttc_dkb can only configure rbswap in "dma input" part, not
> support rbswap in dsi interface part.
> What do you think?
The point I am trying to make is that your patch is changing behaviour
for ttc_dkb, so you need to address that at the same time.
Right now ttc_dkb does this:
#define CFG_GRA_SWAPRB(x) (x << 0) /* 1: rbswap enabled */
.link_config = CFG_DUMBMODE(0x2) | CFG_GRA_SWAPRB(0x1),
i.e. SWAPRB requested through bit 0 in link_config
And this is obeyed by the existing code in fmt_to_reg:
u32 link_config = path_to_path_plat(overlay->path)->link_config;
rbswap = link_config & 0x1;
Your patch removes the handling of link_config bit 0, without fixing
up its only user (even if that user was incorrect). That is not good
practice.
Another question: why is this change needed?
We can request rb swapping either in DMA input or in the output
interface. I can understand the driver maybe supporting one option or
the other. But after your patch, it seems like both are supported: RB
swapping could be enabled either through choice of input format, or
through configuration of output parameters.
Daniel
^ permalink raw reply
* [PATCH 23/23] video/da8xx-fb adding am33xx as dependency
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
Updating Kconfig to allow am33xx to include lcdc fbdev driver
including some extra dependencies needed by device tree mods.
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/Kconfig | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2e937bd..8ae6d2a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2226,15 +2226,16 @@ config FB_SH7760
panels <= 320 pixel horizontal resolution.
config FB_DA8XX
- tristate "DA8xx/OMAP-L1xx Framebuffer support"
- depends on FB && ARCH_DAVINCI_DA8XX
+ tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
+ depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_CFB_REV_PIXELS_IN_BYTE
+ select VIDEOMODE_HELPERS
---help---
This is the frame buffer device driver for the TI LCD controller
- found on DA8xx/OMAP-L1xx SoCs.
+ found on DA8xx/OMAP-L1xx/AM335x SoCs.
If unsure, say N.
config FB_VIRTUAL
--
1.7.0.4
^ permalink raw reply related
* [PATCH 22/23] video: da8xx-fb: set upstream clock rate (if reqd)
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
LCDC IP has a clock divider to adjust pixel clock, this limits pixel
clock range to fck/255 - fck/2(fck - rate of input clock to LCDC IP).
In the case of AM335x, where this IP is present, default fck is not
sufficient to provide normal pixel clock rates, hence rendering this
driver unusable on AM335x.
If input clock too is configurable, allowable range of pixel clock
would increase. Here initially it is checked whether with present fck,
divider in IP could be configured to obtain required rate, if not,
fck is adjusted. This makes it usable on AM335x.
Note:
Another solution would be to model an inherited basic clock divider of
CCF, an advantage would be a better possible resolution for pixel clk.
And trying to instantiate a CCF clock would mean that to be consistent,
3 bits being turned on to enable clocks of LCDC IP would have to be
modeled as gate clocks. Now that would bring in a total of 4 clocks,
including necessity to create a new inherited divider clock, and that
mean a branch of clock tree would be present in LCDC driver. This
would add complexity to LCDC driver bringing in considerable amount
of clock handling code, and this would not bring in much advantage
for existing use cases other than providing a higher resolution of
pixel clock. And existing use cases work without relying on clock
modeling. Another fact is that out of the two platform's using this
driver DaVinci is not yet converted to CCF. In future if higher
resolution of pixel clock is required, and probably after DaVinci is
CCF'ed, modeling clock nodes inside driver may be considered.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 76 +++++++++++++++++++++++++++++++++++-----------
1 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 5455682..09dfa12 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -133,6 +133,9 @@
#define WSI_TIMEOUT 50
#define PALETTE_SIZE 256
+#define CLK_MIN_DIV 2
+#define CLK_MAX_DIV 255
+
static void __iomem *da8xx_fb_reg_base;
static struct resource *lcdc_regs;
static unsigned int lcd_revision;
@@ -683,23 +686,21 @@ static void da8xx_fb_lcd_reset(void)
}
}
-static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
- unsigned pixclock)
-{
- return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
-}
-
-static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
- unsigned pixclock)
+static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
+ unsigned div, unsigned rate)
{
- unsigned div;
+ int ret;
- div = da8xx_fb_calc_clk_divider(par, pixclock);
- return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
-}
+ if (par->lcd_fck_rate != rate) {
+ ret = clk_set_rate(par->lcdc_clk, rate);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(par->dev,
+ "unable to set clock rate at %u\n", rate);
+ return ret;
+ }
+ par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
+ }
-static inline void da8xx_fb_config_clk_divider(unsigned div)
-{
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
@@ -707,14 +708,49 @@ static inline void da8xx_fb_config_clk_divider(unsigned div)
if (lcd_revision = LCD_VERSION_2)
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
+ return 0;
+}
+
+static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
+ unsigned pixclock,
+ unsigned *rate)
+{
+ unsigned div;
+
+ pixclock = PICOS2KHZ(pixclock) * 1000;
+
+ *rate = par->lcd_fck_rate;
+
+ if (pixclock < (*rate / CLK_MAX_DIV)) {
+ *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MAX_DIV);
+ div = CLK_MAX_DIV;
+ } else if (pixclock > (*rate / CLK_MIN_DIV)) {
+ *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MIN_DIV);
+ div = CLK_MIN_DIV;
+ } else {
+ div = *rate / pixclock;
+ }
+
+ return div;
}
-static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
+static inline int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
struct fb_videomode *mode)
{
- unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
+ unsigned rate;
+ unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock, &rate);
- da8xx_fb_config_clk_divider(div);
+ return da8xx_fb_config_clk_divider(par, div, rate);
+}
+
+static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
+ unsigned pixclock)
+{
+ unsigned div, rate;
+
+ div = da8xx_fb_calc_clk_divider(par, pixclock, &rate);
+ return KHZ2PICOS(rate / (1000 * div));
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -723,7 +759,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
u32 bpp;
int ret = 0;
- da8xx_fb_calc_config_clk_divider(par, panel);
+ ret = da8xx_fb_calc_config_clk_divider(par, panel);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(par->dev, "unable to configure clock\n");
+ return ret;
+ }
if (panel->sync & FB_SYNC_CLK_INVERT)
lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
--
1.7.0.4
^ permalink raw reply related
* [PATCH 21/23] video: da8xx-fb: setup struct lcd_ctrl_config for dt
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
strcut lcd_ctrl_config information required for driver is currently
obtained via platform data. To handle DT probing, create
lcd_ctrl_config and populate it with default values, these values are
sufficient for the panels so far used with this controller to work.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 1c1a616..5455682 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1254,6 +1254,35 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev)
+{
+ struct lcd_ctrl_config *cfg;
+
+ cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL);
+ if (!cfg) {
+ dev_err(&dev->dev, "memory allocation failed\n");
+ return NULL;
+ }
+
+ /* default values */
+
+ if (lcd_revision = LCD_VERSION_1)
+ cfg->bpp = 16;
+ else
+ cfg->bpp = 32;
+
+ /*
+ * For panels so far used with this LCDC, below statement is sufficient.
+ * For new panels, if required, struct lcd_ctrl_cfg fields to be updated
+ * with additional/modified values. Those values would have to be then
+ * obtained from dt(requiring new dt bindings).
+ */
+
+ cfg->panel_shade = COLOR_ACTIVE;
+
+ return cfg;
+}
+
static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
{
struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
@@ -1345,7 +1374,10 @@ static int fb_probe(struct platform_device *device)
break;
}
- lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
+ if (device->dev.of_node)
+ lcd_cfg = da8xx_fb_create_cfg(device);
+ else
+ lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
if (!lcd_cfg) {
ret = -EINVAL;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 20/23] video: da8xx-fb: ensure pdata only for non-dt
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
This driver is DT probe-able, hence ensure presence of platform data
only for non-DT boot.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0c68712..1c1a616 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1303,7 +1303,7 @@ static int fb_probe(struct platform_device *device)
int ret;
unsigned long ulcm;
- if (fb_pdata = NULL) {
+ if (fb_pdata = NULL && !device->dev.of_node) {
dev_err(&device->dev, "Can not get platform data\n");
return -ENOENT;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 19/23] video: da8xx-fb: obtain fb_videomode info from dt
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Obtain fb_videomode details for the connected lcd panel using the
display timing details present in DT.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
.../devicetree/bindings/video/fb-da8xx.txt | 21 ++++++++++++++++++++
drivers/video/da8xx-fb.c | 17 ++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
index 581e014..0741f78 100644
--- a/Documentation/devicetree/bindings/video/fb-da8xx.txt
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -6,6 +6,12 @@ Required properties:
AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
- reg: Address range of lcdc register set
- interrupts: lcdc interrupt
+- display-timings: typical videomode of lcd panel, represented as child.
+ Refer Documentation/devicetree/bindings/video/display-timing.txt for
+ display timing binding details. If multiple videomodes are mentioned
+ in display timings node, typical videomode has to be mentioned as the
+ native mode or it has to be first child (driver cares only for native
+ videomode).
Example:
@@ -13,4 +19,19 @@ lcdc@4830e000 {
compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
reg = <0x4830e000 0x1000>;
interrupts = <36>;
+ display-timings {
+ 800x480p62 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <39>;
+ hback-porch = <39>;
+ hsync-len = <47>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
};
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0beed20..0c68712 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/lcm.h>
+#include <video/of_display_timing.h>
#include <video/da8xx-fb.h>
#include <asm/div64.h>
@@ -1257,8 +1258,24 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
{
struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
struct fb_videomode *lcdc_info;
+ struct device_node *np = dev->dev.of_node;
int i;
+ if (np) {
+ lcdc_info = devm_kzalloc(&dev->dev,
+ sizeof(struct fb_videomode),
+ GFP_KERNEL);
+ if (!lcdc_info) {
+ dev_err(&dev->dev, "memory allocation failed\n");
+ return NULL;
+ }
+ if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) {
+ dev_err(&dev->dev, "timings not available in DT\n");
+ return NULL;
+ }
+ return lcdc_info;
+ }
+
for (i = 0, lcdc_info = known_lcd_panels;
i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
--
1.7.0.4
^ permalink raw reply related
* [PATCH 18/23] video: da8xx-fb: invoke platform callback safely
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Ensure that platform data is present before checking whether platform
callback is present (the one used to control backlight). So far this
was not an issue as driver was purely non-DT triggered, but now DT
support has been added.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 08ee8eb..0beed20 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1347,7 +1347,7 @@ static int fb_probe(struct platform_device *device)
par->dev = &device->dev;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
- if (fb_pdata->panel_power_ctrl) {
+ if (fb_pdata && fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 17/23] video: da8xx-fb: minimal dt support
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Driver is provided a means to have the probe triggered by DT.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
.../devicetree/bindings/video/fb-da8xx.txt | 16 ++++++++++++++++
drivers/video/da8xx-fb.c | 7 +++++++
2 files changed, 23 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt
diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
new file mode 100644
index 0000000..581e014
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -0,0 +1,16 @@
+TI LCD Controller on DA830/DA850/AM335x SoC's
+
+Required properties:
+- compatible:
+ DA830 - "ti,da830-lcdc"
+ AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
+- reg: Address range of lcdc register set
+- interrupts: lcdc interrupt
+
+Example:
+
+lcdc@4830e000 {
+ compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
+ reg = <0x4830e000 0x1000>;
+ interrupts = <36>;
+};
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index b6ea5e9..08ee8eb 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1595,6 +1595,12 @@ static int fb_resume(struct platform_device *dev)
#define fb_resume NULL
#endif
+static const struct of_device_id da8xx_fb_of_match[] = {
+ {.compatible = "ti,da830-lcdc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, da8xx_fb_of_match);
+
static struct platform_driver da8xx_fb_driver = {
.probe = fb_probe,
.remove = fb_remove,
@@ -1603,6 +1609,7 @@ static struct platform_driver da8xx_fb_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(da8xx_fb_of_match),
},
};
--
1.7.0.4
^ permalink raw reply related
* [PATCH 16/23] video: da8xx-fb: reorganize panel detection
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Move panel detection to a separate function, this helps in readability
as well as makes DT support cleaner.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 42 ++++++++++++++++++++++++++----------------
1 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 3b146bc..b6ea5e9 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1253,6 +1253,27 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
+{
+ struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
+ struct fb_videomode *lcdc_info;
+ int i;
+
+ for (i = 0, lcdc_info = known_lcd_panels;
+ i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
+ if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
+ break;
+ }
+
+ if (i = ARRAY_SIZE(known_lcd_panels)) {
+ dev_err(&dev->dev, "no panel found\n");
+ return NULL;
+ }
+ dev_info(&dev->dev, "found %s panel\n", lcdc_info->name);
+
+ return lcdc_info;
+}
+
static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1262,7 +1283,7 @@ static int fb_probe(struct platform_device *device)
struct fb_info *da8xx_fb_info;
struct clk *fb_clk = NULL;
struct da8xx_fb_par *par;
- int ret, i;
+ int ret;
unsigned long ulcm;
if (fb_pdata = NULL) {
@@ -1270,6 +1291,10 @@ static int fb_probe(struct platform_device *device)
return -ENOENT;
}
+ lcdc_info = da8xx_fb_get_videomode(device);
+ if (lcdc_info = NULL)
+ return -ENODEV;
+
lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
if (!da8xx_fb_reg_base) {
@@ -1303,21 +1328,6 @@ static int fb_probe(struct platform_device *device)
break;
}
- for (i = 0, lcdc_info = known_lcd_panels;
- i < ARRAY_SIZE(known_lcd_panels);
- i++, lcdc_info++) {
- if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
- break;
- }
-
- if (i = ARRAY_SIZE(known_lcd_panels)) {
- dev_err(&device->dev, "GLCD: No valid panel found\n");
- ret = -ENODEV;
- goto err_pm_runtime_disable;
- } else
- dev_info(&device->dev, "GLCD: Found %s panel\n",
- fb_pdata->type);
-
lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
if (!lcd_cfg) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 15/23] video: da8xx-fb: ensure non-null cfg in pdata
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Ensure that platform data contains pointer for lcd_ctrl_config.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7a32e83..3b146bc 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1320,6 +1320,11 @@ static int fb_probe(struct platform_device *device)
lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
+ if (!lcd_cfg) {
+ ret = -EINVAL;
+ goto err_pm_runtime_disable;
+ }
+
da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
&device->dev);
if (!da8xx_fb_info) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 14/23] video: da8xx-fb: use devres
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Replace existing resource handling in the driver with managed device
resource.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 35 ++++++-----------------------------
1 files changed, 6 insertions(+), 29 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index ca69e01..7a32e83 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1036,12 +1036,9 @@ static int fb_remove(struct platform_device *dev)
par->p_palette_base);
dma_free_coherent(NULL, par->vram_size, par->vram_virt,
par->vram_phys);
- free_irq(par->irq, par);
pm_runtime_put_sync(&dev->dev);
pm_runtime_disable(&dev->dev);
framebuffer_release(info);
- iounmap(da8xx_fb_reg_base);
- release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
}
return 0;
@@ -1265,7 +1262,6 @@ static int fb_probe(struct platform_device *device)
struct fb_info *da8xx_fb_info;
struct clk *fb_clk = NULL;
struct da8xx_fb_par *par;
- resource_size_t len;
int ret, i;
unsigned long ulcm;
@@ -1275,29 +1271,16 @@ static int fb_probe(struct platform_device *device)
}
lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
- if (!lcdc_regs) {
- dev_err(&device->dev,
- "Can not get memory resource for LCD controller\n");
- return -ENOENT;
- }
-
- len = resource_size(lcdc_regs);
-
- lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
- if (!lcdc_regs)
- return -EBUSY;
-
- da8xx_fb_reg_base = ioremap(lcdc_regs->start, len);
+ da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
if (!da8xx_fb_reg_base) {
- ret = -EBUSY;
- goto err_request_mem;
+ dev_err(&device->dev, "memory resource setup failed\n");
+ return -EADDRNOTAVAIL;
}
- fb_clk = clk_get(&device->dev, "fck");
+ fb_clk = devm_clk_get(&device->dev, "fck");
if (IS_ERR(fb_clk)) {
dev_err(&device->dev, "Can not get device clock\n");
- ret = -ENODEV;
- goto err_ioremap;
+ return -ENODEV;
}
pm_runtime_enable(&device->dev);
@@ -1458,7 +1441,7 @@ static int fb_probe(struct platform_device *device)
lcdc_irq_handler = lcdc_irq_handler_rev02;
}
- ret = request_irq(par->irq, lcdc_irq_handler, 0,
+ ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0,
DRIVER_NAME, par);
if (ret)
goto irq_freq;
@@ -1488,12 +1471,6 @@ err_pm_runtime_disable:
pm_runtime_put_sync(&device->dev);
pm_runtime_disable(&device->dev);
-err_ioremap:
- iounmap(da8xx_fb_reg_base);
-
-err_request_mem:
- release_mem_region(lcdc_regs->start, len);
-
return ret;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 13/23] video: da8xx-fb: enable sync lost intr for v2 ip
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
interrupt handler is checking for sync lost interrupt, but it was not
enabled, enable it.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7f92f37..ca69e01 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -318,7 +318,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_END_OF_FRAME0_INT_ENA |
LCD_V2_END_OF_FRAME1_INT_ENA |
- LCD_FRAME_DONE;
+ LCD_FRAME_DONE | LCD_SYNC_LOST;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 12/23] video: da8xx-fb: fix 24bpp raster configuration
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Manjunathappa, Prakash <prakash.pm@ti.com>
Set only LCD_V2_TFT_24BPP_MODE bit for 24bpp and LCD_V2_TFT_24BPP_UNPACK
bit along with LCD_V2_TFT_24BPP_MODE for 32bpp configuration.
Patch is tested on am335x-evm for 24bpp and da850-evm for 16bpp
configurations.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 35a33ca..7f92f37 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -550,10 +550,10 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
case 4:
case 16:
break;
- case 24:
- reg |= LCD_V2_TFT_24BPP_MODE;
case 32:
reg |= LCD_V2_TFT_24BPP_UNPACK;
+ case 24:
+ reg |= LCD_V2_TFT_24BPP_MODE;
break;
case 8:
--
1.7.0.4
^ permalink raw reply related
* [PATCH 11/23] video: da8xx-fb: make io operations safe
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Replace __raw_readl/__raw_writel with readl/writel; this driver is
reused on ARMv7 (AM335x SoC).
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 720604c..35a33ca 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -141,12 +141,12 @@ static int frame_done_flag;
static inline unsigned int lcdc_read(unsigned int addr)
{
- return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
+ return (unsigned int)readl(da8xx_fb_reg_base + (addr));
}
static inline void lcdc_write(unsigned int val, unsigned int addr)
{
- __raw_writel(val, da8xx_fb_reg_base + (addr));
+ writel(val, da8xx_fb_reg_base + (addr));
}
struct da8xx_fb_par {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 10/23] video: da8xx-fb: fb_set_par support
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
fb_set_par helps in runtime configuration of lcd controller like
changing resolution, pixel clock etc. (eg. using fbset utility)
Reconfigure lcd controller based on information passed by framework.
Enable raster back if it was already enabled.
As fb_set_par would get invoked indirectly from probe via fb_set_var,
remove existing lcdc initialization in probe and do lcdc reset in
probe so that reset happens only at the begining.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 60 +++++++++++++++++++++++++++++++++++++--------
1 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0f73c76..720604c 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -243,6 +243,11 @@ static struct fb_videomode known_lcd_panels[] = {
},
};
+static inline bool da8xx_fb_is_raster_enabled(void)
+{
+ return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE);
+}
+
/* Enable the Raster Engine of the LCD Controller */
static inline void lcd_enable_raster(void)
{
@@ -665,9 +670,6 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
static void da8xx_fb_lcd_reset(void)
{
- /* Disable the Raster if previously Enabled */
- lcd_disable_raster(false);
-
/* DMA has to be disabled */
lcdc_write(0, LCD_DMA_CTRL_REG);
lcdc_write(0, LCD_RASTER_CTRL_REG);
@@ -720,8 +722,6 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
u32 bpp;
int ret = 0;
- da8xx_fb_lcd_reset();
-
da8xx_fb_calc_config_clk_divider(par, panel);
if (panel->sync & FB_SYNC_CLK_INVERT)
@@ -1201,9 +1201,52 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
return ret;
}
+static int da8xxfb_set_par(struct fb_info *info)
+{
+ struct da8xx_fb_par *par = info->par;
+ int ret;
+ bool raster = da8xx_fb_is_raster_enabled();
+
+ if (raster)
+ lcd_disable_raster(true);
+ else
+ lcd_disable_raster(false);
+
+ fb_var_to_videomode(&par->mode, &info->var);
+
+ par->cfg.bpp = info->var.bits_per_pixel;
+
+ info->fix.visual = (par->cfg.bpp <= 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8;
+
+ ret = lcd_init(par, &par->cfg, &par->mode);
+ if (ret < 0) {
+ dev_err(par->dev, "lcd init failed\n");
+ return ret;
+ }
+
+ par->dma_start = info->fix.smem_start +
+ info->var.yoffset * info->fix.line_length +
+ info->var.xoffset * info->var.bits_per_pixel / 8;
+ par->dma_end = par->dma_start +
+ info->var.yres * info->fix.line_length - 1;
+
+ lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+ lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+ lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+ lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+
+ if (raster)
+ lcd_enable_raster();
+
+ return 0;
+}
+
static struct fb_ops da8xx_fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = fb_check_var,
+ .fb_set_par = da8xxfb_set_par,
.fb_setcolreg = fb_setcolreg,
.fb_pan_display = da8xx_pan_display,
.fb_ioctl = fb_ioctl,
@@ -1312,14 +1355,9 @@ static int fb_probe(struct platform_device *device)
}
fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
- fb_var_to_videomode(&par->mode, &da8xx_fb_var);
par->cfg = *lcd_cfg;
- if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
- dev_err(&device->dev, "lcd_init failed\n");
- ret = -EFAULT;
- goto err_release_fb;
- }
+ da8xx_fb_lcd_reset();
/* allocate frame buffer */
par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 09/23] video: da8xx-fb: report correct pixclock
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Update "var" pixclock with the value that is configurable in hardware.
This lets user know the actual pixclock.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index a5341d0..0f73c76 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -686,6 +686,15 @@ static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
}
+static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
+ unsigned pixclock)
+{
+ unsigned div;
+
+ div = da8xx_fb_calc_clk_divider(par, pixclock);
+ return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
+}
+
static inline void da8xx_fb_config_clk_divider(unsigned div)
{
/* Configure the LCD clock divisor. */
@@ -962,6 +971,8 @@ static int fb_check_var(struct fb_var_screeninfo *var,
if (var->yres + var->yoffset > var->yres_virtual)
var->yoffset = var->yres_virtual - var->yres;
+ var->pixclock = da8xx_fb_round_clk(par, var->pixclock);
+
return err;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 08/23] video: da8xx-fb: store struct device *
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
store struct device pointer so that dev_dbg/err can be used outside
of probe.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7f08644..a5341d0 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -150,6 +150,7 @@ static inline void lcdc_write(unsigned int val, unsigned int addr)
}
struct da8xx_fb_par {
+ struct device *dev;
resource_size_t p_palette_base;
unsigned char *v_palette_base;
dma_addr_t vram_phys;
@@ -1291,6 +1292,7 @@ static int fb_probe(struct platform_device *device)
}
par = da8xx_fb_info->par;
+ par->dev = &device->dev;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
if (fb_pdata->panel_power_ctrl) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 07/23] video: da8xx-fb: pix clk and clk div handling cleanup
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Use the new modedb field to store pix clk. Reorganize existing clock
divider functions with names now corresponding to what they do, add
common function prefix.
Fix existing panel modedb pixclock to be in ps instead of Hz. This
needed a change in the way clock divider is calculated. As modedb
pixclock information is now in ps, override on "var" pixclock over
modedb to var conversion is removed.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 48 +++++++++++++++++----------------------------
1 files changed, 18 insertions(+), 30 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index f1d88ac..7f08644 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -160,7 +160,6 @@ struct da8xx_fb_par {
struct clk *lcdc_clk;
int irq;
unsigned int palette_sz;
- unsigned int pxl_clk;
int blank;
wait_queue_head_t vsync_wait;
int vsync_flag;
@@ -201,7 +200,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "Sharp_LCD035Q3DG01",
.xres = 320,
.yres = 240,
- .pixclock = 4608000,
+ .pixclock = 217014,
.left_margin = 6,
.right_margin = 8,
.upper_margin = 2,
@@ -216,7 +215,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "Sharp_LK043T1DG01",
.xres = 480,
.yres = 272,
- .pixclock = 7833600,
+ .pixclock = 127655,
.left_margin = 2,
.right_margin = 2,
.upper_margin = 2,
@@ -231,7 +230,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "SP10Q010",
.xres = 320,
.yres = 240,
- .pixclock = 7833600,
+ .pixclock = 127655,
.left_margin = 10,
.right_margin = 10,
.upper_margin = 10,
@@ -680,13 +679,14 @@ static void da8xx_fb_lcd_reset(void)
}
}
-static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
+static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
+ unsigned pixclock)
{
- unsigned int lcd_clk, div;
-
- lcd_clk = clk_get_rate(par->lcdc_clk);
- div = lcd_clk / par->pxl_clk;
+ return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
+}
+static inline void da8xx_fb_config_clk_divider(unsigned div)
+{
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
@@ -694,7 +694,14 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
if (lcd_revision = LCD_VERSION_2)
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+}
+
+static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
+ struct fb_videomode *mode)
+{
+ unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
+ da8xx_fb_config_clk_divider(div);
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -705,8 +712,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
da8xx_fb_lcd_reset();
- /* Calculate the divider */
- lcd_calc_clk_divider(par);
+ da8xx_fb_calc_config_clk_divider(par, panel);
if (panel->sync & FB_SYNC_CLK_INVERT)
lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
@@ -969,7 +975,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
lcd_disable_raster(true);
- lcd_calc_clk_divider(par);
+ da8xx_fb_calc_config_clk_divider(par, &par->mode);
if (par->blank = FB_BLANK_UNBLANK)
lcd_enable_raster();
}
@@ -1195,22 +1201,6 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
-/* Calculate and return pixel clock period in pico seconds */
-static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
-{
- unsigned int lcd_clk, div;
- unsigned int configured_pix_clk;
- unsigned long long pix_clk_period_picosec = 1000000000000ULL;
-
- lcd_clk = clk_get_rate(par->lcdc_clk);
- div = lcd_clk / par->pxl_clk;
- configured_pix_clk = (lcd_clk / div);
-
- do_div(pix_clk_period_picosec, configured_pix_clk);
-
- return pix_clk_period_picosec;
-}
-
static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1303,7 +1293,6 @@ static int fb_probe(struct platform_device *device)
par = da8xx_fb_info->par;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
- par->pxl_clk = lcdc_info->pixclock;
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
@@ -1368,7 +1357,6 @@ static int fb_probe(struct platform_device *device)
da8xx_fb_var.grayscale lcd_cfg->panel_shade = MONOCHROME ? 1 : 0;
da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
- da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 06/23] video: da8xx-fb: store clk rate even if !CPUFREQ
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
store lcd clk rate always, i.e. irrespective of whether CPUFREQ is
enabled or not. This can be used to get clk rate directly instead of
enquiring with clock framework with clk handle every time.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index d060f14..f1d88ac 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -174,8 +174,8 @@ struct da8xx_fb_par {
unsigned int which_dma_channel_done;
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
- unsigned int lcd_fck_rate;
#endif
+ unsigned int lcd_fck_rate;
void (*panel_power_ctrl)(int);
u32 pseudo_palette[16];
struct fb_videomode mode;
@@ -1302,9 +1302,7 @@ static int fb_probe(struct platform_device *device)
par = da8xx_fb_info->par;
par->lcdc_clk = fb_clk;
-#ifdef CONFIG_CPU_FREQ
par->lcd_fck_rate = clk_get_rate(fb_clk);
-#endif
par->pxl_clk = lcdc_info->pixclock;
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 05/23] video: da8xx-fb: store current display information
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
store current videomode and controller data so that reconfiguring can
be done easily. Reconfiguring would be required in fb_set_par, which
is going to be added soon.
If these details are not stored, the work probe does to retrieve these
information would have to repeated at the place of reconfiguring and
modifying platform data would be necessary to handle controller data
changes like bpp.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 18834fa..d060f14 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -178,6 +178,8 @@ struct da8xx_fb_par {
#endif
void (*panel_power_ctrl)(int);
u32 pseudo_palette[16];
+ struct fb_videomode mode;
+ struct lcd_ctrl_config cfg;
};
static struct fb_var_screeninfo da8xx_fb_var;
@@ -1310,6 +1312,8 @@ static int fb_probe(struct platform_device *device)
}
fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
+ fb_var_to_videomode(&par->mode, &da8xx_fb_var);
+ par->cfg = *lcd_cfg;
if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
dev_err(&device->dev, "lcd_init failed\n");
--
1.7.0.4
^ permalink raw reply related
* [PATCH 04/23] video: da8xx-fb: remove unneeded "var" initialization
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
modedb helper now updates "var" information based on the detected
panel, remove the unnecessary initialization.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 22 +---------------------
1 files changed, 1 insertions(+), 21 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index a1f6544..18834fa 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -131,10 +131,6 @@
#define WSI_TIMEOUT 50
#define PALETTE_SIZE 256
-#define LEFT_MARGIN 64
-#define RIGHT_MARGIN 64
-#define UPPER_MARGIN 32
-#define LOWER_MARGIN 32
static void __iomem *da8xx_fb_reg_base;
static struct resource *lcdc_regs;
@@ -184,23 +180,7 @@ struct da8xx_fb_par {
u32 pseudo_palette[16];
};
-/* Variable Screen Information */
-static struct fb_var_screeninfo da8xx_fb_var = {
- .xoffset = 0,
- .yoffset = 0,
- .transp = {0, 0, 0},
- .nonstd = 0,
- .activate = 0,
- .height = -1,
- .width = -1,
- .accel_flags = 0,
- .left_margin = LEFT_MARGIN,
- .right_margin = RIGHT_MARGIN,
- .upper_margin = UPPER_MARGIN,
- .lower_margin = LOWER_MARGIN,
- .sync = 0,
- .vmode = FB_VMODE_NONINTERLACED
-};
+static struct fb_var_screeninfo da8xx_fb_var;
static struct fb_fix_screeninfo da8xx_fb_fix = {
.id = "DA8xx FB Drv",
--
1.7.0.4
^ permalink raw reply related
* [PATCH 03/23] video: da8xx-fb: use modedb helper to update var
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
modedb structure is now used to store panel information, run modedb
helper over it for initial update of "var" information instead of
equating each fields.
While at it, remove redundant update of bits_per_pixel.
Note: pixclock is overridden with proper value using an existing code
as currently modedb is having it in Hz instead of ps, this would be
fixed in a later change and this overide would be removed.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 18 ++----------------
1 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 52977b1..a1f6544 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1329,6 +1329,8 @@ static int fb_probe(struct platform_device *device)
par->panel_power_ctrl(1);
}
+ fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
+
if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
dev_err(&device->dev, "lcd_init failed\n");
ret = -EFAULT;
@@ -1381,25 +1383,9 @@ static int fb_probe(struct platform_device *device)
goto err_release_pl_mem;
}
- /* Initialize par */
- da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
-
- da8xx_fb_var.xres = lcdc_info->xres;
- da8xx_fb_var.xres_virtual = lcdc_info->xres;
-
- da8xx_fb_var.yres = lcdc_info->yres;
- da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
-
da8xx_fb_var.grayscale lcd_cfg->panel_shade = MONOCHROME ? 1 : 0;
da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
-
- da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
- da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
- da8xx_fb_var.right_margin = lcdc_info->right_margin;
- da8xx_fb_var.left_margin = lcdc_info->left_margin;
- da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
- da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
--
1.7.0.4
^ permalink raw reply related
* [PATCH 02/23] video: da8xx-fb: simplify lcd_reset
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
lcd_reset function doesn't require any arguement, remove it.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index d00dd17..52977b1 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -681,7 +681,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
}
#undef CNVT_TOHW
-static void lcd_reset(struct da8xx_fb_par *par)
+static void da8xx_fb_lcd_reset(void)
{
/* Disable the Raster if previously Enabled */
lcd_disable_raster(false);
@@ -721,7 +721,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
u32 bpp;
int ret = 0;
- lcd_reset(par);
+ da8xx_fb_lcd_reset();
/* Calculate the divider */
lcd_calc_clk_divider(par);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 01/23] video: da8xx-fb: fb_check_var enhancement
From: Darren Etheridge @ 2013-06-25 14:22 UTC (permalink / raw)
To: linux-fbdev
From: Afzal Mohammed <afzal@ti.com>
Check whether "struct fb_var_screeninfo" fields are sane, if not
update it to be within allowed limits.
If user sends down buggy "var" values, this will bring those within
allowable limits. And fb_set_par is not supposed to change "var"
values, fb_check_var has to ensure that values are proper.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
drivers/video/da8xx-fb.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0810939..d00dd17 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -888,6 +888,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int err = 0;
+ struct da8xx_fb_par *par = info->par;
+ int bpp = var->bits_per_pixel >> 3;
+ unsigned long line_size = var->xres_virtual * bpp;
if (var->bits_per_pixel > 16 && lcd_revision = LCD_VERSION_1)
return -EINVAL;
@@ -955,6 +958,21 @@ static int fb_check_var(struct fb_var_screeninfo *var,
var->green.msb_right = 0;
var->blue.msb_right = 0;
var->transp.msb_right = 0;
+
+ if (line_size * var->yres_virtual > par->vram_size)
+ var->yres_virtual = par->vram_size / line_size;
+
+ if (var->yres > var->yres_virtual)
+ var->yres = var->yres_virtual;
+
+ if (var->xres > var->xres_virtual)
+ var->xres = var->xres_virtual;
+
+ if (var->xres + var->xoffset > var->xres_virtual)
+ var->xoffset = var->xres_virtual - var->xres;
+ if (var->yres + var->yoffset > var->yres_virtual)
+ var->yoffset = var->yres_virtual - var->yres;
+
return err;
}
--
1.7.0.4
^ permalink raw reply related
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