diff options
-rw-r--r-- | Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt | 3 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt | 7 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/panel/panel-simple.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/hdmi.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/output.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/rgb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/intr_hw.c | 1 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 26 |
13 files changed, 164 insertions, 62 deletions
diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index 9e9008f8fa32..efaeec8961b6 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -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 diff --git a/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt b/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt new file mode 100644 index 000000000000..f24614e4d5ec --- /dev/null +++ b/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt @@ -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. diff --git a/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt b/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt new file mode 100644 index 000000000000..ef522c6bb85f --- /dev/null +++ b/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt @@ -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. diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 266a01d7f635..3b7d32da1604 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -675,6 +675,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 * @mode: mode data diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 245fe4fa9c9e..ea92b827e787 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -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 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 40a9338ad54f..9fa24347963a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -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); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 3e611afc93f4..59d52ca2c67f 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -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,14 +361,42 @@ 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", }, { /* sentinel */ diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 386f3b4b0094..9336006b475d 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -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"); diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index bc9cb1ac709b..6928015d11a4 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -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); diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index f1b5030f55e3..57cecbd18ca8 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -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; diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 03885bb8dcc0..338f7f6561d7 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -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; } diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index b26dcc83bc1b..db9017adfe2b 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -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" diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e963470efd39..71727b6210ae 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.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, |