Skip to content

Commit

Permalink
Merge tag 'omapdrm-5.2' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/tomba/linux into drm-next

omapdrm changes for 5.2

- Implement drm_bridge and drm_panel support for omapdrm
- Drop omapdrm's panel-dpi, tfp410 and connector-dvi drivers
- New DRM_BUS_FLAG_*_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags
- Improvements to tfp410 driver
- OSD070T1718-19TS panel support to simple-panel
- panel-tpo-td028ttec1 backlight support

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/670dc1ce-feaf-b88e-780f-b99251b88a82@ti.com
  • Loading branch information
Dave Airlie committed Mar 25, 2019
2 parents 8c2ffd9 + 5880955 commit b9e687f
Show file tree
Hide file tree
Showing 58 changed files with 1,206 additions and 2,098 deletions.
24 changes: 18 additions & 6 deletions Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,33 @@ Required properties:

Optional properties:
- powerdown-gpios: power-down gpio
- reg: I2C address. If and only if present the device node
should be placed into the i2c controller node where the
tfp410 i2c is connected to.
- reg: I2C address. If and only if present the device node should be placed
into the I2C controller node where the TFP410 I2C is connected to.
- ti,deskew: data de-skew in 350ps increments, from -4 to +3, as configured
through th DK[3:1] pins. This property shall be present only if the TFP410
is not connected through I2C.

Required nodes:
- Video port 0 for DPI input [1].
- Video port 1 for DVI output [1].

