kernel-5.15/0618-baikal_vdu-avoid-using-SMC-calls-for-updating-frameb.patch
Mikhail Novosyolov 839b6a86b6 Add support of Baikal-M SoCs
Information about config values was taken from:

From 804820df7bcb3d53a33ecd074b1eac277e938f24 Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 4 Feb 2021 19:35:14 +0400
Subject: [PATCH] config-aarch64: adjusted for Baikal-M (MBM1.0 board)

* DW_APB_TIMER=y, DW_APB_TIMER_OF=y: SoC clocks

* SERIAL_8250_DW=y: serial console

* I2C_DESIGNWARE_CORE=y, I2C_DESIGNWARE_PLATFORM=y: BMC (board
  management controller) and RTC (Real Time Clock) are connected
  via I2C.

* GPIO_DWAPB=y: device (PCIe, PHY, etc) reset/configuration

* RTC_DRV_PCF2127=y: RTC compiled in so the kernel automatically
  sets the system time from the hardware clock

* TP_BMC=y: amongst other things handles the power button

* DRM_BAIKAL_VDU=m, DRM_BAIKAL_HDMI=m: video unit and HDMI transmitter

* CMA_SIZE_MBYTES=256: video display unit and GPU use system RAM, hence
  CMA should reserve enough (contiguous) memory.
  Note: CMA reserves memory during very early init, hence the size
  has to be hard-coded into CONFIG

* MALI_MIDGARD=m: GPU driver, kernel side of proprietary mali blob.
  Note: kernel mode code is GPLv2, so it's fine to distribute it.

* SENSORS_BT1_PVT=m: hardware temperature/voltage sensors

* PCI_BAIKAL=m: PCIe root complex. Compiled as a module since takes
  ages (60 seconds or so) to probe the hardware. If compiled in
  substantially increases the boot time, and machine is completely
  unresponsive during probing PCIe. When built as a module probing
  executes concurrently with other boot activities (unless booting
  from a PCIe device)

* STMMAC_ETH=m, STMMAC_PLATFORM=m, DWMAC_BAIKAL=m: Ethernet driver
2021-06-22 16:35:50 +03:00

223 lines
6.3 KiB
Diff

