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). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJS4TK6AAoJEN0jrNd/PrOhwXoP/i09xa9CKOnpy8Ewdmgi5gBt vnjzqjwmHzZRpNeWw2xvcqzv5kKgXkpPdMhNUjErlJTUC1S6uCf/Uj+ExppYYysW 7uxNjPQQc6jgX+0342MabKITeZyTk9iEWPqTDtHDP5O2vXi4XSaQTMm9HpWGe1qZ 1CTb0yJc1epXGJPutlqhJSZgKwzrs6Pm2Q/nsTdxpGPAoTQj9J0NebDaZwJmmFGi qNyfI4DVBp1sj8AgtUkQQn9x5oLDpdvHKLPHsAWgHnNTKqRxY8C0EL+S2TYGa812 sx8jvZgjvBoPuwaOr4hcOx91OFdfOoKVap9D/corU+UjstF9lTd+PvAHzZMO5qte yQhWmYFn1gGr/I9b9K/mAB98s83W7lMmSs/7HtiawvLtogZ/t8xvSp94R7X8SGd1 wYcw3NqzgDxrcpJjDOsLIw1Pa4PxXoChtV0SfiaEoVlGn5WSONS/8cKeNwbO6e9D gKkd/zvCMsYqHt7p8zDizcQKi4W+8zYiZySOfLohZzhf0qaoQnnD5yirfiIpljqA Ql40F4XP3OF3CliikcSwFhvrTUCLb08Ol0MV6FX1H1iMae0dgiFqtz7AihFTbKHZ PQeskMgEemxhIqKEsH0JcpV3+YxLRlWy/3I+OO7QczsL0xKD30FQ9Xhsu9EFx8gu jXVvMDldeefaVBuTdqCb =NfNj -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
45ab1e0780
|
@ -118,6 +118,9 @@ of the following host1x client modules:
|
|||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- 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
|
||||
the RGB output associated with the controller. It can take the following
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
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.
|
|
@ -0,0 +1,7 @@
|
|||
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)
|
|||
}
|
||||
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
|
||||
* @connector: connector the new mode
|
||||
|
|
|
@ -324,35 +324,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
|
|||
}
|
||||
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
|
||||
* 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 = {
|
|||
.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
|
||||
*
|
||||
|
@ -9940,8 +9918,8 @@ intel_modeset_stage_output_state(struct drm_device *dev,
|
|||
}
|
||||
|
||||
/* Make sure the new CRTC will work with the encoder */
|
||||
if (!intel_encoder_crtc_ok(&connector->new_encoder->base,
|
||||
new_crtc)) {
|
||||
if (!drm_encoder_crtc_ok(&connector->new_encoder->base,
|
||||
new_crtc)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
connector->encoder->new_crtc = to_intel_crtc(new_crtc);
|
||||
|
|
|
@ -162,6 +162,7 @@ static int panel_simple_get_modes(struct drm_panel *panel)
|
|||
/* probe EDID if a DDC bus is available */
|
||||
if (p->ddc) {
|
||||
struct edid *edid = drm_get_edid(panel->connector, p->ddc);
|
||||
drm_mode_connector_update_edid_property(panel->connector, edid);
|
||||
if (edid) {
|
||||
num += drm_add_edid_modes(panel->connector, edid);
|
||||
kfree(edid);
|
||||
|
@ -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 = {
|
||||
.clock = 69300,
|
||||
.hdisplay = 1366,
|
||||
|
@ -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[] = {
|
||||
{
|
||||
.compatible = "auo,b101aw03",
|
||||
.data = &auo_b101aw03,
|
||||
}, {
|
||||
.compatible = "chunghwa,claa101wa01a",
|
||||
.data = &chunghwa_claa101wa01a
|
||||
}, {
|
||||
.compatible = "chunghwa,claa101wb01",
|
||||
.data = &chunghwa_claa101wb01
|
||||
}, {
|
||||
.compatible = "samsung,ltn101nt05",
|
||||
.data = &samsung_ltn101nt05,
|
||||
}, {
|
||||
.compatible = "simple-panel",
|
||||
}, {
|
||||
|
|
|
@ -1100,8 +1100,6 @@ static int tegra_dc_init(struct host1x_client *client)
|
|||
struct tegra_dc *dc = host1x_client_to_dc(client);
|
||||
int err;
|
||||
|
||||
dc->pipe = tegra->drm->mode_config.num_crtc;
|
||||
|
||||
drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&dc->base, 256);
|
||||
drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
|
||||
|
@ -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)
|
||||
{
|
||||
const struct of_device_id *id;
|
||||
|
@ -1207,6 +1240,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
|
|||
dc->dev = &pdev->dev;
|
||||
dc->soc = id->data;
|
||||
|
||||
err = tegra_dc_parse_dt(dc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
dc->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(dc->clk)) {
|
||||
dev_err(&pdev->dev, "failed to get clock\n");
|
||||
|
|
|
@ -1418,9 +1418,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!regs)
|
||||
return -ENXIO;
|
||||
|
||||
hdmi->regs = devm_ioremap_resource(&pdev->dev, regs);
|
||||
if (IS_ERR(hdmi->regs))
|
||||
return PTR_ERR(hdmi->regs);
|
||||
|
|
|
@ -18,6 +18,10 @@ static int tegra_connector_get_modes(struct drm_connector *connector)
|
|||
struct edid *edid = NULL;
|
||||
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) {
|
||||
err = output->panel->funcs->get_modes(output->panel);
|
||||
if (err > 0)
|
||||
|
@ -187,8 +191,7 @@ int tegra_output_probe(struct tegra_output *output)
|
|||
{
|
||||
struct device_node *ddc, *panel;
|
||||
enum of_gpio_flags flags;
|
||||
size_t size;
|
||||
int err;
|
||||
int err, size;
|
||||
|
||||
if (!output->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)
|
|||
* RGB outputs are an exception, so we make sure they can be attached
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include "../intr.h"
|
||||
#include "../dev.h"
|
||||
|
|
|
@ -931,6 +931,19 @@ extern int drm_crtc_init(struct drm_device *dev,
|
|||
struct drm_crtc *crtc,
|
||||
const struct drm_crtc_funcs *funcs);
|
||||
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_destroy(void);
|
||||
|
@ -952,6 +965,19 @@ extern int drm_encoder_init(struct drm_device *dev,
|
|||
const struct drm_encoder_funcs *funcs,
|
||||
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,
|
||||
struct drm_plane *plane,
|
||||
unsigned long possible_crtcs,
|
||||
|
|
Loading…
Reference in New Issue