* [PATCH 07/15] OMAPDSS: HDMI5: use common AVI infoframe support
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
Instead of using OMAP specific AVI infoframe structs, use the common one
from include/linux/hdmi.h.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi5_core.c | 122 +++++++++++++++--------------
1 file changed, 65 insertions(+), 57 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index 7528c7a42aa5..d46cb13b06bf 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -290,7 +290,6 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s)
}
static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
- struct hdmi_core_infoframe_avi *avi_cfg,
struct hdmi_config *cfg)
{
DSSDBG("hdmi_core_init\n");
@@ -314,25 +313,6 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
cfg->timings.vfp + cfg->timings.vbp;
video_cfg->v_fc_config.cm.mode = cfg->cm.mode;
video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
-
- /* info frame */
- avi_cfg->db1_format = 0;
- avi_cfg->db1_active_info = 0;
- avi_cfg->db1_bar_info_dv = 0;
- avi_cfg->db1_scan_info = 0;
- avi_cfg->db2_colorimetry = 0;
- avi_cfg->db2_aspect_ratio = 0;
- avi_cfg->db2_active_fmt_ar = 0;
- avi_cfg->db3_itc = 0;
- avi_cfg->db3_ec = 0;
- avi_cfg->db3_q_range = 0;
- avi_cfg->db3_nup_scaling = 0;
- avi_cfg->db4_videocode = 0;
- avi_cfg->db5_pixel_repeat = 0;
- avi_cfg->db6_7_line_eoftop = 0;
- avi_cfg->db8_9_line_sofbottom = 0;
- avi_cfg->db10_11_pixel_eofleft = 0;
- avi_cfg->db12_13_pixel_sofright = 0;
}
/* DSS_HDMI_CORE_VIDEO_CONFIG */
@@ -440,22 +420,55 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core)
static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
{
+ struct hdmi_avi_infoframe *frame = &core->avi_infoframe;
void __iomem *base = core->base;
- struct hdmi_core_infoframe_avi avi = core->avi_cfg;
-
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0);
- REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0);
- REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0);
+ u8 data[HDMI_INFOFRAME_SIZE(AVI)];
+ u8 *ptr;
+ unsigned y, a, b, s;
+ unsigned c, m, r;
+ unsigned itc, ec, q, sc;
+ unsigned vic;
+ unsigned yq, cn, pr;
+
+ hdmi_avi_infoframe_pack(frame, data, sizeof(data));
+
+ ptr = data + HDMI_INFOFRAME_HEADER_SIZE;
+
+ y = (ptr[0] >> 5) & 0x3;
+ a = (ptr[0] >> 4) & 0x1;
+ b = (ptr[0] >> 2) & 0x3;
+ s = (ptr[0] >> 0) & 0x3;
+
+ c = (ptr[1] >> 6) & 0x3;
+ m = (ptr[1] >> 4) & 0x3;
+ r = (ptr[1] >> 0) & 0x3;
+
+ itc = (ptr[2] >> 7) & 0x1;
+ ec = (ptr[2] >> 4) & 0x7;
+ q = (ptr[2] >> 2) & 0x3;
+ sc = (ptr[2] >> 0) & 0x3;
+
+ vic = ptr[3];
+
+ yq = (ptr[4] >> 6) & 0x3;
+ cn = (ptr[4] >> 4) & 0x3;
+ pr = (ptr[4] >> 0) & 0xf;
+
+ hdmi_write_reg(base, HDMI_CORE_FC_AVICONF0,
+ (a << 6) | (s << 4) | (b << 2) | (y << 0));
+
+ hdmi_write_reg(base, HDMI_CORE_FC_AVICONF1,
+ (c << 6) | (m << 4) | (r << 0));
+
+ hdmi_write_reg(base, HDMI_CORE_FC_AVICONF2,
+ (itc << 7) | (ec << 4) | (q << 2) | (sc << 0));
+
+ hdmi_write_reg(base, HDMI_CORE_FC_AVIVID, vic);
+
+ hdmi_write_reg(base, HDMI_CORE_FC_AVICONF3,
+ (yq << 2) | (cn << 0));
+
+ REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, pr, 3, 0);
}
static void hdmi_core_csc_config(struct hdmi_core_data *core,
@@ -497,7 +510,7 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core)
/* support limited range with 24 bit color depth for now */
csc_coeff = csc_table_deepcolor[0];
- core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR;
+ core->avi_infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;
hdmi_core_csc_config(core, csc_coeff);
hdmi_core_aux_infoframe_avi_config(core);
@@ -591,11 +604,11 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
struct omap_video_timings video_timing;
struct hdmi_video_format video_format;
struct hdmi_core_vid_config v_core_cfg;
- struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
+ struct hdmi_avi_infoframe *avi_infoframe = &core->avi_infoframe;
hdmi_core_mask_interrupts(core);
- hdmi_core_init(&v_core_cfg, avi_cfg, cfg);
+ hdmi_core_init(&v_core_cfg, cfg);
hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
@@ -624,25 +637,20 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
/*
* configure packet info frame video see doc CEA861-D page 65
*/
- avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
- avi_cfg->db1_active_info - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
- avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
- avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
- avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
- avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
- avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
- avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
- avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
- avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
- avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
- avi_cfg->db4_videocode = cfg->cm.code;
- avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
- avi_cfg->db6_7_line_eoftop = 0;
- avi_cfg->db8_9_line_sofbottom = 0;
- avi_cfg->db10_11_pixel_eofleft = 0;
- avi_cfg->db12_13_pixel_sofright = 0;
-
+ hdmi_avi_infoframe_init(avi_infoframe);
+ avi_infoframe->colorspace = HDMI_COLORSPACE_RGB;
+ avi_infoframe->scan_mode = HDMI_SCAN_MODE_NONE;
+ avi_infoframe->colorimetry = HDMI_COLORIMETRY_NONE;
+ avi_infoframe->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
+ avi_infoframe->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+ avi_infoframe->itc = 0;
+ avi_infoframe->extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
+ avi_infoframe->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+ avi_infoframe->nups = HDMI_NUPS_UNKNOWN;
+ avi_infoframe->video_code = cfg->cm.code;
+ avi_infoframe->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+ avi_infoframe->content_type = HDMI_CONTENT_TYPE_NONE;
+ avi_infoframe->pixel_repeat = 0;
hdmi_core_aux_infoframe_avi_config(core);
hdmi_core_enable_video_path(core);
--
1.9.1
^ permalink raw reply related
* [PATCH 06/15] OMAPDSS: HDMI4: use common AVI infoframe support
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
Instead of using OMAP specific AVI infoframe structs, use the common one
from include/linux/hdmi.h.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 2 +
drivers/video/fbdev/omap2/dss/hdmi4_core.c | 136 ++++++-----------------------
drivers/video/fbdev/omap2/dss/hdmi4_core.h | 1 +
3 files changed, 28 insertions(+), 111 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 1a62dc3fe54e..6cd4a755b0ac 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/hdmi.h>
#include <video/omapdss.h>
#include "dss.h"
@@ -360,6 +361,7 @@ struct hdmi_core_data {
void __iomem *base;
struct hdmi_core_infoframe_avi avi_cfg;
+ struct hdmi_avi_infoframe avi_infoframe;
};
static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 8bde7b7e95ff..dbdbc5836d51 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -198,7 +198,6 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
- struct hdmi_core_infoframe_avi *avi_cfg,
struct hdmi_core_packet_enable_repeat *repeat_cfg)
{
DSSDBG("Enter hdmi_core_init\n");
@@ -211,25 +210,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
video_cfg->hdmi_dvi = HDMI_DVI;
video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
- /* info frame */
- avi_cfg->db1_format = 0;
- avi_cfg->db1_active_info = 0;
- avi_cfg->db1_bar_info_dv = 0;
- avi_cfg->db1_scan_info = 0;
- avi_cfg->db2_colorimetry = 0;
- avi_cfg->db2_aspect_ratio = 0;
- avi_cfg->db2_active_fmt_ar = 0;
- avi_cfg->db3_itc = 0;
- avi_cfg->db3_ec = 0;
- avi_cfg->db3_q_range = 0;
- avi_cfg->db3_nup_scaling = 0;
- avi_cfg->db4_videocode = 0;
- avi_cfg->db5_pixel_repeat = 0;
- avi_cfg->db6_7_line_eoftop = 0;
- avi_cfg->db8_9_line_sofbottom = 0;
- avi_cfg->db10_11_pixel_eofleft = 0;
- avi_cfg->db12_13_pixel_sofright = 0;
-
/* packet enable and repeat */
repeat_cfg->audio_pkt = 0;
repeat_cfg->audio_pkt_repeat = 0;
@@ -305,78 +285,17 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
{
- u32 val;
- char sum = 0, checksum = 0;
void __iomem *av_base = hdmi_av_base(core);
- struct hdmi_core_infoframe_avi info_avi = core->avi_cfg;
-
- sum += 0x82 + 0x002 + 0x00D;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
-
- val = (info_avi.db1_format << 5) |
- (info_avi.db1_active_info << 4) |
- (info_avi.db1_bar_info_dv << 2) |
- (info_avi.db1_scan_info);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
- sum += val;
-
- val = (info_avi.db2_colorimetry << 6) |
- (info_avi.db2_aspect_ratio << 4) |
- (info_avi.db2_active_fmt_ar);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
- sum += val;
-
- val = (info_avi.db3_itc << 7) |
- (info_avi.db3_ec << 4) |
- (info_avi.db3_q_range << 2) |
- (info_avi.db3_nup_scaling);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
- sum += val;
-
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
- info_avi.db4_videocode);
- sum += info_avi.db4_videocode;
-
- val = info_avi.db5_pixel_repeat;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
- sum += val;
-
- val = info_avi.db6_7_line_eoftop & 0x00FF;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
- sum += val;
-
- val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
- sum += val;
-
- val = info_avi.db8_9_line_sofbottom & 0x00FF;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
- sum += val;
-
- val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
- sum += val;
-
- val = info_avi.db10_11_pixel_eofleft & 0x00FF;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
- sum += val;
-
- val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
- sum += val;
-
- val = info_avi.db12_13_pixel_sofright & 0x00FF;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
- sum += val;
-
- val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
- sum += val;
+ struct hdmi_avi_infoframe *frame = &core->avi_infoframe;
+ u8 data[HDMI_INFOFRAME_SIZE(AVI)];
+ int i;
- checksum = 0x100 - sum;
- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);
+ hdmi_avi_infoframe_pack(frame, data, sizeof(data));
+
+ for (i = 0; i < sizeof(data); ++i) {
+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
+ data[i]);
+ }
}
static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
@@ -404,11 +323,11 @@ void hdmi4_configure(struct hdmi_core_data *core,
struct omap_video_timings video_timing;
struct hdmi_video_format video_format;
/* HDMI core */
- struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
struct hdmi_core_video_config v_core_cfg;
struct hdmi_core_packet_enable_repeat repeat_cfg;
+ struct hdmi_avi_infoframe *avi_infoframe = &core->avi_infoframe;
- hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg);
+ hdmi_core_init(&v_core_cfg, &repeat_cfg);
hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
@@ -442,25 +361,20 @@ void hdmi4_configure(struct hdmi_core_data *core,
* configure packet
* info frame video see doc CEA861-D page 65
*/
- avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
- avi_cfg->db1_active_info - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
- avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
- avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
- avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
- avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
- avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
- avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
- avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
- avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
- avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
- avi_cfg->db4_videocode = cfg->cm.code;
- avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
- avi_cfg->db6_7_line_eoftop = 0;
- avi_cfg->db8_9_line_sofbottom = 0;
- avi_cfg->db10_11_pixel_eofleft = 0;
- avi_cfg->db12_13_pixel_sofright = 0;
-
+ hdmi_avi_infoframe_init(avi_infoframe);
+ avi_infoframe->colorspace = HDMI_COLORSPACE_RGB;
+ avi_infoframe->scan_mode = HDMI_SCAN_MODE_NONE;
+ avi_infoframe->colorimetry = HDMI_COLORIMETRY_NONE;
+ avi_infoframe->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
+ avi_infoframe->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+ avi_infoframe->itc = 0;
+ avi_infoframe->extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
+ avi_infoframe->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+ avi_infoframe->nups = HDMI_NUPS_UNKNOWN;
+ avi_infoframe->video_code = cfg->cm.code;
+ avi_infoframe->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+ avi_infoframe->content_type = HDMI_CONTENT_TYPE_NONE;
+ avi_infoframe->pixel_repeat = 0;
hdmi_core_aux_infoframe_avi_config(core);
/* enable/repeat the infoframe */
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
index bb646896fa82..827909eb6c50 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
@@ -145,6 +145,7 @@
#define HDMI_CORE_AV_DPD 0xF4
#define HDMI_CORE_AV_PB_CTRL1 0xF8
#define HDMI_CORE_AV_PB_CTRL2 0xFC
+#define HDMI_CORE_AV_AVI_BASE 0x100
#define HDMI_CORE_AV_AVI_TYPE 0x100
#define HDMI_CORE_AV_AVI_VERS 0x104
#define HDMI_CORE_AV_AVI_LEN 0x108
--
1.9.1
^ permalink raw reply related
* [PATCH 05/15] OMAPDSS: Kconfig: select HDMI
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
Select HDMI support to be able to use HDMI infoframe helpers.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
index 285bcd103dce..3d5eb6c36c22 100644
--- a/drivers/video/fbdev/omap2/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/dss/Kconfig
@@ -5,6 +5,7 @@ menuconfig OMAP2_DSS
tristate "OMAP2+ Display Subsystem support"
select VIDEOMODE_HELPERS
select OMAP2_DSS_INIT
+ select HDMI
help
OMAP2+ Display Subsystem support.
--
1.9.1
^ permalink raw reply related
* [PATCH 04/15] OMAPDSS: HDMI: fix name conflict
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
OMAP HDMI driver has an 'enum hdmi_audio_sample_size', which conflicts
with the common include/linux/hdmi.h.
Change the name of the OMAP specific enum with '_omap" postfix.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/hdmi.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index fbee07816337..1a62dc3fe54e 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -142,7 +142,7 @@ enum hdmi_audio_samples_perword {
HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
};
-enum hdmi_audio_sample_size {
+enum hdmi_audio_sample_size_omap {
HDMI_AUDIO_SAMPLE_16BITS = 0,
HDMI_AUDIO_SAMPLE_24BITS = 1
};
@@ -260,7 +260,7 @@ struct hdmi_audio_format {
enum hdmi_audio_justify justification;
enum hdmi_audio_sample_order sample_order;
enum hdmi_audio_samples_perword samples_per_word;
- enum hdmi_audio_sample_size sample_size;
+ enum hdmi_audio_sample_size_omap sample_size;
enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
};
--
1.9.1
^ permalink raw reply related
* [PATCH 03/15] OMAPDSS: DISPC: clean up dispc_mgr_timings_ok
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
dispc_mgr_timings_ok() is a bit confusing how it handles the return
value.
Change the function to just return immediately when a timing is deemed
not valid, making the code much easier to follow.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dispc.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 37373b61784e..be053aa80880 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2879,22 +2879,24 @@ static bool _dispc_mgr_pclk_ok(enum omap_channel channel,
bool dispc_mgr_timings_ok(enum omap_channel channel,
const struct omap_video_timings *timings)
{
- bool timings_ok;
-
- timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
+ if (!_dispc_mgr_size_ok(timings->x_res, timings->y_res))
+ return false;
- timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
+ if (!_dispc_mgr_pclk_ok(channel, timings->pixelclock))
+ return false;
if (dss_mgr_is_lcd(channel)) {
/* TODO: OMAP4+ supports interlace for LCD outputs */
- timings_ok &= timings->interlace = false;
+ if (timings->interlace)
+ return false;
- timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
+ if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
timings->hbp, timings->vsw, timings->vfp,
- timings->vbp);
+ timings->vbp))
+ return false;
}
- return timings_ok;
+ return true;
}
static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
--
1.9.1
^ permalink raw reply related
* [PATCH 02/15] OMAPDSS: DISPC: reject interlace for lcd out
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
OMAP2/3 does not support interlace for LCD out. OMAP4+ does, but is not
supported by the driver at the moment.
The driver still accepts interlaced mode for LCD out, causing broken
display output.
This patch makes dispc reject interlace for LCD out.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dispc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index d1f0dbb486b8..37373b61784e 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2886,6 +2886,9 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
if (dss_mgr_is_lcd(channel)) {
+ /* TODO: OMAP4+ supports interlace for LCD outputs */
+ timings_ok &= timings->interlace = false;
+
timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
timings->hbp, timings->vsw, timings->vfp,
timings->vbp);
--
1.9.1
^ permalink raw reply related
* [PATCH 01/15] OMAPDSS: DISPC: fix debugfs reg dump
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
In-Reply-To: <1403604240-16738-1-git-send-email-tomi.valkeinen@ti.com>
DISPC reg dump prints a few registers twice. Remove the extra prints.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/omap2/dss/dispc.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 7aa33b0f4a1f..d1f0dbb486b8 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -3257,13 +3257,10 @@ static void dispc_dump_regs(struct seq_file *s)
if (i = OMAP_DSS_CHANNEL_DIGIT)
continue;
- DUMPREG(i, DISPC_DEFAULT_COLOR);
- DUMPREG(i, DISPC_TRANS_COLOR);
DUMPREG(i, DISPC_TIMING_H);
DUMPREG(i, DISPC_TIMING_V);
DUMPREG(i, DISPC_POL_FREQ);
DUMPREG(i, DISPC_DIVISORo);
- DUMPREG(i, DISPC_SIZE_MGR);
DUMPREG(i, DISPC_DATA_CYCLE1);
DUMPREG(i, DISPC_DATA_CYCLE2);
--
1.9.1
^ permalink raw reply related
* [PATCH 00/15] OMAPDSS: HDMI infoframe & cleanup
From: Tomi Valkeinen @ 2014-06-24 10:03 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Jyri Sarha, Tomi Valkeinen
This series makes OMAP HDMI drivers use the common infoframe functionality and
makes the drivers get the infoframe from the upper layer, instead of using
hardcoded infoframes.
This allows us to remove quite a bit of ugly code from the drivers.
The downside is that the infoframe functionality is only there for DRM, not for
FB. So when using omapfb, the HDMI output will always use DVI mode, i.e.
without sound support and without the HDMI features like color ranges.
Considering that the HDMI audio hasn't been working for some time, and the
other features were always hardcoded, this doesn't sound like a big issue.
Tomi
Tomi Valkeinen (15):
OMAPDSS: DISPC: fix debugfs reg dump
OMAPDSS: DISPC: reject interlace for lcd out
OMAPDSS: DISPC: clean up dispc_mgr_timings_ok
OMAPDSS: HDMI: fix name conflict
OMAPDSS: Kconfig: select HDMI
OMAPDSS: HDMI4: use common AVI infoframe support
OMAPDSS: HDMI5: use common AVI infoframe support
OMAPDSS: HDMI: remove custom avi infoframe
OMAPDSS: add hdmi ops to hdmi_ops and omap_dss_driver
OMAPDSS: add hdmi ops to hdmi-connector and tpd12s015
OMAPDSS: HDMI: add infoframe and hdmi_dvi_mode fields
OMAPDSS: HDMI4: add support to set infoframe & HDMI mode
OMAPDSS: HDMI5: add support to set infoframe & HDMI mode
OMAPDSS: HDMI: remove the unused code
drm/omap: Add infoframe & dvi/hdmi mode support
drivers/gpu/drm/omapdrm/omap_connector.c | 12 +
drivers/gpu/drm/omapdrm/omap_drv.h | 1 +
drivers/gpu/drm/omapdrm/omap_encoder.c | 27 ++
.../fbdev/omap2/displays-new/connector-hdmi.c | 19 ++
.../fbdev/omap2/displays-new/encoder-tpd12s015.c | 20 ++
drivers/video/fbdev/omap2/dss/Kconfig | 1 +
drivers/video/fbdev/omap2/dss/dispc.c | 22 +-
drivers/video/fbdev/omap2/dss/hdmi.h | 107 +------
drivers/video/fbdev/omap2/dss/hdmi4.c | 47 ++-
drivers/video/fbdev/omap2/dss/hdmi4_core.c | 164 ++---------
drivers/video/fbdev/omap2/dss/hdmi4_core.h | 1 +
drivers/video/fbdev/omap2/dss/hdmi5.c | 47 ++-
drivers/video/fbdev/omap2/dss/hdmi5_core.c | 124 ++++----
drivers/video/fbdev/omap2/dss/hdmi_common.c | 316 ---------------------
include/video/omapdss.h | 9 +
15 files changed, 231 insertions(+), 686 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH 3/10] video: use safer test on the result of find_first_zero_bit
From: Tomi Valkeinen @ 2014-06-24 7:56 UTC (permalink / raw)
To: Julia Lawall
Cc: Jean-Christophe Plagniol-Villard, kernel-janitors, linux-fbdev,
linux-kernel
In-Reply-To: <alpine.DEB.2.10.1406231612030.3905@hadrien>
[-- Attachment #1: Type: text/plain, Size: 595 bytes --]
On 23/06/14 17:12, Julia Lawall wrote:
> On Mon, 23 Jun 2014, Tomi Valkeinen wrote:
>
>> On 04/06/14 12:07, Julia Lawall wrote:
>>> From: Julia Lawall <Julia.Lawall@lip6.fr>
>>>
>>> Find_first_zero_bit considers BITS_PER_LONG bits at a time, and thus may
>>> return a larger number than the maximum position argument if that position
>>> is not a multiple of BITS_PER_LONG.
>>
>> Thanks, queued for 3.17.
>
> No, sorry you can drop it. It doesn't hurt anything, but it is not
> necessary either. Returning a larger number is actually not possible.
Ok, dropped.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [RFC v3 2/2] backlight: device tree: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 7:18 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA, Daniel Jeong
In-Reply-To: <1403594330-15387-1-git-send-email-gshark.jeong-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This commit is about tps611xx device tree documentation.
Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
.../video/backlight/tps611xx-backlight.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
diff --git a/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
new file mode 100644
index 0000000..01f110d
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
@@ -0,0 +1,16 @@
+TPS611xx family of backlight driver based on EasyScale.
+
+It supports tps61158, tps61161, tps61163 and tps61165.
+
+Required properties:
+- compatible: "ti,tps61158_bl", "ti,tps61161_bl", "ti,tps61163_bl", "ti,tps61165_bl"
+- rfa_en: enable request for acknowledge. ( 0 : disable , 1 : enable )
+- en_gpio_num: gpio number for en pin.
+
+Example:
+
+ backlight {
+ compatible = "ti,tps61163_bl";
+ rfa_en = <1>;
+ en_gpio_num = <45>;
+ };
--
1.7.9.5
^ permalink raw reply related
* [RFC v3 1/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 7:18 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
Daniel Jeong
In-Reply-To: <1403594330-15387-1-git-send-email-gshark.jeong@gmail.com>
This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol(1-Wire Control Interface).
EasyScale
EasyScale is a simple but flexible one pin interface to configure the current.
The interface is based on a master-slave structure, where the master is
typically a microcontroller or application processor and the IC is the slave.
The advantage of EasyScale compared with other one pin interfaces is that
its bit detection is in a large extent independent from the bit transmission rate.
It can automatically detect bit rates between 1.7kBit/sec and up to 160kBit/sec.
EasyScale on TPS61163
A command consists of 24 bits, including an 8-bit device address byte and a 16-bit data byte.
All of the 24 bits should be transmitted together each time, and the LSB bit should be
transmitted first. The device address byte A7(MSB)~A0(LSB) is fixed to 0x8F.
The data byte includes 9 bits D8(MSB)~D0(LSB) for brightness information and an RFA bit.
The RFA bit set to "1" indicates the Request for Acknowledge condition. The Acknowledge
condition is only applied when the protocol is received correctly.
Bit sream : D0-D8 | 0 | RFA | 00000 | A0-A7
Please refer http://www.ti.com/lit/ds/symlink/tps61163.pdf for more details.
EasyScale on TPS61158/61/65
A command consists of 16 bits, including an 8-bit device address byte and a 8-bit data byte.
All of the 16 bits should be transmitted together each time, and the MSB bit should be
transmitted first. The device address byte A7(MSB)~A0(LSB) is fixed (tps61158 0x58
tps61161 and tps61165 0x72). The data byte includes an RFA bit.
The RFA bit set to "1" indicates the Request for Acknowledge condition. The Acknowledge
condition is only applied when the protocol is received correctly.
Bit sream : A7-A0 | RFA | 00 | D4-D0
Please refer the links below for more details.
tps61158 : http://www.ti.com/lit/ds/symlink/tps61158.pdf
tps61161 : http://www.ti.com.cn/cn/lit/ds/symlink/tps61161-q1.pdf
tps61165 : http://www.ti.com/lit/ds/symlink/tps61165.pdf
Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/tps611xx_bl.c | 494 +++++++++++++++++++++++++++++
include/linux/platform_data/tps611xx_bl.h | 31 ++
4 files changed, 533 insertions(+)
create mode 100644 drivers/video/backlight/tps611xx_bl.c
create mode 100644 include/linux/platform_data/tps611xx_bl.h
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2e..c779a85 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -418,6 +418,13 @@ config BACKLIGHT_TPS65217
If you have a Texas Instruments TPS65217 say Y to enable the
backlight driver.
+config BACKLIGHT_TPS611xx
+ tristate "TPS611xx Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && GPIOLIB
+ help
+ This supports TI TPS61158,TPS61161, TPS61163 and TPS61165
+ backlight driver based on EasyScale Protocol.
+
config BACKLIGHT_AS3711
tristate "AS3711 Backlight"
depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb82002..44f1641 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -52,4 +52,5 @@ obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS611xx) += tps611xx_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/tps611xx_bl.c b/drivers/video/backlight/tps611xx_bl.c
new file mode 100644
index 0000000..8dcc88a
--- /dev/null
+++ b/drivers/video/backlight/tps611xx_bl.c
@@ -0,0 +1,494 @@
+/*
+ * Simple driver for Texas Instruments TPS611XX Backlight driver chip
+ * using EasyScale Interface. It supports TPS61158, TPS61161,
+ * TPS61163 and TPS61165.
+ *
+ * Copyright (C) 2014 Texas Instruments
+ * Author: Daniel Jeong <gshark.jeong@gmail.com>
+ * Ldd Mlp <ldd-mlp@list.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/backlight.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/tps611xx_bl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define CMD_FORWARD 0
+#define CMD_BACKWARD 1
+
+enum tps611xx_id {
+ TPS61158_ID = 0,
+ TPS61161_ID,
+ TPS61163_ID,
+ TPS61165_ID,
+};
+
+/*
+ * easyscale time spec
+ * @es_delay : es delay time(ns)
+ * @es_det : es detection time(ns)
+ * @start : start time of data stream(ns)
+ * @eos : end time of data stream(ns)
+ * @reset : ic shutdown time(ms)
+ * @logic_1_low : low time high bit(ns)
+ * @logic_0_low : low time low bit(ns)
+ * @ackn : duation of ack condistion(ns)
+ * @ack_poll : ack polling duration(ns)
+ */
+struct tps611xx_time {
+ unsigned int es_delay;
+ unsigned int es_det;
+ unsigned int start;
+ unsigned int eos;
+ unsigned int reset;
+ unsigned int logic_1_low;
+ unsigned int logic_0_low;
+ unsigned int ackn;
+ unsigned int ack_poll;
+};
+
+/*
+ * @seq : sequence of data transfer
+ * @size: size of data
+ * @brt_max : max brightness
+ * @brt_bmask : bit mask of dimming bits
+ * @rfa_bmask : bit mask of RFA(Request for Acknowledge condition)
+ */
+struct tps611xx_command {
+ int seq;
+ int size;
+ int brt_max;
+ int brt_bmask;
+ int rfa_bmask;
+};
+
+/*
+ * @id : product id
+ * @name : product name
+ * @addr : device address
+ * @cmd : es command info
+ * @time : es time info
+ */
+struct tps611xx_esdata {
+ enum tps611xx_id id;
+ char *name;
+ int addr;
+ struct tps611xx_command cmd;
+ struct tps611xx_time time;
+};
+
+struct tps611xx_bl_data {
+ struct device *dev;
+ struct backlight_device *bled;
+ struct tps611xx_platform_data *pdata;
+
+ /*
+ * @rfa_en : RFA enable (Request for Acknowledge condition)
+ * @en_gpio: enable pin gpio no.
+ * @esdata : easyscale data
+ */
+ int rfa_en;
+ unsigned int en_gpio;
+ const struct tps611xx_esdata *esdata;
+};
+
+static struct tps611xx_esdata tps611xx_info[] = {
+ [TPS61158_ID] = {
+ .id = TPS61158_ID,
+ .name = "tps61158",
+ .addr = 0x5800,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 100000,
+ .es_det = 450000,
+ .start = 3500,
+ .eos = 3500,
+ .reset = 4,
+ .logic_1_low = 5000,
+ .logic_0_low = 15000,
+ .ackn = 900000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61161_ID] = {
+ .id = TPS61161_ID,
+ .name = "tps61161",
+ .addr = 0x7200,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 120000,
+ .es_det = 280000,
+ .start = 2000,
+ .eos = 2000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61163_ID] = {
+ .id = TPS61163_ID,
+ .name = "tps61163",
+ .addr = 0x8F0000,
+ .cmd = {
+ .seq = CMD_BACKWARD,
+ .size = 24,
+ .brt_max = 511,
+ .brt_bmask = 0x1ff,
+ .rfa_bmask = 0x400
+ },
+ .time = {
+ .es_delay = 100000,
+ .es_det = 260000,
+ .start = 2000,
+ .eos = 2000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61165_ID] = {
+ .id = TPS61165_ID,
+ .name = "tps61165",
+ .addr = 0x7200,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 120000,
+ .es_det = 280000,
+ .start = 4000,
+ .eos = 4000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+};
+
+static int tps611xx_bl_update_status(struct backlight_device *bl)
+{
+ struct tps611xx_bl_data *pchip = bl_get_data(bl);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+ int data_in, t_low, t_logic, max_bmask;
+ unsigned long flags;
+
+ data_in = esdata->addr | (bl->props.brightness & esdata->cmd.brt_bmask);
+ if (pchip->rfa_en)
+ data_in |= esdata->cmd.rfa_bmask;
+
+ max_bmask = 0x1 << esdata->cmd.size;
+ t_logic = esdata->time.logic_1_low + esdata->time.logic_0_low;
+
+ local_irq_save(flags);
+ /* t_start : 2us high before data byte */
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.start);
+
+ /* forward command transfer */
+ if (esdata->cmd.seq = CMD_FORWARD) {
+ int addr_bmask = max_bmask >> 8;
+
+ for (max_bmask >>= 1; max_bmask > 0x0; max_bmask >>= 1) {
+ if (data_in & max_bmask)
+ t_low = esdata->time.logic_1_low;
+ else
+ t_low = esdata->time.logic_0_low;
+
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(t_low);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(t_logic - t_low);
+
+ if (max_bmask = addr_bmask) {
+ gpio_direction_output(pchip->en_gpio, 0);
+ /* t_eos : low after address byte */
+ ndelay(esdata->time.eos);
+ gpio_direction_output(pchip->en_gpio, 1);
+ /* t_start : high before data byte */
+ ndelay(esdata->time.start);
+ }
+ }
+ } else {
+ /* backward command tansfer */
+ int bmask;
+
+ for (bmask = 0x01; bmask < max_bmask; bmask <<= 1) {
+ if (data_in & bmask)
+ t_low = esdata->time.logic_1_low;
+ else
+ t_low = esdata->time.logic_0_low;
+
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(t_low);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(t_logic - t_low);
+ }
+ }
+
+ /*
+ * t_eos : low after address byte
+ * t_ackVal is also t_eos
+ */
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.eos);
+
+ /* RFA management */
+ if (pchip->rfa_en) {
+ int max_ack_time = esdata->time.ackn;
+ /* set input */
+ gpio_direction_input(pchip->en_gpio);
+ /* read acknowledge from chip */
+ while (max_ack_time > 0) {
+ if (gpio_get_value(pchip->en_gpio) = 0)
+ break;
+ max_ack_time -= esdata->time.ack_poll;
+ }
+ if (max_ack_time <= 0)
+ dev_err(pchip->dev,
+ "easyscale : no ack from %s\n", esdata->name);
+ else
+ ndelay(max_ack_time);
+ }
+ gpio_direction_output(pchip->en_gpio, 1);
+ local_irq_restore(flags);
+
+ return bl->props.brightness;
+}
+
+static int tps611xx_bl_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops tps611xx_bl_ops = {
+ .update_status = tps611xx_bl_update_status,
+ .get_brightness = tps611xx_bl_get_brightness,
+};
+
+static ssize_t tps611xx_enable_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ struct tps611xx_bl_data *pchip = dev_get_drvdata(dev);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+ unsigned long flags;
+ unsigned int input;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &input);
+ if (ret)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ if (input = 0) {
+ /* chip disable */
+ gpio_direction_output(pchip->en_gpio, 0);
+ /* low more than reset ms to reset */
+ mdelay(esdata->time.reset);
+ } else {
+ /* easyscale detection window */
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.es_delay);
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.es_det);
+ gpio_direction_output(pchip->en_gpio, 1);
+ }
+ local_irq_restore(flags);
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR, NULL, tps611xx_enable_store);
+
+#ifdef CONFIG_OF
+static const struct of_device_id tps611xx_backlight_of_match[] = {
+ {.compatible = "ti,tps61158_bl", .data = &tps611xx_info[TPS61158_ID]},
+ {.compatible = "ti,tps61161_bl", .data = &tps611xx_info[TPS61161_ID]},
+ {.compatible = "ti,tps61163_bl", .data = &tps611xx_info[TPS61163_ID]},
+ {.compatible = "ti,tps61165_bl", .data = &tps611xx_info[TPS61165_ID]},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, tps611xx_backlight_of_match);
+
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+ struct device *dev = pchip->dev;
+ struct device_node *node = dev->of_node;
+ const struct of_device_id *of_id + of_match_device(tps611xx_backlight_of_match, dev);
+ u32 value;
+ int ret;
+
+ if (!node)
+ return -ENODEV;
+
+ if (!of_id || !of_id->data) {
+ dev_err(dev, "Failed to find tps611xx chip id\n");
+ return -EFAULT;
+ }
+ pchip->esdata = of_id->data;
+
+ ret = of_property_read_u32(node, "en_gpio_num", &value);
+ if (ret < 0)
+ return ret;
+ pchip->en_gpio = value;
+ ret = of_property_read_u32(node, "rfa_en", &value);
+ if (ret < 0)
+ return ret;
+ pchip->rfa_en = value;
+
+ return 0;
+}
+#else
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+ return -ENODEV;
+}
+#endif
+
+static int tps611xx_backlight_probe(struct platform_device *pdev)
+{
+ struct tps611xx_bl_data *pchip;
+ struct backlight_properties props;
+ const struct tps611xx_esdata *esdata;
+ struct tps611xx_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ unsigned long flags;
+ int ret;
+
+ pchip = devm_kzalloc(&pdev->dev,
+ sizeof(struct tps611xx_bl_data), GFP_KERNEL);
+ if (pchip = NULL)
+ return -ENOMEM;
+ pchip->dev = &pdev->dev;
+
+ if (pdata = NULL) {
+ ret = tps611xx_backlight_parse_dt(pchip);
+ if (ret < 0)
+ return ret;
+ } else {
+ pchip->rfa_en = pdata->rfa_en;
+ pchip->en_gpio = pdata->en_gpio_num;
+ pchip->esdata = (const struct tps611xx_esdata *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+ esdata = pchip->esdata;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.brightness = esdata->cmd.brt_max;
+ props.max_brightness = esdata->cmd.brt_max;
+ props.type = BACKLIGHT_RAW;
+ pchip->bled + devm_backlight_device_register(pchip->dev, TPS611XX_NAME,
+ pchip->dev, pchip,
+ &tps611xx_bl_ops, &props);
+ if (IS_ERR(pchip->bled))
+ return PTR_ERR(pchip->bled);
+
+ /* for enable/disable */
+ ret = device_create_file(&(pchip->bled->dev), &dev_attr_enable);
+ if (ret < 0) {
+ dev_err(pchip->dev, "failed : add sysfs entries\n");
+ return ret;
+ }
+ platform_set_drvdata(pdev, pchip);
+
+ /* EasyScale init */
+ ret = gpio_request_one(pchip->en_gpio, GPIOF_OUT_INIT_HIGH, "tps611xx");
+ if (ret) {
+ device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+ dev_err(pchip->dev, "failed : get gpio %d\n", pchip->en_gpio);
+ return ret;
+ }
+
+ /*
+ * ES Detection Window
+ * - ES detect delay
+ * - ES detect time
+ */
+ local_irq_save(flags);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.es_delay);
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.es_det);
+ gpio_direction_output(pchip->en_gpio, 1);
+ local_irq_restore(flags);
+ dev_info(pchip->dev,
+ "%s EasyScale is initialized\n", pchip->esdata->name);
+ return 0;
+}
+
+static int tps611xx_backlight_remove(struct platform_device *pdev)
+{
+ struct tps611xx_bl_data *pchip = platform_get_drvdata(pdev);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+
+ device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+ gpio_direction_output(pchip->en_gpio, 0);
+ mdelay(esdata->time.reset);
+ return 0;
+}
+
+static const struct platform_device_id tps611xx_id_table[] = {
+ {TPS61158_NAME, (unsigned long)&tps611xx_info[TPS61158_ID]},
+ {TPS61161_NAME, (unsigned long)&tps611xx_info[TPS61161_ID]},
+ {TPS61163_NAME, (unsigned long)&tps611xx_info[TPS61163_ID]},
+ {TPS61165_NAME, (unsigned long)&tps611xx_info[TPS61165_ID]},
+ {}
+};
+
+static struct platform_driver tps611xx_backlight_driver = {
+ .driver = {
+ .name = TPS611XX_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tps611xx_backlight_of_match),
+ },
+ .probe = tps611xx_backlight_probe,
+ .remove = tps611xx_backlight_remove,
+ .id_table = tps611xx_id_table,
+};
+
+module_platform_driver(tps611xx_backlight_driver);
+
+MODULE_DESCRIPTION("EasyScale based tps611xx Backlight Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps611xx_bl");
diff --git a/include/linux/platform_data/tps611xx_bl.h b/include/linux/platform_data/tps611xx_bl.h
new file mode 100644
index 0000000..73d1f08
--- /dev/null
+++ b/include/linux/platform_data/tps611xx_bl.h
@@ -0,0 +1,31 @@
+/*
+ * Simple driver for Texas Instruments TPS61163a Backlight driver chip
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * 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 __TPS611XX_H
+#define __TPS611XX_H
+
+#define TPS611XX_NAME "tps611xx_bl"
+#define TPS61158_NAME "tps61158_bl"
+#define TPS61161_NAME "tps61161_bl"
+#define TPS61163_NAME "tps61163_bl"
+#define TPS61165_NAME "tps61165_bl"
+
+/*
+ * struct tps61163a platform data
+ * @rfa_en : request for acknowledge
+ * @en_gpio_num : gpio number for en_pin
+ */
+struct tps611xx_platform_data {
+
+ int rfa_en;
+ unsigned int en_gpio_num;
+};
+
+#endif /* __TPS611XX_H */
--
1.7.9.5
^ permalink raw reply related
* [RFC v3 0/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 7:18 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA, Daniel Jeong
This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.
Daniel Jeong (2):
backlight
backlight: add new tps611xx backlight device tree support This
commit is tps611xx device tree documentation.
.../video/backlight/tps611xx-backlight.txt | 16 +
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/tps611xx_bl.c | 494 ++++++++++++++++++++
include/linux/platform_data/tps611xx_bl.h | 31 ++
5 files changed, 549 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
create mode 100644 drivers/video/backlight/tps611xx_bl.c
create mode 100644 include/linux/platform_data/tps611xx_bl.h
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH] video: OF display-timings support for ocfb
From: Stefan Kristiansson @ 2014-06-24 6:59 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: Franck Jullien, linux-kernel, linux-fbdev, plagnioj
In-Reply-To: <53A81720.2050507@ti.com>
On Mon, Jun 23, 2014 at 03:01:36PM +0300, Tomi Valkeinen wrote:
> On 11/06/14 23:17, Franck Jullien wrote:
> > Signed-off-by: Franck Jullien <franck.jullien@gmail.com>
> > ---
> > drivers/video/fbdev/Kconfig | 2 ++
> > drivers/video/fbdev/ocfb.c | 31 ++++++++++++++++++++++++++-----
> > 2 files changed, 28 insertions(+), 5 deletions(-)
>
> You need to add binding documentation if you add new things to the
> driver's DT support. Actually, we seem to be missing the the binding
> documentation totally, even if the driver has 'of_device_id' table...
>
Right, I'll take the blame for the missing driver binding documentation,
I'll write something up and post a patch for that.
But, where should it go?
Documentation/devicetree/bindings/video/
or
Documentation/devicetree/bindings/fb/
Stefan
^ permalink raw reply
* [RFC v2 2/2] backlight: device tree: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 6:17 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
Daniel Jeong
In-Reply-To: <1403590674-14361-1-git-send-email-gshark.jeong@gmail.com>
This commit is about tps611xx device tree documentation.
Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
.../video/backlight/tps611xx-backlight.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
diff --git a/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
new file mode 100644
index 0000000..01f110d
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
@@ -0,0 +1,16 @@
+TPS611xx family of backlight driver based on EasyScale.
+
+It supports tps61158, tps61161, tps61163 and tps61165.
+
+Required properties:
+- compatible: "ti,tps61158_bl", "ti,tps61161_bl", "ti,tps61163_bl", "ti,tps61165_bl"
+- rfa_en: enable request for acknowledge. ( 0 : disable , 1 : enable )
+- en_gpio_num: gpio number for en pin.
+
+Example:
+
+ backlight {
+ compatible = "ti,tps61163_bl";
+ rfa_en = <1>;
+ en_gpio_num = <45>;
+ };
--
1.7.9.5
^ permalink raw reply related
* [RFC v2 1/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 6:17 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
Daniel Jeong
In-Reply-To: <1403590674-14361-1-git-send-email-gshark.jeong@gmail.com>
This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol(1-Wire Control Interface).
EasyScale
EasyScale is a simple but flexible one pin interface to configure the current.
The interface is based on a master-slave structure, where the master is
typically a microcontroller or application processor and the IC is the slave.
The advantage of EasyScale compared with other one pin interfaces is that
its bit detection is in a large extent independent from the bit transmission rate.
It can automatically detect bit rates between 1.7kBit/sec and up to 160kBit/sec.
EasyScale on TPS61163
A command consists of 24 bits, including an 8-bit device address byte and a 16-bit data byte.
All of the 24 bits should be transmitted together each time, and the LSB bit should be
transmitted first. The device address byte A7(MSB)~A0(LSB) is fixed to 0x8F.
The data byte includes 9 bits D8(MSB)~D0(LSB) for brightness information and an RFA bit.
The RFA bit set to "1" indicates the Request for Acknowledge condition. The Acknowledge
condition is only applied when the protocol is received correctly.
Bit sream : D0-D8 | 0 | RFA | 00000 | A0-A7
Please refer http://www.ti.com/lit/ds/symlink/tps61163.pdf for more details.
EasyScale on TPS61158/61/65
A command consists of 16 bits, including an 8-bit device address byte and a 8-bit data byte.
All of the 16 bits should be transmitted together each time, and the MSB bit should be
transmitted first. The device address byte A7(MSB)~A0(LSB) is fixed (tps61158 0x58
tps61161 and tps61165 0x72). The data byte includes an RFA bit.
The RFA bit set to "1" indicates the Request for Acknowledge condition. The Acknowledge
condition is only applied when the protocol is received correctly.
Bit sream : A7-A0 | RFA | 00 | D4-D0
Please refer the links below for more details.
tps61158 : http://www.ti.com/lit/ds/symlink/tps61158.pdf
tps61161 : http://www.ti.com.cn/cn/lit/ds/symlink/tps61161-q1.pdf
tps61165 : http://www.ti.com/lit/ds/symlink/tps61165.pdf
Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/tps611xx_bl.c | 494 +++++++++++++++++++++++++++++
include/linux/platform_data/tps611xx_bl.h | 31 ++
4 files changed, 533 insertions(+)
create mode 100644 drivers/video/backlight/tps611xx_bl.c
create mode 100644 include/linux/platform_data/tps611xx_bl.h
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2e..c779a85 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -418,6 +418,13 @@ config BACKLIGHT_TPS65217
If you have a Texas Instruments TPS65217 say Y to enable the
backlight driver.
+config BACKLIGHT_TPS611xx
+ tristate "TPS611xx Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && GPIOLIB
+ help
+ This supports TI TPS61158,TPS61161, TPS61163 and TPS61165
+ backlight driver based on EasyScale Protocol.
+
config BACKLIGHT_AS3711
tristate "AS3711 Backlight"
depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb82002..44f1641 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -52,4 +52,5 @@ obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS611xx) += tps611xx_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/tps611xx_bl.c b/drivers/video/backlight/tps611xx_bl.c
new file mode 100644
index 0000000..f7e08a3
--- /dev/null
+++ b/drivers/video/backlight/tps611xx_bl.c
@@ -0,0 +1,494 @@
+/*
+ * Simple driver for Texas Instruments TPS611XX Backlight driver chip
+ * using EasyScale Interface. It supports TPS61158, TPS61161,
+ * TPS61163 and TPS61165.
+ *
+ * Copyright (C) 2014 Texas Instruments
+ * Author: Daniel Jeong <gshark.jeong@gmail.com>
+ * Ldd Mlp <ldd-mlp@list.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/backlight.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/tps611xx_bl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define CMD_FORWARD 0
+#define CMD_BACKWARD 1
+
+enum tps611xx_id {
+ TPS61158_ID = 0,
+ TPS61161_ID,
+ TPS61163_ID,
+ TPS61165_ID,
+};
+
+/*
+ * easyscale time spec
+ * @es_delay : es delay time(ns)
+ * @es_det : es detection time(ns)
+ * @start : start time of data stream(ns)
+ * @eos : end time of data stream(ns)
+ * @reset : ic shutdown time(ms)
+ * @logic_1_low : low time high bit(ns)
+ * @logic_0_low : low time low bit(ns)
+ * @ackn : duation of ack condistion(ns)
+ * @ack_poll : ack polling duration(ns)
+ */
+struct tps611xx_time {
+ unsigned int es_delay;
+ unsigned int es_det;
+ unsigned int start;
+ unsigned int eos;
+ unsigned int reset;
+ unsigned int logic_1_low;
+ unsigned int logic_0_low;
+ unsigned int ackn;
+ unsigned int ack_poll;
+};
+
+/*
+ * @seq : sequence of data transfer
+ * @size: size of data
+ * @brt_max : max brightness
+ * @brt_bmask : bit mask of dimming bits
+ * @rfa_bmask : bit mask of RFA(Request for Acknowledge condition)
+ */
+struct tps611xx_command {
+ int seq;
+ int size;
+ int brt_max;
+ int brt_bmask;
+ int rfa_bmask;
+};
+
+/*
+ * @id : product id
+ * @name : product name
+ * @addr : device address
+ * @cmd : es command info
+ * @time : es time info
+ */
+struct tps611xx_esdata {
+ enum tps611xx_id id;
+ char *name;
+ int addr;
+ struct tps611xx_command cmd;
+ struct tps611xx_time time;
+};
+
+struct tps611xx_bl_data {
+ struct device *dev;
+ struct backlight_device *bled;
+ struct tps611xx_platform_data *pdata;
+
+ /*
+ * @rfa_en : RFA enable (Request for Acknowledge condition)
+ * @en_gpio: enable pin gpio no.
+ * @esdata : easyscale data
+ */
+ int rfa_en;
+ unsigned int en_gpio;
+ const struct tps611xx_esdata *esdata;
+};
+
+static struct tps611xx_esdata tps611xx_info[] = {
+ [TPS61158_ID] = {
+ .id = TPS61158_ID,
+ .name = "tps61158",
+ .addr = 0x5800,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 100000,
+ .es_det = 450000,
+ .start = 3500,
+ .eos = 3500,
+ .reset = 4,
+ .logic_1_low = 5000,
+ .logic_0_low = 15000,
+ .ackn = 900000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61161_ID] = {
+ .id = TPS61161_ID,
+ .name = "tps61161",
+ .addr = 0x7200,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 120000,
+ .es_det = 280000,
+ .start = 2000,
+ .eos = 2000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61163_ID] = {
+ .id = TPS61163_ID,
+ .name = "tps61163",
+ .addr = 0x8F0000,
+ .cmd = {
+ .seq = CMD_BACKWARD,
+ .size = 24,
+ .brt_max = 511,
+ .brt_bmask = 0x1ff,
+ .rfa_bmask = 0x400
+ },
+ .time = {
+ .es_delay = 100000,
+ .es_det = 260000,
+ .start = 2000,
+ .eos = 2000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+
+ [TPS61165_ID] = {
+ .id = TPS61165_ID,
+ .name = "tps61165",
+ .addr = 0x7200,
+ .cmd = {
+ .seq = CMD_FORWARD,
+ .size = 16,
+ .brt_max = 31,
+ .brt_bmask = 0x1f,
+ .rfa_bmask = 0x80
+ },
+ .time = {
+ .es_delay = 120000,
+ .es_det = 280000,
+ .start = 4000,
+ .eos = 4000,
+ .reset = 3,
+ .logic_1_low = 3000,
+ .logic_0_low = 7000,
+ .ackn = 512000,
+ .ack_poll = 2000
+ },
+ },
+};
+
+static int tps611xx_bl_update_status(struct backlight_device *bl)
+{
+ struct tps611xx_bl_data *pchip = bl_get_data(bl);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+ int data_in, t_low, t_logic, max_bmask;
+ unsigned long flags;
+
+ data_in = esdata->addr | (bl->props.brightness & esdata->cmd.brt_bmask);
+ if (pchip->rfa_en)
+ data_in |= esdata->cmd.rfa_bmask;
+
+ max_bmask = 0x1 << esdata->cmd.size;
+ t_logic = esdata->time.logic_1_low + esdata->time.logic_0_low;
+
+ local_irq_save(flags);
+ /* t_start : 2us high before data byte */
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.start);
+
+ /* forward command transfer */
+ if (esdata->cmd.seq = CMD_FORWARD) {
+ int addr_bmask = max_bmask >> 8;
+
+ for (max_bmask >>= 1; max_bmask > 0x0; max_bmask >>= 1) {
+ if (data_in & max_bmask)
+ t_low = esdata->time.logic_1_low;
+ else
+ t_low = esdata->time.logic_0_low;
+
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(t_low);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(t_logic - t_low);
+
+ if (max_bmask = addr_bmask) {
+ gpio_direction_output(pchip->en_gpio, 0);
+ /* t_eos : low after address byte */
+ ndelay(esdata->time.eos);
+ gpio_direction_output(pchip->en_gpio, 1);
+ /* t_start : high before data byte */
+ ndelay(esdata->time.start);
+ }
+ }
+ } else {
+ /* backward command tansfer */
+ int bmask;
+
+ for (bmask = 0x01; bmask < max_bmask; bmask <<= 1) {
+ if (data_in & bmask)
+ t_low = esdata->time.logic_1_low;
+ else
+ t_low = esdata->time.logic_0_low;
+
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(t_low);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(t_logic - t_low);
+ }
+ }
+
+ /*
+ * t_eos : low after address byte
+ * t_ackVal is also t_eos
+ */
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.eos);
+
+ /* RFA management */
+ if (pchip->rfa_en) {
+ int max_ack_time = esdata->time.ackn;
+ /* set input */
+ gpio_direction_input(pchip->en_gpio);
+ /* read acknowledge from chip */
+ while (max_ack_time > 0) {
+ if (gpio_get_value(pchip->en_gpio) = 0)
+ break;
+ max_ack_time -= esdata->time.ack_poll;
+ }
+ if (max_ack_time <= 0)
+ dev_err(pchip->dev,
+ "easyscale : no ack from %s\n", esdata->name);
+ else
+ ndelay(max_ack_time);
+ }
+ gpio_direction_output(pchip->en_gpio, 1);
+ local_irq_restore(flags);
+
+ return bl->props.brightness;
+}
+
+static int tps611xx_bl_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops tps611xx_bl_ops = {
+ .update_status = tps611xx_bl_update_status,
+ .get_brightness = tps611xx_bl_get_brightness,
+};
+
+static ssize_t tps611xx_enable_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ struct tps611xx_bl_data *pchip = dev_get_drvdata(dev);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+ unsigned long flags;
+ unsigned int input;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &input);
+ if (ret)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ if (input = 0) {
+ /* chip disable */
+ gpio_direction_output(pchip->en_gpio, 0);
+ /* low more than reset ms to reset */
+ mdelay(esdata->time.reset);
+ } else {
+ /* easyscale detection window */
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.es_delay);
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.es_det);
+ gpio_direction_output(pchip->en_gpio, 1);
+ }
+ local_irq_restore(flags);
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR, NULL, tps611xx_enable_store);
+
+#ifdef CONFIG_OF
+static const struct of_device_id tps611xx_backlight_of_match[] = {
+ {.compatible = "ti,tps61158_bl",.data = &tps611xx_info[TPS61158_ID]},
+ {.compatible = "ti,tps61161_bl",.data = &tps611xx_info[TPS61161_ID]},
+ {.compatible = "ti,tps61163_bl",.data = &tps611xx_info[TPS61163_ID]},
+ {.compatible = "ti,tps61165_bl",.data = &tps611xx_info[TPS61165_ID]},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, tps611xx_backlight_of_match);
+
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+ struct device *dev = pchip->dev;
+ struct device_node *node = dev->of_node;
+ const struct of_device_id *of_id + of_match_device(tps611xx_backlight_of_match, dev);
+ u32 value;
+ int ret;
+
+ if (!node)
+ return -ENODEV;
+
+ if (!of_id || !of_id->data) {
+ dev_err(dev, "Failed to find tps611xx chip id\n");
+ return -EFAULT;
+ }
+ pchip->esdata = of_id->data;
+
+ ret = of_property_read_u32(node, "en_gpio_num", &value);
+ if (ret < 0)
+ return ret;
+ pchip->en_gpio = value;
+ ret = of_property_read_u32(node, "rfa_en", &value);
+ if (ret < 0)
+ return ret;
+ pchip->rfa_en = value;
+
+ return 0;
+}
+#else
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+ return -ENODEV;
+}
+#endif
+
+static int tps611xx_backlight_probe(struct platform_device *pdev)
+{
+ struct tps611xx_bl_data *pchip;
+ struct backlight_properties props;
+ const struct tps611xx_esdata *esdata;
+ struct tps611xx_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ unsigned long flags;
+ int ret;
+
+ pchip = devm_kzalloc(&pdev->dev,
+ sizeof(struct tps611xx_bl_data), GFP_KERNEL);
+ if (pchip = NULL)
+ return -ENOMEM;
+ pchip->dev = &pdev->dev;
+
+ if (pdata = NULL) {
+ ret = tps611xx_backlight_parse_dt(pchip);
+ if (ret < 0)
+ return ret;
+ } else {
+ pchip->rfa_en = pdata->rfa_en;
+ pchip->en_gpio = pdata->en_gpio_num;
+ pchip->esdata = (const struct tps611xx_esdata *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+ esdata = pchip->esdata;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.brightness = esdata->cmd.brt_max;
+ props.max_brightness = esdata->cmd.brt_max;
+ props.type = BACKLIGHT_RAW;
+ pchip->bled + devm_backlight_device_register(pchip->dev, TPS611XX_NAME,
+ pchip->dev, pchip,
+ &tps611xx_bl_ops, &props);
+ if (IS_ERR(pchip->bled))
+ return PTR_ERR(pchip->bled);
+
+ /* for enable/disable */
+ ret = device_create_file(&(pchip->bled->dev), &dev_attr_enable);
+ if (ret < 0) {
+ dev_err(pchip->dev, "failed : add sysfs entries\n");
+ return ret;
+ }
+ platform_set_drvdata(pdev, pchip);
+
+ /* EasyScale init */
+ ret = gpio_request_one(pchip->en_gpio, GPIOF_OUT_INIT_HIGH, "tps611xx");
+ if (ret) {
+ device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+ dev_err(pchip->dev, "failed : get gpio %d\n", pchip->en_gpio);
+ return ret;
+ }
+
+ /*
+ * ES Detection Window
+ * - ES detect delay
+ * - ES detect time
+ */
+ local_irq_save(flags);
+ gpio_direction_output(pchip->en_gpio, 1);
+ ndelay(esdata->time.es_delay);
+ gpio_direction_output(pchip->en_gpio, 0);
+ ndelay(esdata->time.es_det);
+ gpio_direction_output(pchip->en_gpio, 1);
+ local_irq_restore(flags);
+ dev_info(pchip->dev,
+ "%s EasyScale is initialized\n", pchip->esdata->name);
+ return 0;
+}
+
+static int tps611xx_backlight_remove(struct platform_device *pdev)
+{
+ struct tps611xx_bl_data *pchip = platform_get_drvdata(pdev);
+ const struct tps611xx_esdata *esdata = pchip->esdata;
+
+ device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+ gpio_direction_output(pchip->en_gpio, 0);
+ mdelay(esdata->time.reset);
+ return 0;
+}
+
+static const struct platform_device_id tps611xx_id_table[] = {
+ {TPS61158_NAME, (unsigned long)&tps611xx_info[TPS61158_ID]},
+ {TPS61161_NAME, (unsigned long)&tps611xx_info[TPS61161_ID]},
+ {TPS61163_NAME, (unsigned long)&tps611xx_info[TPS61163_ID]},
+ {TPS61165_NAME, (unsigned long)&tps611xx_info[TPS61165_ID]},
+ {}
+};
+
+static struct platform_driver tps611xx_backlight_driver = {
+ .driver = {
+ .name = TPS611XX_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tps611xx_backlight_of_match),
+ },
+ .probe = tps611xx_backlight_probe,
+ .remove = tps611xx_backlight_remove,
+ .id_table = tps611xx_id_table,
+};
+
+module_platform_driver(tps611xx_backlight_driver);
+
+MODULE_DESCRIPTION("EasyScale based tps611xx Backlight Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps611xx_bl");
diff --git a/include/linux/platform_data/tps611xx_bl.h b/include/linux/platform_data/tps611xx_bl.h
new file mode 100644
index 0000000..73d1f08
--- /dev/null
+++ b/include/linux/platform_data/tps611xx_bl.h
@@ -0,0 +1,31 @@
+/*
+ * Simple driver for Texas Instruments TPS61163a Backlight driver chip
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * 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 __TPS611XX_H
+#define __TPS611XX_H
+
+#define TPS611XX_NAME "tps611xx_bl"
+#define TPS61158_NAME "tps61158_bl"
+#define TPS61161_NAME "tps61161_bl"
+#define TPS61163_NAME "tps61163_bl"
+#define TPS61165_NAME "tps61165_bl"
+
+/*
+ * struct tps61163a platform data
+ * @rfa_en : request for acknowledge
+ * @en_gpio_num : gpio number for en_pin
+ */
+struct tps611xx_platform_data {
+
+ int rfa_en;
+ unsigned int en_gpio_num;
+};
+
+#endif /* __TPS611XX_H */
--
1.7.9.5
^ permalink raw reply related
* [RFC v2 0/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-24 6:17 UTC (permalink / raw)
To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
Daniel Jeong
This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.
Daniel Jeong (2):
backlight
backlight: add new tps611xx backlight device tree support This
commit is tps611xx device tree documentation.
.../video/backlight/tps611xx-backlight.txt | 16 +
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/tps611xx_bl.c | 494 ++++++++++++++++++++
include/linux/platform_data/tps611xx_bl.h | 31 ++
5 files changed, 549 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
create mode 100644 drivers/video/backlight/tps611xx_bl.c
create mode 100644 include/linux/platform_data/tps611xx_bl.h
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Rob Herring @ 2014-06-23 17:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1403539186.3804.46.camel@hornet>
On Mon, Jun 23, 2014 at 10:59 AM, Pawel Moll <pawel.moll@arm.com> wrote:
> On Mon, 2014-06-23 at 16:43 +0100, Rob Herring wrote:
>> On Mon, Jun 23, 2014 at 9:13 AM, Pawel Moll <pawel.moll@arm.com> wrote:
>> > On Fri, 2014-06-20 at 18:09 +0100, Mark Rutland wrote:
>> >> > +- max-memory-bandwidth: maximum bandwidth in bytes per second that the
>> >> > + cell's memory interface can handle
>> >>
>> >> When should I set this, given it is optional?
>> >
>> > When there is a (significant) limitation of the bandwidth available for
>> > the cell's memory interface. One will either be told by the soc guys or
>> > will figure it out in the hard way, as we did :-(
>>
>> What are you going to do with this information? b/w is a function of
>> screen size and pixel depth. Are you going to refuse certain configs
>> based on that? Seems like someone doing their own modes should know
>> what they are doing and the limitations.
>>
>> Again, drop it until there is a defined need for this.
>
> Yes, there is. Use case: PL111 is wired up to a HDMI formatter, which
> will take everything up to 1080p. This is what a DRM driver (what/if
> it's ready) will get from the encoder driver (and rightly so). But the
> chip interconnect limitations is make the chip being able to get 480p at
> 60Hz tops.
>
> Or do you want me to add a subnode with timings for all achievable modes
> instead?
I want this solved in a generic way and not something pl111 specific.
If this is already defined then use it. If not, I would drop this for
now and get a pl111 binding in place finally.
Rob
^ permalink raw reply
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-06-23 15:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAL_Jsq+6SveWhzWPrtziTJ-tDOFaJV4sXO+r_CEhAZf=tQE6FA@mail.gmail.com>
On Mon, 2014-06-23 at 16:43 +0100, Rob Herring wrote:
> On Mon, Jun 23, 2014 at 9:13 AM, Pawel Moll <pawel.moll@arm.com> wrote:
> > On Fri, 2014-06-20 at 18:09 +0100, Mark Rutland wrote:
> >> > +- clocks-names: should contain "clcdclk" and "apb_pclk"
> >>
> >> s/clocks-names/clock-names/
> >
> > Haha - it took quite a few patch revisions to spot this one, thanks!
>
> Was this tested?
Yes it was. The typo sneaked in the documentation only, dts changes were
fine.
> >> > +- clocks: contains phandle and clock specifier pairs for the entries
> >> > + in the clock-names property. See
> >> > + Documentation/devicetree/binding/clock/clock-bindings.txt
> >> > +
> >> > +Optional properties:
> >> > +
> >> > +- arm,pl11x,framebuffer-base: a pair of two 32-bit values, address and size,
> >> > + defining the framebuffer that must be used; if not present, the
> >> > + framebuffer may be located anywhere in the memory
> >>
> >> The name is confusing: this is a base _and_ size.
> >
> > True. Can split it into two -base and -size or rename it into
> > framebuffer or video-memory.
> >
> >> When should this be used, and what is valid to point it at?
> >
> > When the hardware design determines the address the memory transactions
> > must be issued at. This is aimed at a situation (allegedly not
> > impossible) when the memory map from the CLCD's point of view is
> > different from the CPU's one (eg. the video memory is mapped at xxx for
> > the CPU and yyy for the CLCD).
>
> Humm, that sounds like what dma-ranges is for.
>
> >
> >> How does this play with memory carveouts (CMA, reserved-memory)?
> >
> > It doesn't, and wasn't intended to (the original version of the binding
> > was trying to do something like reserved-memory before it was defined),
> > but someone managed to convince me not to do this, if it's a "low level"
> > feature.
> >
> > I guess I can be re-convinced (again).
>
> NAK on this property. Convinced?
Sure. Shame you weren't so clear in any of v3 to v6 nor in the
discussions around v2.
> If this is only theoretical, then just drop it for now.
>
> >> > +- max-memory-bandwidth: maximum bandwidth in bytes per second that the
> >> > + cell's memory interface can handle
> >>
> >> When should I set this, given it is optional?
> >
> > When there is a (significant) limitation of the bandwidth available for
> > the cell's memory interface. One will either be told by the soc guys or
> > will figure it out in the hard way, as we did :-(
>
> What are you going to do with this information? b/w is a function of
> screen size and pixel depth. Are you going to refuse certain configs
> based on that? Seems like someone doing their own modes should know
> what they are doing and the limitations.
>
> Again, drop it until there is a defined need for this.
Yes, there is. Use case: PL111 is wired up to a HDMI formatter, which
will take everything up to 1080p. This is what a DRM driver (what/if
it's ready) will get from the encoder driver (and rightly so). But the
chip interconnect limitations is make the chip being able to get 480p at
60Hz tops.
Or do you want me to add a subnode with timings for all achievable modes
instead?
Pawel
^ permalink raw reply
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Rob Herring @ 2014-06-23 15:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1403532837.3804.29.camel@hornet>
On Mon, Jun 23, 2014 at 9:13 AM, Pawel Moll <pawel.moll@arm.com> wrote:
> On Fri, 2014-06-20 at 18:09 +0100, Mark Rutland wrote:
>> > +- clocks-names: should contain "clcdclk" and "apb_pclk"
>>
>> s/clocks-names/clock-names/
>
> Haha - it took quite a few patch revisions to spot this one, thanks!
Was this tested?
>> > +- clocks: contains phandle and clock specifier pairs for the entries
>> > + in the clock-names property. See
>> > + Documentation/devicetree/binding/clock/clock-bindings.txt
>> > +
>> > +Optional properties:
>> > +
>> > +- arm,pl11x,framebuffer-base: a pair of two 32-bit values, address and size,
>> > + defining the framebuffer that must be used; if not present, the
>> > + framebuffer may be located anywhere in the memory
>>
>> The name is confusing: this is a base _and_ size.
>
> True. Can split it into two -base and -size or rename it into
> framebuffer or video-memory.
>
>> When should this be used, and what is valid to point it at?
>
> When the hardware design determines the address the memory transactions
> must be issued at. This is aimed at a situation (allegedly not
> impossible) when the memory map from the CLCD's point of view is
> different from the CPU's one (eg. the video memory is mapped at xxx for
> the CPU and yyy for the CLCD).
Humm, that sounds like what dma-ranges is for.
>
>> How does this play with memory carveouts (CMA, reserved-memory)?
>
> It doesn't, and wasn't intended to (the original version of the binding
> was trying to do something like reserved-memory before it was defined),
> but someone managed to convince me not to do this, if it's a "low level"
> feature.
>
> I guess I can be re-convinced (again).
NAK on this property. Convinced?
If this is only theoretical, then just drop it for now.
>> > +- max-memory-bandwidth: maximum bandwidth in bytes per second that the
>> > + cell's memory interface can handle
>>
>> When should I set this, given it is optional?
>
> When there is a (significant) limitation of the bandwidth available for
> the cell's memory interface. One will either be told by the soc guys or
> will figure it out in the hard way, as we did :-(
What are you going to do with this information? b/w is a function of
screen size and pixel depth. Are you going to refuse certain configs
based on that? Seems like someone doing their own modes should know
what they are doing and the limitations.
Again, drop it until there is a defined need for this.
>
>> > +
>> > +Required sub-nodes:
>> > +
>> > +- port: describes LCD panel signals, following the common binding
>> > + for video transmitter interfaces; see
>> > + Documentation/devicetree/bindings/media/video-interfaces.txt;
>> > + when it is a TFT panel, the port's endpoint must define the
>> > + following property:
>> > +
>> > + - arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values,
>> > + defining the way CLD pads are wired up; this implicitly
>> > + defines available color modes, for example:
>> > + - PL111 TFT 4:4:4 panel:
>> > + arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
>> > + - PL110 TFT (1:)5:5:5 panel:
>> > + arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
>> > + - PL111 TFT (1:)5:5:5 panel:
>> > + arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
>> > + - PL111 TFT 5:6:5 panel:
>> > + arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
>> > + - PL110 and PL111 TFT 8:8:8 panel:
>> > + arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
>> > + - PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
>> > + arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
>>
>> I'm somewhat lost trying to figure out this mapping. Am I not looking at
>> this in the right way, or is there any documentation which makes this
>> clearer?
>
> Yeah, looking at this now, it definitely needs some more explanation.
> Something like this?
>
> First value contains index of the "CLD" external pin (pad)
> used as R0 (first bit of the red component), second value
> index of the pad used as G0, third value index of the pad
> used as B0, see also "LCD panel signal multiplexing details"
> paragraph in the PL11x Technical Reference Manuals.
>
> Pawel
>
^ permalink raw reply
* [PATCH v2 2/2] ARM: vexpress: Add CLCD Device Tree properties
From: Pawel Moll @ 2014-06-23 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1403535318-19333-1-git-send-email-pawel.moll@arm.com>
... for V2M-P1 motherboard CLCD (limited to 640x480 16bpp and using
dedicated video RAM bank) and for V2P-CA9 (up to 1024x768 16bpp).
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 34 ++++++++++++++++++++++++++++++++-
arch/arm/boot/dts/vexpress-v2m.dtsi | 34 ++++++++++++++++++++++++++++++++-
arch/arm/boot/dts/vexpress-v2p-ca9.dts | 31 ++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index 756c986..c14c026 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -246,9 +246,41 @@
clcd@1f0000 {
compatible = "arm,pl111", "arm,primecell";
reg = <0x1f0000 0x1000>;
+ interrupt-names = "combined";
interrupts = <14>;
clocks = <&v2m_oscclk1>, <&smbclk>;
clock-names = "clcdclk", "apb_pclk";
+ arm,pl11x,framebuffer = <0x18000000 0x00800000>;
+ max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+
+ port {
+ v2m_clcd_pads: endpoint {
+ remote-endpoint = <&v2m_clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ v2m_clcd_panel: endpoint {
+ remote-endpoint = <&v2m_clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ hsync-len = <96>;
+ vactive = <480>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <2>;
+ };
+ };
};
};
@@ -350,7 +382,7 @@
/* CLCD clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
- freq-range = <23750000 63500000>;
+ freq-range = <23750000 65000000>;
#clock-cells = <0>;
clock-output-names = "v2m:oscclk1";
};
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index ba856d6..a448420 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -245,9 +245,41 @@
clcd@1f000 {
compatible = "arm,pl111", "arm,primecell";
reg = <0x1f000 0x1000>;
+ interrupt-names = "combined";
interrupts = <14>;
clocks = <&v2m_oscclk1>, <&smbclk>;
clock-names = "clcdclk", "apb_pclk";
+ arm,pl11x,framebuffer = <0x4c000000 0x00800000>;
+ max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+
+ port {
+ v2m_clcd_pads: endpoint {
+ remote-endpoint = <&v2m_clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ v2m_clcd_panel: endpoint {
+ remote-endpoint = <&v2m_clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ hsync-len = <96>;
+ vactive = <480>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <2>;
+ };
+ };
};
};
@@ -349,7 +381,7 @@
/* CLCD clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 1>;
- freq-range = <23750000 63500000>;
+ freq-range = <23750000 65000000>;
#clock-cells = <0>;
clock-output-names = "v2m:oscclk1";
};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 62d9b22..31107cd 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -70,9 +70,40 @@
clcd@10020000 {
compatible = "arm,pl111", "arm,primecell";
reg = <0x10020000 0x1000>;
+ interrupt-names = "combined";
interrupts = <0 44 4>;
clocks = <&oscclk1>, <&oscclk2>;
clock-names = "clcdclk", "apb_pclk";
+ max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */
+
+ port {
+ clcd_pads: endpoint {
+ remote-endpoint = <&clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ clcd_panel: endpoint {
+ remote-endpoint = <&clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <63500127>;
+ hactive = <1024>;
+ hback-porch = <152>;
+ hfront-porch = <48>;
+ hsync-len = <104>;
+ vactive = <768>;
+ vback-porch = <23>;
+ vfront-porch = <3>;
+ vsync-len = <4>;
+ };
+ };
};
memory-controller@100e0000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v8 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-06-23 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1403532837.3804.29.camel@hornet>
This patch adds basic DT bindings for the PL11x CLCD cells
and make their fbdev driver use them.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
Changes since v7:
- fixed typo in "clock-names" documentation
- renamed "arm,pl11x,framebuffer-base" into "arm,pl11x,framebuffer"
as it is describing both base and size
- added some more explanation for "max-memory-bandwidth" property
- added more explanation for "arm,pl11x,tft-r0g0b0" property
Changes since v6:
- replaced in-node device-timing subnode with the standard
video interface bindings (as in: ports & endpoints); only
"panel-dpi" compatible panels are supported in the driver
Changes since v5:
- realised that dma_alloc_writecombine() is a arm-specific function;
replaced with generic dma_alloc_coherent()/dma_mmap_writecombine()
Changes since v4:
- simplified the pads description property and made it optional
Changes since v3:
- changed wording and order of interrupt-names and interrupts
properties documentation
- changed wording of arm,pl11x,framebuffer-base property
documentation
- cleaned up binding documentation indentation
Changes since v2:
- replaced video-ram phandle with arm,pl11x,framebuffer-base
- replaced panel-* properties with arm,pl11x,panel-data-pads
- replaced max-framebuffer-size with max-memory-bandwidth
- modified clcdfb_of_init_tft_panel() to use the pads
data and take differences between PL110 and PL110 into
account
Changes since v1:
- minor code cleanups as suggested by Sylwester Nawrocki
.../devicetree/bindings/video/arm,pl11x.txt | 109 +++++++++
drivers/video/fbdev/Kconfig | 1 +
drivers/video/fbdev/amba-clcd.c | 267 +++++++++++++++++++++
3 files changed, 377 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/arm,pl11x.txt
diff --git a/Documentation/devicetree/bindings/video/arm,pl11x.txt b/Documentation/devicetree/bindings/video/arm,pl11x.txt
new file mode 100644
index 0000000..32f3acf
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/arm,pl11x.txt
@@ -0,0 +1,109 @@
+* ARM PrimeCell Color LCD Controller PL110/PL111
+
+See also Documentation/devicetree/bindings/arm/primecell.txt
+
+Required properties:
+
+- compatible: must be one of:
+ "arm,pl110", "arm,primecell"
+ "arm,pl111", "arm,primecell"
+
+- reg: base address and size of the control registers block
+
+- interrupt-names: either the single entry "combined" representing a
+ combined interrupt output (CLCDINTR), or the four entries
+ "mbe", "vcomp", "lnbu", "fuf" representing the individual
+ CLCDMBEINTR, CLCDVCOMPINTR, CLCDLNBUINTR, CLCDFUFINTR interrupts
+
+- interrupts: contains an interrupt specifier for each entry in
+ interrupt-names
+
+- clock-names: should contain "clcdclk" and "apb_pclk"
+
+- clocks: contains phandle and clock specifier pairs for the entries
+ in the clock-names property. See
+ Documentation/devicetree/binding/clock/clock-bindings.txt
+
+Optional properties:
+
+- arm,pl11x,framebuffer: a pair of two 32-bit values, address and size,
+ defining the framebuffer that must be used; if not present, the
+ framebuffer may be located anywhere in the memory
+
+- max-memory-bandwidth: maximum bandwidth in bytes per second that the
+ cell's memory interface can handle; if not present, the memory
+ interface is fast enough to handle all possible video modes
+
+Required sub-nodes:
+
+- port: describes LCD panel signals, following the common binding
+ for video transmitter interfaces; see
+ Documentation/devicetree/bindings/media/video-interfaces.txt;
+ when it is a TFT panel, the port's endpoint must define the
+ following property:
+
+ - arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values,
+ defining the way CLD pads are wired up; first value
+ contains index of the "CLD" external pin (pad) used
+ as R0 (first bit of the red component), second value
+ index of the pad used as G0, third value index of the
+ pad used as B0, see also "LCD panel signal multiplexing
+ details" paragraphs in the PL110/PL111 Technical
+ Reference Manuals; this implicitly defines available
+ color modes, for example:
+ - PL111 TFT 4:4:4 panel:
+ arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
+ - PL110 TFT (1:)5:5:5 panel:
+ arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
+ - PL111 TFT (1:)5:5:5 panel:
+ arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
+ - PL111 TFT 5:6:5 panel:
+ arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
+ - PL110 and PL111 TFT 8:8:8 panel:
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ - PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
+ arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
+
+
+Example:
+
+ clcd@1f0000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0x1f0000 0x1000>;
+ interrupt-names = "combined";
+ interrupts = <14>;
+ clock-names = "clcdclk", "apb_pclk";
+ clocks = <&v2m_oscclk1>, <&smbclk>;
+ arm,pl11x,framebuffer-base = <0x18000000 0x00800000>;
+ max-memory-bandwidth = <36864000>; /* bps, 640x480@60 16bpp */
+
+ port {
+ v2m_clcd_pads: endpoint {
+ remote-endpoint = <&v2m_clcd_panel>;
+ arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+ };
+ };
+
+ };
+
+ panel {
+ compatible = "panel-dpi";
+
+ port {
+ v2m_clcd_panel: endpoint {
+ remote-endpoint = <&v2m_clcd_pads>;
+ };
+ };
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ hback-porch = <40>;
+ hfront-porch = <24>;
+ hsync-len = <96>;
+ vactive = <480>;
+ vback-porch = <32>;
+ vfront-porch = <11>;
+ vsync-len = <2>;
+ };
+ };
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 59c98bfd..a518fe5 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -280,6 +280,7 @@ config FB_ARMCLCD
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VIDEOMODE_HELPERS if OF
help
This framebuffer device driver is for the ARM PrimeCell PL110
Colour LCD controller. ARM PrimeCells provide the building
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 14d6b37..71492e9 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -26,6 +26,13 @@
#include <linux/amba/clcd.h>
#include <linux/clk.h>
#include <linux/hardirq.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_graph.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
#include <asm/sizes.h>
@@ -543,6 +550,263 @@ static int clcdfb_register(struct clcd_fb *fb)
return ret;
}
+#ifdef CONFIG_OF
+static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
+ struct fb_videomode *mode)
+{
+ int err;
+ struct display_timing timing;
+ struct videomode video;
+
+ err = of_get_display_timing(node, "panel-timing", &timing);
+ if (err)
+ return err;
+
+ videomode_from_timing(&timing, &video);
+
+ err = fb_videomode_from_videomode(&video, mode);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
+{
+ return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
+ mode->refresh);
+}
+
+static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
+ struct fb_videomode *mode)
+{
+ int err;
+ struct device_node *panel;
+ char *name;
+ int len;
+
+ panel = of_graph_get_remote_port_parent(endpoint);
+ if (!panel)
+ return -ENODEV;
+
+ /* Only directly connected DPI panels supported for now */
+ if (of_device_is_compatible(panel, "panel-dpi"))
+ err = clcdfb_of_get_dpi_panel_mode(panel, mode);
+ else
+ err = -ENOENT;
+ if (err)
+ return err;
+
+ len = clcdfb_snprintf_mode(NULL, 0, mode);
+ name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
+ clcdfb_snprintf_mode(name, len + 1, mode);
+ mode->name = name;
+
+ return 0;
+}
+
+static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
+{
+ static struct {
+ unsigned int part;
+ u32 r0, g0, b0;
+ u32 caps;
+ } panels[] = {
+ { 0x110, 1, 7, 13, CLCD_CAP_5551 },
+ { 0x110, 0, 8, 16, CLCD_CAP_888 },
+ { 0x111, 4, 14, 20, CLCD_CAP_444 },
+ { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
+ { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
+ CLCD_CAP_565 },
+ { 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
+ CLCD_CAP_565 | CLCD_CAP_888 },
+ };
+ int i;
+
+ /* Bypass pixel clock divider, data output on the falling edge */
+ fb->panel->tim2 = TIM2_BCD | TIM2_IPC;
+
+ /* TFT display, vert. comp. interrupt at the start of the back porch */
+ fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
+
+ fb->panel->caps = 0;
+
+ /* Match the setup with known variants */
+ for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
+ if (amba_part(fb->dev) != panels[i].part)
+ continue;
+ if (g0 != panels[i].g0)
+ continue;
+ if (r0 = panels[i].r0 && b0 = panels[i].b0)
+ fb->panel->caps = panels[i].caps & CLCD_CAP_RGB;
+ if (r0 = panels[i].b0 && b0 = panels[i].r0)
+ fb->panel->caps = panels[i].caps & CLCD_CAP_BGR;
+ }
+
+ return fb->panel->caps ? 0 : -EINVAL;
+}
+
+static int clcdfb_of_init_display(struct clcd_fb *fb)
+{
+ struct device_node *endpoint;
+ int err;
+ u32 max_bandwidth;
+ u32 tft_r0b0g0[3];
+
+ fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
+ if (!fb->panel)
+ return -ENOMEM;
+
+ endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
+ if (!endpoint)
+ return -ENODEV;
+
+ err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
+ if (err)
+ return err;
+
+ err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
+ &max_bandwidth);
+ if (!err)
+ fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres *
+ fb->panel->mode.yres * fb->panel->mode.refresh);
+ else
+ fb->panel->bpp = 32;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ fb->panel->cntl |= CNTL_BEBO;
+#endif
+ fb->panel->width = -1;
+ fb->panel->height = -1;
+
+ if (of_property_read_u32_array(endpoint,
+ "arm,pl11x,tft-r0g0b0-pads",
+ tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) = 0)
+ return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
+ tft_r0b0g0[1], tft_r0b0g0[2]);
+
+ return -ENOENT;
+}
+
+static int clcdfb_of_vram_setup(struct clcd_fb *fb)
+{
+ int err;
+ u32 values[2];
+ phys_addr_t phys_base;
+ size_t size;
+
+ err = clcdfb_of_init_display(fb);
+ if (err)
+ return err;
+
+ err = of_property_read_u32_array(fb->dev->dev.of_node,
+ "arm,pl11x,framebuffer", values, ARRAY_SIZE(values));
+ if (err)
+ return err;
+
+ phys_base = values[0];
+ size = values[1];
+
+ fb->fb.screen_base = ioremap(phys_base, size);
+ if (!fb->fb.screen_base)
+ return -ENOMEM;
+
+ fb->fb.fix.smem_start = phys_base;
+ fb->fb.fix.smem_len = size;
+
+ return 0;
+}
+
+static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ unsigned long off, user_size, kernel_size;
+
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ user_size = vma->vm_end - vma->vm_start;
+ kernel_size = fb->fb.fix.smem_len;
+
+ if (off >= kernel_size || user_size > (kernel_size - off))
+ return -ENXIO;
+
+ return remap_pfn_range(vma, vma->vm_start,
+ __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
+ user_size,
+ pgprot_writecombine(vma->vm_page_prot));
+}
+
+static void clcdfb_of_vram_remove(struct clcd_fb *fb)
+{
+ iounmap(fb->fb.screen_base);
+}
+
+static int clcdfb_of_dma_setup(struct clcd_fb *fb)
+{
+ unsigned long framesize;
+ dma_addr_t dma;
+ int err;
+
+ err = clcdfb_of_init_display(fb);
+ if (err)
+ return err;
+
+ framesize = fb->panel->mode.xres * fb->panel->mode.yres *
+ fb->panel->bpp / 8;
+ fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
+ &dma, GFP_KERNEL);
+ if (!fb->fb.screen_base)
+ return -ENOMEM;
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = framesize;
+
+ return 0;
+}
+
+static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+ fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void clcdfb_of_dma_remove(struct clcd_fb *fb)
+{
+ dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
+{
+ struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
+ GFP_KERNEL);
+ struct device_node *node = dev->dev.of_node;
+
+ if (!board)
+ return NULL;
+
+ board->name = of_node_full_name(node);
+ board->caps = CLCD_CAP_ALL;
+ board->check = clcdfb_check;
+ board->decode = clcdfb_decode;
+ if (of_find_property(node, "arm,pl11x,framebuffer-base", NULL)) {
+ board->setup = clcdfb_of_vram_setup;
+ board->mmap = clcdfb_of_vram_mmap;
+ board->remove = clcdfb_of_vram_remove;
+ } else {
+ board->setup = clcdfb_of_dma_setup;
+ board->mmap = clcdfb_of_dma_mmap;
+ board->remove = clcdfb_of_dma_remove;
+ }
+
+ return board;
+}
+#else
+static struct clcd_board *clcdfb_of_get_board(struct amba_dev *dev)
+{
+ return NULL;
+}
+#endif
+
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct clcd_board *board = dev_get_platdata(&dev->dev);
@@ -550,6 +814,9 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
int ret;
if (!board)
+ board = clcdfb_of_get_board(dev);
+
+ if (!board)
return -EINVAL;
ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-06-23 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140623141022.GJ32514@n2100.arm.linux.org.uk>
On Mon, 2014-06-23 at 15:10 +0100, Russell King - ARM Linux wrote:
> As far as the CLD outputs are concerned, they are standard. The PLD on
> their outputs routes the CLD bits to the 8-bit red, green and blue
> channels according to the configuration of SYS_CLCD to achieve the
> various colour formats which the CLCD does not natively provide for.
>
> So, it /is/ a PL110 with an independent external muxer.
Cool, this means that one can still use this property do define which
CLDs are wired to R/G/B-0s and make an informed decision in the driver
based on this (although with a separate compatible value it won't be
really necessary).
Pawel
^ permalink raw reply
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-06-23 14:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140620170901.GA12059@leverpostej>
On Fri, 2014-06-20 at 18:09 +0100, Mark Rutland wrote:
> > +- clocks-names: should contain "clcdclk" and "apb_pclk"
>
> s/clocks-names/clock-names/
Haha - it took quite a few patch revisions to spot this one, thanks!
> > +
> > +- clocks: contains phandle and clock specifier pairs for the entries
> > + in the clock-names property. See
> > + Documentation/devicetree/binding/clock/clock-bindings.txt
> > +
> > +Optional properties:
> > +
> > +- arm,pl11x,framebuffer-base: a pair of two 32-bit values, address and size,
> > + defining the framebuffer that must be used; if not present, the
> > + framebuffer may be located anywhere in the memory
>
> The name is confusing: this is a base _and_ size.
True. Can split it into two -base and -size or rename it into
framebuffer or video-memory.
> When should this be used, and what is valid to point it at?
When the hardware design determines the address the memory transactions
must be issued at. This is aimed at a situation (allegedly not
impossible) when the memory map from the CLCD's point of view is
different from the CPU's one (eg. the video memory is mapped at xxx for
the CPU and yyy for the CLCD).
> How does this play with memory carveouts (CMA, reserved-memory)?
It doesn't, and wasn't intended to (the original version of the binding
was trying to do something like reserved-memory before it was defined),
but someone managed to convince me not to do this, if it's a "low level"
feature.
I guess I can be re-convinced (again).
> > +- max-memory-bandwidth: maximum bandwidth in bytes per second that the
> > + cell's memory interface can handle
>
> When should I set this, given it is optional?
When there is a (significant) limitation of the bandwidth available for
the cell's memory interface. One will either be told by the soc guys or
will figure it out in the hard way, as we did :-(
> > +
> > +Required sub-nodes:
> > +
> > +- port: describes LCD panel signals, following the common binding
> > + for video transmitter interfaces; see
> > + Documentation/devicetree/bindings/media/video-interfaces.txt;
> > + when it is a TFT panel, the port's endpoint must define the
> > + following property:
> > +
> > + - arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values,
> > + defining the way CLD pads are wired up; this implicitly
> > + defines available color modes, for example:
> > + - PL111 TFT 4:4:4 panel:
> > + arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
> > + - PL110 TFT (1:)5:5:5 panel:
> > + arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
> > + - PL111 TFT (1:)5:5:5 panel:
> > + arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
> > + - PL111 TFT 5:6:5 panel:
> > + arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
> > + - PL110 and PL111 TFT 8:8:8 panel:
> > + arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
> > + - PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
> > + arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
>
> I'm somewhat lost trying to figure out this mapping. Am I not looking at
> this in the right way, or is there any documentation which makes this
> clearer?
Yeah, looking at this now, it definitely needs some more explanation.
Something like this?
First value contains index of the "CLD" external pin (pad)
used as R0 (first bit of the red component), second value
index of the pad used as G0, third value index of the pad
used as B0, see also "LCD panel signal multiplexing details"
paragraph in the PL11x Technical Reference Manuals.
Pawel
^ permalink raw reply
* Re: [PATCH 3/10] video: use safer test on the result of find_first_zero_bit
From: Julia Lawall @ 2014-06-23 14:12 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Julia Lawall, Jean-Christophe Plagniol-Villard, kernel-janitors,
linux-fbdev, linux-kernel
In-Reply-To: <53A81470.5030606@ti.com>
On Mon, 23 Jun 2014, Tomi Valkeinen wrote:
> On 04/06/14 12:07, Julia Lawall wrote:
> > From: Julia Lawall <Julia.Lawall@lip6.fr>
> >
> > Find_first_zero_bit considers BITS_PER_LONG bits at a time, and thus may
> > return a larger number than the maximum position argument if that position
> > is not a multiple of BITS_PER_LONG.
>
> Thanks, queued for 3.17.
No, sorry you can drop it. It doesn't hurt anything, but it is not
necessary either. Returning a larger number is actually not possible.
julia
^ permalink raw reply
* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Russell King - ARM Linux @ 2014-06-23 14:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1403531535.3804.11.camel@hornet>
On Mon, Jun 23, 2014 at 02:52:15PM +0100, Pawel Moll wrote:
> On Fri, 2014-06-20 at 23:27 +0100, Peter Maydell wrote:
> > How does this work for boards like the versatilepb which have a
> > mux between a PL110 and the TFT, allowing it to efffectively
> > rewire the pads at runtime under control of the SYS_CLCD
> > sysreg (to give a wider range of colour modes than the
> > PL110 supports natively)?
>
> The particular case you're referring has been already discussed several
> times, and the bottom line here is that it's not PL111 compatible (there
> are more changes than just the mux) and will need separate "compatible"
> value and some tweaks in the driver (in the places currently doing
> CONFIG_ARCH_VERSATILE).
>
> Now, if it was PL111 with an external, independent muxer, the pads
> description would still hold its value (PL111's R would still be wired
> up at a particular pad etc.) and the display pipeline drivers would have
> to handle the case.
Err. Somehow, I don't think you understand the hardware you're messing
with there. Remember, I wrote support all the support code for the
PL11x and supporting this.
Yes, the Versatile PL110 has one difference: it has the IENB and CNTL
registers swapped compared to the conventional PL110 devices. This can
be handled via an appropriate compatible property. The hardware cursor
registers are also omitted, but that's irrelevant as we don't use that.
Other than that, it's a standard PL110. Connected to its outputs is a
PLD. Inside the PLD is a mux controlled via the SYS_CLCD register.
As far as the CLD outputs are concerned, they are standard. The PLD on
their outputs routes the CLD bits to the 8-bit red, green and blue
channels according to the configuration of SYS_CLCD to achieve the
various colour formats which the CLCD does not natively provide for.
So, it /is/ a PL110 with an independent external muxer.
--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox