Received: by 2002:ab2:3350:0:b0:1f4:6588:b3a7 with SMTP id o16csp1193838lqe; Mon, 8 Apr 2024 01:12:19 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXisMM3gaWempfL91JuK1tg/k9Lvmcj3GxQD1dm9OQobDvgdTUv4CSxYKk18iAU7Iq6CXj5k5xzre1gEv8q39aqR6C41nSBrxBANqio5A== X-Google-Smtp-Source: AGHT+IE8plwIx85uZEhZZzgAW8xNNf5sNHG4IwMNXdWELFALmHVPhHkEvLKhQLx54MlRi05LraXD X-Received: by 2002:a50:d518:0:b0:56e:2daf:1ed9 with SMTP id u24-20020a50d518000000b0056e2daf1ed9mr6261201edi.23.1712563939231; Mon, 08 Apr 2024 01:12:19 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712563939; cv=pass; d=google.com; s=arc-20160816; b=KDgyhL1QrZ0+D4uUuhC4noWDyRPlcMMg9QWr7nq4/HP9h5aST+3u8g/LaBMVXOopX2 N4/tbaOcpYH5lQOsmDx4wzElthAYVNYsxImCIMSZn6Joskzy0Fdm1VezFT/Kjq/YCY97 K+U5zcQMpfOpWYDzkmJuxq54QzSo+pzqGKog+EP6Me1tn/4UiQmk3fxJANflYwuWLbW7 0Xk6grsc9R5JAvmXPA8gEJJBzD/MrIa0sNkWCs5cv7Og6+P5rt1G+KBBdfNSLq1EeXth CdqAF3yFYABNDaxdKfCyTU0Qm3R8XYfJI/NknJMKu+J/a46GaXyd+ayOkN1j7tATu7lK DuRA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=reply-to:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:subject:date:from:dkim-signature; bh=RxQ2wcAGAGC+sGd6eEzZVmDLrEhgRwlb8XOxTrTCZ1g=; fh=mybq7tpzq6JoVoMMHnsHHfUpqIDX99zshjW5ffzbbIc=; b=Mo8Yc+XAVnKgyCk/Fgs2H0Q8ReeVTJOt1fEQw01yN8rPI/ionqhKJg0MWX/sK/VBo4 1pGeUBUyoGzpbNBa5vpnDof/5sNurUYJH5KwraZrvhFnnneCuRjIScn7NYs4qIP1b/D3 AeNI29heprJGLqPlJC1s5ci6OJVrPszpi1RnZqXKZa+IwlLU7f88ZSZx6YnmlT4H4jsy JFEAzY4UZrj6Blx11uoSPoLin6BzwUfB5bEnUNuGL3DnscpY+H8FsI5ic4JxDjyVI4Vn ZgFIw0FC4gxPcRNejOG6zpua8YhYO9BHbyyGReA1KxjQnGC3HokJgwPDGpMdjL3PRloU ZrmQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QJcxOP90; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-135006-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-135006-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id c12-20020a50f60c000000b0056e090436ddsi3411047edn.90.2024.04.08.01.12.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Apr 2024 01:12:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-135006-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QJcxOP90; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-135006-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-135006-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id C83BC1F21B4F for ; Mon, 8 Apr 2024 08:12:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B078E4D9F5; Mon, 8 Apr 2024 08:10:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QJcxOP90" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4772347F7D; Mon, 8 Apr 2024 08:10:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712563810; cv=none; b=ky8V5wgUhdNIWJOYJsRaWLuaaiJHKdwsFckyNgXcJIRbUJqKHg3aKafohA3Rh2vGTUzHhPLjYcEuIGcb3ZY5pW6Ef4GPn1zPQ5kivaPWrCKPGI0dcPnZ4FXHFBfmR4YZ68oXx6msZJsWZCmGhx7rVuDe5KOwM7mVoETRj/m3Gd0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712563810; c=relaxed/simple; bh=K3MlCnAHGE0KdYMKZRXMDWW+AJZKZ7PhF4nQoH8MG8c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NrqPghIZomW/0zR6xv+ovpDJcAEqNbZGZmqak0WMRp0mnnlewZptlGvqtY6kPFP8DJAH0ePlt65kekiH841eTHjJcdWX1pZJvNPLbPG2tfG8HWicXB9VPSi4wc1WfsQnbIe3Y9UI3k0AC4V95PQqaSJD1BhYexMqmbMfBePdow0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QJcxOP90; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPS id 24EE8C4166B; Mon, 8 Apr 2024 08:10:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712563810; bh=K3MlCnAHGE0KdYMKZRXMDWW+AJZKZ7PhF4nQoH8MG8c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=QJcxOP90xJN3K4MZBWb2MR3LfO1a+lUo6nbf5Uco29rOlAoNemjT9qGey4P6z0dCK ArrGqWvAQyQuW4LikJeaNuOpQWmxfLjjixve9fzQgjWBIK1C/oEQ3tTlsXwFJSqgMY fyUkfW0pRFkM+/9i4Qtcg5LsiBrq+VpeoF4ks5+6WGT3joTMP+AJ/3nT1RirtXdpzg z2rHdOciywwMgZDlWdI5ykWkVP7MG+7LCRUIz9ApP3orCMbEl3X4MkpxYPjYpMo9qM kKDxv/cLCIldGziVw+hlylpS46KjjSHEX37S/9O6fd5j8951Z59F9xA42XWmS0wINF omAI62zZsjGwQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12C6BCD1292; Mon, 8 Apr 2024 08:10:10 +0000 (UTC) From: Nikita Shubin via B4 Relay Date: Mon, 08 Apr 2024 11:09:56 +0300 Subject: [PATCH 4/4] soc: Add SoC driver for Cirrus ep93xx Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20240408-ep93xx-clk-v1-4-1d0f4c324647@maquefel.me> References: <20240408-ep93xx-clk-v1-0-1d0f4c324647@maquefel.me> In-Reply-To: <20240408-ep93xx-clk-v1-0-1d0f4c324647@maquefel.me> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Alexander Sverdlin Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, Nikita Shubin , Arnd Bergmann , Linus Walleij X-Mailer: b4 0.12.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1712563809; l=9488; i=nikita.shubin@maquefel.me; s=20230718; h=from:subject:message-id; bh=wZmf3C8FYeQa2ojy8vOAXoBHARKvrMsAqpZe5AE7EKw=; b=2GyI0+OuCcGWfMVj05RtJdfwE7N0WkF0fCuX524je4uYYy6Wv4a7LhHIYHLLwuZc0Q51SOg6Wx9x ZgvuuJB8D0Tntc+DRYLQRKzM9f1rssQklnlJecVi+JY+MqGvHWzo X-Developer-Key: i=nikita.shubin@maquefel.me; a=ed25519; pk=vqf5YIUJ7BJv3EJFaNNxWZgGuMgDH6rwufTLflwU9ac= X-Endpoint-Received: by B4 Relay for nikita.shubin@maquefel.me/20230718 with auth_id=65 X-Original-From: Nikita Shubin Reply-To: nikita.shubin@maquefel.me From: Nikita Shubin Add an SoC driver for the ep93xx. Currently there is only one thing not fitting into any other framework, and that is the swlock setting. Used for clock settings, pinctrl and restart. Signed-off-by: Nikita Shubin Tested-by: Alexander Sverdlin Acked-by: Alexander Sverdlin Reviewed-by: Linus Walleij --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/cirrus/Kconfig | 13 +++ drivers/soc/cirrus/Makefile | 2 + drivers/soc/cirrus/soc-ep93xx.c | 240 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+) diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 5d924e946507..6a8daeb8c4b9 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -7,6 +7,7 @@ source "drivers/soc/aspeed/Kconfig" source "drivers/soc/atmel/Kconfig" source "drivers/soc/bcm/Kconfig" source "drivers/soc/canaan/Kconfig" +source "drivers/soc/cirrus/Kconfig" source "drivers/soc/fsl/Kconfig" source "drivers/soc/fujitsu/Kconfig" source "drivers/soc/hisilicon/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index ba8f5b5460e1..5f88bd3aefe3 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -8,6 +8,7 @@ obj-y += aspeed/ obj-$(CONFIG_ARCH_AT91) += atmel/ obj-y += bcm/ obj-$(CONFIG_SOC_CANAAN) += canaan/ +obj-$(CONFIG_EP93XX_SOC) += cirrus/ obj-$(CONFIG_ARCH_DOVE) += dove/ obj-$(CONFIG_MACH_DOVE) += dove/ obj-y += fsl/ diff --git a/drivers/soc/cirrus/Kconfig b/drivers/soc/cirrus/Kconfig new file mode 100644 index 000000000000..306499692e8c --- /dev/null +++ b/drivers/soc/cirrus/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +if ARCH_EP93XX + +config EP93XX_SOC + bool "Cirrus EP93xx chips SoC" + select SOC_BUS + select AUXILIARY_BUS + default y if !EP93XX_SOC_COMMON + help + Support SoC for Cirrus EP93xx chips. + +endif diff --git a/drivers/soc/cirrus/Makefile b/drivers/soc/cirrus/Makefile new file mode 100644 index 000000000000..9e6608b67f76 --- /dev/null +++ b/drivers/soc/cirrus/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-y += soc-ep93xx.o diff --git a/drivers/soc/cirrus/soc-ep93xx.c b/drivers/soc/cirrus/soc-ep93xx.c new file mode 100644 index 000000000000..044f17f9ba55 --- /dev/null +++ b/drivers/soc/cirrus/soc-ep93xx.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * SoC driver for Cirrus EP93xx chips. + * Copyright (C) 2022 Nikita Shubin + * + * Based on a rewrite of arch/arm/mach-ep93xx/core.c + * Copyright (C) 2006 Lennert Buytenhek + * Copyright (C) 2007 Herbert Valerio Riedel + * + * Thanks go to Michael Burian and Ray Lehtiniemi for their key + * role in the ep93xx Linux community. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define EP93XX_SYSCON_DEVCFG 0x80 + +#define EP93XX_SWLOCK_MAGICK 0xaa +#define EP93XX_SYSCON_SWLOCK 0xc0 +#define EP93XX_SYSCON_SYSCFG 0x9c +#define EP93XX_SYSCON_SYSCFG_REV_MASK GENMASK(31, 28) +#define EP93XX_SYSCON_SYSCFG_REV_SHIFT 28 + +struct ep93xx_map_info { + spinlock_t lock; + void __iomem *base; + struct regmap *map; +}; + +/* + * EP93xx System Controller software locked register write + * + * Logic safeguards are included to condition the control signals for + * power connection to the matrix to prevent part damage. In addition, a + * software lock register is included that must be written with 0xAA + * before each register write to change the values of the four switch + * matrix control registers. + */ +static void ep93xx_regmap_write(struct regmap *map, spinlock_t *lock, + unsigned int reg, unsigned int val) +{ + guard(spinlock_irqsave)(lock); + + regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK); + regmap_write(map, reg, val); +} + +static void ep93xx_regmap_update_bits(struct regmap *map, spinlock_t *lock, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + guard(spinlock_irqsave)(lock); + + regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK); + /* force write is required to clear swlock if is no changes are made */ + regmap_update_bits_base(map, reg, mask, val, NULL, false, true); +} + +static void ep93xx_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev = _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static void ep93xx_adev_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + struct ep93xx_regmap_adev *rdev = to_ep93xx_regmap_adev(adev); + + kfree(rdev); +} + +static struct auxiliary_device *ep93xx_adev_alloc(struct device *parent, const char *name, + struct ep93xx_map_info *info) +{ + struct ep93xx_regmap_adev *rdev __free(kfree) = NULL; + struct auxiliary_device *adev; + int ret; + + rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + if (!rdev) + return ERR_PTR(-ENOMEM); + + rdev->map = info->map; + rdev->base = info->base; + rdev->lock = &info->lock; + rdev->write = ep93xx_regmap_write; + rdev->update_bits = ep93xx_regmap_update_bits; + + adev = &rdev->adev; + adev->name = name; + adev->dev.parent = parent; + adev->dev.release = ep93xx_adev_release; + + ret = auxiliary_device_init(adev); + if (ret) + return ERR_PTR(ret); + + return &no_free_ptr(rdev)->adev; +} + +static int ep93xx_controller_register(struct device *parent, const char *name, + struct ep93xx_map_info *info) +{ + struct auxiliary_device *adev; + int ret; + + adev = ep93xx_adev_alloc(parent, name, info); + if (IS_ERR(adev)) + return PTR_ERR(adev); + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(parent, ep93xx_unregister_adev, adev); +} + +static unsigned int __init ep93xx_soc_revision(struct regmap *map) +{ + unsigned int val; + + regmap_read(map, EP93XX_SYSCON_SYSCFG, &val); + val &= EP93XX_SYSCON_SYSCFG_REV_MASK; + val >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT; + return val; +} + +static const char __init *ep93xx_get_soc_rev(struct regmap *map) +{ + switch (ep93xx_soc_revision(map)) { + case EP93XX_CHIP_REV_D0: + return "D0"; + case EP93XX_CHIP_REV_D1: + return "D1"; + case EP93XX_CHIP_REV_E0: + return "E0"; + case EP93XX_CHIP_REV_E1: + return "E1"; + case EP93XX_CHIP_REV_E2: + return "E2"; + default: + return "unknown"; + } +} + +const char *pinctrl_names[] = { + "pinctrl-ep9301", /* EP93XX_9301_SOC */ + "pinctrl-ep9307", /* EP93XX_9307_SOC */ + "pinctrl-ep9312", /* EP93XX_9312_SOC */ +}; + +static int __init ep93xx_syscon_probe(struct platform_device *pdev) +{ + enum ep93xx_soc_model model; + struct ep93xx_map_info *map_info; + struct soc_device_attribute *attrs; + struct soc_device *soc_dev; + struct device *dev = &pdev->dev; + struct regmap *map; + void __iomem *base; + int ret; + + model = (enum ep93xx_soc_model)(uintptr_t)device_get_match_data(dev); + + map = device_node_to_regmap(dev->of_node); + if (IS_ERR(map)) + return PTR_ERR(map); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + attrs = devm_kzalloc(dev, sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return -ENOMEM; + + attrs->machine = of_flat_dt_get_machine_name(); + attrs->family = "Cirrus Logic EP93xx"; + attrs->revision = ep93xx_get_soc_rev(map); + + soc_dev = soc_device_register(attrs); + if (IS_ERR(soc_dev)) + return PTR_ERR(soc_dev); + + map_info = devm_kzalloc(dev, sizeof(*map_info), GFP_KERNEL); + if (!map_info) + return -ENOMEM; + + spin_lock_init(&map_info->lock); + map_info->map = map; + map_info->base = base; + + ret = ep93xx_controller_register(dev, pinctrl_names[model], map_info); + if (ret) + dev_err(dev, "registering pinctrl controller failed\n"); + + ret = ep93xx_controller_register(dev, "clk-ep93xx", map_info); + if (ret) + dev_err(dev, "registering clock controller failed\n"); + + ret = ep93xx_controller_register(dev, "reset-ep93xx", map_info); + if (ret) + dev_err(dev, "registering reset controller failed\n"); + + return 0; +} + +static const struct of_device_id ep9301_syscon_of_device_ids[] = { + { .compatible = "cirrus,ep9301-syscon", .data = (void *)EP93XX_9301_SOC }, + { .compatible = "cirrus,ep9302-syscon", .data = (void *)EP93XX_9301_SOC }, + { .compatible = "cirrus,ep9307-syscon", .data = (void *)EP93XX_9307_SOC }, + { .compatible = "cirrus,ep9312-syscon", .data = (void *)EP93XX_9312_SOC }, + { .compatible = "cirrus,ep9315-syscon", .data = (void *)EP93XX_9312_SOC }, + { /* sentinel */ } +}; + +static struct platform_driver ep9301_syscon_driver = { + .driver = { + .name = "ep9301-syscon", + .of_match_table = ep9301_syscon_of_device_ids, + }, +}; +builtin_platform_driver_probe(ep9301_syscon_driver, ep93xx_syscon_probe); -- 2.41.0