[linux-sunxi] Re: [RFC PATCH] arm64: dts: allwinner: a64/h5: Add CPU idle states

2021-03-23 Thread Samuel Holland
On 3/22/21 8:56 PM, Andre Przywara wrote:
>> I'm sending this patch as an RFC because it raises questions about how
>> we handle firmware versioning. How far back does (or should) our support
>> for old TF-A and Crust versions go?
>>
>> cpuidle has a problem that without working firmware support, CPUs will
>> enter idle states and be unable to wake up. As a result, the system will
>> hang at some point during boot, usually before getting to userspace.
>>
>> For over a year[0], TF-A has exposed the PSCI CPU_SUSPEND function when
>> a SCPI implementation is present[1]. Implementing CPU_SUSPEND is
>> required for implementing SYSTEM_SUSPEND[2], even if CPU_SUSPEND is not
>> itself used for anything. 
>>
>> However, there was no code to actually wake up a CPU once it called the
>> CPU_SUSPEND function, because I could not find the register providing
>> the necessary information. The fact that CPU_SUSPEND was broken affected
>> nobody, because nothing ever called it -- there were no idle states in
>> the DTS. In hindsight, what I should have done was always return failure
>> from sunxi_validate_power_state(), but that ship has long sailed.
>>
>> I finally found the elusive register and implemented the wakeup code
>> earlier this month[3]. So now, CPU_SUSPEND actually works, if all of
>> your firmware is up to date, and cpuidle works if you add the states in
>> your device tree.
>>
>> Unfortunately, there is currently nothing verifying that compatibility.
>> So you can get into four possible scenarios:
>>   1) No idle states in DTS, any firmware => Linux works, with baseline
>>  power consumption.
>>   2) Idle states added to DTS, no Crust/SCPI => Linux works, but every
>>  attempt to enter an idle state is rejected because CPU_SUSPEND is
>>  not hooked up. So power consumption increases by a sizable amount.
>>   3) Idle states added to DTS, "old" Crust/SCPI (before [3]) => Linux
>>  fails to boot, because CPUs never return from idle states.
>>   4) Idle states added to DTS, "new" Crust/SCPI (after [3]) => Linux
>>  works, with improved power consumption compared to the baseline.
>>
>> Obviously, we want to prevent scenario 3 if possible.
> 
> So I think the core of the problem is that the DT describes some
> firmware feature, but we have the DT bundled with the kernel, not the
> firmware.

I would say the core problem is that the firmware lies about supporting
PSCI CPU_SUSPEND. Linux shouldn't be calling CPU_SUSPEND if the firmware
declares it as unavailable, regardless of what is in the DTS.
(Technically, per the PSCI standard, CPU_SUSPEND is a mandatory
function, but a quick survey of the TF-A platforms shows it is far from
universally implemented.)

> So is there any way we can detect an older crust version in U-Boot,
> then remove any potential idle states from the DT?

Let's assume that we are using a functioning SoC (H3) or the secure fuse
is blown (A64) and therefore U-Boot cannot access SRAM A2. I can think
of three ways it can learn about crust:

a) PSCI_FEATURES (e.g. is CPU_SUSPEND supported)
b) Metadata in the FIT image
c) Custom SMCs

TF-A has some additional methods available:

d) The SCPI-reported firmware version
e) The magic number at the beginning of the firmware binary

> Granted, this requires recent U-Boot as well, but at least we could try
> to mitigate the worst case a bit?

If we're okay with modifying firmware to solve this problem, then I
propose the following solution:

1) Version bump crust or change its magic number.
2) Modify TF-A to only report CPU_SUSPEND as available if it detects the
   new crust version. This would involve conditionally setting
   sunxi_scpi_psci_ops.validate_power_state, and updating psci_setup.c
   to also check for .validate_power_state when setting psci_caps.
3) Modify the Linux PSCI client to respect PSCI_FEATURES when setting
   psci_ops.cpu_suspend. cpuidle-psci checks for this function before
   setting up idle states.
4) Finally, after some time, add the idle states to the DTS.

In fact, this solution solves both scenarios 2 and 3, because it also
takes care of the native PM implementation, which doesn't implement
CPU_SUSPEND at all.

Does that sound workable?

Regards,
Samuel

