Skip to content

Commit

Permalink
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next
Browse files Browse the repository at this point in the history
Pull in drm-next with Dave's DP MST support so that I can merge some
conflicting patches which also touch the driver load sequencing around
interrupt handling.

Conflicts:
	drivers/gpu/drm/i915/intel_display.c
	drivers/gpu/drm/i915/intel_dp.c

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Jul 29, 2014
2 parents 4877776 + e05444b commit 4dac3ed
Show file tree
Hide file tree
Showing 155 changed files with 6,469 additions and 1,218 deletions.
12 changes: 9 additions & 3 deletions Documentation/DocBook/drm.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,7 @@ int max_width, max_height;</synopsis>
The connector is then registered with a call to
<function>drm_connector_init</function> with a pointer to the connector
functions and a connector type, and exposed through sysfs with a call to
<function>drm_sysfs_connector_add</function>.
<function>drm_connector_register</function>.
</para>
<para>
Supported connector types are
Expand Down Expand Up @@ -1768,7 +1768,7 @@ int max_width, max_height;</synopsis>
(<function>drm_encoder_cleanup</function>) and connectors
(<function>drm_connector_cleanup</function>). Furthermore, connectors
that have been added to sysfs must be removed by a call to
<function>drm_sysfs_connector_remove</function> before calling
<function>drm_connector_unregister</function> before calling
<function>drm_connector_cleanup</function>.
</para>
<para>
Expand Down Expand Up @@ -1813,7 +1813,7 @@ void intel_crt_init(struct drm_device *dev)
drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_sysfs_connector_add(connector);
drm_connector_register(connector);
}]]></programlisting>
<para>
In the example above (taken from the i915 driver), a CRTC, connector and
Expand Down Expand Up @@ -2336,6 +2336,12 @@ void intel_crt_init(struct drm_device *dev)
!Pdrivers/gpu/drm/drm_dp_helper.c dp helpers
!Iinclude/drm/drm_dp_helper.h
!Edrivers/gpu/drm/drm_dp_helper.c
</sect2>
<sect2>
<title>Display Port MST Helper Functions Reference</title>
!Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper
!Iinclude/drm/drm_dp_mst_helper.h
!Edrivers/gpu/drm/drm_dp_mst_topology.c
</sect2>
<sect2>
<title>EDID Helper Functions Reference</title>
Expand Down
30 changes: 30 additions & 0 deletions Documentation/devicetree/bindings/drm/armada/marvell,dove-lcd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Device Tree bindings for Armada DRM CRTC driver

Required properties:
- compatible: value should be "marvell,dove-lcd".
- reg: base address and size of the LCD controller
- interrupts: single interrupt number for the LCD controller
- port: video output port with endpoints, as described by graph.txt

Optional properties:

- clocks: as described by clock-bindings.txt
- clock-names: as described by clock-bindings.txt
"axiclk" - axi bus clock for pixel clock
"plldivider" - pll divider clock for pixel clock
"ext_ref_clk0" - external clock 0 for pixel clock
"ext_ref_clk1" - external clock 1 for pixel clock

Note: all clocks are optional but at least one must be specified.
Further clocks may be added in the future according to requirements of
different SoCs.

Example:

lcd0: lcd-controller@820000 {
compatible = "marvell,dove-lcd";
reg = <0x820000 0x1000>;
interrupts = <47>;
clocks = <&si5351 0>;
clock-names = "ext_ref_clk_1";
};
192 changes: 157 additions & 35 deletions drivers/base/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,23 @@
#include <linux/mutex.h>
#include <linux/slab.h>

struct component_match {
size_t alloc;
size_t num;
struct {
void *data;
int (*fn)(struct device *, void *);
} compare[0];
};

struct master {
struct list_head node;
struct list_head components;
bool bound;

const struct component_master_ops *ops;
struct device *dev;
struct component_match *match;
};

struct component {
Expand Down Expand Up @@ -69,18 +79,24 @@ static void component_detach_master(struct master *master, struct component *c)
c->master = NULL;
}

