* Re: [patch] OMAPDSS: reading past end of array in dispc_dump_regs()
From: Dan Carpenter @ 2012-12-17 12:39 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Archit Taneja, Florian Tobias Schandinat, Chandrabhanu Mahapatra,
linux-omap, linux-fbdev, kernel-janitors
In-Reply-To: <50CF0B5C.9080707@ti.com>
On Mon, Dec 17, 2012 at 02:09:00PM +0200, Tomi Valkeinen wrote:
> Why does the static checker think OMAP_DSS_WB is needed in the array?
drivers/video/omap2/dss/dispc.c +3284
3274 #define DISPC_REG(plane, name, i) name(plane, i)
3275 #define DUMPREG(plane, name, i) \
3276 seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \
3277 (int)(46 - strlen(#name) - strlen(p_names[plane])), " ", \
3278 dispc_read_reg(DISPC_REG(plane, name, i)))
3279
3280 /* Video pipeline coefficient registers */
3281
3282 /* start from OMAP_DSS_VIDEO1 */
3283 for (i = 1; i < dss_feat_get_num_ovls(); i++) {
3284 for (j = 0; j < 8; j++)
3285 DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
The logic here is that we pass i to DISPC_OVL_FIR_COEF_H() which
passes i to DISPC_FIR_COEF_H_OFFSET(). Anything higher than
OMAP_DSS_WB will trigger a BUG() in DISPC_FIR_COEF_H_OFFSET().
So it's not rock hard logic at all.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH V2 2/6] OMAPDSS: DISPC: Move DISPC specific dss_reg_fields to dispc_features
From: Tomi Valkeinen @ 2012-12-17 12:37 UTC (permalink / raw)
To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev
In-Reply-To: <08d6240ab26427a9e437421c2cc76ade29036817.1354702077.git.cmahapatra@ti.com>
[-- Attachment #1: Type: text/plain, Size: 10254 bytes --]
On 2012-12-05 12:16, Chandrabhanu Mahapatra wrote:
> The register fields in dss_reg_fields specific to DISPC are moved from struct
> omap_dss_features to corresponding dispc_reg_fields, initialized in struct
> dispc_features, thereby enabling local access.
>
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
> drivers/video/omap2/dss/dispc.c | 114 ++++++++++++++++++++++++--------
> drivers/video/omap2/dss/dss.h | 4 ++
> drivers/video/omap2/dss/dss_features.c | 28 --------
> drivers/video/omap2/dss/dss_features.h | 7 --
> 4 files changed, 89 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index bbba83f..ee4b152 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -80,6 +80,16 @@ struct dispc_irq_stats {
> unsigned irqs[32];
> };
>
> +struct dispc_reg_fields {
> + struct omapdss_reg_field firhinc;
> + struct omapdss_reg_field firvinc;
> + struct omapdss_reg_field fifo_low_thresh;
> + struct omapdss_reg_field fifo_high_thresh;
> + struct omapdss_reg_field fifosize;
> + struct omapdss_reg_field hori_accu;
> + struct omapdss_reg_field vert_accu;
> +};
> +
> struct dispc_features {
> u8 sw_start;
> u8 fp_start;
> @@ -110,6 +120,8 @@ struct dispc_features {
>
> u32 buffer_size_unit; /* in bytes */
> u32 burst_size_unit; /* in bytes */
> +
> + struct dispc_reg_fields *reg_fields;
This can be pointer to const.
> };
>
> #define DISPC_MAX_NR_FIFOS 5
> @@ -1137,17 +1149,17 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
>
> static void dispc_init_fifos(void)
> {
> - u32 size;
> + u32 size, unit;
> int fifo;
> - u8 start, end;
> - u32 unit;
> + const struct omapdss_reg_field *fifo_field;
>
> unit = dispc.feat->buffer_size_unit;
>
> - dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
> + fifo_field = &dispc.feat->reg_fields->fifosize;
>
> for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
> - size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
> + size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo),
> + fifo_field->start, fifo_field->end);
> size *= unit;
> dispc.fifo_size[fifo] = size;
>
> @@ -1197,8 +1209,8 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
>
> void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
> {
> - u8 hi_start, hi_end, lo_start, lo_end;
> u32 unit;
> + const struct omapdss_reg_field *hi_field, *lo_field;
>
> unit = dispc.feat->buffer_size_unit;
>
> @@ -1208,20 +1220,20 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
> 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);
> + hi_field = &dispc.feat->reg_fields->fifo_high_thresh;
> + lo_field = &dispc.feat->reg_fields->fifo_low_thresh;
>
> DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
> plane,
> REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
> - lo_start, lo_end) * unit,
> + lo_field->start, lo_field->end) * unit,
> REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
> - hi_start, hi_end) * unit,
> + hi_field->start, hi_field->end) * unit,
> low * unit, high * unit);
>
> dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
> - FLD_VAL(high, hi_start, hi_end) |
> - FLD_VAL(low, lo_start, lo_end));
> + FLD_VAL(high, hi_field->start, hi_field->end) |
> + FLD_VAL(low, lo_field->start, lo_field->end));
> }
>
> void dispc_enable_fifomerge(bool enable)
> @@ -1289,14 +1301,13 @@ static void dispc_ovl_set_fir(enum omap_plane plane,
> u32 val;
>
> if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
> - u8 hinc_start, hinc_end, vinc_start, vinc_end;
> + const struct omapdss_reg_field *hinc_field, *vinc_field;
>
> - dss_feat_get_reg_field(FEAT_REG_FIRHINC,
> - &hinc_start, &hinc_end);
> - dss_feat_get_reg_field(FEAT_REG_FIRVINC,
> - &vinc_start, &vinc_end);
> - val = FLD_VAL(vinc, vinc_start, vinc_end) |
> - FLD_VAL(hinc, hinc_start, hinc_end);
> + hinc_field = &dispc.feat->reg_fields->firhinc;
> + vinc_field = &dispc.feat->reg_fields->firvinc;
> +
> + val = FLD_VAL(vinc, vinc_field->start, vinc_field->end) |
> + FLD_VAL(hinc, hinc_field->start, hinc_field->end);
>
> dispc_write_reg(DISPC_OVL_FIR(plane), val);
> } else {
> @@ -1308,13 +1319,13 @@ static void dispc_ovl_set_fir(enum omap_plane plane,
> static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
> {
> u32 val;
> - u8 hor_start, hor_end, vert_start, vert_end;
> + const struct omapdss_reg_field *haccu_field, *vaccu_field;
>
> - dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
> - dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
> + haccu_field = &dispc.feat->reg_fields->hori_accu;
> + vaccu_field = &dispc.feat->reg_fields->vert_accu;
>
> - val = FLD_VAL(vaccu, vert_start, vert_end) |
> - FLD_VAL(haccu, hor_start, hor_end);
> + val = FLD_VAL(vaccu, vaccu_field->start, vaccu_field->end) |
> + FLD_VAL(haccu, haccu_field->start, haccu_field->end);
>
> dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
> }
> @@ -1322,13 +1333,13 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
> static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
> {
> u32 val;
> - u8 hor_start, hor_end, vert_start, vert_end;
> + const struct omapdss_reg_field *haccu_field, *vaccu_field;
>
> - dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
> - dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
> + haccu_field = &dispc.feat->reg_fields->hori_accu;
> + vaccu_field = &dispc.feat->reg_fields->vert_accu;
>
> - val = FLD_VAL(vaccu, vert_start, vert_end) |
> - FLD_VAL(haccu, hor_start, hor_end);
> + val = FLD_VAL(vaccu, vaccu_field->start, vaccu_field->end) |
> + FLD_VAL(haccu, haccu_field->start, haccu_field->end);
>
> dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
> }
> @@ -4048,6 +4059,46 @@ static void _omap_dispc_initial_config(void)
> dispc_ovl_enable_zorder_planes();
> }
>
> +static struct dispc_reg_fields omap2_dispc_reg_fields = {
> + .firhinc = { 11, 0 },
> + .firvinc = { 27, 16 },
> + .fifo_low_thresh = { 8, 0 },
> + .fifo_high_thresh = { 24, 16 },
> + .fifosize = { 8, 0 },
> + .hori_accu = { 9, 0 },
> + .vert_accu = { 25, 16 },
> +};
And these tables can be consts.
> +static struct dispc_reg_fields omap3_dispc_reg_fields = {
> + .firhinc = { 12, 0 },
> + .firvinc = { 28, 16 },
> + .fifo_low_thresh = { 11, 0 },
> + .fifo_high_thresh = { 27, 16 },
> + .fifosize = { 10, 0 },
> + .hori_accu = { 9, 0 },
> + .vert_accu = { 25, 16 },
> +};
> +
> +static struct dispc_reg_fields omap4_dispc_reg_fields = {
> + .firhinc = { 12, 0 },
> + .firvinc = { 28, 16 },
> + .fifo_low_thresh = { 15, 0 },
> + .fifo_high_thresh = { 31, 16 },
> + .fifosize = { 15, 0 },
> + .hori_accu = { 10, 0 },
> + .vert_accu = { 26, 16 },
> +};
> +
> +static struct dispc_reg_fields omap5_dispc_reg_fields = {
> + .firhinc = { 12, 0 },
> + .firvinc = { 28, 16 },
> + .fifo_low_thresh = { 15, 0 },
> + .fifo_high_thresh = { 31, 16 },
> + .fifosize = { 15, 0 },
> + .hori_accu = { 10, 0 },
> + .vert_accu = { 26, 16 },
> +};
> +
> static const struct dispc_features omap24xx_dispc_feats __initconst = {
> .sw_start = 5,
> .fp_start = 15,
> @@ -4065,6 +4116,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
> .no_framedone_tv = true,
> .buffer_size_unit = 1,
> .burst_size_unit = 8,
> + .reg_fields = &omap2_dispc_reg_fields,
> };
>
> static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
> @@ -4084,6 +4136,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
> .no_framedone_tv = true,
> .buffer_size_unit = 1,
> .burst_size_unit = 8,
> + .reg_fields = &omap3_dispc_reg_fields,
> };
>
> static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
> @@ -4103,6 +4156,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
> .no_framedone_tv = true,
> .buffer_size_unit = 1,
> .burst_size_unit = 8,
> + .reg_fields = &omap3_dispc_reg_fields,
> };
>
> static const struct dispc_features omap44xx_dispc_feats __initconst = {
> @@ -4122,6 +4176,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
> .gfx_fifo_workaround = true,
> .buffer_size_unit = 16,
> .burst_size_unit = 16,
> + .reg_fields = &omap4_dispc_reg_fields,
> };
>
> static const struct dispc_features omap54xx_dispc_feats __initconst = {
> @@ -4141,6 +4196,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
> .gfx_fifo_workaround = true,
> .buffer_size_unit = 16,
> .burst_size_unit = 16,
> + .reg_fields = &omap5_dispc_reg_fields,
> };
There's one thing to note here (and the same applies to DSI patches).
The *_dispc_feats tables above are __initconst, and we make a copy of
the needed table at probe time, so that the unneeded tables can be
discarded. Now you add new tables, but they are not handled the same
way. This is not a bug, but it's a bit inconsistent.
So I think we have three options:
- Make the new tables also __initconst, and create a copy of the needed
tables, and fix up the pointers to point to the copied tables.
- Embed the new tables into the *_dispc_feats table, as you suggested
previously. This would mean multiple copies of the same data in some cases.
- Remove the __initconst and the copy code.
I'm not sure which one to pick. The first one feels a bit complex, but
perhaps it should be tried first to see how the actual code would look
like. If it's just a few lines per table, I guess it's ok.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* Re: [PATCH V2 4/6] OMAPDSS: DSI: Move DSI specific reg_fields to dsi_feats
From: Tomi Valkeinen @ 2012-12-17 12:23 UTC (permalink / raw)
To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev
In-Reply-To: <55965d940f45ecaf56f5145d7dcc8c28e4c9586f.1354702077.git.cmahapatra@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1561 bytes --]
Hi,
On 2012-12-05 12:16, Chandrabhanu Mahapatra wrote:
> The DSI specific dss_reg_fields are moved to corresponding dsi_reg_fields
> initialized in dsi_feats. The dsi_feats structure is initialized as per
> corresponding DSS version in dsi_init_features().
>
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
> drivers/video/omap2/dss/dsi.c | 126 +++++++++++++++++++++++++++++---
> drivers/video/omap2/dss/dss_features.c | 16 ----
> drivers/video/omap2/dss/dss_features.h | 4 -
> 3 files changed, 114 insertions(+), 32 deletions(-)
>
> +static int __init dsi_init_features(struct platform_device *dsidev)
> +{
> + const struct feats *src;
> + struct feats *dst;
> +
> + dst = devm_kzalloc(&dsidev->dev, sizeof(*dst), GFP_KERNEL);
> + if (!dst) {
> + dev_err(&dsidev->dev, "Failed to allocate DISPC Features\n");
> + return -ENOMEM;
> + }
> +
> + switch (omapdss_get_version()) {
> + case OMAPDSS_VER_OMAP24xx:
> + src = &omap24xx_dsi_feats;
> + break;
> +
> + case OMAPDSS_VER_OMAP34xx_ES1:
> + case OMAPDSS_VER_OMAP34xx_ES3:
> + case OMAPDSS_VER_OMAP3630:
> + case OMAPDSS_VER_AM35xx:
> + src = &omap34xx_dsi_feats;
> + break;
> +
> + case OMAPDSS_VER_OMAP4430_ES1:
> + case OMAPDSS_VER_OMAP4430_ES2:
> + case OMAPDSS_VER_OMAP4:
> + src = &omap44xx_dsi_feats;
> + break;
> +
> + case OMAPDSS_VER_OMAP5:
> + src = &omap54xx_dsi_feats;
> + break;
> +
> + default:
> + return -ENODEV;
> + }
There's no DSI on OMAP2, so that case can be left out.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* Re: [patch] OMAPDSS: reading past end of array in dispc_dump_regs()
From: Tomi Valkeinen @ 2012-12-17 12:09 UTC (permalink / raw)
To: Dan Carpenter, Archit Taneja
Cc: Florian Tobias Schandinat, Chandrabhanu Mahapatra, linux-omap,
linux-fbdev, kernel-janitors
In-Reply-To: <20121214150133.GB15839@elgon.mountain>
[-- Attachment #1: Type: text/plain, Size: 1183 bytes --]
On 2012-12-14 17:01, Dan Carpenter wrote:
> We added another kind of plane in 66a0f9e4ac "OMAPDSS: Use WB fifo for
> GFX overlay" so this array needs a new entry as well.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> Static checker work. I don't have a way to test this.
>
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index fedbd2c..bfe62cc 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -3163,6 +3163,7 @@ static void dispc_dump_regs(struct seq_file *s)
> [OMAP_DSS_VIDEO1] = "VID1",
> [OMAP_DSS_VIDEO2] = "VID2",
> [OMAP_DSS_VIDEO3] = "VID3",
> + [OMAP_DSS_WB] = "WB",
> };
> const char **p_names;
>
>
We don't count WB as an overlay currently, as it's handled a bit
differently, so we never try to access that array with OMAP_DSS_WB. We
don't actually dump any WB related registers currently, it seems.
So I think I'll leave this out for now.
Why does the static checker think OMAP_DSS_WB is needed in the array? I
wonder if I'm reading the code wrong, and we indeed do access the array
with OMAP_DSS_WB...
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* [PATCH 2/2] smscufx: fix EDID parsing on big-endian systems
From: Steve Glendinning @ 2012-12-17 11:24 UTC (permalink / raw)
To: linux-fbdev
This patch allows smscufx to correctly detect the resolution of a
connected monitor on big-endian systems.
Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
---
drivers/video/smscufx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 8009400..bdf7d36 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -1465,8 +1465,9 @@ static int ufx_read_edid(struct ufx_data *dev, u8 *edid, int edid_len)
for (j = 0; j < 16; j++) {
u32 data_reg_addr = 0x1110 + (j * 4);
- status = ufx_reg_read(dev, data_reg_addr, edid_u32++);
+ status = ufx_reg_read(dev, data_reg_addr, &temp);
check_warn_return(status, "Error reading i2c data");
+ *edid_u32++ = cpu_to_le32(temp);
}
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/2] smscufx: ensure framebuffer is byte-swapped to LE
From: Steve Glendinning @ 2012-12-17 11:24 UTC (permalink / raw)
To: linux-fbdev
This patch fixes the smscufx driver on big endian platforms, by
ensuring the framebuffer is correctly byte-swapped before sending
to the device.
Register and control words were already correctly swapped, so
without this patch the device "works" but with obviously incorrect
RGB values displayed on the output device.
This is implemented as an ifdef so platforms that don't require
byte swapping can use the faster memcpy method.
Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
---
drivers/video/smscufx.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 97bd662..8009400 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -840,8 +840,16 @@ static void ufx_raw_rect(struct ufx_data *dev, u16 *cmd, int x, int y,
for (line = 0; line < height; line++) {
const int line_offset = dev->info->fix.line_length * (y + line);
const int byte_offset = line_offset + (x * BPP);
- memcpy(&cmd[(24 + (packed_line_len * line)) / 2],
- (char *)dev->info->fix.smem_start + byte_offset, width * BPP);
+ const int cmd_base = (24 + (packed_line_len * line)) / 2;
+ const u16 *source = (u16 *)((char *)dev->info->fix.smem_start + byte_offset);
+ u16 *dest = (u16 *)(&cmd[cmd_base]);
+#ifdef __BIG_ENDIAN
+ int pixel;
+ for (pixel = 0; pixel < width; pixel++)
+ dest[pixel] = cpu_to_le16(source[pixel]);
+#else /* __BIG_ENDIAN */
+ memcpy(dest, source, width * BPP);
+#endif /* __BIG_ENDIAN */
}
}
--
1.7.10.4
^ permalink raw reply related
* Re: [GIT PULL] fbdev changes for 3.8
From: Felipe Balbi @ 2012-12-17 10:05 UTC (permalink / raw)
To: Tony Lindgren
Cc: Dave Jones, Linus Torvalds, Tomi Valkeinen, linux-omap,
linux-fbdev, linux-kernel, Florian Tobias Schandinat,
Dmitry Torokhov, Felipe Balbi, Evgeniy Polyakov, Arnd Bergmann
In-Reply-To: <20121216203536.GR4989@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 4094 bytes --]
Hi,
On Sun, Dec 16, 2012 at 12:35:37PM -0800, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [121216 09:49]:
> > * Dave Jones <davej@redhat.com> [121215 14:27]:
> > > On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> > > > On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > > > > Hi Linus,
> > > > >
> > > > > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > > > > the pull request for fbdev for this merge window.
> > > >
> > > > Pulled. However, with this I get the Kconfig question
> > > >
> > > > OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
> > > >
> > > > which doesn't make a whole lot of sense on x86-64, unless there's
> > > > something about OMAP2 that I don't know.
> > > >
> > > > So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> > > > least ARM. Because showing it to anybody else seems insane.
> > > >
> > > > Same goes for FB_OMAP2 for that matter. I realize that it's likely
> > > > nice to get compile testing for this on x86-64 too, but if that's the
> > > > intent, we need to think about it some more. I don't think it's good
> > > > to ask actual normal users questions like this just for compile
> > > > coverage.
> > >
> > > This OMAP stuff has been creeping into x86 builds for a while.
> > > Grep from my current build config ..
> > >
> > > # CONFIG_OMAP_OCP2SCP is not set
> > > # CONFIG_KEYBOARD_OMAP4 is not set
> > > # CONFIG_OMAP2_DSS is not set
> > > # CONFIG_OMAP_USB2 is not set
> > >
> > > There was some other arm-ism that does the same that I' currently forgetting,
> > > or maybe that got fixed..
> >
> > Those are all omap internal devices and should be all marked with
> > depends on ARCH_OMAP2PLUS.
> >
> > It's a different story for external devices that may be used on other
> > architectures.
> >
> > I only came up with one reason to compile internal devices for other
> > architectures: In some cases the driver subsystem maintainer may want to
> > be able to compile test subsystem wide changes without having to compile
> > for each target separately. But for those cases it's trivial to carry a
> > compile test patch that just drops the depends Kconfig entries.
>
> And here's a patch to limit the omap drivers above to omap only.
>
> Regards,
>
> Tony
>
>
> From: Tony Lindgren <tony@atomide.com>
> Date: Sun, 16 Dec 2012 12:28:46 -0800
> Subject: [PATCH] ARM: OMAP: Fix drivers to depend on omap for internal devices
>
> These devices are not available on other architectures, so
> let's limit them to omap.
>
> If the driver subsystem maintainers want to build test
> system wide changes without building for each target,
> it's easy to carry a test patch that just strips out the
> depends entries from Kconfig files.
>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
>
> --- a/drivers/bus/Kconfig
> +++ b/drivers/bus/Kconfig
> @@ -6,6 +6,7 @@ menu "Bus devices"
>
> config OMAP_OCP2SCP
> tristate "OMAP OCP2SCP DRIVER"
> + depends on ARCH_OMAP2PLUS
> help
> Driver to enable ocp2scp module which transforms ocp interface
> protocol to scp protocol. In OMAP4, USB PHY is connected via
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -544,6 +544,7 @@ config KEYBOARD_OMAP
>
> config KEYBOARD_OMAP4
> tristate "TI OMAP4+ keypad support"
> + depends on ARCH_OMAP2PLUS
> select INPUT_MATRIXKMAP
> help
> Say Y here if you want to use the OMAP4+ keypad.
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -6,6 +6,7 @@ comment "USB Physical Layer drivers"
>
> config OMAP_USB2
> tristate "OMAP USB2 PHY Driver"
> + depends on ARCH_OMAP2PLUS
> select USB_OTG_UTILS
> help
> Enable this to support the transceiver that is part of SOC. This
for Keypad, PHY and OCP2SCP I would rather not as I want to use
linux-next for compile testing our stuff in all arches.
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Tomi Valkeinen @ 2012-12-17 9:03 UTC (permalink / raw)
To: Tony Lindgren
Cc: Dave Jones, Linus Torvalds, linux-omap, linux-fbdev, linux-kernel,
Florian Tobias Schandinat, Dmitry Torokhov, Felipe Balbi,
Evgeniy Polyakov, Arnd Bergmann
In-Reply-To: <20121216203536.GR4989@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 1072 bytes --]
On 2012-12-16 22:35, Tony Lindgren wrote:
>> Those are all omap internal devices and should be all marked with
>> depends on ARCH_OMAP2PLUS.
>>
>> It's a different story for external devices that may be used on other
>> architectures.
>>
>> I only came up with one reason to compile internal devices for other
>> architectures: In some cases the driver subsystem maintainer may want to
>> be able to compile test subsystem wide changes without having to compile
>> for each target separately. But for those cases it's trivial to carry a
>> compile test patch that just drops the depends Kconfig entries.
>
> And here's a patch to limit the omap drivers above to omap only.
The patch looks good to me.
The reason I removed the OMAP dependency from OMAP DSS was not (only)
because of the compile testing, but also because I thought it was right:
a driver for an IP block shouldn't presume that the IP is used only on
particular SoC.
But perhaps that's a bit too academic approach for an IP that's in real
world only used for OMAP.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* [PATCH v2 RESEND] video console: add a driver for lcd2s character display
From: Lars Poeschel @ 2012-12-17 8:34 UTC (permalink / raw)
To: Arnd Bergmann, FlorianSchandinat
Cc: mathieu.poirier, linux-fbdev, linux-kernel
From: Lars Poeschel <poeschel@lemonage.de>
This driver allows to use a lcd2s 20x4 character display as
a linux console output device.
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
drivers/video/console/Kconfig | 10 ++
drivers/video/console/Makefile | 1 +
drivers/video/console/lcd2scon.c | 360 ++++++++++++++++++++++++++++++++++++++
3 files changed, 371 insertions(+)
create mode 100644 drivers/video/console/lcd2scon.c
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index e2c96d0..44fc3bf 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -129,6 +129,16 @@ config STI_CONSOLE
machines. Say Y here to build support for it into your kernel.
The alternative is to use your primary serial port as a console.
+config LCD2S_CONSOLE
+ tristate "lcd2s 20x4 character display over I2C console"
+ depends on I2C
+ default n
+ help
+ This is a driver that lets you use the lcd2s 20x4 character display
+ from modtronix engineering as a console output device. The display
+ is a simple single color character display. You have to connect it
+ to an I2C bus.
+
config FONTS
bool "Select compiled-in fonts"
depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index a862e91..74d5993 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -23,6 +23,7 @@ font-objs += $(font-objs-y)
obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
+obj-$(CONFIG_LCD2S_CONSOLE) += lcd2scon.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
diff --git a/drivers/video/console/lcd2scon.c b/drivers/video/console/lcd2scon.c
new file mode 100644
index 0000000..c139811
--- /dev/null
+++ b/drivers/video/console/lcd2scon.c
@@ -0,0 +1,360 @@
+/*
+ * console driver for LCD2S 4x20 character displays connected through i2c.
+ *
+ * This is a driver allowing you to use a LCD2S 4x20 from modtronix
+ * engineering as console output device.
+ *
+ * (C) 2012 by Lemonage Software GmbH
+ * Author: Lars Poeschel <poeschel@lemonage.de>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/console_struct.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include <linux/i2c.h>
+
+#define LCD2S_CMD_CUR_BLINK_OFF 0x10
+#define LCD2S_CMD_CUR_UL_OFF 0x11
+#define LCD2S_CMD_DISPLAY_OFF 0x12
+#define LCD2S_CMD_CUR_BLINK_ON 0x18
+#define LCD2S_CMD_CUR_UL_ON 0x19
+#define LCD2S_CMD_DISPLAY_ON 0x1a
+#define LCD2S_CMD_BACKLIGHT_OFF 0x20
+#define LCD2S_CMD_BACKLIGHT_ON 0x28
+#define LCD2S_CMD_WRITE 0x80
+#define LCD2S_CMD_SHIFT_UP 0x87
+#define LCD2S_CMD_SHIFT_DOWN 0x88
+#define LCD2S_CMD_CUR_ADDR 0x89
+#define LCD2S_CMD_CUR_POS 0x8a
+#define LCD2S_CMD_CUR_RESET 0x8b
+#define LCD2S_CMD_CLEAR 0x8c
+
+#define LCD2S_FIRST 8
+#define LCD2S_LAST 9
+
+#define LCD2S_ROWS 4
+#define LCD2S_COLS 20
+
+struct lcd2s_data {
+ struct i2c_client *i2c;
+ int row;
+ int col;
+ unsigned int cur_blink:1;
+ unsigned int cur_ul:1;
+};
+
+static struct lcd2s_data lcd2s;
+
+static void lcd2s_set_cursor(int row, int col)
+{
+ u8 buf[] = { LCD2S_CMD_CUR_POS, row + 1, col + 1};
+
+ if (row = lcd2s.row && col = lcd2s.col)
+ return;
+
+ i2c_master_send(lcd2s.i2c, buf, sizeof(buf));
+ lcd2s.row = row;
+ lcd2s.col = col;
+}
+
+static void lcd2s_reset_cursor(void)
+{
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CUR_RESET);
+ lcd2s.row = 0;
+ lcd2s.col = 0;
+}
+
+static void lcd2s_increase_cursor(struct vc_data *con, int inc)
+{
+ lcd2s.col += inc;
+ if ((lcd2s.col / con->vc_cols) >= 1) {
+ lcd2s.row += (lcd2s.col / con->vc_cols);
+ lcd2s.col %= con->vc_cols;
+ }
+}
+
+static void lcd2s_cursor_ul_on(void)
+{
+ if (!lcd2s.cur_ul) {
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CUR_UL_ON);
+ lcd2s.cur_ul = 1;
+ }
+}
+
+static void lcd2s_cursor_ul_off(void)
+{
+ if (lcd2s.cur_ul) {
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CUR_UL_OFF);
+ lcd2s.cur_ul = 0;
+ }
+}
+
+static void lcd2s_cursor_blink_on(void)
+{
+ if (!lcd2s.cur_blink) {
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CUR_BLINK_ON);
+ lcd2s.cur_blink = 1;
+ }
+}
+
+static void lcd2s_cursor_blink_off(void)
+{
+ if (lcd2s.cur_blink) {
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CUR_BLINK_OFF);
+ lcd2s.cur_blink = 0;
+ }
+}
+
+static const char *lcd2s_startup(void)
+{
+ return "lcd2s console";
+}
+
+
+/*
+ * init is set if console is currently allocated during init
+ */
+static void lcd2s_init(struct vc_data *con, int init)
+{
+ lcd2s.cur_blink = 0;
+ lcd2s.cur_ul = 0;
+
+ /* turn display on */
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_DISPLAY_ON);
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_BACKLIGHT_ON);
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CLEAR);
+ lcd2s_cursor_ul_on();
+ lcd2s_reset_cursor();
+
+ con->vc_can_do_color = 0;
+ con->vc_hi_font_mask = 0;
+
+ if (init) {
+ con->vc_rows = LCD2S_ROWS;
+ con->vc_cols = LCD2S_COLS;
+ } else
+ vc_resize(con, LCD2S_COLS, LCD2S_ROWS);
+}
+
+static void lcd2s_deinit(struct vc_data *con)
+{
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_DISPLAY_OFF);
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_BACKLIGHT_OFF);
+ lcd2s_cursor_blink_off();
+ lcd2s_cursor_ul_off();
+}
+
+static void lcd2s_clear(struct vc_data *con, int s_row, int s_col,
+ int height, int width)
+{
+ u8 buf[width];
+ int i;
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ /* if the whole display is to clear, we have a single command */
+ if (s_col = 0 && s_row = 0 &&
+ height >= con->vc_rows - 1 && width >= con->vc_cols - 1) {
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_CLEAR);
+ return;
+ }
+
+ for (i = 0; i <= width; i++)
+ buf[i] = ' ';
+
+ for (i = s_col; i <= height; i++) {
+ lcd2s_set_cursor(s_row, i);
+ i2c_master_send(lcd2s.i2c, buf, width);
+ }
+}
+
+static void lcd2s_putc(struct vc_data *con, int data, int row, int col)
+{
+ u8 buf[] = {LCD2S_CMD_WRITE, data};
+
+ lcd2s_set_cursor(row, col);
+
+ i2c_master_send(lcd2s.i2c, buf, sizeof(buf));
+ lcd2s_increase_cursor(con, 1);
+}
+
+static void lcd2s_putcs(struct vc_data *con, const unsigned short *buf,
+ int len, int row, int col)
+{
+ u8 *i2c_buf;
+ int i;
+
+ i2c_buf = kzalloc(len + 1, GFP_KERNEL);
+ if (!i2c_buf)
+ return;
+
+ lcd2s_set_cursor(row, col);
+
+ i2c_buf[0] = LCD2S_CMD_WRITE;
+ for (i = 0; i < len ; i++)
+ i2c_buf[i + 1] = buf[i];
+
+ i2c_master_send(lcd2s.i2c, i2c_buf, len + 1);
+ kfree(i2c_buf);
+ lcd2s_increase_cursor(con, len);
+}
+
+static void lcd2s_cursor(struct vc_data *con, int mode)
+{
+ switch (mode) {
+ case CM_ERASE:
+ lcd2s_cursor_blink_off();
+ lcd2s_cursor_ul_off();
+ break;
+ case CM_MOVE:
+ case CM_DRAW:
+ lcd2s_set_cursor(con->vc_y, con->vc_x);
+
+ switch (con->vc_cursor_type & CUR_HWMASK) {
+ case CUR_UNDERLINE:
+ lcd2s_cursor_ul_on();
+ lcd2s_cursor_blink_off();
+ break;
+ case CUR_NONE:
+ lcd2s_cursor_blink_off();
+ lcd2s_cursor_ul_off();
+ break;
+ default:
+ lcd2s_cursor_blink_on();
+ lcd2s_cursor_ul_off();
+ break;
+ }
+ break;
+ }
+}
+
+static int lcd2s_scroll(struct vc_data *con, int top, int bot,
+ int dir, int lines)
+{
+ /* we can only scroll the whole display */
+ if (top = 0 && bot = con->vc_rows) {
+ while (lines--) {
+ switch (dir) {
+ case SM_UP:
+ i2c_smbus_write_byte(lcd2s.i2c,
+ LCD2S_CMD_SHIFT_UP);
+ break;
+ case SM_DOWN:
+ i2c_smbus_write_byte(lcd2s.i2c,
+ LCD2S_CMD_SHIFT_DOWN);
+ break;
+ }
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static void lcd2s_bmove(struct vc_data *conp, int s_row, int s_col,
+ int d_row, int d_col, int height, int width)
+{
+}
+
+static int lcd2s_switch(struct vc_data *con)
+{
+ return 1;
+}
+
+static int lcd2s_blank(struct vc_data *con, int blank, int mode_switch)
+{
+ switch (blank) {
+ case 0: /* unblank */
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_DISPLAY_ON);
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_BACKLIGHT_ON);
+ break;
+ case 1: /* normal blanking */
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_DISPLAY_OFF);
+ i2c_smbus_write_byte(lcd2s.i2c, LCD2S_CMD_BACKLIGHT_OFF);
+ break;
+ }
+ return 0;
+}
+
+static int lcd2s_set_palette(struct vc_data *con, unsigned char *table)
+{
+ return -EINVAL;
+}
+
+static int lcd2s_scrolldelta(struct vc_data *con, int lines)
+{
+ return 0;
+}
+
+static struct consw lcd2s_con = {
+ .owner = THIS_MODULE,
+ .con_startup = lcd2s_startup,
+ .con_init = lcd2s_init,
+ .con_deinit = lcd2s_deinit,
+ .con_clear = lcd2s_clear,
+ .con_putc = lcd2s_putc,
+ .con_putcs = lcd2s_putcs,
+ .con_cursor = lcd2s_cursor,
+ .con_scroll = lcd2s_scroll,
+ .con_bmove = lcd2s_bmove,
+ .con_switch = lcd2s_switch,
+ .con_blank = lcd2s_blank,
+ .con_set_palette = lcd2s_set_palette,
+ .con_scrolldelta = lcd2s_scrolldelta,
+};
+
+static int __devinit lcd2s_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ if (!i2c_check_functionality(i2c->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
+ return -EIO;
+
+ lcd2s.i2c = i2c;
+
+ take_over_console(&lcd2s_con, LCD2S_FIRST, LCD2S_LAST, 1);
+
+ return 0;
+}
+
+static __devexit int lcd2s_i2c_remove(struct i2c_client *i2c)
+{
+ /* unregister from console subsystem */
+ unregister_con_driver(&lcd2s_con);
+ return 0;
+}
+
+static const struct i2c_device_id lcd2s_i2c_id[] = {
+ { "lcd2s", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lcd2s_i2c_id);
+
+static struct i2c_driver lcd2s_i2c_driver = {
+ .driver = {
+ .name = "lcd2s",
+ .owner = THIS_MODULE,
+ },
+ .probe = lcd2s_i2c_probe,
+ .remove = __devexit_p(lcd2s_i2c_remove),
+ .id_table = lcd2s_i2c_id,
+};
+
+module_i2c_driver(lcd2s_i2c_driver)
+
+MODULE_DESCRIPTION("LCD2S character display console driver");
+MODULE_AUTHOR("Lars Poeschel");
+MODULE_LICENSE("GPL");
--
1.7.10.4
^ permalink raw reply related
* Re: [GIT PULL] fbdev changes for 3.8
From: Dmitry Torokhov @ 2012-12-17 6:00 UTC (permalink / raw)
To: Tony Lindgren
Cc: Dave Jones, Linus Torvalds, Tomi Valkeinen, linux-omap,
linux-fbdev, linux-kernel, Florian Tobias Schandinat,
Felipe Balbi, Evgeniy Polyakov, Arnd Bergmann
In-Reply-To: <20121216203536.GR4989@atomide.com>
On Sun, Dec 16, 2012 at 12:35:37PM -0800, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [121216 09:49]:
> > * Dave Jones <davej@redhat.com> [121215 14:27]:
> > > On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> > > > On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > > > > Hi Linus,
> > > > >
> > > > > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > > > > the pull request for fbdev for this merge window.
> > > >
> > > > Pulled. However, with this I get the Kconfig question
> > > >
> > > > OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
> > > >
> > > > which doesn't make a whole lot of sense on x86-64, unless there's
> > > > something about OMAP2 that I don't know.
> > > >
> > > > So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> > > > least ARM. Because showing it to anybody else seems insane.
> > > >
> > > > Same goes for FB_OMAP2 for that matter. I realize that it's likely
> > > > nice to get compile testing for this on x86-64 too, but if that's the
> > > > intent, we need to think about it some more. I don't think it's good
> > > > to ask actual normal users questions like this just for compile
> > > > coverage.
> > >
> > > This OMAP stuff has been creeping into x86 builds for a while.
> > > Grep from my current build config ..
> > >
> > > # CONFIG_OMAP_OCP2SCP is not set
> > > # CONFIG_KEYBOARD_OMAP4 is not set
> > > # CONFIG_OMAP2_DSS is not set
> > > # CONFIG_OMAP_USB2 is not set
> > >
> > > There was some other arm-ism that does the same that I' currently forgetting,
> > > or maybe that got fixed..
> >
> > Those are all omap internal devices and should be all marked with
> > depends on ARCH_OMAP2PLUS.
> >
> > It's a different story for external devices that may be used on other
> > architectures.
> >
> > I only came up with one reason to compile internal devices for other
> > architectures: In some cases the driver subsystem maintainer may want to
> > be able to compile test subsystem wide changes without having to compile
> > for each target separately. But for those cases it's trivial to carry a
> > compile test patch that just drops the depends Kconfig entries.
>
> And here's a patch to limit the omap drivers above to omap only.
Do you think we could add a new symbol to debug options, something like
COMPILE_COVERAGE, and have drivers that can be compiled on platforms
other than ones having the hardware to do
depend on ARCH_XXX || COMPILE_CONVERAGE
This way people who want to do compile coverage do not have to carry
patches and allyesconfig will pick this right up.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] video: exynos_mipi_dsi: Add missing mutex_unlock
From: Donghwa Lee @ 2012-12-17 1:31 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <000801cdd9d5$a9536a10$fbfa3e30$%choi@samsung.com>
On Fri, Dec 14, 2012 at 17:33, Jonghwan Choi wrote:
> Add a mutex_unlock on the error path.
>
> Signed-off-by: Jonghwan Choi<jhbird.choi@samsung.com>
> ---
> drivers/video/exynos/exynos_mipi_dsi_common.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c
> b/drivers/video/exynos/exynos_mipi_dsi_common.c
> index 3cd29a4..bd7f4f2 100644
> --- a/drivers/video/exynos/exynos_mipi_dsi_common.c
> +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
> @@ -377,6 +377,7 @@ int exynos_mipi_dsi_rd_data(struct mipi_dsim_device
> *dsim, unsigned int data_id,
> "data id %x is not supported current DSI spec.\n",
> data_id);
>
> + mutex_unlock(&dsim->lock);
> return -EINVAL;
> }
>
It looks good to me.
Acked-by: Donghwa Lee <dh09.lee@samsung.com>
Thank you,
Donghwa Lee
^ permalink raw reply
* Re: [PATCH 1/1] video: exynos: Use devm_* APIs in s6e8ax0.c
From: Donghwa Lee @ 2012-12-17 0:36 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1355289083-28269-1-git-send-email-sachin.kamat@linaro.org>
On Wed, Dec 12, 2012 at 14:11, Sachin Kamat wrote:
> devm_* APIs are device managed and make error handling
> and code cleanup simpler.
>
> Cc: Donghwa Lee <dh09.lee@samsung.com>
> Cc: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
> Compile tested against linux-next.
> ---
> drivers/video/exynos/s6e8ax0.c | 14 ++++----------
> 1 files changed, 4 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
> index 05d080b..ca26024 100644
> --- a/drivers/video/exynos/s6e8ax0.c
> +++ b/drivers/video/exynos/s6e8ax0.c
> @@ -776,7 +776,7 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
> int ret;
> u8 mtp_id[3] = {0, };
>
> - lcd = kzalloc(sizeof(struct s6e8ax0), GFP_KERNEL);
> + lcd = devm_kzalloc(&dsim_dev->dev, sizeof(struct s6e8ax0), GFP_KERNEL);
> if (!lcd) {
> dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
> return -ENOMEM;
> @@ -788,18 +788,17 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
>
> mutex_init(&lcd->lock);
>
> - ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
> + ret = devm_regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
> if (ret) {
> dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
> - goto err_lcd_register;
> + return ret;
> }
>
> lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
> &s6e8ax0_lcd_ops);
> if (IS_ERR(lcd->ld)) {
> dev_err(lcd->dev, "failed to register lcd ops.\n");
> - ret = PTR_ERR(lcd->ld);
> - goto err_lcd_register;
> + return PTR_ERR(lcd->ld);
> }
>
> lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
> @@ -838,11 +837,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
>
> err_backlight_register:
> lcd_device_unregister(lcd->ld);
> -
> -err_lcd_register:
> - regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
> - kfree(lcd);
> -
> return ret;
> }
>
It looks good to me.
Acked-by: Donghwa Lee <dh09.lee@samsung.com>
Thank you,
Donghwa Lee
^ permalink raw reply
* Re: [PATCHv4 1/9] video: mmp display subsystem
From: Haojian Zhuang @ 2012-12-16 23:47 UTC (permalink / raw)
To: linux-fbdev
On Wed, Oct 24, 2012 at 2:56 PM, Zhou Zhu <zzhu3@marvell.com> wrote:
> Added mmp display subsystem to support Marvell MMP display controllers.
>
> This subsystem contains 4 parts:
> --fb folder
> --core.c
> --hw folder
> --panel folder
>
> 1. fb folder contains implementation of fb.
> fb get path and ovly from common interface and operates on these structures.
>
> 2. core.c provides common interface for a hardware abstraction.
> Major parts of this interface are:
> a) Path: path is a output device connected to a panel or HDMI TV.
> Main operations of the path is set/get timing/output color.
> fb operates output device through path structure.
> b) Ovly: Ovly is a buffer shown on the path.
> Ovly describes frame buffer and its source/destination size, offset, input
> color, buffer address, z-order, and so on.
> Each fb device maps to one ovly.
>
> 3. hw folder contains implementation of hardware operations defined by core.c.
> It registers paths for fb use.
>
> 4. panel folder contains implementation of panels.
> It's connected to path. Panel drivers would also regiester panels and linked
> to path when probe.
>
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Lisa Du <cldu@marvell.com>
> ---
> drivers/video/Kconfig | 1 +
> drivers/video/Makefile | 1 +
> drivers/video/mmp/Kconfig | 5 +
> drivers/video/mmp/Makefile | 1 +
> drivers/video/mmp/core.c | 217 +++++++++++++++++++++++++++
> include/video/mmp_disp.h | 351 ++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 576 insertions(+), 0 deletions(-)
> create mode 100644 drivers/video/mmp/Kconfig
> create mode 100644 drivers/video/mmp/Makefile
> create mode 100644 drivers/video/mmp/core.c
> create mode 100644 include/video/mmp_disp.h
>
Hi Florian,
This patch series have been sent for a long time. And there's no
comments on this.
I need this patch series on enabling LCD on pxa910 platform. Do you
think it's OK to merge?
Best Regards
Haojian
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Tony Lindgren @ 2012-12-16 20:35 UTC (permalink / raw)
To: Dave Jones, Linus Torvalds, Tomi Valkeinen, linux-omap,
linux-fbdev, linux-kernel, Florian Tobias Schandinat
Cc: Dmitry Torokhov, Felipe Balbi, Evgeniy Polyakov, Arnd Bergmann
In-Reply-To: <20121216174613.GA18490@atomide.com>
* Tony Lindgren <tony@atomide.com> [121216 09:49]:
> * Dave Jones <davej@redhat.com> [121215 14:27]:
> > On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> > > On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > > > Hi Linus,
> > > >
> > > > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > > > the pull request for fbdev for this merge window.
> > >
> > > Pulled. However, with this I get the Kconfig question
> > >
> > > OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
> > >
> > > which doesn't make a whole lot of sense on x86-64, unless there's
> > > something about OMAP2 that I don't know.
> > >
> > > So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> > > least ARM. Because showing it to anybody else seems insane.
> > >
> > > Same goes for FB_OMAP2 for that matter. I realize that it's likely
> > > nice to get compile testing for this on x86-64 too, but if that's the
> > > intent, we need to think about it some more. I don't think it's good
> > > to ask actual normal users questions like this just for compile
> > > coverage.
> >
> > This OMAP stuff has been creeping into x86 builds for a while.
> > Grep from my current build config ..
> >
> > # CONFIG_OMAP_OCP2SCP is not set
> > # CONFIG_KEYBOARD_OMAP4 is not set
> > # CONFIG_OMAP2_DSS is not set
> > # CONFIG_OMAP_USB2 is not set
> >
> > There was some other arm-ism that does the same that I' currently forgetting,
> > or maybe that got fixed..
>
> Those are all omap internal devices and should be all marked with
> depends on ARCH_OMAP2PLUS.
>
> It's a different story for external devices that may be used on other
> architectures.
>
> I only came up with one reason to compile internal devices for other
> architectures: In some cases the driver subsystem maintainer may want to
> be able to compile test subsystem wide changes without having to compile
> for each target separately. But for those cases it's trivial to carry a
> compile test patch that just drops the depends Kconfig entries.
And here's a patch to limit the omap drivers above to omap only.
Regards,
Tony
From: Tony Lindgren <tony@atomide.com>
Date: Sun, 16 Dec 2012 12:28:46 -0800
Subject: [PATCH] ARM: OMAP: Fix drivers to depend on omap for internal devices
These devices are not available on other architectures, so
let's limit them to omap.
If the driver subsystem maintainers want to build test
system wide changes without building for each target,
it's easy to carry a test patch that just strips out the
depends entries from Kconfig files.
Signed-off-by: Tony Lindgren <tony@atomide.com>
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -6,6 +6,7 @@ menu "Bus devices"
config OMAP_OCP2SCP
tristate "OMAP OCP2SCP DRIVER"
+ depends on ARCH_OMAP2PLUS
help
Driver to enable ocp2scp module which transforms ocp interface
protocol to scp protocol. In OMAP4, USB PHY is connected via
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -544,6 +544,7 @@ config KEYBOARD_OMAP
config KEYBOARD_OMAP4
tristate "TI OMAP4+ keypad support"
+ depends on ARCH_OMAP2PLUS
select INPUT_MATRIXKMAP
help
Say Y here if you want to use the OMAP4+ keypad.
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -6,6 +6,7 @@ comment "USB Physical Layer drivers"
config OMAP_USB2
tristate "OMAP USB2 PHY Driver"
+ depends on ARCH_OMAP2PLUS
select USB_OTG_UTILS
help
Enable this to support the transceiver that is part of SOC. This
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -1,6 +1,10 @@
config OMAP2_VRFB
bool
+if ARCH_OMAP2PLUS
+
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/omapfb/Kconfig"
source "drivers/video/omap2/displays/Kconfig"
+
+endif
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -60,6 +60,7 @@ config W1_MASTER_GPIO
config HDQ_MASTER_OMAP
tristate "OMAP HDQ driver"
+ depends on ARCH_OMAP
help
Say Y here if you want support for the 1-wire or HDQ Interface
on an OMAP processor.
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Tony Lindgren @ 2012-12-16 17:46 UTC (permalink / raw)
To: Dave Jones, Linus Torvalds, Tomi Valkeinen, linux-omap,
linux-fbdev, linux-kernel, Florian Tobias Schandinat
In-Reply-To: <20121215222431.GA7153@redhat.com>
* Dave Jones <davej@redhat.com> [121215 14:27]:
> On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> > On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > > Hi Linus,
> > >
> > > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > > the pull request for fbdev for this merge window.
> >
> > Pulled. However, with this I get the Kconfig question
> >
> > OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
> >
> > which doesn't make a whole lot of sense on x86-64, unless there's
> > something about OMAP2 that I don't know.
> >
> > So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> > least ARM. Because showing it to anybody else seems insane.
> >
> > Same goes for FB_OMAP2 for that matter. I realize that it's likely
> > nice to get compile testing for this on x86-64 too, but if that's the
> > intent, we need to think about it some more. I don't think it's good
> > to ask actual normal users questions like this just for compile
> > coverage.
>
> This OMAP stuff has been creeping into x86 builds for a while.
> Grep from my current build config ..
>
> # CONFIG_OMAP_OCP2SCP is not set
> # CONFIG_KEYBOARD_OMAP4 is not set
> # CONFIG_OMAP2_DSS is not set
> # CONFIG_OMAP_USB2 is not set
>
> There was some other arm-ism that does the same that I' currently forgetting,
> or maybe that got fixed..
Those are all omap internal devices and should be all marked with
depends on ARCH_OMAP2PLUS.
It's a different story for external devices that may be used on other
architectures.
I only came up with one reason to compile internal devices for other
architectures: In some cases the driver subsystem maintainer may want to
be able to compile test subsystem wide changes without having to compile
for each target separately. But for those cases it's trivial to carry a
compile test patch that just drops the depends Kconfig entries.
Regards,
Tony
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Dave Jones @ 2012-12-15 22:24 UTC (permalink / raw)
To: Linus Torvalds
Cc: Tomi Valkeinen, linux-omap, linux-fbdev, linux-kernel,
Florian Tobias Schandinat
In-Reply-To: <CA+55aFz9+3mOZcjJ9C-izKkidT9mxeO7xUubJER0OTjcZjE=2A@mail.gmail.com>
On Sat, Dec 15, 2012 at 01:11:04PM -0800, Linus Torvalds wrote:
> On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > Hi Linus,
> >
> > Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> > the pull request for fbdev for this merge window.
>
> Pulled. However, with this I get the Kconfig question
>
> OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
>
> which doesn't make a whole lot of sense on x86-64, unless there's
> something about OMAP2 that I don't know.
>
> So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
> least ARM. Because showing it to anybody else seems insane.
>
> Same goes for FB_OMAP2 for that matter. I realize that it's likely
> nice to get compile testing for this on x86-64 too, but if that's the
> intent, we need to think about it some more. I don't think it's good
> to ask actual normal users questions like this just for compile
> coverage.
This OMAP stuff has been creeping into x86 builds for a while.
Grep from my current build config ..
# CONFIG_OMAP_OCP2SCP is not set
# CONFIG_KEYBOARD_OMAP4 is not set
# CONFIG_OMAP2_DSS is not set
# CONFIG_OMAP_USB2 is not set
There was some other arm-ism that does the same that I' currently forgetting,
or maybe that got fixed..
Dave
^ permalink raw reply
* Re: [GIT PULL] fbdev changes for 3.8
From: Linus Torvalds @ 2012-12-15 21:11 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: linux-omap, linux-fbdev, linux-kernel, Florian Tobias Schandinat
In-Reply-To: <50CAFDFF.3070802@ti.com>
On Fri, Dec 14, 2012 at 2:22 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> Hi Linus,
>
> Florian, the fbdev maintainer, has been very busy lately, so I offered to send
> the pull request for fbdev for this merge window.
Pulled. However, with this I get the Kconfig question
OMAP2+ Display Subsystem support (OMAP2_DSS) [N/m/y/?] (NEW)
which doesn't make a whole lot of sense on x86-64, unless there's
something about OMAP2 that I don't know.
So I'd suggest making that OMAP2_DSS be dependent on OMAP2. Or at
least ARM. Because showing it to anybody else seems insane.
Same goes for FB_OMAP2 for that matter. I realize that it's likely
nice to get compile testing for this on x86-64 too, but if that's the
intent, we need to think about it some more. I don't think it's good
to ask actual normal users questions like this just for compile
coverage.
Hmm?
Linus
^ permalink raw reply
* [PATCH] fbcon: clear the logo bitmap from the margin area
From: Kamal Mostafa @ 2012-12-14 20:30 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev, linux-kernel
Explicitly clear_margins when clearing the logo, in case the font dimensions
are non-integral to the framebuffer dimensions.
Signed-off-by: Kamal Mostafa <kamal@whence.com>
---
drivers/video/console/fbcon.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 8745637..b51a4bd 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -1236,8 +1236,16 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
if (!height || !width)
return;
- if (sy < vc->vc_top && vc->vc_top = logo_lines)
+ if (sy < vc->vc_top && vc->vc_top = logo_lines) {
vc->vc_top = 0;
+ /*
+ * If the font dimensions are not an integral of the display
+ * dimensions then the ops->clear below won't end up clearing
+ * the margins. Call clear_margins here in case the logo
+ * bitmap stretched into the margin area.
+ */
+ fbcon_clear_margins(vc, 0);
+ }
/* Split blits that cross physical y_wrap boundary */
--
1.7.10.4
^ permalink raw reply related
* [patch] OMAPDSS: reading past end of array in dispc_dump_regs()
From: Dan Carpenter @ 2012-12-14 15:01 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Florian Tobias Schandinat, Archit Taneja, Chandrabhanu Mahapatra,
linux-omap, linux-fbdev, kernel-janitors
We added another kind of plane in 66a0f9e4ac "OMAPDSS: Use WB fifo for
GFX overlay" so this array needs a new entry as well.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
Static checker work. I don't have a way to test this.
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fedbd2c..bfe62cc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3163,6 +3163,7 @@ static void dispc_dump_regs(struct seq_file *s)
[OMAP_DSS_VIDEO1] = "VID1",
[OMAP_DSS_VIDEO2] = "VID2",
[OMAP_DSS_VIDEO3] = "VID3",
+ [OMAP_DSS_WB] = "WB",
};
const char **p_names;
^ permalink raw reply related
* [RFC 6/6] video: add makefile & kconfig
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/Kconfig | 1 +
drivers/video/Makefile | 1 +
drivers/video/display/Kconfig | 26 ++++++++++++++++++++++++++
drivers/video/display/Makefile | 5 +++++
4 files changed, 33 insertions(+)
create mode 100644 drivers/video/display/Kconfig
create mode 100644 drivers/video/display/Makefile
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c5b7bcf..e91f03e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2442,6 +2442,7 @@ source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
source "drivers/video/exynos/Kconfig"
source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
if VT
source "drivers/video/console/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index b936b00..0a4cfea 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -14,6 +14,7 @@ fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
obj-y += backlight/
+obj-y += display/
obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 0000000..1d1a590
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,26 @@
+menuconfig DISPLAY_CORE
+ tristate "Display Core"
+ ---help---
+ Support common display framework for graphics devices.
+
+if DISPLAY_CORE
+
+config DISPLAY_PANEL_DPI
+ tristate "DPI (Parallel) Display Panels"
+ ---help---
+ Support for simple digital (parallel) pixel interface panels. Those
+ panels receive pixel data through a parallel bus and have no control
+ bus.
+
+ If you are in doubt, say N.
+
+config DISPLAY_PANEL_DVI
+ tristate "DVI Monitor"
+
+config DISPLAY_PANEL_TAAL
+ tristate "Taal DSI command mode panel"
+
+config DISPLAY_CHIP_TFP410
+ tristate "DPI to DVI chip"
+
+endif # DISPLAY_CORE
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 0000000..ac97dfd
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_DISPLAY_CORE) += display-core.o
+obj-$(CONFIG_DISPLAY_PANEL_DPI) += panel-dpi.o
+obj-$(CONFIG_DISPLAY_PANEL_DVI) += panel-dvi.o
+obj-$(CONFIG_DISPLAY_PANEL_TAAL) += panel-taal.o
+obj-$(CONFIG_DISPLAY_CHIP_TFP410) += chip-tfp410.o
--
1.7.10.4
^ permalink raw reply related
* [RFC 5/6] video: add taal panel
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/display/panel-taal.c | 383 ++++++++++++++++++++++++++++++++++
include/video/omap-panel-nokia-dsi.h | 4 +-
2 files changed, 385 insertions(+), 2 deletions(-)
create mode 100644 drivers/video/display/panel-taal.c
diff --git a/drivers/video/display/panel-taal.c b/drivers/video/display/panel-taal.c
new file mode 100644
index 0000000..f1c2196
--- /dev/null
+++ b/drivers/video/display/panel-taal.c
@@ -0,0 +1,383 @@
+/*
+ * Taal DSI command mode panel
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DEBUG
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/videomode.h>
+
+#include <video/omapdss.h>
+#include <video/display.h>
+#include <video/omap-panel-nokia-dsi.h>
+#include <video/mipi_display.h>
+
+/* DSI Virtual channel. Hardcoded for now. */
+#define TCH 0
+
+#define DCS_READ_NUM_ERRORS 0x05
+#define DCS_BRIGHTNESS 0x51
+#define DCS_CTRL_DISPLAY 0x53
+#define DCS_WRITE_CABC 0x55
+#define DCS_READ_CABC 0x56
+#define DCS_GET_ID1 0xda
+#define DCS_GET_ID2 0xdb
+#define DCS_GET_ID3 0xdc
+
+struct taal_data {
+ struct platform_device *pdev;
+ struct video_source *src;
+ struct display_entity entity;
+
+ struct mutex lock;
+
+ unsigned long hw_guard_end; /* next value of jiffies when we can
+ * issue the next sleep in/out command
+ */
+ unsigned long hw_guard_wait; /* max guard time in jiffies */
+
+ /* panel HW configuration from DT or platform data */
+ int reset_gpio;
+
+ /* runtime variables */
+ bool enabled;
+
+ bool te_enabled;
+
+ int channel;
+
+ bool cabc_broken;
+ unsigned cabc_mode;
+
+ bool intro_printed;
+};
+
+static void hw_guard_start(struct taal_data *td, int guard_msec)
+{
+ td->hw_guard_wait = msecs_to_jiffies(guard_msec);
+ td->hw_guard_end = jiffies + td->hw_guard_wait;
+}
+
+static void hw_guard_wait(struct taal_data *td)
+{
+ unsigned long wait = td->hw_guard_end - jiffies;
+
+ if ((long)wait > 0 && wait <= td->hw_guard_wait) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(wait);
+ }
+}
+
+static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
+{
+ int r;
+ u8 buf[1];
+ struct video_source *src = td->src;
+
+ r = src->ops.dsi->dcs_read(src, td->channel, dcs_cmd, buf, 1);
+ if (r < 0)
+ return r;
+
+ *data = buf[0];
+
+ return 0;
+}
+
+static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
+{
+ struct video_source *src = td->src;
+
+ return src->ops.dsi->dcs_write(src, td->channel, &dcs_cmd, 1);
+}
+
+static int taal_sleep_out(struct taal_data *td)
+{
+ int r;
+
+ hw_guard_wait(td);
+
+ r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
+ if (r)
+ return r;
+
+ hw_guard_start(td, 120);
+
+ msleep(5);
+
+ return 0;
+}
+
+static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
+{
+ int r;
+
+ r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
+ if (r)
+ return r;
+ r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
+ if (r)
+ return r;
+ r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void taal_hw_reset(struct taal_data *td)
+{
+ if (!gpio_is_valid(td->reset_gpio))
+ return;
+
+ gpio_set_value(td->reset_gpio, 1);
+ udelay(10);
+ /* reset the panel */
+ gpio_set_value(td->reset_gpio, 0);
+ /* assert reset */
+ udelay(10);
+ gpio_set_value(td->reset_gpio, 1);
+ /* wait after releasing reset */
+ msleep(5);
+}
+
+#define to_panel(p) container_of(p, struct taal_data, entity)
+
+static int taal_set_state(struct display_entity *entity,
+ enum display_entity_state state)
+{
+ struct taal_data *td = to_panel(entity);
+ struct video_source *src = td->src;
+ int r;
+
+ switch (state) {
+ case DISPLAY_ENTITY_STATE_OFF:
+ case DISPLAY_ENTITY_STATE_STANDBY:
+ r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
+ if (r)
+ printk("display off failed\n");
+
+ src->ops.dsi->disable(src);
+
+ break;
+
+ case DISPLAY_ENTITY_STATE_ON:
+ r = src->ops.dsi->enable(src);
+ if (r)
+ printk("failed to enable bus\n");
+
+ taal_hw_reset(td);
+
+ r = taal_sleep_out(td);
+ if (r)
+ printk("sleep out failed\n");
+
+ src->ops.dsi->enable_hs(src, true);
+
+
+ r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
+ if (r)
+ printk("display on failed\n");
+ break;
+ }
+
+ return 0;
+}
+
+static const struct videomode taal_mode = {
+ .hactive = 864,
+ .vactive = 480,
+};
+
+static int taal_get_modes(struct display_entity *entity,
+ const struct videomode **modes)
+{
+ //struct panel_data *data = to_panel(entity);
+
+ *modes = &taal_mode;
+ return 1;
+}
+
+static int taal_get_size(struct display_entity *entity,
+ unsigned int *width, unsigned int *height)
+{
+ //struct panel_data *data = to_panel(entity);
+
+ *width = 10;
+ *height = 10;
+ return 0;
+}
+
+static int taal_update(struct display_entity *entity,
+ void (*callback)(int, void *), void *data)
+{
+ struct taal_data *td = to_panel(entity);
+ struct video_source *src = td->src;
+
+ return src->ops.dsi->update(src, td->channel, callback, data);
+}
+
+static const struct display_entity_control_ops taal_control_ops = {
+ .set_state = taal_set_state,
+ .get_modes = taal_get_modes,
+ .get_size = taal_get_size,
+ .update = taal_update,
+};
+
+static void panel_taal_release(struct display_entity *entity)
+{
+ printk("panel taal release\n");
+}
+
+static int taal_probe(struct platform_device *pdev)
+{
+ const struct nokia_dsi_panel_data *pdata = pdev->dev.platform_data;
+ struct taal_data *td;
+ int r;
+ u8 id1, id2, id3;
+ struct video_source *src;
+
+ dev_dbg(&pdev->dev, "probe\n");
+
+ td = devm_kzalloc(&pdev->dev, sizeof(*td), GFP_KERNEL);
+ if (!td)
+ return -ENOMEM;
+
+ td->pdev = pdev;
+
+
+ td->reset_gpio = pdata->reset_gpio;
+
+ platform_set_drvdata(pdev, td);
+
+ mutex_init(&td->lock);
+
+ if (gpio_is_valid(td->reset_gpio)) {
+ r = devm_gpio_request_one(&pdev->dev, td->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "taal rst");
+ if (r) {
+ dev_err(&pdev->dev, "failed to request reset gpio\n");
+ return r;
+ }
+ }
+
+
+ /* setup input */
+ src = video_source_find(pdata->video_source);
+ if (src = NULL) {
+ printk("failed to get video source\n");
+ return -EINVAL;
+ }
+
+ td->src = src;
+
+ r = src->ops.dsi->configure_pins(src, &pdata->pin_config);
+ if (r)
+ dev_err(&pdev->dev, "failed to configure DSI pins\n");
+
+ r = src->ops.dsi->set_clocks(src, 216000000, 10000000);
+ if (r)
+ dev_err(&pdev->dev, "failed to set HS and LP clocks\n");
+
+ src->ops.dsi->set_size(src, 864, 480);
+ src->ops.dsi->set_pixel_format(src, OMAP_DSS_DSI_FMT_RGB888);
+ src->ops.dsi->set_operation_mode(src, OMAP_DSS_DSI_CMD_MODE);
+
+ /* setup panel entity */
+
+ td->entity.dev = &pdev->dev;
+ td->entity.release = panel_taal_release;
+ td->entity.ops = &taal_control_ops;
+
+ r = display_entity_register(&td->entity);
+ if (r < 0) {
+ printk("failed to register display entity\n");
+ return r;
+ }
+
+ /* show version */
+
+ r = src->ops.dsi->enable(src);
+ if (r)
+ dev_err(&pdev->dev, "failed to enable bus\n");
+
+ taal_hw_reset(td);
+
+ r = taal_get_id(td, &id1, &id2, &id3);
+ if (r)
+ return r;
+
+ dev_info(&pdev->dev, "panel revision %02x.%02x.%02x\n", id1, id2, id3);
+
+ src->ops.dsi->disable(src);
+
+
+ return 0;
+#if 0
+ r = omap_dsi_request_vc(dssdev, &td->channel);
+ if (r) {
+ dev_err(&pdev->dev, "failed to get virtual channel\n");
+ goto err_req_vc;
+ }
+
+ r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
+ if (r) {
+ dev_err(&pdev->dev, "failed to set VC_ID\n");
+ goto err_vc_id;
+ }
+#endif
+}
+
+static int taal_remove(struct platform_device *pdev)
+{
+ struct taal_data *td = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "remove\n");
+
+ display_entity_unregister(&td->entity);
+
+ video_source_put(td->src);
+
+ /* reset, to be sure that the panel is in a valid state */
+ taal_hw_reset(td);
+
+#if 0
+ omap_dsi_release_vc(dssdev, td->channel);
+#endif
+ return 0;
+}
+
+static struct platform_driver taal_driver = {
+ .probe = taal_probe,
+ .remove = taal_remove,
+ .driver = {
+ .name = "taal",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(taal_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("Taal Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/video/omap-panel-nokia-dsi.h b/include/video/omap-panel-nokia-dsi.h
index 225a841..fe274a5 100644
--- a/include/video/omap-panel-nokia-dsi.h
+++ b/include/video/omap-panel-nokia-dsi.h
@@ -14,6 +14,8 @@ struct omap_dss_device;
* @pin_config: DSI pin configuration
*/
struct nokia_dsi_panel_data {
+ const char *video_source;
+
const char *name;
int reset_gpio;
@@ -27,8 +29,6 @@ struct nokia_dsi_panel_data {
bool use_dsi_backlight;
struct omap_dsi_pin_config pin_config;
-
- void *video_source;
};
#endif /* __OMAP_NOKIA_DSI_PANEL_H */
--
1.7.10.4
^ permalink raw reply related
* [RFC 4/6] video: add generic dvi monitor
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/display/panel-dvi.c | 164 +++++++++++++++++++++++++++++++++++++
include/video/panel-dvi.h | 18 ++++
2 files changed, 182 insertions(+)
create mode 100644 drivers/video/display/panel-dvi.c
create mode 100644 include/video/panel-dvi.h
diff --git a/drivers/video/display/panel-dvi.c b/drivers/video/display/panel-dvi.c
new file mode 100644
index 0000000..01cea09
--- /dev/null
+++ b/drivers/video/display/panel-dvi.c
@@ -0,0 +1,164 @@
+/*
+ * Generic DVI monitor
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * Contacts: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * 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/module.h>
+#include <linux/platform_device.h>
+
+#include <video/display.h>
+#include <video/panel-dvi.h>
+
+struct panel_data {
+ struct display_entity entity;
+ struct video_source *in;
+};
+
+#define to_panel(p) container_of(p, struct panel_data, entity)
+
+static int panel_dvi_set_state(struct display_entity *entity,
+ enum display_entity_state state)
+{
+ struct panel_data *data = to_panel(entity);
+ struct video_source *in = data->in;
+
+ switch (state) {
+ case DISPLAY_ENTITY_STATE_OFF:
+ case DISPLAY_ENTITY_STATE_STANDBY:
+ in->common_ops->set_stream(in, DISPLAY_ENTITY_STREAM_STOPPED);
+ break;
+
+ case DISPLAY_ENTITY_STATE_ON:
+ in->common_ops->set_stream(in, DISPLAY_ENTITY_STREAM_CONTINUOUS);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct videomode vga_mode = {
+ .pixelclock = 23500,
+
+ .hactive = 640,
+ .hfront_porch = 48,
+ .hback_porch = 80,
+ .hsync_len = 32,
+
+ .vactive = 480,
+ .vfront_porch = 3,
+ .vback_porch = 7,
+ .vsync_len = 4,
+
+ .hah = true,
+ .vah = true,
+ .de = true,
+};
+
+static int panel_dvi_get_modes(struct display_entity *entity,
+ const struct videomode **modes)
+{
+ //struct panel_data *data = to_panel(entity);
+
+ *modes = &vga_mode;
+ return 1;
+}
+
+static int panel_dvi_get_size(struct display_entity *entity,
+ unsigned int *width, unsigned int *height)
+{
+ //struct panel_data *data = to_panel(entity);
+
+ *width = 10;
+ *height = 10;
+ return 0;
+}
+
+static const struct display_entity_control_ops panel_dvi_control_ops = {
+ .set_state = panel_dvi_set_state,
+ .get_modes = panel_dvi_get_modes,
+ .get_size = panel_dvi_get_size,
+};
+
+static void panel_dvi_release(struct display_entity *entity)
+{
+ printk("panel dvi release\n");
+}
+
+static int __devinit panel_dvi_probe(struct platform_device *pdev)
+{
+ const struct panel_dvi_platform_data *pdata = pdev->dev.platform_data;
+ struct panel_data *data;
+ int ret;
+
+ if (pdata = NULL)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (data = NULL)
+ return -ENOMEM;
+
+ /* setup input */
+ data->in = video_source_find(pdata->video_source);
+ if (data->in = NULL) {
+ printk("failed to get video source\n");
+ return -EINVAL;
+ }
+
+ /* setup default mode */
+ data->in->ops.dvi->set_videomode(data->in, &vga_mode);
+
+ /* setup panel entity */
+
+ data->entity.dev = &pdev->dev;
+ data->entity.release = panel_dvi_release;
+ data->entity.ops = &panel_dvi_control_ops;
+
+ ret = display_entity_register(&data->entity);
+ if (ret < 0) {
+ video_source_put(data->in);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int panel_dvi_remove(struct platform_device *pdev)
+{
+ struct panel_data *data = platform_get_drvdata(pdev);
+
+ display_entity_unregister(&data->entity);
+
+ video_source_put(data->in);
+
+ return 0;
+}
+
+
+static const struct dev_pm_ops panel_dvi_dev_pm_ops = {
+};
+
+static struct platform_driver panel_dvi_driver = {
+ .probe = panel_dvi_probe,
+ .remove = panel_dvi_remove,
+ .driver = {
+ .name = "panel_dvi",
+ .owner = THIS_MODULE,
+ .pm = &panel_dvi_dev_pm_ops,
+ },
+};
+
+module_platform_driver(panel_dvi_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("DVI Monitor");
+MODULE_LICENSE("GPL");
diff --git a/include/video/panel-dvi.h b/include/video/panel-dvi.h
new file mode 100644
index 0000000..ab88380
--- /dev/null
+++ b/include/video/panel-dvi.h
@@ -0,0 +1,18 @@
+/*
+ * DVI Display Panel
+ *
+ * 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 __PANEL_DVI_H__
+#define __PANEL_DVI_H__
+
+#include <linux/videomode.h>
+
+struct panel_dvi_platform_data {
+ const char *video_source;
+};
+
+#endif /* __PANEL_DVI_H__ */
--
1.7.10.4
^ permalink raw reply related
* [RFC 3/6] video: add tfp410
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/display/chip-tfp410.c | 164 +++++++++++++++++++++++++++++++++++
include/video/omap-panel-tfp410.h | 4 +
2 files changed, 168 insertions(+)
create mode 100644 drivers/video/display/chip-tfp410.c
diff --git a/drivers/video/display/chip-tfp410.c b/drivers/video/display/chip-tfp410.c
new file mode 100644
index 0000000..2f8bdb6
--- /dev/null
+++ b/drivers/video/display/chip-tfp410.c
@@ -0,0 +1,164 @@
+/*
+ * TFP410 DPI-to-DVI bridge
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * Contacts: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * 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/module.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <video/display.h>
+#include <video/omap-panel-tfp410.h>
+
+struct tfp410_data {
+ struct video_source *in;
+
+ struct video_source out;
+
+ int power_down_gpio;
+};
+
+#define to_tfp410(p) container_of(p, struct tfp410_data, out)
+
+static int tfp410_set_stream(struct video_source *src,
+ enum video_source_stream_state state)
+{
+ struct tfp410_data *data = to_tfp410(src);
+ struct video_source *in = data->in;
+ int r;
+
+ r = in->common_ops->set_stream(in, state);
+ if (r)
+ return r;
+
+ switch (state) {
+ case DISPLAY_ENTITY_STREAM_STOPPED:
+ printk("tfp410 set_stream: STOPPED\n");
+
+ gpio_set_value_cansleep(data->power_down_gpio, 0);
+
+ break;
+
+ case DISPLAY_ENTITY_STREAM_CONTINUOUS:
+ printk("tfp410 set_stream: CONTINUOUS\n");
+
+ gpio_set_value_cansleep(data->power_down_gpio, 1);
+
+ break;
+
+ default:
+ printk("tfp410 set_stream error\n");
+ break;
+ }
+
+ return 0;
+}
+
+static int tfp410_set_vm(struct video_source *src, const struct videomode *vm)
+{
+ struct tfp410_data *data = to_tfp410(src);
+ struct video_source *in = data->in;
+
+ printk("tfp410 set vm\n");
+
+ return in->ops.dpi->set_videomode(in, vm);
+}
+
+static const struct common_video_source_ops tfp410_common_ops = {
+ .set_stream = tfp410_set_stream,
+};
+
+static const struct dvi_video_source_ops tfp410_dvi_ops = {
+ .set_videomode = tfp410_set_vm,
+};
+
+static void tfp410_release(struct video_source *src)
+{
+ printk("tfp410 entity release\n");
+}
+
+static int __devinit tfp410_probe(struct platform_device *pdev)
+{
+ const struct tfp410_platform_data *pdata = pdev->dev.platform_data;
+ struct tfp410_data *data;
+ int r;
+
+ if (pdata = NULL)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (data = NULL)
+ return -ENOMEM;
+
+ data->power_down_gpio = pdata->power_down_gpio;
+
+ r = devm_gpio_request_one(&pdev->dev, pdata->power_down_gpio,
+ GPIOF_OUT_INIT_LOW, "tfp410 pd");
+ if (r) {
+ printk("failed to request pd gpio\n");
+ return r;
+ }
+
+ /* setup input */
+
+ data->in = video_source_find(pdata->video_source);
+ if (data->in = NULL) {
+ printk("failed to get video source\n");
+ return -EINVAL;
+ }
+
+ data->in->ops.dpi->set_data_lines(data->in, 24);
+
+ /* setup output */
+
+ data->out.dev = &pdev->dev;
+ data->out.release = tfp410_release;
+ data->out.common_ops = &tfp410_common_ops;
+ data->out.ops.dvi = &tfp410_dvi_ops;
+ data->out.name = pdata->video_output;
+
+ r = video_source_register(&data->out);
+ if (r < 0) {
+ printk("tfp410 entity register failed\n");
+ video_source_put(data->in);
+ return r;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int tfp410_remove(struct platform_device *pdev)
+{
+ struct tfp410_data *data = platform_get_drvdata(pdev);
+
+ video_source_unregister(&data->out);
+
+ video_source_put(data->in);
+
+ return 0;
+}
+
+static struct platform_driver tfp410_driver = {
+ .probe = tfp410_probe,
+ .remove = tfp410_remove,
+ .driver = {
+ .name = "tfp410",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(tfp410_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("TFP410 DPI-to-DVI Bridge");
+MODULE_LICENSE("GPL");
diff --git a/include/video/omap-panel-tfp410.h b/include/video/omap-panel-tfp410.h
index b5b05f4..18f2b46 100644
--- a/include/video/omap-panel-tfp410.h
+++ b/include/video/omap-panel-tfp410.h
@@ -30,6 +30,10 @@ struct omap_dss_device;
*/
struct tfp410_platform_data {
const char *name;
+
+ const char *video_source;
+ const char *video_output;
+
u16 i2c_bus_num;
int power_down_gpio;
};
--
1.7.10.4
^ permalink raw reply related
* [RFC 2/6] video: add generic dpi panel
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/display/panel-dpi.c | 155 +++++++++++++++++++++++++++++++++++++
include/video/panel-dpi.h | 25 ++++++
2 files changed, 180 insertions(+)
create mode 100644 drivers/video/display/panel-dpi.c
create mode 100644 include/video/panel-dpi.h
diff --git a/drivers/video/display/panel-dpi.c b/drivers/video/display/panel-dpi.c
new file mode 100644
index 0000000..824cd88
--- /dev/null
+++ b/drivers/video/display/panel-dpi.c
@@ -0,0 +1,155 @@
+/*
+ * DPI Display Panel
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/display.h>
+#include <video/panel-dpi.h>
+
+struct panel_dpi {
+ struct display_entity entity;
+ struct video_source *src;
+ const struct panel_dpi_platform_data *pdata;
+};
+
+#define to_panel_dpi(p) container_of(p, struct panel_dpi, entity)
+
+static int panel_dpi_set_state(struct display_entity *entity,
+ enum display_entity_state state)
+{
+ struct panel_dpi *panel = to_panel_dpi(entity);
+ struct video_source *src = panel->src;
+
+ switch (state) {
+ case DISPLAY_ENTITY_STATE_OFF:
+ case DISPLAY_ENTITY_STATE_STANDBY:
+ src->common_ops->set_stream(src,
+ DISPLAY_ENTITY_STREAM_STOPPED);
+ break;
+
+ case DISPLAY_ENTITY_STATE_ON:
+ src->common_ops->set_stream(src,
+ DISPLAY_ENTITY_STREAM_CONTINUOUS);
+ break;
+ }
+
+ return 0;
+}
+
+static int panel_dpi_get_modes(struct display_entity *entity,
+ const struct videomode **modes)
+{
+ struct panel_dpi *panel = to_panel_dpi(entity);
+
+ *modes = panel->pdata->mode;
+ return 1;
+}
+
+static int panel_dpi_get_size(struct display_entity *entity,
+ unsigned int *width, unsigned int *height)
+{
+ struct panel_dpi *panel = to_panel_dpi(entity);
+
+ *width = panel->pdata->width;
+ *height = panel->pdata->height;
+ return 0;
+}
+
+static const struct display_entity_control_ops panel_dpi_control_ops = {
+ .set_state = panel_dpi_set_state,
+ .get_modes = panel_dpi_get_modes,
+ .get_size = panel_dpi_get_size,
+};
+
+static void panel_dpi_release(struct display_entity *entity)
+{
+ struct panel_dpi *panel = to_panel_dpi(entity);
+
+ kfree(panel);
+}
+
+static int panel_dpi_remove(struct platform_device *pdev)
+{
+ struct panel_dpi *panel = platform_get_drvdata(pdev);
+
+ display_entity_unregister(&panel->entity);
+
+ if (panel->src) {
+ video_source_put(panel->src);
+ panel->src = NULL;
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static int __devinit panel_dpi_probe(struct platform_device *pdev)
+{
+ const struct panel_dpi_platform_data *pdata = pdev->dev.platform_data;
+ struct panel_dpi *panel;
+ int ret;
+
+ if (pdata = NULL)
+ return -ENODEV;
+
+ panel = kzalloc(sizeof(*panel), GFP_KERNEL);
+ if (panel = NULL)
+ return -ENOMEM;
+
+ panel->pdata = pdata;
+
+ panel->src = video_source_find(pdata->video_source);
+ if (panel->src = NULL) {
+ printk("failed to get video source\n");
+ return -EINVAL;
+ }
+
+ panel->src->ops.dpi->set_data_lines(panel->src, 24);
+ panel->src->ops.dpi->set_videomode(panel->src, pdata->mode);
+
+ panel->entity.dev = &pdev->dev;
+ panel->entity.release = panel_dpi_release;
+ panel->entity.ops = &panel_dpi_control_ops;
+
+ ret = display_entity_register(&panel->entity);
+ if (ret < 0) {
+ kfree(panel);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, panel);
+
+ return 0;
+}
+
+static const struct dev_pm_ops panel_dpi_dev_pm_ops = {
+};
+
+static struct platform_driver panel_dpi_driver = {
+ .probe = panel_dpi_probe,
+ .remove = panel_dpi_remove,
+ .driver = {
+ .name = "panel_dpi",
+ .owner = THIS_MODULE,
+ .pm = &panel_dpi_dev_pm_ops,
+ },
+};
+
+module_platform_driver(panel_dpi_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("DPI Display Panel");
+MODULE_LICENSE("GPL");
diff --git a/include/video/panel-dpi.h b/include/video/panel-dpi.h
new file mode 100644
index 0000000..0c5856e
--- /dev/null
+++ b/include/video/panel-dpi.h
@@ -0,0 +1,25 @@
+/*
+ * DPI Display Panel
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * 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 __PANEL_DPI_H__
+#define __PANEL_DPI_H__
+
+#include <linux/videomode.h>
+
+struct panel_dpi_platform_data {
+ const char *video_source;
+ unsigned long width; /* Panel width in mm */
+ unsigned long height; /* Panel height in mm */
+ const struct videomode *mode;
+};
+
+#endif /* __PANEL_DPI_H__ */
--
1.7.10.4
^ permalink raw reply related
* [RFC 1/6] video: add display-core
From: Tomi Valkeinen @ 2012-12-14 14:27 UTC (permalink / raw)
To: Laurent Pinchart, linux-fbdev, dri-devel; +Cc: Tomi Valkeinen
In-Reply-To: <1355495252-26364-1-git-send-email-tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/display/display-core.c | 207 ++++++++++++++++++++++++++++++++++
include/video/display.h | 166 +++++++++++++++++++++++++++
2 files changed, 373 insertions(+)
create mode 100644 drivers/video/display/display-core.c
create mode 100644 include/video/display.h
diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
new file mode 100644
index 0000000..5f8be30
--- /dev/null
+++ b/drivers/video/display/display-core.c
@@ -0,0 +1,207 @@
+/*
+ * Display Core
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * 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/export.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/videomode.h>
+
+#include <video/display.h>
+
+/* -----------------------------------------------------------------------------
+ * Display Entity
+ */
+
+static LIST_HEAD(display_entity_list);
+static DEFINE_MUTEX(display_entity_mutex);
+
+struct display_entity *display_entity_get_first(void)
+{
+ if (list_empty(&display_entity_list))
+ return NULL;
+
+ return list_first_entry(&display_entity_list, struct display_entity,
+ list);
+}
+EXPORT_SYMBOL(display_entity_get_first);
+
+int display_entity_set_state(struct display_entity *entity,
+ enum display_entity_state state)
+{
+ int ret;
+
+ if (entity->state = state)
+ return 0;
+
+ if (!entity->ops || !entity->ops->set_state)
+ return 0;
+
+ ret = entity->ops->set_state(entity, state);
+ if (ret < 0)
+ return ret;
+
+ entity->state = state;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_set_state);
+
+int display_entity_get_modes(struct display_entity *entity,
+ const struct videomode **modes)
+{
+ if (!entity->ops || !entity->ops->get_modes)
+ return 0;
+
+ return entity->ops->get_modes(entity, modes);
+}
+EXPORT_SYMBOL_GPL(display_entity_get_modes);
+
+int display_entity_get_size(struct display_entity *entity,
+ unsigned int *width, unsigned int *height)
+{
+ if (!entity->ops || !entity->ops->get_size)
+ return -EOPNOTSUPP;
+
+ return entity->ops->get_size(entity, width, height);
+}
+EXPORT_SYMBOL_GPL(display_entity_get_size);
+
+static void display_entity_release(struct kref *ref)
+{
+ struct display_entity *entity + container_of(ref, struct display_entity, ref);
+
+ if (entity->release)
+ entity->release(entity);
+}
+
+struct display_entity *display_entity_get(struct display_entity *entity)
+{
+ if (entity = NULL)
+ return NULL;
+
+ kref_get(&entity->ref);
+ return entity;
+}
+EXPORT_SYMBOL_GPL(display_entity_get);
+
+void display_entity_put(struct display_entity *entity)
+{
+ kref_put(&entity->ref, display_entity_release);
+}
+EXPORT_SYMBOL_GPL(display_entity_put);
+
+int __must_check __display_entity_register(struct display_entity *entity,
+ struct module *owner)
+{
+ kref_init(&entity->ref);
+ entity->owner = owner;
+ entity->state = DISPLAY_ENTITY_STATE_OFF;
+
+ mutex_lock(&display_entity_mutex);
+ list_add(&entity->list, &display_entity_list);
+
+ mutex_unlock(&display_entity_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__display_entity_register);
+
+void display_entity_unregister(struct display_entity *entity)
+{
+ mutex_lock(&display_entity_mutex);
+
+ list_del(&entity->list);
+ mutex_unlock(&display_entity_mutex);
+
+ display_entity_put(entity);
+}
+EXPORT_SYMBOL_GPL(display_entity_unregister);
+
+/* -----------------------------------------------------------------------------
+ * Video Source
+ */
+
+static LIST_HEAD(video_source_list);
+static DEFINE_MUTEX(video_source_mutex);
+
+int __must_check __video_source_register(struct video_source *src,
+ struct module *owner)
+{
+ kref_init(&src->ref);
+ src->owner = owner;
+
+ mutex_lock(&video_source_mutex);
+ list_add(&src->list, &video_source_list);
+
+ mutex_unlock(&video_source_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__video_source_register);
+
+void video_source_unregister(struct video_source *src)
+{
+ mutex_lock(&video_source_mutex);
+
+ list_del(&src->list);
+ mutex_unlock(&video_source_mutex);
+
+ video_source_put(src);
+}
+EXPORT_SYMBOL_GPL(video_source_unregister);
+
+
+static void video_source_release(struct kref *ref)
+{
+ struct video_source *src + container_of(ref, struct video_source, ref);
+
+ if (src->release)
+ src->release(src);
+}
+
+struct video_source *video_source_get(struct video_source *src)
+{
+ if (src = NULL)
+ return NULL;
+
+ kref_get(&src->ref);
+ return src;
+}
+EXPORT_SYMBOL_GPL(video_source_get);
+
+void video_source_put(struct video_source *src)
+{
+ kref_put(&src->ref, video_source_release);
+}
+EXPORT_SYMBOL_GPL(video_source_put);
+
+struct video_source *video_source_find(const char *name)
+{
+ struct video_source *src;
+
+ list_for_each_entry(src, &video_source_list, list) {
+ if (strcmp(src->name, name) = 0) {
+ kref_get(&src->ref);
+ return src;
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(video_source_find);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Display Core");
+MODULE_LICENSE("GPL");
diff --git a/include/video/display.h b/include/video/display.h
new file mode 100644
index 0000000..b639fd0
--- /dev/null
+++ b/include/video/display.h
@@ -0,0 +1,166 @@
+/*
+ * Display Core
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * 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 __DISPLAY_H__
+#define __DISPLAY_H__
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <video/omapdss.h>
+
+struct display_entity;
+struct video_source;
+struct videomode;
+
+/* -----------------------------------------------------------------------------
+ * Display Entity
+ */
+
+/* Hack to get the first registered display entity */
+struct display_entity *display_entity_get_first(void);
+
+enum display_entity_state {
+ DISPLAY_ENTITY_STATE_OFF,
+ DISPLAY_ENTITY_STATE_STANDBY,
+ DISPLAY_ENTITY_STATE_ON,
+};
+
+struct display_entity_control_ops {
+ int (*set_state)(struct display_entity *ent,
+ enum display_entity_state state);
+ int (*update)(struct display_entity *ent,
+ void (*callback)(int, void *), void *data);
+ int (*get_modes)(struct display_entity *ent,
+ const struct videomode **modes);
+ int (*get_size)(struct display_entity *ent,
+ unsigned int *width, unsigned int *height);
+};
+
+struct display_entity {
+ struct list_head list;
+ struct device *dev;
+ struct module *owner;
+ struct kref ref;
+
+ const struct display_entity_control_ops *ops;
+
+ void(*release)(struct display_entity *ent);
+
+ enum display_entity_state state;
+};
+
+int display_entity_set_state(struct display_entity *entity,
+ enum display_entity_state state);
+int display_entity_get_modes(struct display_entity *entity,
+ const struct videomode **modes);
+int display_entity_get_size(struct display_entity *entity,
+ unsigned int *width, unsigned int *height);
+
+struct display_entity *display_entity_get(struct display_entity *entity);
+void display_entity_put(struct display_entity *entity);
+
+int __must_check __display_entity_register(struct display_entity *entity,
+ struct module *owner);
+void display_entity_unregister(struct display_entity *entity);
+
+#define display_entity_register(display_entity) \
+ __display_entity_register(display_entity, THIS_MODULE)
+
+
+/* -----------------------------------------------------------------------------
+ * Video Source
+ */
+
+enum video_source_stream_state {
+ DISPLAY_ENTITY_STREAM_STOPPED,
+ DISPLAY_ENTITY_STREAM_CONTINUOUS,
+};
+
+struct common_video_source_ops {
+ int (*set_stream)(struct video_source *src,
+ enum video_source_stream_state state);
+};
+
+struct dpi_video_source_ops {
+ int (*set_videomode)(struct video_source *src,
+ const struct videomode *vm);
+ int (*set_data_lines)(struct video_source *src, int lines);
+};
+
+struct dsi_video_source_ops {
+ /* enable/disable dsi bus */
+ int (*enable)(struct video_source *src);
+ void (*disable)(struct video_source *src);
+
+ /* bus configuration */
+ int (*configure_pins)(struct video_source *src,
+ const struct omap_dsi_pin_config *pins);
+ int (*set_clocks)(struct video_source *src,
+ unsigned long ddr_clk,
+ unsigned long lp_clk);
+
+ void (*set_operation_mode)(struct video_source *src,
+ enum omap_dss_dsi_mode mode);
+ void (*set_pixel_format)(struct video_source *src,
+ enum omap_dss_dsi_pixel_format fmt);
+ void (*set_size)(struct video_source *src, u16 w, u16 h);
+
+ void (*enable_hs)(struct video_source *src, bool enable);
+
+ /* data transfer */
+ int (*dcs_write)(struct video_source *src, int channel,
+ u8 *data, size_t len);
+ int (*dcs_read)(struct video_source *src, int channel, u8 dcs_cmd,
+ u8 *data, size_t len);
+ int (*update)(struct video_source *src, int channel,
+ void (*callback)(int, void *), void *data);
+};
+
+struct dvi_video_source_ops {
+ int (*set_videomode)(struct video_source *src,
+ const struct videomode *vm);
+};
+
+struct video_source {
+ struct list_head list;
+ struct device *dev;
+ struct module *owner;
+ struct kref ref;
+
+ const char *name;
+
+ const struct common_video_source_ops *common_ops;
+
+ union {
+ const struct dpi_video_source_ops *dpi;
+ const struct dsi_video_source_ops *dsi;
+ const struct dvi_video_source_ops *dvi;
+ } ops;
+
+ void(*release)(struct video_source *src);
+};
+
+
+#define video_source_register(video_source) \
+ __video_source_register(video_source, THIS_MODULE)
+
+int __must_check __video_source_register(struct video_source *entity,
+ struct module *owner);
+void video_source_unregister(struct video_source *entity);
+
+struct video_source *video_source_get(struct video_source *src);
+void video_source_put(struct video_source *src);
+
+struct video_source *video_source_find(const char *name);
+
+#endif /* __DISPLAY_H__ */
--
1.7.10.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