-Innolux TV123WAM 12.3 inch eDP 2K display panel
+Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
Required properties:
-- compatible: should be "innolux,tv123wam"
+- compatible: should be "innolux,p120zdg-bf1"
- power-supply: regulator to provide the supply voltage
Optional properties:
- enable-gpios: GPIO pin to enable or disable the panel
- backlight: phandle of the backlight device attached to the panel
+- no-hpd: If HPD isn't hooked up; add this property.
Example:
panel_edp: panel-edp {
- compatible = "innolux,tv123wam";
+ compatible = "innolux,p120zdg-bf1";
enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
power-supply = <&pm8916_l2>;
backlight = <&backlight>;
+ no-hpd;
};
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- enable-gpios: GPIO pin to enable or disable the panel
- backlight: phandle of the backlight device attached to the panel
+- no-hpd: This panel is supposed to communicate that it's ready via HPD
+ (hot plug detect) signal, but the signal isn't hooked up so we should
+ hardcode the max delay from the panel spec when powering up the panel.
Example:
unsigned int val;
int ret;
- /*
- * FIXME:
- * This 70ms was found necessary by experimentation. If it's not
- * present, link training fails. It seems like it can go anywhere from
- * pre_enable() up to semi-auto link training initiation below.
- *
- * Neither the datasheet for the bridge nor the panel tested mention a
- * delay of this magnitude in the timing requirements. So for now, add
- * the mystery delay until someone figures out a better fix.
- */
- msleep(70);
-
/* DSI_A lane config */
val = CHA_DSI_LANES(4 - pdata->dsi->lanes);
regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
/* configure bridge ref_clk */
ti_sn_bridge_set_refclk_freq(pdata);
- /* in case drm_panel is connected then HPD is not supported */
+ /*
+ * HPD on this bridge chip is a bit useless. This is an eDP bridge
+ * so the HPD is an internal signal that's only there to signal that
+ * the panel is done powering up. ...but the bridge chip debounces
+ * this signal by between 100 ms and 400 ms (depending on process,
+ * voltage, and temperate--I measured it at about 200 ms). One
+ * particular panel asserted HPD 84 ms after it was powered on meaning
+ * that we saw HPD 284 ms after power on. ...but the same panel said
+ * that instead of looking at HPD you could just hardcode a delay of
+ * 200 ms. We'll assume that the panel driver will have the hardcoded
+ * delay in its prepare and always disable HPD.
+ *
+ * If HPD somehow makes sense on some future panel we'll have to
+ * change this to be conditional on someone specifying that HPD should
+ * be used.
+ */
regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
HPD_DISABLE);
/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
{ "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
+ /* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
+ { "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
+
/* Belinea 10 15 55 */
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
/**
* @prepare: the time (in milliseconds) that it takes for the panel to
* become ready and start receiving video data
+ * @hpd_absent_delay: Add this to the prepare delay if we know Hot
+ * Plug Detect isn't used.
* @enable: the time (in milliseconds) that it takes for the panel to
* display the first valid frame after starting to receive
* video data
*/
struct {
unsigned int prepare;
+ unsigned int hpd_absent_delay;
unsigned int enable;
unsigned int disable;
unsigned int unprepare;
struct drm_panel base;
bool prepared;
bool enabled;
+ bool no_hpd;
const struct panel_desc *desc;
static int panel_simple_prepare(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);
+ unsigned int delay;
int err;
if (p->prepared)
gpiod_set_value_cansleep(p->enable_gpio, 1);
- if (p->desc->delay.prepare)
- msleep(p->desc->delay.prepare);
+ delay = p->desc->delay.prepare;
+ if (p->no_hpd)
+ delay += p->desc->delay.hpd_absent_delay;
+ if (delay)
+ msleep(delay);
p->prepared = true;
panel->prepared = false;
panel->desc = desc;
+ panel->no_hpd = of_property_read_bool(dev->of_node, "no-hpd");
+
panel->supply = devm_regulator_get(dev, "power");
if (IS_ERR(panel->supply))
return PTR_ERR(panel->supply);
},
};
-static const struct drm_display_mode innolux_tv123wam_mode = {
+static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
.clock = 206016,
.hdisplay = 2160,
.hsync_start = 2160 + 48,
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
};
-static const struct panel_desc innolux_tv123wam = {
- .modes = &innolux_tv123wam_mode,
+static const struct panel_desc innolux_p120zdg_bf1 = {
+ .modes = &innolux_p120zdg_bf1_mode,
.num_modes = 1,
.bpc = 8,
.size = {
- .width = 259,
- .height = 173,
+ .width = 254,
+ .height = 169,
},
.delay = {
+ .hpd_absent_delay = 200,
.unprepare = 500,
},
};
.compatible = "innolux,n156bge-l21",
.data = &innolux_n156bge_l21,
}, {
- .compatible = "innolux,tv123wam",
- .data = &innolux_tv123wam,
+ .compatible = "innolux,p120zdg-bf1",
+ .data = &innolux_p120zdg_bf1,
}, {
.compatible = "innolux,zj070na-01p",
.data = &innolux_zj070na_01p,