> A better solution could be to only *add* the idle states if the rest of
> the firmware is deemed worthy. So the mainline DTs would not carry the
> properties in the first place, and only U-Boot adds them, on detecting
> a capable firmware?
> Admittedly this changes the "flow" of the DT, where the kernel is the
> authority, but it might help to solve this problem?
> 
> Or any other way, which involves U-Boot patching the DTB? (This would
> apply to the DTB passed to the kernel, regardless of where and when
> it's loaded from)
> 
> Any opinions?
> 
> Cheers,
> Andre
> 
>> Enter the current patch: I chose the arm,psci-suspend-param values
>> specifically so they would be _rejected_ by the current TF-A code. This
>> makes scenario 3 behave like scenario 2. I 

[linux-sunxi] Re: [PATCH v4 2/4] drm: sun4i: dsi: Add bridge support

2021-03-23 Thread Samuel Holland
On 3/22/21 9:01 AM, Jagan Teki wrote:
> Some display panels would come up with a non-DSI output which
> can have an option to connect DSI interface by means of bridge
> converter.
> 
> This DSI to non-DSI bridge converter would require a bridge
> driver that would communicate the DSI controller for bridge
> functionalities.
> 
> So, add support for bridge functionalities in Allwinner DSI
> controller.
> 
> Cc: Samuel Holland 
> Signed-off-by: Jagan Teki 
> ---
> Note: 
> Samuel Holland, The existing kms hotplug dropped in order to 
> attach the bridge properly. 
> 
> However, I did try several ways to support hotplug with the 
> bridge but it's resulting in a deadlock where bind never attach 
> bridge until bridge pointer found and bridge pointer cannot 
> found until bind finishes. Any inputs on this would be appreciated.

The intended behavior is that sun6i_dsi_bind() is independent of any DSI
device. And sun6i_dsi_attach() must only be called after bind completes
and the DRM device is registered. This design allows the rest of the
display engine (such as the HDMI output) to work even if no panel is
listed in the device tree, or if a panel driver is missing.

> Changes for v4:
> - none
> Changes for v3:
> - updated with new API's 
> 
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 34 +-
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |  2 +-
>  2 files changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c 
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> index 2e9e7b2d4145..39321299dc27 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> @@ -773,6 +773,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   if (dsi->panel)
>   drm_panel_prepare(dsi->panel);
>  
> + if (dsi->panel_bridge)
> + dsi->panel_bridge->funcs->pre_enable(dsi->panel_bridge);
> +
>   /*
>* FIXME: This should be moved after the switch to HS mode.
>*
> @@ -788,6 +791,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   if (dsi->panel)
>   drm_panel_enable(dsi->panel);
>  
> + if (dsi->panel_bridge)
> + dsi->panel_bridge->funcs->enable(dsi->panel_bridge);
> +
>   sun6i_dsi_start(dsi, DSI_START_HSC);
>  
>   udelay(1000);
> @@ -804,6 +810,9 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder 
> *encoder)
>   if (dsi->panel) {
>   drm_panel_disable(dsi->panel);
>   drm_panel_unprepare(dsi->panel);
> + } else if (dsi->panel_bridge) {
> + dsi->panel_bridge->funcs->disable(dsi->panel_bridge);
> + dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
>   }
>  
>   phy_power_off(dsi->dphy);
> @@ -964,23 +973,17 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
>   struct mipi_dsi_device *device)
>  {
>   struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
> - struct drm_panel *panel;
>   int ret;
>  
>   ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 0, 0,
> -   , NULL);
> +   >panel, >panel_bridge);
>   if (ret)
>   return ret;
>  
> - if (!dsi->drm || !dsi->drm->registered)
> - return -EPROBE_DEFER;
> -
> - dsi->panel = panel;
>   dsi->device = device;
>  
> - drm_kms_helper_hotplug_event(dsi->drm);
> -
> - dev_info(host->dev, "Attached device %s\n", device->name);
> + dev_info(host->dev, "Attached %s %s\n",
> +  device->name, dsi->panel ? "panel" : "bridge");
>  
>   return 0;
>  }
> @@ -991,9 +994,10 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host,
>   struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
>  
>   dsi->panel = NULL;
> + dsi->panel_bridge = NULL;
>   dsi->device = NULL;
>  
> - drm_kms_helper_hotplug_event(dsi->drm);
> + drm_of_panel_bridge_remove(dsi->dev->of_node, 0, 0);
>  
>   return 0;
>  }
> @@ -1082,7 +1086,13 @@ static int sun6i_dsi_bind(struct device *dev, struct 
> device *master,
>  
>   drm_connector_attach_encoder(>connector, >encoder);
>  
> - dsi->drm = drm;
> + if (dsi->panel_bridge) {
> + ret = drm_bridge_attach(>encoder, dsi->panel_bridge, NULL, 
> 0);
> + if (ret) {
> + dev_err(dsi->dev, "Couldn't attach drm bridge\n");
> + goto err_cleanup_connector;
> + }
> + }

You initialize dsi->panel_bridge in sun6i_dsi_attach() above, but that
function may run long after sun6i_dsi_bind() has completed -- for
example if this driver is built in, but the panel/bridge driver is built
as a module. So you cannot reference dsi->panel_bridge from this function.

Regards,
Samuel

>  
>   return 0;
>  
> @@ -1096,7 +1106,7 @@ static void sun6i_dsi_unbind(struct device *dev, struct 
> device 

Re: [linux-sunxi] [PATCH v2] ARM: dts: sun8i: h3: beelink-x2: Add power button

2021-03-23 Thread Chen-Yu Tsai
On Wed, Mar 24, 2021 at 4:44 AM Jernej Skrabec  wrote:
>
> Beelink X2 has power button. Add node for it.
>
> Signed-off-by: Jernej Skrabec 

Acked-by: Chen-Yu Tsai 

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/CAGb2v645M9rrQ_c9P8yBckxz8QsZW6-srhOeTyQkSc0cOo0Wug%40mail.gmail.com.


[linux-sunxi] Re: [PATCH v4 1/4] drm: sun4i: dsi: Use drm_of_find_panel_or_bridge

2021-03-23 Thread Samuel Holland
On 3/23/21 5:53 PM, Laurent Pinchart wrote:
> Hi Jagan,
> 
> Thank you for the patch.
> 
> On Mon, Mar 22, 2021 at 07:31:49PM +0530, Jagan Teki wrote:
>> Replace of_drm_find_panel with drm_of_find_panel_or_bridge
>> for finding panel, this indeed help to find the bridge if
>> bridge support added.
>>
>> Added NULL in bridge argument, same will replace with bridge
>> parameter once bridge supported.
>>
>> Signed-off-by: Jagan Teki 
> 
> Looks good, there should be no functional change.

Actually this breaks all existing users of this driver, see below.

> Reviewed-by: Laurent Pinchart 
> 
>> ---
>> Changes for v4, v3:
>> - none
>>
>>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 11 ---
>>  1 file changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c 
>> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
>> index 4f5efcace68e..2e9e7b2d4145 100644
>> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
>> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
>> @@ -21,6 +21,7 @@
>>  
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -963,10 +964,14 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
>>  struct mipi_dsi_device *device)
>>  {
>>  struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
>> -struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);

This is using the OF node of the DSI device, which is a direct child of
the DSI host's OF node. There is no OF graph involved.

>> +struct drm_panel *panel;
>> +int ret;
>> +
>> +ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 0, 0,
>> +  , NULL);

However, this function expects to find the panel using OF graph. This
does not work with existing device trees (PinePhone, PineTab) which do
not use OF graph to connect the panel. And it cannot work, because the
DSI host's binding specifies a single port: the input port from the
display engine.

Regards,
Samuel

>> +if (ret)
>> +return ret;
>>  
>> -if (IS_ERR(panel))
>> -return PTR_ERR(panel);
>>  if (!dsi->drm || !dsi->drm->registered)
>>  return -EPROBE_DEFER;
>>  
> 

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/f47bc0ad-dbd6-05b5-aaec-2e3256e3715a%40sholland.org.


[linux-sunxi] Re: [PATCH v4 3/4] drm: sun4i: dsi: Convert to bridge driver

2021-03-23 Thread Laurent Pinchart
Hi Jagan,

Thank you for the patch.

On Mon, Mar 22, 2021 at 07:31:51PM +0530, Jagan Teki wrote:
> DRM bridge drivers have build-in handling of treating all display
> pipeline components as bridges.
> 
> So, convert the existing to a drm bridge driver with a built-in
> encoder support for compatibility with existing component drivers.

It would be best if possible to move this patch before 2/4, to first
convert to the bridge model, and then build on top of it.

> Signed-off-by: Jagan Teki 
> ---
> Changes for v4:
> - none
> Changes for v3:
> - new patch
> 
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 75 --
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |  6 +++
>  2 files changed, 54 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c 
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> index 39321299dc27..6f3c5330a468 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> @@ -714,10 +714,10 @@ static int sun6i_dsi_start(struct sun6i_dsi *dsi,
>   return 0;
>  }
>  
> -static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
> +static void sun6i_dsi_bridge_enable(struct drm_bridge *bridge)
>  {
> - struct drm_display_mode *mode = >crtc->state->adjusted_mode;
> - struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
> + struct drm_display_mode *mode = 
> >encoder->crtc->state->adjusted_mode;
> + struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
>   struct mipi_dsi_device *device = dsi->device;
>   union phy_configure_opts opts = { };
>   struct phy_configure_opts_mipi_dphy *cfg = _dphy;
> @@ -801,9 +801,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   sun6i_dsi_start(dsi, DSI_START_HSD);
>  }
>  
> -static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
> +static void sun6i_dsi_bridge_disable(struct drm_bridge *bridge)
>  {
> - struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
> + struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
>  
>   DRM_DEBUG_DRIVER("Disabling DSI output\n");
>  
> @@ -852,9 +852,40 @@ static const struct drm_connector_funcs 
> sun6i_dsi_connector_funcs = {
>   .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
>  };
>  
> -static const struct drm_encoder_helper_funcs sun6i_dsi_enc_helper_funcs = {
> - .disable= sun6i_dsi_encoder_disable,
> - .enable = sun6i_dsi_encoder_enable,
> +static int sun6i_dsi_bridge_attach(struct drm_bridge *bridge,
> +enum drm_bridge_attach_flags flags)
> +{
> + struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
> + int ret;
> +
> + if (dsi->panel_bridge)
> + return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, 
> NULL, 0);
> +
> + if (dsi->panel) {
> + drm_connector_helper_add(>connector,
> +  _dsi_connector_helper_funcs);
> + ret = drm_connector_init(bridge->dev, >connector,
> +  _dsi_connector_funcs,
> +  DRM_MODE_CONNECTOR_DSI);
> + if (ret) {
> + dev_err(dsi->dev, "Couldn't initialise the DSI 
> connector\n");
> + goto err_cleanup_connector;
> + }
> +
> + drm_connector_attach_encoder(>connector, >encoder);
> + }
> +
> + return 0;
> +
> +err_cleanup_connector:
> + drm_encoder_cleanup(>encoder);
> + return ret;
> +}
> +
> +static const struct drm_bridge_funcs sun6i_dsi_bridge_funcs = {
> + .enable = sun6i_dsi_bridge_enable,
> + .disable= sun6i_dsi_bridge_disable,
> + .attach = sun6i_dsi_bridge_attach,
>  };
>  
>  static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
> @@ -1063,8 +1094,6 @@ static int sun6i_dsi_bind(struct device *dev, struct 
> device *master,
>   struct sun6i_dsi *dsi = dev_get_drvdata(dev);
>   int ret;
>  
> - drm_encoder_helper_add(>encoder,
> -_dsi_enc_helper_funcs);
>   ret = drm_simple_encoder_init(drm, >encoder,
> DRM_MODE_ENCODER_DSI);
>   if (ret) {
> @@ -1073,27 +1102,12 @@ static int sun6i_dsi_bind(struct device *dev, struct 
> device *master,
>   }
>   dsi->encoder.possible_crtcs = BIT(0);
>  
> - drm_connector_helper_add(>connector,
> -  _dsi_connector_helper_funcs);
> - ret = drm_connector_init(drm, >connector,
> -  _dsi_connector_funcs,
> -  DRM_MODE_CONNECTOR_DSI);
> + ret = drm_bridge_attach(>encoder, >bridge, NULL, 0);
>   if (ret) {
> - dev_err(dsi->dev,
> - "Couldn't initialise the DSI connector\n");
> + dev_err(dsi->dev, "Couldn't attach drm bridge\n");
>   goto err_cleanup_connector;
>   }

[linux-sunxi] Re: [PATCH v4 2/4] drm: sun4i: dsi: Add bridge support

2021-03-23 Thread Laurent Pinchart
Hi Jagan,

Thank you for the patch.

On Mon, Mar 22, 2021 at 07:31:50PM +0530, Jagan Teki wrote:
> Some display panels would come up with a non-DSI output which

Did you mean input instead of output ?

> can have an option to connect DSI interface by means of bridge
> converter.
> 
> This DSI to non-DSI bridge converter would require a bridge
> driver that would communicate the DSI controller for bridge
> functionalities.
> 
> So, add support for bridge functionalities in Allwinner DSI
> controller.
> 
> Cc: Samuel Holland 
> Signed-off-by: Jagan Teki 
> ---
> Note: 
> Samuel Holland, The existing kms hotplug dropped in order to 
> attach the bridge properly. 
> 
> However, I did try several ways to support hotplug with the 
> bridge but it's resulting in a deadlock where bind never attach 
> bridge until bridge pointer found and bridge pointer cannot 
> found until bind finishes. Any inputs on this would be appreciated.
> 
> Changes for v4:
> - none
> Changes for v3:
> - updated with new API's 
> 
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 34 +-
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |  2 +-
>  2 files changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c 
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> index 2e9e7b2d4145..39321299dc27 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> @@ -773,6 +773,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   if (dsi->panel)
>   drm_panel_prepare(dsi->panel);
>  
> + if (dsi->panel_bridge)
> + dsi->panel_bridge->funcs->pre_enable(dsi->panel_bridge);
> +
>   /*
>* FIXME: This should be moved after the switch to HS mode.
>*
> @@ -788,6 +791,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder 
> *encoder)
>   if (dsi->panel)
>   drm_panel_enable(dsi->panel);
>  
> + if (dsi->panel_bridge)
> + dsi->panel_bridge->funcs->enable(dsi->panel_bridge);
> +
>   sun6i_dsi_start(dsi, DSI_START_HSC);
>  
>   udelay(1000);
> @@ -804,6 +810,9 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder 
> *encoder)
>   if (dsi->panel) {
>   drm_panel_disable(dsi->panel);
>   drm_panel_unprepare(dsi->panel);
> + } else if (dsi->panel_bridge) {
> + dsi->panel_bridge->funcs->disable(dsi->panel_bridge);
> + dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
>   }

Instead of having code paths that depend on whether you have a panel or
a bridge, it would be better to wrap the panel a bridge (using
drivers/gpu/drm/bridge/panel.c). The dsi->panel_bridge pointer should be
renamed to next_bridge, and all the code (except in probe) can the use
next_bridge without caring if it's a direct connection to a panel or
another bridge.

Furthermore, the encoder should call bridge functions explicitly, this
should be handled by the DRM core.

>  
>   phy_power_off(dsi->dphy);
> @@ -964,23 +973,17 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
>   struct mipi_dsi_device *device)
>  {
>   struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
> - struct drm_panel *panel;
>   int ret;
>  
>   ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 0, 0,
> -   , NULL);
> +   >panel, >panel_bridge);
>   if (ret)
>   return ret;
>  
> - if (!dsi->drm || !dsi->drm->registered)
> - return -EPROBE_DEFER;
> -
> - dsi->panel = panel;
>   dsi->device = device;
>  
> - drm_kms_helper_hotplug_event(dsi->drm);
> -
> - dev_info(host->dev, "Attached device %s\n", device->name);
> + dev_info(host->dev, "Attached %s %s\n",
> +  device->name, dsi->panel ? "panel" : "bridge");
>  
>   return 0;
>  }
> @@ -991,9 +994,10 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host,
>   struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
>  
>   dsi->panel = NULL;
> + dsi->panel_bridge = NULL;
>   dsi->device = NULL;
>  
> - drm_kms_helper_hotplug_event(dsi->drm);
> + drm_of_panel_bridge_remove(dsi->dev->of_node, 0, 0);
>  
>   return 0;
>  }
> @@ -1082,7 +1086,13 @@ static int sun6i_dsi_bind(struct device *dev, struct 
> device *master,
>  
>   drm_connector_attach_encoder(>connector, >encoder);
>  
> - dsi->drm = drm;
> + if (dsi->panel_bridge) {
> + ret = drm_bridge_attach(>encoder, dsi->panel_bridge, NULL, 
> 0);
> + if (ret) {
> + dev_err(dsi->dev, "Couldn't attach drm bridge\n");
> + goto err_cleanup_connector;
> + }
> + }
>  
>   return 0;
>  
> @@ -1096,7 +1106,7 @@ static void sun6i_dsi_unbind(struct device *dev, struct 
> device *master,
>  {
>   struct sun6i_dsi *dsi = dev_get_drvdata(dev);
>  
> 

[linux-sunxi] gpio-poweroff driver

2021-03-23 Thread XY
Hi,

I am using mainline kernel 5.6 on a BPI M2 zero and I compiled the kernel 
with the gpio-poweroff driver. Did somebody already try to use the 
gpio-poweroff driver ? On my side nothing seems to work.

I tried to implement this on PA17.

Here are my modifications on the device tree :

/dts-v1/;
 /
 { 

 ...
 
 pinctrl@1c20800 { 
reg = <0x1c20800 0x400>; 
interrupts = <0x0 0xb 0x4 0x0 0x11 0x4>; 
clocks = <0x3 0x36 0x10 0x11 0x0>; 
clock-names = "apb", "hosc", "losc";
gpio-controller; #gpio-cells = <0x3>;
interrupt-controller; 
#interrupt-cells = <0x3>; 
 compatible = "allwinner,sun8i-h3-pinctrl"; 
 phandle = <0xc>;
 ... 
* poweroff_pins@0 {  /* This line has been added */ *
*  pins = "PA17"; /* This line has been added */ *
*  function = "gpio_out"; /* This line has been added */ *
*   }; /* This line has been added */ *
 };

 ...
 