/*
* Add a component to a master, finding the component via the compare
* function and compare data. This is safe to call for duplicate matches
* and will not result in the same component being added multiple times.
*/
int component_master_add_child(struct master *master,
int (*compare)(struct device *, void *), void *compare_data)
{
struct component *c;
int ret = -ENXIO;

list_for_each_entry(c, &component_list, node) {
if (c->master)
if (c->master && c->master != master)
continue;

if (compare(c->dev, compare_data)) {
component_attach_master(master, c);
if (!c->master)
component_attach_master(master, c);
ret = 0;
break;
}
Expand All @@ -90,6 +106,34 @@ int component_master_add_child(struct master *master,
}
EXPORT_SYMBOL_GPL(component_master_add_child);

static int find_components(struct master *master)
{
struct component_match *match = master->match;
size_t i;
int ret = 0;

if (!match) {
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
return master->ops->add_components(master->dev, master);
}

/*
* Scan the array of match functions and attach
* any components which are found to this master.
*/
for (i = 0; i < match->num; i++) {
ret = component_master_add_child(master,
match->compare[i].fn,
match->compare[i].data);
if (ret)
break;
}
return ret;
}

/* Detach all attached components from this master */
static void master_remove_components(struct master *master)
{
Expand All @@ -113,44 +157,44 @@ static void master_remove_components(struct master *master)
static int try_to_bring_up_master(struct master *master,
struct component *component)
{
int ret = 0;
int ret;

if (!master->bound) {
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
if (master->ops->add_components(master->dev, master)) {
/* Failed to find all components */
master_remove_components(master);
ret = 0;
goto out;
}
if (master->bound)
return 0;

if (component && component->master != master) {
master_remove_components(master);
ret = 0;
goto out;
}
/*
* Search the list of components, looking for components that
* belong to this master, and attach them to the master.
*/
if (find_components(master)) {
/* Failed to find all components */
ret = 0;
goto out;
}

if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
ret = -ENOMEM;
goto out;
}
if (component && component->master != master) {
ret = 0;
goto out;
}

/* Found all components */
ret = master->ops->bind(master->dev);
if (ret < 0) {
devres_release_group(master->dev, NULL);
dev_info(master->dev, "master bind failed: %d\n", ret);
master_remove_components(master);
goto out;
}
if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
ret = -ENOMEM;
goto out;
}

master->bound = true;
ret = 1;
/* Found all components */
ret = master->ops->bind(master->dev);
if (ret < 0) {
devres_release_group(master->dev, NULL);
dev_info(master->dev, "master bind failed: %d\n", ret);
goto out;
}

master->bound = true;
return 1;

out:
master_remove_components(master);

return ret;
}
Expand Down Expand Up @@ -180,18 +224,89 @@ static void take_down_master(struct master *master)
master_remove_components(master);
}

int component_master_add(struct device *dev,
const struct component_master_ops *ops)
static size_t component_match_size(size_t num)
{
return offsetof(struct component_match, compare[num]);
}

static struct component_match *component_match_realloc(struct device *dev,
struct component_match *match, size_t num)
{
struct component_match *new;

if (match && match->alloc == num)
return match;

new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
if (!new)
return ERR_PTR(-ENOMEM);

if (match) {
memcpy(new, match, component_match_size(min(match->num, num)));
devm_kfree(dev, match);
} else {
new->num = 0;
}

new->alloc = num;

return new;
}

/*
* Add a component to be matched.
*
* The match array is first created or extended if necessary.
*/
void component_match_add(struct device *dev, struct component_match **matchptr,
int (*compare)(struct device *, void *), void *compare_data)
{
struct component_match *match = *matchptr;

if (IS_ERR(match))
return;

if (!match || match->num == match->alloc) {
size_t new_size = match ? match->alloc + 16 : 15;

match = component_match_realloc(dev, match, new_size);

*matchptr = match;

if (IS_ERR(match))
return;
}

match->compare[match->num].fn = compare;
match->compare[match->num].data = compare_data;
match->num++;
}
EXPORT_SYMBOL(component_match_add);

int component_master_add_with_match(struct device *dev,
const struct component_master_ops *ops,
struct component_match *match)
{
struct master *master;
int ret;

if (ops->add_components && match)
return -EINVAL;

if (match) {
/* Reallocate the match array for its true size */
match = component_match_realloc(dev, match, match->num);
if (IS_ERR(match))
return PTR_ERR(match);
}

master = kzalloc(sizeof(*master), GFP_KERNEL);
if (!master)
return -ENOMEM;

master->dev = dev;
master->ops = ops;
master->match = match;
INIT_LIST_HEAD(&master->components);

/* Add to the list of available masters. */
Expand All @@ -209,6 +324,13 @@ int component_master_add(struct device *dev,

return ret < 0 ? ret : 0;
}
EXPORT_SYMBOL_GPL(component_master_add_with_match);

int component_master_add(struct device *dev,
const struct component_master_ops *ops)
{
return component_master_add_with_match(dev, ops, NULL);
}
EXPORT_SYMBOL_GPL(component_master_add);

void component_master_del(struct device *dev,
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
drm-$(CONFIG_PCI) += ati_pcigart.o
drm-$(CONFIG_DRM_PANEL) += drm_panel.o
drm-$(CONFIG_OF) += drm_of.o

drm-usb-y := drm_usb.o

drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o
drm_plane_helper.o drm_dp_mst_topology.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
Expand Down
Loading

0 comments on commit 4dac3ed

Please sign in to comment.