Hi,
Maxime Ripard maxime@cerno.tech 于2021年4月15日周四 下午5:03写道:
Hi,
On Thu, Apr 15, 2021 at 08:18:52AM +0800, Kevin Tang wrote:
Maxime Ripard maxime@cerno.tech 于2021年3月24日周三 下午7:10写道:
+static struct sprd_dpu *sprd_crtc_init(struct drm_device *drm,
struct drm_plane *primary)
+{
struct device_node *port;
struct sprd_dpu *dpu;
/*
* set crtc port so that drm_of_find_possible_crtcs call works
*/
port = of_parse_phandle(drm->dev->of_node, "ports", 0);
if (!port) {
drm_err(drm, "find 'ports' phandle of %s failed\n",
drm->dev->of_node->full_name);
return ERR_PTR(-EINVAL);
}
of_node_put(port);
The YAML binding should already make sure that your binding is sane, and if you still get a DT that doesn't follow it, you have a whole lot of other issues than whether ports is there :)
dpu = drmm_crtc_alloc_with_planes(drm, struct sprd_dpu, base,
primary, NULL,
&sprd_crtc_funcs, NULL);
if (IS_ERR(dpu)) {
drm_err(drm, "failed to init crtc.\n");
return dpu;
}
dpu->base.port = port;
But you're still referencing it here, while you called of_node_put on it already? You should only call it once you're done with it.
of_node_put should be called after done with it, this maybe indeed be a bug. i will fix it.
I'm not really sure why you would need drm_of_find_possible_crtcs to work then if you don't follow the OF-Graph bindings.
it scan all endports of encoder, if a matching crtc is found by OF-Graph bindings and then genarate the crtc mask, here is description: 41 /** 42 * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port 43 * @dev: DRM device 44 * @port: encoder port to scan for endpoints 45 * 46 * Scan all endpoints attached to a port, locate their attached CRTCs, 47 * and generate the DRM mask of CRTCs which may be attached to this 48 * encoder. 49 * if we don't follow the OF-Graph bindings, crtc can't attched to encoder.
Yeah, what I'm actually confused about is why you would need the of_parse_phandle call. You usually call drm_of_find_possible_crtcs with the encoder device node, so from your MIPI-DSI driver in your case, and with it's device->of_node pointer and it should work perfectly fine?
I still confused about use drm_of_find_possible_crtcs to bind crtc and encoder, the port of drm_crtc, default is null?
709 /** 710 * struct drm_crtc - central CRTC control structure 711 * @dev: parent DRM device 712 * @port: OF node used by drm_of_find_possible_crtcs() ----------------------------------------------------------------------------------------------------- 25 static uint32_t drm_crtc_port_mask(struct drm_device *dev, 26 struct device_node *port) 27 { 28 unsigned int index = 0; 29 struct drm_crtc *tmp; 30 31 drm_for_each_crtc(tmp, dev) { 32 if (tmp->port == port) 33 return 1 << index; 34 35 index++; 36 } 37 38 return 0; 39 }
I did not see any place to initialize the port of drm_crtc in the drm framework, if not setup it. it looks like the port of drm_crtc is undefined.
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/rockchip/rock... https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/tilcdc/tilcdc...
The difference from others is that we use of_parse_phandle, as you said, follow the OF-Graph bindings , should be also use of_get_child_by_name replace it? like this: ----------------------------------------------------------------------------------- struct device_node *port; port = of_get_child_by_name(dpu->dev->of_node, "port"); if (!port) { DRM_ERROR("find 'ports' phandle of %s failed\n", dpu->dev->of_node->full_name); return -EINVAL; } crtc->port = port; of_node_put(port); ------------------------------------------------------------------------------------
If we have multiple display controllers, use of_parse_phandle by different index also seem is ok. display-subsystem { compatible = "sprd,display-subsystem"; ports = <&dpu0_port, &dpu1_port, &dpu2_port......>; };
dpu0_port = of_parse_phandle(drm->dev->of_node, "ports", 0); dpu1_port = of_parse_phandle(drm->dev->of_node, "ports", 1); dpu2_port = of_parse_phandle(drm->dev->of_node, "ports", 2);
Maxime