* gpio_power_off { /* This line has been added */ *
*   compatible = "gpio-poweroff"; /* This line has been added */ *
*   gpios = <0xc 0x0 0x11 0x1>; /* This line has been added */ *
*; /* This line has been added */*
 };

But nothing happens when I shut down the device .

Any thoughts ?

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/44fc3f15-61a6-4f61-af22-4163ea361131n%40googlegroups.com.


[linux-sunxi] Re: [PATCH v4 1/4] drm: sun4i: dsi: Use drm_of_find_panel_or_bridge

2021-03-23 Thread Laurent Pinchart
Hi Jagan,

Thank you for the patch.

On Mon, Mar 22, 2021 at 07:31:49PM +0530, Jagan Teki wrote:
> Replace of_drm_find_panel with drm_of_find_panel_or_bridge
> for finding panel, this indeed help to find the bridge if
> bridge support added.
> 
> Added NULL in bridge argument, same will replace with bridge
> parameter once bridge supported.
> 
> Signed-off-by: Jagan Teki 

Looks good, there should be no functional change.

Reviewed-by: Laurent Pinchart 

> ---
> Changes for v4, v3:
> - none
> 
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 11 ---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c 
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> index 4f5efcace68e..2e9e7b2d4145 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> @@ -21,6 +21,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -963,10 +964,14 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
>   struct mipi_dsi_device *device)
>  {
>   struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
> - struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
> + struct drm_panel *panel;
> + int ret;
> +
> + ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 0, 0,
> +   , NULL);
> + if (ret)
> + return ret;
>  
> - if (IS_ERR(panel))
> - return PTR_ERR(panel);
>   if (!dsi->drm || !dsi->drm->registered)
>   return -EPROBE_DEFER;
>  

