drm/tegra: Changes for v5.3-rc1 This contains a couple of small improvements and cleanups for the Tegra DRM driver. Signed-off-by: Dave Airlie <airlied@redhat.com>
Unified · Split
| @@ -485,11 +485,16 @@ static int tegra_dpaux_probe(struct platform_device *pdev) · 484 unmodified lines | |||
| 485 | return err; | 485 | return err; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd"); | 488 | dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); |
| 489 | if (IS_ERR(dpaux->vdd)) { | 489 | if (IS_ERR(dpaux->vdd)) { |
| 490 | dev_err(&pdev->dev, "failed to get VDD supply: %ld\n", | 490 | if (PTR_ERR(dpaux->vdd) != -ENODEV) { |
| 491 | PTR_ERR(dpaux->vdd)); | 491 | if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER) |
| 492 | return PTR_ERR(dpaux->vdd); | 492 | dev_err(&pdev->dev, |
| 493 | "failed to get VDD supply: %ld\n", | ||
| 494 | PTR_ERR(dpaux->vdd)); | ||
| 495 | |||
| 496 | return PTR_ERR(dpaux->vdd); | ||
| 497 | } | ||
| 493 | } | 498 | } |
| 494 | 499 | ||
| 495 | platform_set_drvdata(pdev, dpaux); | 500 | platform_set_drvdata(pdev, dpaux); |
| @@ -127,8 +127,7 @@ struct tegra_output { · 126 unmodified lines | |||
| 127 | const struct edid *edid; | 127 | const struct edid *edid; |
| 128 | struct cec_notifier *cec; | 128 | struct cec_notifier *cec; |
| 129 | unsigned int hpd_irq; | 129 | unsigned int hpd_irq; |
| 130 | int hpd_gpio; | 130 | struct gpio_desc *hpd_gpio; |
| 131 | enum of_gpio_flags hpd_gpio_flags; | ||
| 132 | 131 | ||
| 133 | struct drm_encoder encoder; | 132 | struct drm_encoder encoder; |
| 134 | struct drm_connector connector; | 133 | struct drm_connector connector; |
| @@ -53,18 +53,11 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force) · 52 unmodified lines | |||
| 53 | struct tegra_output *output = connector_to_output(connector); | 53 | struct tegra_output *output = connector_to_output(connector); |
| 54 | enum drm_connector_status status = connector_status_unknown; | 54 | enum drm_connector_status status = connector_status_unknown; |
| 55 | 55 | ||
| 56 | if (gpio_is_valid(output->hpd_gpio)) { | 56 | if (output->hpd_gpio) { |
| 57 | if (output->hpd_gpio_flags & OF_GPIO_ACTIVE_LOW) { | 57 | if (gpiod_get_value(output->hpd_gpio) == 0) |
| 58 | if (gpio_get_value(output->hpd_gpio) != 0) | 58 | status = connector_status_disconnected; |
| 59 | status = connector_status_disconnected; | 59 | else |
| 60 | else | 60 | status = connector_status_connected; |
| 61 | status = connector_status_connected; | ||
| 62 | } else { | ||
| 63 | if (gpio_get_value(output->hpd_gpio) == 0) | ||
| 64 | status = connector_status_disconnected; | ||
| 65 | else | ||
| 66 | status = connector_status_connected; | ||
| 67 | } | ||
| 68 | } else { | 61 | } else { |
| 69 | if (!output->panel) | 62 | if (!output->panel) |
| 70 | status = connector_status_disconnected; | 63 | status = connector_status_disconnected; |
| @@ -102,6 +95,7 @@ static irqreturn_t hpd_irq(int irq, void *data) · 31 unmodified lines | |||
| 102 | int tegra_output_probe(struct tegra_output *output) | 95 | int tegra_output_probe(struct tegra_output *output) |
| 103 | { | 96 | { |
| 104 | struct device_node *ddc, *panel; | 97 | struct device_node *ddc, *panel; |
| 98 | unsigned long flags; | ||
| 105 | int err, size; | 99 | int err, size; |
| 106 | 100 | ||
| 107 | if (!output->of_node) | 101 | if (!output->of_node) |
| @@ -130,23 +124,18 @@ int tegra_output_probe(struct tegra_output *output) · 22 unmodified lines | |||
| 130 | of_node_put(ddc); | 124 | of_node_put(ddc); |
| 131 | } | 125 | } |
| 132 | 126 | ||
| 133 | output->hpd_gpio = of_get_named_gpio_flags(output->of_node, | 127 | output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev, |
| 134 | "nvidia,hpd-gpio", 0, | 128 | output->of_node, |
| 135 | &output->hpd_gpio_flags); | 129 | "nvidia,hpd-gpio", 0, |
| 136 | if (gpio_is_valid(output->hpd_gpio)) { | 130 | GPIOD_IN, |
| 137 | unsigned long flags; | 131 | "HDMI hotplug detect"); |
| 132 | if (IS_ERR(output->hpd_gpio)) | ||
| 133 | return PTR_ERR(output->hpd_gpio); | ||
| 138 | 134 | ||
| 139 | err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN, | 135 | if (output->hpd_gpio) { |
| 140 | "HDMI hotplug detect"); | 136 | err = gpiod_to_irq(output->hpd_gpio); |
| 141 | if (err < 0) { | 137 | if (err < 0) { |
| 142 | dev_err(output->dev, "gpio_request_one(): %d\n", err); | 138 | dev_err(output->dev, "gpiod_to_irq(): %d\n", err); |
| 143 | return err; | ||
| 144 | } | ||
| 145 | |||
| 146 | err = gpio_to_irq(output->hpd_gpio); | ||
| 147 | if (err < 0) { | ||
| 148 | dev_err(output->dev, "gpio_to_irq(): %d\n", err); | ||
| 149 | gpio_free(output->hpd_gpio); | ||
| 150 | return err; | 139 | return err; |
| 151 | } | 140 | } |
| 152 | 141 | ||
| @@ -160,7 +149,6 @@ int tegra_output_probe(struct tegra_output *output) · 7 unmodified lines | |||
| 160 | if (err < 0) { | 149 | if (err < 0) { |
| 161 | dev_err(output->dev, "failed to request IRQ#%u: %d\n", | 150 | dev_err(output->dev, "failed to request IRQ#%u: %d\n", |
| 162 | output->hpd_irq, err); | 151 | output->hpd_irq, err); |
| 163 | gpio_free(output->hpd_gpio); | ||
| 164 | return err; | 152 | return err; |
| 165 | } | 153 | } |
| 166 | 154 | ||
| @@ -186,10 +174,8 @@ void tegra_output_remove(struct tegra_output *output) · 19 unmodified lines | |||
| 186 | if (output->cec) | 174 | if (output->cec) |
| 187 | cec_notifier_put(output->cec); | 175 | cec_notifier_put(output->cec); |
| 188 | 176 | ||
| 189 | if (gpio_is_valid(output->hpd_gpio)) { | 177 | if (output->hpd_gpio) |
| 190 | free_irq(output->hpd_irq, output); | 178 | free_irq(output->hpd_irq, output); |
| 191 | gpio_free(output->hpd_gpio); | ||
| 192 | } | ||
| 193 | 179 | ||
| 194 | if (output->ddc) | 180 | if (output->ddc) |
| 195 | put_device(&output->ddc->dev); | 181 | put_device(&output->ddc->dev); |
| @@ -209,7 +195,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) · 13 unmodified lines | |||
| 209 | * The connector is now registered and ready to receive hotplug events | 195 | * The connector is now registered and ready to receive hotplug events |
| 210 | * so the hotplug interrupt can be enabled. | 196 | * so the hotplug interrupt can be enabled. |
| 211 | */ | 197 | */ |
| 212 | if (gpio_is_valid(output->hpd_gpio)) | 198 | if (output->hpd_gpio) |
| 213 | enable_irq(output->hpd_irq); | 199 | enable_irq(output->hpd_irq); |
| 214 | 200 | ||
| 215 | return 0; | 201 | return 0; |
| @@ -221,7 +207,7 @@ void tegra_output_exit(struct tegra_output *output) · 5 unmodified lines | |||
| 221 | * The connector is going away, so the interrupt must be disabled to | 207 | * The connector is going away, so the interrupt must be disabled to |
| 222 | * prevent the hotplug interrupt handler from potentially crashing. | 208 | * prevent the hotplug interrupt handler from potentially crashing. |
| 223 | */ | 209 | */ |
| 224 | if (gpio_is_valid(output->hpd_gpio)) | 210 | if (output->hpd_gpio) |
| 225 | disable_irq(output->hpd_irq); | 211 | disable_irq(output->hpd_irq); |
| 226 | 212 | ||
| 227 | if (output->panel) | 213 | if (output->panel) |
| @@ -305,6 +305,36 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv) · 304 unmodified lines | |||
| 305 | return strcmp(dev_name(dev), drv->name) == 0; | 305 | return strcmp(dev_name(dev), drv->name) == 0; |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | static int host1x_device_uevent(struct device *dev, | ||
| 309 | struct kobj_uevent_env *env) | ||
| 310 | { | ||
| 311 | struct device_node *np = dev->parent->of_node; | ||
| 312 | unsigned int count = 0; | ||
| 313 | struct property *p; | ||
| 314 | const char *compat; | ||
| 315 | |||
| 316 | /* | ||
| 317 | * This duplicates most of of_device_uevent(), but the latter cannot | ||
| 318 | * be called from modules and operates on dev->of_node, which is not | ||
| 319 | * available in this case. | ||
| 320 | * | ||
| 321 | * Note that this is really only needed for backwards compatibility | ||
| 322 | * with libdrm, which parses this information from sysfs and will | ||
| 323 | * fail if it can't find the OF_FULLNAME, specifically. | ||
| 324 | */ | ||
| 325 | add_uevent_var(env, "OF_NAME=%pOFn", np); | ||
| 326 | add_uevent_var(env, "OF_FULLNAME=%pOF", np); | ||
| 327 | |||
| 328 | of_property_for_each_string(np, "compatible", p, compat) { | ||
| 329 | add_uevent_var(env, "OF_COMPATIBLE_%u=%s", count, compat); | ||
| 330 | count++; | ||
| 331 | } | ||
| 332 | |||
| 333 | add_uevent_var(env, "OF_COMPATIBLE_N=%u", count); | ||
| 334 | |||
| 335 | return 0; | ||
| 336 | } | ||
| 337 | |||
| 308 | static int host1x_dma_configure(struct device *dev) | 338 | static int host1x_dma_configure(struct device *dev) |
| 309 | { | 339 | { |
| 310 | return of_dma_configure(dev, dev->of_node, true); | 340 | return of_dma_configure(dev, dev->of_node, true); |
| @@ -322,6 +352,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = { · 11 unmodified lines | |||
| 322 | struct bus_type host1x_bus_type = { | 352 | struct bus_type host1x_bus_type = { |
| 323 | .name = "host1x", | 353 | .name = "host1x", |
| 324 | .match = host1x_device_match, | 354 | .match = host1x_device_match, |
| 355 | .uevent = host1x_device_uevent, | ||
| 325 | .dma_configure = host1x_dma_configure, | 356 | .dma_configure = host1x_dma_configure, |
| 326 | .pm = &host1x_device_pm_ops, | 357 | .pm = &host1x_device_pm_ops, |
| 327 | }; | 358 | }; |
| @@ -408,12 +439,14 @@ static int host1x_device_add(struct host1x *host1x, · 80 unmodified lines | |||
| 408 | device->dev.dma_mask = &device->dev.coherent_dma_mask; | 439 | device->dev.dma_mask = &device->dev.coherent_dma_mask; |
| 409 | dev_set_name(&device->dev, "%s", driver->driver.name); | 440 | dev_set_name(&device->dev, "%s", driver->driver.name); |
| 410 | device->dev.release = host1x_device_release; | 441 | device->dev.release = host1x_device_release; |
| 411 | device->dev.of_node = host1x->dev->of_node; | ||
| 412 | device->dev.bus = &host1x_bus_type; | 442 | device->dev.bus = &host1x_bus_type; |
| 413 | device->dev.parent = host1x->dev; | 443 | device->dev.parent = host1x->dev; |
| 414 | 444 | ||
| 415 | of_dma_configure(&device->dev, host1x->dev->of_node, true); | 445 | of_dma_configure(&device->dev, host1x->dev->of_node, true); |
| 416 | 446 | ||
| 447 | device->dev.dma_parms = &device->dma_parms; | ||
| 448 | dma_set_max_seg_size(&device->dev, SZ_4M); | ||
| 449 | |||
| 417 | err = host1x_device_parse_dt(device, driver); | 450 | err = host1x_device_parse_dt(device, driver); |
| 418 | if (err < 0) { | 451 | if (err < 0) { |
| 419 | kfree(device); | 452 | kfree(device); |
| @@ -162,9 +162,6 @@ static void host1x_debugfs_init(struct host1x *host1x) · 161 unmodified lines | |||
| 162 | { | 162 | { |
| 163 | struct dentry *de = debugfs_create_dir("tegra-host1x", NULL); | 163 | struct dentry *de = debugfs_create_dir("tegra-host1x", NULL); |
| 164 | 164 | ||
| 165 | if (!de) | ||
| 166 | return; | ||
| 167 | |||
| 168 | /* Store the created entry */ | 165 | /* Store the created entry */ |
| 169 | host1x->debugfs = de; | 166 | host1x->debugfs = de; |
| 170 | 167 | ||
| @@ -247,8 +247,11 @@ static int host1x_probe(struct platform_device *pdev) · 246 unmodified lines | |||
| 247 | 247 | ||
| 248 | host->clk = devm_clk_get(&pdev->dev, NULL); | 248 | host->clk = devm_clk_get(&pdev->dev, NULL); |
| 249 | if (IS_ERR(host->clk)) { | 249 | if (IS_ERR(host->clk)) { |
| 250 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 251 | err = PTR_ERR(host->clk); | 250 | err = PTR_ERR(host->clk); |
| 251 | |||
| 252 | if (err != -EPROBE_DEFER) | ||
| 253 | dev_err(&pdev->dev, "failed to get clock: %d\n", err); | ||
| 254 | |||
| 252 | return err; | 255 | return err; |
| 253 | } | 256 | } |
| 254 | 257 | ||
| @@ -297,6 +297,8 @@ struct host1x_device { · 296 unmodified lines | |||
| 297 | struct list_head clients; | 297 | struct list_head clients; |
| 298 | 298 | ||
| 299 | bool registered; | 299 | bool registered; |
| 300 | |||
| 301 | struct device_dma_parameters dma_parms; | ||
| 300 | }; | 302 | }; |
| 301 | 303 | ||
| 302 | static inline struct host1x_device *to_host1x_device(struct device *dev) | 304 | static inline struct host1x_device *to_host1x_device(struct device *dev) |