Commit 45ab1e07 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm/for-3.14-rc1-20140123' of git://anongit.freedesktop.org/tegra/linux into drm-next

drm/tegra: Changes for v3.14-rc1 (update)

These patches fix some issues caused by the DRM panel support from the
previous pull request and add two more panels (for the Toshiba AC100 as
well as the Seaboard and Ventana).

* tag 'drm/for-3.14-rc1-20140123' of git://anongit.freedesktop.org/tegra/linux:
  drm/tegra: Obtain head number from DT
  drm/panel: update EDID BLOB in panel_simple_get_modes()
  gpu: host1x: Remove unnecessary include
  drm/tegra: Use proper data type
  drm/tegra: Clarify how panel modes override others
  drm/tegra: Fix possible CRTC mask for RGB outputs
  drm/i915: Use drm_encoder_crtc_ok()
  drm: Move drm_encoder_crtc_ok() to core
  drm: provide a helper for the encoder possible_crtcs mask
  drm/tegra: Don't check resource with devm_ioremap_resource()
  drm/panel: Add support for Chunghwa CLAA101WA01A panel
  drm/panel: Add support for Samsung LTN101NT05 panel
parents f4b4718b 13411ddd
...@@ -118,6 +118,9 @@ of the following host1x client modules: ...@@ -118,6 +118,9 @@ of the following host1x client modules:
See ../reset/reset.txt for details. See ../reset/reset.txt for details.
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- dc - dc
- nvidia,head: The number of the display controller head. This is used to
setup the various types of output to receive video data from the given
head.
Each display controller node has a child node, named "rgb", that represents Each display controller node has a child node, named "rgb", that represents
the RGB output associated with the controller. It can take the following the RGB output associated with the controller. It can take the following
......
Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
Required properties:
- compatible: should be "chunghwa,claa101wa01a"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
Samsung Electronics 10.1" WSVGA TFT LCD panel
Required properties:
- compatible: should be "samsung,ltn101nt05"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
...@@ -674,6 +674,29 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) ...@@ -674,6 +674,29 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
} }
EXPORT_SYMBOL(drm_crtc_cleanup); EXPORT_SYMBOL(drm_crtc_cleanup);
/**
* drm_crtc_index - find the index of a registered CRTC
* @crtc: CRTC to find index for
*
* Given a registered CRTC, return the index of that CRTC within a DRM
* device's list of CRTCs.
*/
unsigned int drm_crtc_index(struct drm_crtc *crtc)
{
unsigned int index = 0;
struct drm_crtc *tmp;
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
if (tmp == crtc)
return index;
index++;
}
BUG();
}
EXPORT_SYMBOL(drm_crtc_index);
/** /**
* drm_mode_probed_add - add a mode to a connector's probed mode list * drm_mode_probed_add - add a mode to a connector's probed mode list
* @connector: connector the new mode * @connector: connector the new mode
......
...@@ -324,35 +324,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) ...@@ -324,35 +324,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
} }
EXPORT_SYMBOL(drm_helper_disable_unused_functions); EXPORT_SYMBOL(drm_helper_disable_unused_functions);
/**
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
* @encoder: encoder to test
* @crtc: crtc to test
*
* Return false if @encoder can't be driven by @crtc, true otherwise.
*/
static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
struct drm_device *dev;
struct drm_crtc *tmp;
int crtc_mask = 1;
WARN(!crtc, "checking null crtc?\n");
dev = crtc->dev;
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
if (tmp == crtc)
break;
crtc_mask <<= 1;
}
if (encoder->possible_crtcs & crtc_mask)
return true;
return false;
}
/* /*
* Check the CRTC we're going to map each output to vs. its current * Check the CRTC we're going to map each output to vs. its current
* CRTC. If they don't match, we have to disable the output and the CRTC * CRTC. If they don't match, we have to disable the output and the CRTC
......
...@@ -8744,28 +8744,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = { ...@@ -8744,28 +8744,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = {
.load_lut = intel_crtc_load_lut, .load_lut = intel_crtc_load_lut,
}; };
static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
struct drm_device *dev;
struct drm_crtc *tmp;
int crtc_mask = 1;
WARN(!crtc, "checking null crtc?\n");
dev = crtc->dev;
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
if (tmp == crtc)
break;
crtc_mask <<= 1;
}
if (encoder->possible_crtcs & crtc_mask)
return true;
return false;
}
/** /**
* intel_modeset_update_staged_output_state * intel_modeset_update_staged_output_state
* *
...@@ -9940,8 +9918,8 @@ intel_modeset_stage_output_state(struct drm_device *dev, ...@@ -9940,8 +9918,8 @@ intel_modeset_stage_output_state(struct drm_device *dev,
} }
/* Make sure the new CRTC will work with the encoder */ /* Make sure the new CRTC will work with the encoder */
if (!intel_encoder_crtc_ok(&connector->new_encoder->base, if (!drm_encoder_crtc_ok(&connector->new_encoder->base,
new_crtc)) { new_crtc)) {
return -EINVAL; return -EINVAL;
} }
connector->encoder->new_crtc = to_intel_crtc(new_crtc); connector->encoder->new_crtc = to_intel_crtc(new_crtc);
......
...@@ -162,6 +162,7 @@ static int panel_simple_get_modes(struct drm_panel *panel) ...@@ -162,6 +162,7 @@ static int panel_simple_get_modes(struct drm_panel *panel)
/* probe EDID if a DDC bus is available */ /* probe EDID if a DDC bus is available */
if (p->ddc) { if (p->ddc) {
struct edid *edid = drm_get_edid(panel->connector, p->ddc); struct edid *edid = drm_get_edid(panel->connector, p->ddc);
drm_mode_connector_update_edid_property(panel->connector, edid);
if (edid) { if (edid) {
num += drm_add_edid_modes(panel->connector, edid); num += drm_add_edid_modes(panel->connector, edid);
kfree(edid); kfree(edid);
...@@ -316,6 +317,28 @@ static const struct panel_desc auo_b101aw03 = { ...@@ -316,6 +317,28 @@ static const struct panel_desc auo_b101aw03 = {
}, },
}; };
static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
.clock = 72070,
.hdisplay = 1366,
.hsync_start = 1366 + 58,
.hsync_end = 1366 + 58 + 58,
.htotal = 1366 + 58 + 58 + 58,
.vdisplay = 768,
.vsync_start = 768 + 4,
.vsync_end = 768 + 4 + 4,
.vtotal = 768 + 4 + 4 + 4,
.vrefresh = 60,
};
static const struct panel_desc chunghwa_claa101wa01a = {
.modes = &chunghwa_claa101wa01a_mode,
.num_modes = 1,
.size = {
.width = 220,
.height = 120,
},
};
static const struct drm_display_mode chunghwa_claa101wb01_mode = { static const struct drm_display_mode chunghwa_claa101wb01_mode = {
.clock = 69300, .clock = 69300,
.hdisplay = 1366, .hdisplay = 1366,
...@@ -338,13 +361,41 @@ static const struct panel_desc chunghwa_claa101wb01 = { ...@@ -338,13 +361,41 @@ static const struct panel_desc chunghwa_claa101wb01 = {
}, },
}; };
static const struct drm_display_mode samsung_ltn101nt05_mode = {
.clock = 54030,
.hdisplay = 1024,
.hsync_start = 1024 + 24,
.hsync_end = 1024 + 24 + 136,
.htotal = 1024 + 24 + 136 + 160,
.vdisplay = 600,
.vsync_start = 600 + 3,
.vsync_end = 600 + 3 + 6,
.vtotal = 600 + 3 + 6 + 61,
.vrefresh = 60,
};
static const struct panel_desc samsung_ltn101nt05 = {
.modes = &samsung_ltn101nt05_mode,
.num_modes = 1,
.size = {
.width = 1024,
.height = 600,
},
};
static const struct of_device_id platform_of_match[] = { static const struct of_device_id platform_of_match[] = {
{ {
.compatible = "auo,b101aw03", .compatible = "auo,b101aw03",
.data = &auo_b101aw03, .data = &auo_b101aw03,
}, {
.compatible = "chunghwa,claa101wa01a",
.data = &chunghwa_claa101wa01a
}, { }, {
.compatible = "chunghwa,claa101wb01", .compatible = "chunghwa,claa101wb01",
.data = &chunghwa_claa101wb01 .data = &chunghwa_claa101wb01
}, {
.compatible = "samsung,ltn101nt05",
.data = &samsung_ltn101nt05,
}, { }, {
.compatible = "simple-panel", .compatible = "simple-panel",
}, { }, {
......
...@@ -1100,8 +1100,6 @@ static int tegra_dc_init(struct host1x_client *client) ...@@ -1100,8 +1100,6 @@ static int tegra_dc_init(struct host1x_client *client)
struct tegra_dc *dc = host1x_client_to_dc(client); struct tegra_dc *dc = host1x_client_to_dc(client);
int err; int err;
dc->pipe = tegra->drm->mode_config.num_crtc;
drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs); drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs);
drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_mode_crtc_set_gamma_size(&dc->base, 256);
drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
...@@ -1187,6 +1185,41 @@ static const struct of_device_id tegra_dc_of_match[] = { ...@@ -1187,6 +1185,41 @@ static const struct of_device_id tegra_dc_of_match[] = {
} }
}; };
static int tegra_dc_parse_dt(struct tegra_dc *dc)
{
struct device_node *np;
u32 value = 0;
int err;
err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value);
if (err < 0) {
dev_err(dc->dev, "missing \"nvidia,head\" property\n");
/*
* If the nvidia,head property isn't present, try to find the
* correct head number by looking up the position of this
* display controller's node within the device tree. Assuming
* that the nodes are ordered properly in the DTS file and
* that the translation into a flattened device tree blob
* preserves that ordering this will actually yield the right
* head number.
*
* If those assumptions don't hold, this will still work for
* cases where only a single display controller is used.
*/
for_each_matching_node(np, tegra_dc_of_match) {
if (np == dc->dev->of_node)
break;
value++;
}
}
dc->pipe = value;
return 0;
}
static int tegra_dc_probe(struct platform_device *pdev) static int tegra_dc_probe(struct platform_device *pdev)
{ {
const struct of_device_id *id; const struct of_device_id *id;
...@@ -1207,6 +1240,10 @@ static int tegra_dc_probe(struct platform_device *pdev) ...@@ -1207,6 +1240,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
dc->dev = &pdev->dev; dc->dev = &pdev->dev;
dc->soc = id->data; dc->soc = id->data;
err = tegra_dc_parse_dt(dc);
if (err < 0)
return err;
dc->clk = devm_clk_get(&pdev->dev, NULL); dc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dc->clk)) { if (IS_ERR(dc->clk)) {
dev_err(&pdev->dev, "failed to get clock\n"); dev_err(&pdev->dev, "failed to get clock\n");
......
...@@ -1418,9 +1418,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev) ...@@ -1418,9 +1418,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
return err; return err;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
return -ENXIO;
hdmi->regs = devm_ioremap_resource(&pdev->dev, regs); hdmi->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(hdmi->regs)) if (IS_ERR(hdmi->regs))
return PTR_ERR(hdmi->regs); return PTR_ERR(hdmi->regs);
......
...@@ -18,6 +18,10 @@ static int tegra_connector_get_modes(struct drm_connector *connector) ...@@ -18,6 +18,10 @@ static int tegra_connector_get_modes(struct drm_connector *connector)
struct edid *edid = NULL; struct edid *edid = NULL;
int err = 0; int err = 0;
/*
* If the panel provides one or more modes, use them exclusively and
* ignore any other means of obtaining a mode.
*/
if (output->panel) { if (output->panel) {
err = output->panel->funcs->get_modes(output->panel); err = output->panel->funcs->get_modes(output->panel);
if (err > 0) if (err > 0)
...@@ -187,8 +191,7 @@ int tegra_output_probe(struct tegra_output *output) ...@@ -187,8 +191,7 @@ int tegra_output_probe(struct tegra_output *output)
{ {
struct device_node *ddc, *panel; struct device_node *ddc, *panel;
enum of_gpio_flags flags; enum of_gpio_flags flags;
size_t size; int err, size;
int err;
if (!output->of_node) if (!output->of_node)
output->of_node = output->dev->of_node; output->of_node = output->dev->of_node;
......
...@@ -258,7 +258,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc) ...@@ -258,7 +258,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
* RGB outputs are an exception, so we make sure they can be attached * RGB outputs are an exception, so we make sure they can be attached
* to only their parent display controller. * to only their parent display controller.
*/ */
rgb->output.encoder.possible_crtcs = 1 << dc->pipe; rgb->output.encoder.possible_crtcs = drm_crtc_mask(&dc->base);
return 0; return 0;
} }
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach/irq.h>
#include "../intr.h" #include "../intr.h"
#include "../dev.h" #include "../dev.h"
......
...@@ -931,6 +931,19 @@ extern int drm_crtc_init(struct drm_device *dev, ...@@ -931,6 +931,19 @@ extern int drm_crtc_init(struct drm_device *dev,
struct drm_crtc *crtc, struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs); const struct drm_crtc_funcs *funcs);
extern void drm_crtc_cleanup(struct drm_crtc *crtc); extern void drm_crtc_cleanup(struct drm_crtc *crtc);
extern unsigned int drm_crtc_index(struct drm_crtc *crtc);
/**
* drm_crtc_mask - find the mask of a registered CRTC
* @crtc: CRTC to find mask for
*
* Given a registered CRTC, return the mask bit of that CRTC for an
* encoder's possible_crtcs field.
*/
static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc)
{
return 1 << drm_crtc_index(crtc);
}
extern void drm_connector_ida_init(void); extern void drm_connector_ida_init(void);
extern void drm_connector_ida_destroy(void); extern void drm_connector_ida_destroy(void);
...@@ -952,6 +965,19 @@ extern int drm_encoder_init(struct drm_device *dev, ...@@ -952,6 +965,19 @@ extern int drm_encoder_init(struct drm_device *dev,
const struct drm_encoder_funcs *funcs, const struct drm_encoder_funcs *funcs,
int encoder_type); int encoder_type);
/**
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
* @encoder: encoder to test
* @crtc: crtc to test
*
* Return false if @encoder can't be driven by @crtc, true otherwise.
*/
static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
}
extern int drm_plane_init(struct drm_device *dev, extern int drm_plane_init(struct drm_device *dev,
struct drm_plane *plane, struct drm_plane *plane,
unsigned long possible_crtcs, unsigned long possible_crtcs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment