[PATCH v1] net: phy: add TI DP83TG720 1000BaseT1 PHY support

2023-12-06 Thread Oleksij Rempel
From: Oleksij Rempel 

Add driver for TI DP83TG720 driver support.

Even if the PHY is capable of creating a link on it's own. It needs
proper RGMII configuration and HW reset on link loss.

Signed-off-by: Oleksij Rempel 
---
 drivers/net/phy/Kconfig |   6 +++
 drivers/net/phy/Makefile|   1 +
 drivers/net/phy/dp83tg720.c | 102 
 3 files changed, 109 insertions(+)
 create mode 100644 drivers/net/phy/dp83tg720.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index e95e2a3228..8e12671801 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -35,6 +35,12 @@ config DP83TD510_PHY
  Support for the DP83TD510 Ethernet 10Base-T1L PHY. This PHY supports
  a 10M single pair Ethernet connection for up to 1000 meter cable.
 
+config DP83TG720_PHY
+   tristate "Texas Instruments DP83TG720 Ethernet 1000Base-T1 PHY"
+   help
+ Support for the DP83TG720 Ethernet 1Base-T1 PHY. This PHY supports
+ a 1000M single pair Ethernet.
+
 config LXT_PHY
bool "Driver for the Intel LXT PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 26e4ad884d..ce15e1bab7 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -19,4 +19,5 @@ obj-$(CONFIG_MDIO_BUS_MUX)+= mdio-mux.o
 obj-$(CONFIG_MDIO_BUS_MUX_GPIO)+= mdio-mux-gpio.o
 obj-$(CONFIG_DP83867_PHY)  += dp83867.o
 obj-$(CONFIG_DP83TD510_PHY)+= dp83td510.o
+obj-$(CONFIG_DP83TG720_PHY)+= dp83tg720.o
 
diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c
new file mode 100644
index 00..f0c6e29489
--- /dev/null
+++ b/drivers/net/phy/dp83tg720.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Driver for the Texas Instruments DP83TG720 PHY
+ * Copyright (c) 2023 Pengutronix, Oleksij Rempel 
+ */
+#include 
+#include 
+#include 
+
+#define DP83TG720S_PHY_ID  0x2000a284
+
+/* MDIO_MMD_VEND2 registers */
+#define DP83TG720S_MII_REG_10  0x10
+#define DP83TG720S_LINK_STATUS BIT(0)
+
+#define DP83TG720S_RGMII_DELAY_CTRL0x602
+/* In RGMII mode, Enable or disable the internal delay for RXD */
+#define DP83TG720S_RGMII_RX_CLK_SELBIT(1)
+/* In RGMII mode, Enable or disable the internal delay for TXD */
+#define DP83TG720S_RGMII_TX_CLK_SELBIT(0)
+
+#define DP83TG720S_PHY_RESET   0x1f
+#define DP83TG720S_HW_RESETBIT(15)
+
+static int dp83tg720_config_rgmii_delay(struct phy_device *phydev)
+{
+   u16 rgmii_delay_mask;
+   u16 rgmii_delay = 0;
+
+   switch (phydev->interface) {
+   case PHY_INTERFACE_MODE_RGMII:
+   rgmii_delay = 0;
+   break;
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   rgmii_delay = DP83TG720S_RGMII_RX_CLK_SEL |
+   DP83TG720S_RGMII_TX_CLK_SEL;
+   break;
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   rgmii_delay = DP83TG720S_RGMII_RX_CLK_SEL;
+   break;
+   case PHY_INTERFACE_MODE_RGMII_TXID:
+   rgmii_delay = DP83TG720S_RGMII_TX_CLK_SEL;
+   break;
+   default:
+   return 0;
+   }
+
+   rgmii_delay_mask = DP83TG720S_RGMII_RX_CLK_SEL |
+  DP83TG720S_RGMII_TX_CLK_SEL;
+
+   return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
+ DP83TG720S_RGMII_DELAY_CTRL, rgmii_delay_mask,
+ rgmii_delay);
+}
+
+static int dp83tg720_phy_init(struct phy_device *phydev)
+{
+   /* HW reset is needed to recover link if previous link was lost. SW
+* reset is not enough.
+*/
+   phy_write(phydev, DP83TG720S_PHY_RESET, DP83TG720S_HW_RESET);
+
+   phydev->supported = SUPPORTED_1000baseT_Full;
+   phydev->advertising = SUPPORTED_1000baseT_Full;
+
+   if (phy_interface_is_rgmii(phydev))
+   return dp83tg720_config_rgmii_delay(phydev);
+
+   return 0;
+}
+
+static int dp83tg720_read_status(struct phy_device *phydev)
+{
+   u16 phy_sts;
+
+   phy_sts = phy_read(phydev, DP83TG720S_MII_REG_10);
+   phydev->link = !!(phy_sts & DP83TG720S_LINK_STATUS);
+   if (!phydev->link) {
+   phydev->speed = SPEED_UNKNOWN;
+   phydev->duplex = DUPLEX_UNKNOWN;
+
+   /* According to the "DP83TC81x, DP83TG72x Software
+* Implementation Guide", the PHY needs to be reset after a
+* link loss or if no link is created after at least 100ms.
+*/
+   dp83tg720_phy_init(phydev);
+   return 0;
+   }
+
+   phydev->duplex = DUPLEX_FULL;
+   phydev->speed = SPEED_1000;
+
+   return 0;
+}
+
+static struct phy_driver dp83tg720_driver[] = {
+{
+   PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID),
+   .drv.name   = "TI DP83TG720S",
+   .read_status= dp83t

[PATCH 1/2] efi: add more helper functions to write EFI variables

2023-12-06 Thread Michael Olbrich
Signed-off-by: Michael Olbrich 
---
 common/efi/payload/init.c | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/common/efi/payload/init.c b/common/efi/payload/init.c
index b990b54b2678..19be7ff07fb6 100644
--- a/common/efi/payload/init.c
+++ b/common/efi/payload/init.c
@@ -107,6 +107,44 @@ int efi_set_variable_usec(char *name, efi_guid_t *vendor, 
uint64_t usec)
(strlen(buf)+1) * sizeof(wchar_t));
 }
 
+static int efi_set_variable_printf(char *name, efi_guid_t *vendor, const char 
*fmt, ...)
+{
+   va_list args;
+   char *buf;
+   wchar_t *buf16;
+
+   va_start(args, fmt);
+   buf = xvasprintf(fmt, args);
+   va_end(args);
+   buf16 = xstrdup_char_to_wchar(buf);
+
+   return efi_set_variable(name, vendor,
+   EFI_VARIABLE_BOOTSERVICE_ACCESS |
+   EFI_VARIABLE_RUNTIME_ACCESS, buf16,
+   (strlen(buf)+1) * sizeof(wchar_t));
+   free(buf);
+   free(buf16);
+}
+
+static int efi_set_variable_uint64_le(char *name, efi_guid_t *vendor, uint64_t 
value)
+{
+   uint8_t buf[8];
+
+   buf[0] = (uint8_t)(value >> 0U & 0xFF);
+   buf[1] = (uint8_t)(value >> 8U & 0xFF);
+   buf[2] = (uint8_t)(value >> 16U & 0xFF);
+   buf[3] = (uint8_t)(value >> 24U & 0xFF);
+   buf[4] = (uint8_t)(value >> 32U & 0xFF);
+   buf[5] = (uint8_t)(value >> 40U & 0xFF);
+   buf[6] = (uint8_t)(value >> 48U & 0xFF);
+   buf[7] = (uint8_t)(value >> 56U & 0xFF);
+
+   return efi_set_variable(name, vendor,
+   EFI_VARIABLE_BOOTSERVICE_ACCESS |
+   EFI_VARIABLE_RUNTIME_ACCESS, buf,
+   sizeof(buf));
+}
+
 struct efi_boot {
u32 attributes;
u16 file_path_len;
-- 
2.39.2




[PATCH 2/2] efi: fill more EFI runtime variables defined by systemd

2023-12-06 Thread Michael Olbrich
bootctl will use those variables if available, and produce somethink
like this:

System:
  Firmware: UEFI 2.70 (American Megatrends 5.13)
 Firmware Arch: x64
   Secure Boot: disabled (setup)
  TPM2 Support: firmware only, driver unavailable
  Boot into FW: supported

Current Boot Loader:
  Product: barebox-2023.11.0-dirty
 Features: ✗ Boot counting
   ✗ Menu timeout control
   ✗ One-shot menu timeout control
   ✗ Default entry control
   ✗ One-shot entry control
   ✗ Support for XBOOTLDR partition
   ✗ Support for passing random seed to OS
   ✗ Load drop-in drivers
   ✗ Support Type #1 sort-key field
   ✗ Support @saved pseudo-entry
   ✓ Support Type #1 devicetree field
   ✗ Enroll SecureBoot keys
   ✗ Retain SHIM protocols
   ✗ Boot loader sets ESP information
[...]

Signed-off-by: Michael Olbrich 
---
 common/efi/payload/init.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/common/efi/payload/init.c b/common/efi/payload/init.c
index 19be7ff07fb6..cfacdffa6761 100644
--- a/common/efi/payload/init.c
+++ b/common/efi/payload/init.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 efi_runtime_services_t *RT;
 efi_boot_services_t *BS;
@@ -322,13 +323,46 @@ static int efi_core_init(void)
 }
 core_initcall(efi_core_init);
 