[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
This device has two video ports. Their connections are modeled using the OF
graph bindings specified in [1]. Each port node shall have a single endpoint.

- Port 0 is the DPI input port. Its endpoint subnode shall contain a
pclk-sample property and a remote-endpoint property as specified in [1].

- Port 1 is the DVI output port. Its endpoint subnode shall contain a
remote-endpoint property is specified in [1].

[1] Documentation/devicetree/bindings/media/video-interfaces.txt


Example
-------

tfp410: encoder@0 {
compatible = "ti,tfp410";
powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
ti,deskew = <4>;

ports {
#address-cells = <1>;
Expand All @@ -31,6 +42,7 @@ tfp410: encoder@0 {
reg = <0>;

tfp410_in: endpoint@0 {
pclk-sample = <1>;
remote-endpoint = <&dpi_out>;
};
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
OSD Displays OSD070T1718-19TS 7" WVGA TFT LCD panel

Required properties:
- compatible: shall be "osddisplays,osd070t1718-19ts"
- power-supply: see simple-panel.txt

Optional properties:
- backlight: see simple-panel.txt

This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory. No other simple-panel properties than
the ones specified herein are valid.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Required properties:

Optional properties:
- label: a symbolic name for the panel
- backlight: phandle of the backlight device

Required nodes:
- Video port for DPI input
Expand All @@ -21,6 +22,7 @@ lcd-panel: td028ttec1@0 {
spi-cpha;

label = "lcd";
backlight = <&backlight>;
port {
lcd_in: endpoint {
remote-endpoint = <&dpi_out>;
Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/vendor-prefixes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ oranth Shenzhen Oranth Technology Co., Ltd.
ORCL Oracle Corporation
orisetech Orise Technology
ortustech Ortus Technology Co., Ltd.
osddisplays OSD Displays
ovti OmniVision Technologies
oxsemi Oxford Semiconductor, Ltd.
panasonic Panasonic Corporation
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/bridge/dumb-vga-dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ static int dumb_vga_remove(struct platform_device *pdev)
*/
static const struct drm_bridge_timings default_dac_timings = {
/* Timing specifications, datasheet page 7 */
.sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
.setup_time_ps = 500,
.hold_time_ps = 1500,
};
Expand All @@ -245,7 +245,7 @@ static const struct drm_bridge_timings default_dac_timings = {
*/
static const struct drm_bridge_timings ti_ths8134_dac_timings = {
/* From timing diagram, datasheet page 9 */
.sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 12 */
.setup_time_ps = 3000,
/* I guess this means latched input */
Expand All @@ -258,7 +258,7 @@ static const struct drm_bridge_timings ti_ths8134_dac_timings = {
*/
static const struct drm_bridge_timings ti_ths8135_dac_timings = {
/* From timing diagram, datasheet page 14 */
.sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 16 */
.setup_time_ps = 2000,
.hold_time_ps = 500,
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/bridge/tc358767.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,8 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
&bus_format, 1);
tc->connector.display_info.bus_flags =
DRM_BUS_FLAG_DE_HIGH |
DRM_BUS_FLAG_PIXDATA_NEGEDGE |
DRM_BUS_FLAG_SYNC_NEGEDGE;
DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE |
DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
drm_connector_attach_encoder(&tc->connector, tc->bridge.encoder);

return 0;
Expand Down
109 changes: 105 additions & 4 deletions drivers/gpu/drm/bridge/ti-tfp410.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@
struct tfp410 {
struct drm_bridge bridge;
struct drm_connector connector;
unsigned int connector_type;

struct i2c_adapter *ddc;
struct gpio_desc *hpd;
struct delayed_work hpd_work;
struct gpio_desc *powerdown;

struct drm_bridge_timings timings;

struct device *dev;
};
Expand Down Expand Up @@ -126,7 +130,7 @@ static int tfp410_attach(struct drm_bridge *bridge)
drm_connector_helper_add(&dvi->connector,
&tfp410_con_helper_funcs);
ret = drm_connector_init(bridge->dev, &dvi->connector,
&tfp410_con_funcs, DRM_MODE_CONNECTOR_HDMIA);
&tfp410_con_funcs, dvi->connector_type);
if (ret) {
dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
return ret;
Expand All @@ -138,8 +142,24 @@ static int tfp410_attach(struct drm_bridge *bridge)
return 0;
}

static void tfp410_enable(struct drm_bridge *bridge)
{
struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);

gpiod_set_value_cansleep(dvi->powerdown, 0);
}

static void tfp410_disable(struct drm_bridge *bridge)
{
struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);

gpiod_set_value_cansleep(dvi->powerdown, 1);
}

static const struct drm_bridge_funcs tfp410_bridge_funcs = {
.attach = tfp410_attach,
.enable = tfp410_enable,
.disable = tfp410_disable,
};

static void tfp410_hpd_work_func(struct work_struct *work)
Expand All @@ -162,6 +182,70 @@ static irqreturn_t tfp410_hpd_irq_thread(int irq, void *arg)
return IRQ_HANDLED;
}

static const struct drm_bridge_timings tfp410_default_timings = {
.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
| DRM_BUS_FLAG_DE_HIGH,
.setup_time_ps = 1200,
.hold_time_ps = 1300,
};

static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
{
struct drm_bridge_timings *timings = &dvi->timings;
struct device_node *ep;
u32 pclk_sample = 0;
s32 deskew = 0;

/* Start with defaults. */
*timings = tfp410_default_timings;

if (i2c)
/*
* In I2C mode timings are configured through the I2C interface.
* As the driver doesn't support I2C configuration yet, we just
* go with the defaults (BSEL=1, DSEL=1, DKEN=0, EDGE=1).
*/
return 0;

/*
* In non-I2C mode, timings are configured through the BSEL, DSEL, DKEN
* and EDGE pins. They are specified in DT through endpoint properties
* and vendor-specific properties.
*/
ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
if (!ep)
return -EINVAL;

/* Get the sampling edge from the endpoint. */
of_property_read_u32(ep, "pclk-sample", &pclk_sample);
of_node_put(ep);

timings->input_bus_flags = DRM_BUS_FLAG_DE_HIGH;

switch (pclk_sample) {
case 0:
timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
| DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
break;
case 1:
timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
| DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE;
break;
default:
return -EINVAL;
}

/* Get the setup and hold time from vendor-specific properties. */
of_property_read_u32(dvi->dev->of_node, "ti,deskew", (u32 *)&deskew);
if (deskew < -4 || deskew > 3)
return -EINVAL;

timings->setup_time_ps = min(0, 1200 - 350 * deskew);
timings->hold_time_ps = min(0, 1300 + 350 * deskew);

return 0;
}

static int tfp410_get_connector_properties(struct tfp410 *dvi)
{
struct device_node *connector_node, *ddc_phandle;
Expand All @@ -172,6 +256,11 @@ static int tfp410_get_connector_properties(struct tfp410 *dvi)
if (!connector_node)
return -ENODEV;

if (of_device_is_compatible(connector_node, "hdmi-connector"))
dvi->connector_type = DRM_MODE_CONNECTOR_HDMIA;
else
dvi->connector_type = DRM_MODE_CONNECTOR_DVID;

dvi->hpd = fwnode_get_named_gpiod(&connector_node->fwnode,
"hpd-gpios", 0, GPIOD_IN, "hpd");
if (IS_ERR(dvi->hpd)) {
Expand Down Expand Up @@ -200,7 +289,7 @@ static int tfp410_get_connector_properties(struct tfp410 *dvi)
return ret;
}

static int tfp410_init(struct device *dev)
static int tfp410_init(struct device *dev, bool i2c)
{
struct tfp410 *dvi;
int ret;
Expand All @@ -217,12 +306,24 @@ static int tfp410_init(struct device *dev)

dvi->bridge.funcs = &tfp410_bridge_funcs;
dvi->bridge.of_node = dev->of_node;
dvi->bridge.timings = &dvi->timings;
dvi->dev = dev;

ret = tfp410_parse_timings(dvi, i2c);
if (ret)
goto fail;

ret = tfp410_get_connector_properties(dvi);
if (ret)
goto fail;

dvi->powerdown = devm_gpiod_get_optional(dev, "powerdown",
GPIOD_OUT_HIGH);
if (IS_ERR(dvi->powerdown)) {
dev_err(dev, "failed to parse powerdown gpio\n");
return PTR_ERR(dvi->powerdown);
}

if (dvi->hpd) {
INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);

Expand Down Expand Up @@ -264,7 +365,7 @@ static int tfp410_fini(struct device *dev)

static int tfp410_probe(struct platform_device *pdev)
{
return tfp410_init(&pdev->dev);
return tfp410_init(&pdev->dev, false);
}

static int tfp410_remove(struct platform_device *pdev)
Expand Down Expand Up @@ -301,7 +402,7 @@ static int tfp410_i2c_probe(struct i2c_client *client,
return -ENXIO;
}

return tfp410_init(&client->dev);
return tfp410_init(&client->dev, true);
}

static int tfp410_i2c_remove(struct i2c_client *client)
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_atomic_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ mode_fixup(struct drm_atomic_state *state)
static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
struct drm_encoder *encoder,
struct drm_crtc *crtc,
struct drm_display_mode *mode)
const struct drm_display_mode *mode)
{
enum drm_mode_status ret;

Expand Down Expand Up @@ -534,7 +534,7 @@ mode_valid(struct drm_atomic_state *state)
struct drm_crtc *crtc = conn_state->crtc;
struct drm_crtc_state *crtc_state;
enum drm_mode_status mode_status;
struct drm_display_mode *mode;
const struct drm_display_mode *mode;

if (!crtc || !encoder)
continue;
Expand Down
12 changes: 6 additions & 6 deletions drivers/gpu/drm/drm_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,22 +655,22 @@ EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
* @bus_flags: information about pixelclk, sync and DE polarity will be stored
* here
*
* Sets DRM_BUS_FLAG_DE_(LOW|HIGH), DRM_BUS_FLAG_PIXDATA_(POS|NEG)EDGE and
* DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS
* Sets DRM_BUS_FLAG_DE_(LOW|HIGH), DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE
* and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS
* found in @vm
*/
void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
{
*bus_flags = 0;
if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
*bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
*bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;

if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE)
*bus_flags |= DRM_BUS_FLAG_SYNC_POSEDGE;
*bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE;
if (vm->flags & DISPLAY_FLAGS_SYNC_NEGEDGE)
*bus_flags |= DRM_BUS_FLAG_SYNC_NEGEDGE;
*bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;

if (vm->flags & DISPLAY_FLAGS_DE_LOW)
*bus_flags |= DRM_BUS_FLAG_DE_LOW;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
drm_display_mode_to_videomode(mode, &vm);

/* INV_PXCK as default (most display sample data on rising edge) */
if (!(con->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE))
if (!(con->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE))
pol |= DCU_SYN_POL_INV_PXCK;

if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/imx/ipuv3-crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
sig_cfg.enable_pol = !(imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_LOW);
/* Default to driving pixel data on negative clock edges */
sig_cfg.clk_pol = !!(imx_crtc_state->bus_flags &
DRM_BUS_FLAG_PIXDATA_POSEDGE);
DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE);
sig_cfg.bus_format = imx_crtc_state->bus_format;
sig_cfg.v_to_h_sync = 0;
sig_cfg.hsync_pin = imx_crtc_state->di_hsync_pin;
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/mxsfb/mxsfb_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,12 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
if (!(bus_flags & DRM_BUS_FLAG_DE_LOW))
vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
/*
* DRM_BUS_FLAG_PIXDATA_ defines are controller centric,
* DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric,
* controllers VDCTRL0_DOTCLK is display centric.
* Drive on positive edge -> display samples on falling edge
* DRM_BUS_FLAG_PIXDATA_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
* DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
*/
if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;

writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0);
Expand Down
Loading

0 comments on commit b9e687f

Please sign in to comment.