-- 
Regards,

Laurent Pinchart

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/YFpxYpA%2BEIZm7sOf%40pendragon.ideasonboard.com.


[linux-sunxi] [PATCH v2] ARM: dts: sun8i: h3: beelink-x2: Add power button

2021-03-23 Thread Jernej Skrabec
Beelink X2 has power button. Add node for it.

Signed-off-by: Jernej Skrabec 
---
Changes from v1:
- renamed node name so it doesn't contain underscores

 arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts 
b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
index 62b5280ec093..f0e591e1c771 100644
--- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
+++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
@@ -111,6 +111,17 @@ spdif_out: spdif-out {
#sound-dai-cells = <0>;
compatible = "linux,spdif-dit";
};
+
+   r-gpio-keys {
+   compatible = "gpio-keys";
+
+   power {
+   label = "power";
+   linux,code = ;
+   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>;
+   wakeup-source;
+   };
+   };
 };
 
  {
-- 
2.31.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20210323204341.28825-1-jernej.skrabec%40siol.net.


[linux-sunxi] [PATCH v2] sunxi: add fdtoverlay_addr_r environment variable

2021-03-23 Thread Jernej Skrabec
Commit 69076dff2284 ("cmd: pxe: add support for FDT overlays") added
support for loading DT overlay files to PXE boot. However, it needs
additional environment variable which points to memory location which
can be used to temporary store overlay data.

Add it and in the process unify alignment using spaces and fix comment.

Reviewed-by: Andre Przywara 
Signed-off-by: Jernej Skrabec 
---

Changes from v1:
- added r-b tag
- fixed comment

 include/configs/sunxi-common.h | 49 ++
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index ded5aea551d3..3e1dc47c9c55 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -62,7 +62,7 @@
 #define SDRAM_OFFSET(x) 0x2##x
 #define CONFIG_SYS_SDRAM_BASE  0x2000
 #define CONFIG_SYS_LOAD_ADDR   0x2200 /* default load address */
-/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here 
+/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here
  * since it needs to fit in with the other values. By also #defining it
  * we get warnings if the Kconfig value mismatches. */
 #define CONFIG_SPL_STACK_R_ADDR0x2fe0
@@ -72,7 +72,7 @@
 #define CONFIG_SYS_SDRAM_BASE  0x4000
 #define CONFIG_SYS_LOAD_ADDR   0x4200 /* default load address */
 /* V3s do not have enough memory to place code at 0x4a00 */
-/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here 
+/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here
  * since it needs to fit in with the other values. By also #defining it
  * we get warnings if the Kconfig value mismatches. */
 #define CONFIG_SPL_STACK_R_ADDR0x4fe0
@@ -257,40 +257,42 @@ extern int soft_i2c_gpio_scl;
  * There is no compression for arm64 kernels (yet), so leave some space
  * for really big kernels, say 256MB for now.
  * Scripts, PXE and DTBs should go afterwards, leaving the rest for the initrd.
- * Align the initrd to a 2MB page.
  */
-#define BOOTM_SIZE __stringify(0xa00)
-#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(008))
-#define FDT_ADDR_R __stringify(SDRAM_OFFSET(FA0))
-#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(FC0))
-#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(FD0))
-#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(FE0))
+#define BOOTM_SIZE__stringify(0xa00)
+#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(008))
+#define FDT_ADDR_R__stringify(SDRAM_OFFSET(FA0))
+#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(FC0))
+#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(FD0))
+#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(FE0))
+#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(FF0))
 
 #else
 /*
  * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc.
  * 32M uncompressed kernel, 16M compressed kernel, 1M fdt,
- * 1M script, 1M pxe and the ramdisk at the end.
+ * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end.
  */
 #ifndef CONFIG_MACH_SUN8I_V3S
-#define BOOTM_SIZE __stringify(0xa00)
-#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(200))
-#define FDT_ADDR_R __stringify(SDRAM_OFFSET(300))
-#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(310))
-#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(320))
-#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(330))
+#define BOOTM_SIZE__stringify(0xa00)
+#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(200))
+#define FDT_ADDR_R__stringify(SDRAM_OFFSET(300))
+#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(310))
+#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(320))
+#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(330))
+#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(340))
 #else
 /*
  * 64M RAM minus 2MB heap + 16MB for u-boot, stack, fb, etc.
  * 16M uncompressed kernel, 8M compressed kernel, 1M fdt,
- * 1M script, 1M pxe and the ramdisk at the end.
+ * 1M script, 1M pxe, 1M dt overlay and the ramdisk at the end.
  */
-#define BOOTM_SIZE __stringify(0x2e0)
-#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(100))
-#define FDT_ADDR_R __stringify(SDRAM_OFFSET(180))
-#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(190))
-#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A0))
-#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B0))
+#define BOOTM_SIZE__stringify(0x2e0)
+#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(100))
+#define FDT_ADDR_R__stringify(SDRAM_OFFSET(180))
+#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(190))
+#define PXEFILE_ADDR_R__stringify(SDRAM_OFFSET(1A0))
+#define FDTOVERLAY_ADDR_R __stringify(SDRAM_OFFSET(1B0))
+#define RAMDISK_ADDR_R__stringify(SDRAM_OFFSET(1C0))
 #endif
 #endif
 
@@ -300,6 +302,7 @@ extern int