+/* Features of the loader, i.e. systemd-boot, barebox (imported from systemd) 
*/
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT  (1LL << 0)
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (1LL << 1)
+#define EFI_LOADER_FEATURE_ENTRY_DEFAULT   (1LL << 2)
+#define EFI_LOADER_FEATURE_ENTRY_ONESHOT   (1LL << 3)
+#define EFI_LOADER_FEATURE_BOOT_COUNTING   (1LL << 4)
+#define EFI_LOADER_FEATURE_XBOOTLDR(1LL << 5)
+#define EFI_LOADER_FEATURE_RANDOM_SEED (1LL << 6)
+#define EFI_LOADER_FEATURE_LOAD_DRIVER (1LL << 7)
+#define EFI_LOADER_FEATURE_SORT_KEY(1LL << 8)
+#define EFI_LOADER_FEATURE_SAVED_ENTRY (1LL << 9)
+#define EFI_LOADER_FEATURE_DEVICETREE  (1LL << 10)
+#define EFI_LOADER_FEATURE_SECUREBOOT_ENROLL   (1LL << 11)
+#define EFI_LOADER_FEATURE_RETAIN_SHIM (1LL << 12)
+
+
 static int efi_postcore_init(void)
 {
char *uuid;
+   static const uint64_t loader_features =
+   EFI_LOADER_FEATURE_DEVICETREE;
 
efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
  get_time_ns()/1000);
 
+   efi_set_variable_printf("LoaderInfo", &efi_systemd_vendor_guid,
+   "barebox-" UTS_RELEASE);
+
+   efi_set_variable_printf("LoaderFirmwareInfo", &efi_systemd_vendor_guid,
+   "%ls %u.%02u", efi_sys_table->fw_vendor,
+   efi_sys_table->fw_revision >> 16,
+   efi_sys_table->fw_revision & 0x);
+
+   efi_set_variable_printf("LoaderFirmwareType", &efi_systemd_vendor_guid,
+   "UEFI %u.%02u", efi_sys_table->hdr.revision >> 
16,
+   efi_sys_table->hdr.revision & 0x);
+
+   efi_set_variable_uint64_le("LoaderFeatures", &efi_systemd_vendor_guid,
+  loader_features);
+
uuid = device_path_to_partuuid(device_path_from_handle(
   efi_loaded_image->device_handle));
if (uuid) {
-- 
2.39.2