From 74a27e95a02db904c452f4b06b0e976cbecf113e Mon Sep 17 00:00:00 2001
From: Alexey Sheplyakov <asheplyakov@altlinux.org>
Date: Thu, 28 Jan 2021 18:44:36 +0400
Subject: [PATCH 618/625] baikal_vdu: avoid using SMC calls for updating
framebuffer address
(from SDK-M 4.4)
---
drivers/gpu/drm/baikal/baikal_vdu_drm.h | 16 -----
drivers/gpu/drm/baikal/baikal_vdu_drv.c | 2 -
drivers/gpu/drm/baikal/baikal_vdu_plane.c | 88 ++++++++---------------
3 files changed, 28 insertions(+), 78 deletions(-)
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drm.h b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
index d049335dab1d..2db3fb73c9e7 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drm.h
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drm.h
@@ -22,23 +22,12 @@
#include <drm/drm_gem.h>
#include <drm/drm_simple_kms_helper.h>
-#include <linux/workqueue.h>
struct clk;
struct drm_device;
struct drm_fbdev_cma;
struct drm_panel;
-/*struct baikal_vdu_framebuffer {
- u32 base;
- u32 size;
- u32 index;
- u32 reg_base;
- u32 reg_size;
- u32 reg_width;
- u32 reg_height;
-};*/
-
struct baikal_vdu_drm_connector {
struct drm_connector connector;
struct drm_panel *panel;
@@ -61,8 +50,6 @@ struct baikal_vdu_private {
u32 fb_addr;
u32 fb_end;
-
- struct delayed_work update_work;
};
#define to_baikal_vdu_drm_connector(x) \
@@ -89,7 +76,4 @@ int baikal_vdu_dumb_create(struct drm_file *file_priv,
void baikal_vdu_debugfs_init(struct drm_minor *minor);
-/* Worker functions */
-void baikal_vdu_update_work(struct work_struct *work);
-
#endif /* __BAIKAL_VDU_DRM_H__ */
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_drv.c b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
index 0caa97dcb2e9..5deab510ea57 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_drv.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_drv.c
@@ -152,8 +152,6 @@ static int vdu_modeset_init(struct drm_device *dev)
}
arm_smccc_smc(BAIKAL_SMC_SCP_LOG_DISABLE, 0, 0, 0, 0, 0, 0, 0, &res);
- INIT_DEFERRABLE_WORK(&priv->update_work,
- baikal_vdu_update_work);
drm_mode_config_reset(dev);
diff --git a/drivers/gpu/drm/baikal/baikal_vdu_plane.c b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
index 9817af3c6de8..5a047835e154 100644
--- a/drivers/gpu/drm/baikal/baikal_vdu_plane.c
+++ b/drivers/gpu/drm/baikal/baikal_vdu_plane.c
@@ -17,7 +17,6 @@
*
*/
-#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
@@ -32,42 +31,6 @@
#include "baikal_vdu_drm.h"
#include "baikal_vdu_regs.h"
-#define BAIKAL_SMC_VDU_UPDATE_HDMI 0x82000100
-
-void baikal_vdu_update_work(struct work_struct *work)
-{
- struct arm_smccc_res res;
- unsigned long flags;
- struct baikal_vdu_private *priv = container_of(work, struct baikal_vdu_private,
- update_work.work);
- int count = 0;
- u64 t1, t2;
- t1 = read_sysreg(CNTVCT_EL0);
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, priv->fb_addr, priv->fb_end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
- if (res.a0 == -EBUSY)
- priv->counters[15]++;
- else
- priv->counters[16]++;
- while (res.a0 == -EBUSY && count < 10) {
- count++;
- usleep_range(10000, 20000);
- res.a0 = 0;
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, priv->fb_addr, priv->fb_end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
- if (res.a0 == -EBUSY)
- priv->counters[15]++;
- else
- priv->counters[16]++;
- }
- t2 = read_sysreg(CNTVCT_EL0);
- priv->counters[17] = t2 - t1;
- priv->counters[18] = count;
- priv->counters[19]++;
-}
-
static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@@ -76,6 +39,7 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_crtc_state *crtc_state;
struct drm_display_mode *mode;
int rate, ret;
+ u32 cntl;
if (!state->crtc)
return 0;
@@ -86,6 +50,9 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
if (rate == clk_get_rate(priv->clk))
return 0;
+ /* hold clock domain reset; disable clocking */
+ writel(0, priv->regs + PCTR);
+
if (__clk_is_enabled(priv->clk))
clk_disable_unprepare(priv->clk);
ret = clk_set_rate(priv->clk, rate);
@@ -94,15 +61,23 @@ static int baikal_vdu_primary_plane_atomic_check(struct drm_plane *plane,
if (ret < 0) {
DRM_ERROR("Cannot set desired pixel clock (%d Hz)\n",
rate);
- return -EINVAL;
- }
- clk_prepare_enable(priv->clk);
- if (!__clk_is_enabled(priv->clk)) {
- DRM_ERROR("PLL could not lock at desired frequency (%d Hz)\n",
+ ret = -EINVAL;
+ } else {
+ clk_prepare_enable(priv->clk);
+ if (__clk_is_enabled(priv->clk))
+ ret = 0;
+ else {
+ DRM_ERROR("PLL could not lock at desired frequency (%d Hz)\n",
rate);
- return -EINVAL;
+ ret = -EINVAL;
+ }
}
- return 0;
+
+ /* release clock domain reset; enable clocking */
+ cntl = readl(priv->regs + PCTR);
+ cntl |= PCTR_PCR + PCTR_PCI;
+
+ return ret;
}
static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
@@ -112,28 +87,13 @@ static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
struct baikal_vdu_private *priv = dev->dev_private;
struct drm_plane_state *state = plane->state;
struct drm_framebuffer *fb = state->fb;
- struct arm_smccc_res res;
u32 cntl, addr, end;
- unsigned long flags;
if (!fb)
return;
addr = drm_fb_cma_get_gem_addr(fb, state, 0);
- end = ((addr + fb->height * fb->pitches[0] - 1) & MRR_DEAR_MRR_MASK) | MRR_OUTSTND_RQ(4);
-
- spin_lock_irqsave(&priv->lock, flags);
- arm_smccc_smc(BAIKAL_SMC_VDU_UPDATE_HDMI, addr, end, 0, 0, 0, 0, 0, &res);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (res.a0 == -EBUSY) {
- priv->counters[15]++;
- priv->fb_addr = addr;
- priv->fb_end = end;
- smp_wmb();
- schedule_delayed_work(&priv->update_work, usecs_to_jiffies(250));
- } else
- priv->counters[16]++;
+ priv->fb_addr = addr & 0xfffffff8;
cntl = readl(priv->regs + CR1);
cntl &= ~CR1_BPP_MASK;
@@ -178,6 +138,14 @@ static void baikal_vdu_primary_plane_atomic_update(struct drm_plane *plane,
break;
}
+ writel(priv->fb_addr, priv->regs + DBAR);
+ end = ((priv->fb_addr + fb->height * fb->pitches[0] - 1) & MRR_DEAR_MRR_MASK) | \
+ MRR_OUTSTND_RQ(4);
+
+ if (priv->fb_end < end) {
+ writel(end, priv->regs + MRR);
+ priv->fb_end = end;
+ }
writel(cntl, priv->regs + CR1);
}
--
2.31.1