From patchwork Fri Oct 16 10:46:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383226 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=aH0fwJkI; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNBd3CD8z9sTL for ; Fri, 16 Oct 2020 21:47:05 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9F1E4823B7; Fri, 16 Oct 2020 12:46:50 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="aH0fwJkI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9C801823C9; Fri, 16 Oct 2020 12:46:49 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 9E26C81BD2 for ; Fri, 16 Oct 2020 12:46:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkgpf078271; Fri, 16 Oct 2020 05:46:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845202; bh=iLqOu4IPeCgWUvv/On+vUZQFwETC8H1YmocbTBvDYQI=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=aH0fwJkIhRln5ILhBtRelhcWtYYT4HQktwIcoifovr7q+cnWOKE6CQzwPCoEBjf0R ujZQNNC4+nHV+fZWNElP47At+7hU0tVx6yq3jTgVOSIn3ARu3T94F8ZHPlMjPN0Ys5 CcF4ELJJebTF4mhYU0Ito3ZNKLOof/Jeqr4uySK4= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAkgMg110891 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:42 -0500 Received: from DLEE102.ent.ti.com (157.170.170.32) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:41 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:41 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSd016923; Fri, 16 Oct 2020 05:46:40 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 1/7] drivers: Add a new framework for multiplexer devices Date: Fri, 16 Oct 2020 16:16:30 +0530 Message-ID: <20201016104636.14138-2-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Jean-Jacques Hiblot Add a new subsystem that handles multiplexer controllers. The API is the same as in Linux. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass Signed-off-by: Pratyush Yadav --- Notes: No changes on v4. drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/mux/Kconfig | 11 ++ drivers/mux/Makefile | 6 + drivers/mux/mux-uclass.c | 311 ++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/dt-bindings/mux/mux.h | 17 ++ include/mux-internal.h | 109 ++++++++++++ include/mux.h | 147 ++++++++++++++++ 9 files changed, 605 insertions(+) create mode 100644 drivers/mux/Kconfig create mode 100644 drivers/mux/Makefile create mode 100644 drivers/mux/mux-uclass.c create mode 100644 include/dt-bindings/mux/mux.h create mode 100644 include/mux-internal.h create mode 100644 include/mux.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 613669cb38..ed8a39c994 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -64,6 +64,8 @@ source "drivers/mmc/Kconfig" source "drivers/mtd/Kconfig" +source "drivers/mux/Kconfig" + source "drivers/net/Kconfig" source "drivers/nvme/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 9eb51453e5..33f1d536cd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_TPL_)INPUT) += input/ obj-$(CONFIG_$(SPL_TPL_)LED) += led/ obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += mmc/ obj-y += mtd/ +obj-$(CONFIG_$(SPL_)MULTIPLEXER) += mux/ obj-$(CONFIG_$(SPL_TPL_)PCH_SUPPORT) += pch/ obj-$(CONFIG_$(SPL_TPL_)PCI) += pci/ obj-$(CONFIG_$(SPL_TPL_)PHY) += phy/ diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig new file mode 100644 index 0000000000..35c1c5673c --- /dev/null +++ b/drivers/mux/Kconfig @@ -0,0 +1,11 @@ +menu "Multiplexer drivers" + +config MULTIPLEXER + bool "Multiplexer Support" + depends on DM + help + The mux framework is a minimalistic subsystem that handles multiplexer + controllers. It provides the same API as Linux and mux drivers should + be portable with a minimum effort. + +endmenu diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile new file mode 100644 index 0000000000..351e4363d3 --- /dev/null +++ b/drivers/mux/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2019 +# Jean-Jacques Hiblot + +obj-$(CONFIG_$(SPL_)MULTIPLEXER) += mux-uclass.o diff --git a/drivers/mux/mux-uclass.c b/drivers/mux/mux-uclass.c new file mode 100644 index 0000000000..3c89e0a389 --- /dev/null +++ b/drivers/mux/mux-uclass.c @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Multiplexer subsystem + * + * Based on the linux multiplexer framework + * + * Copyright (C) 2017 Axentia Technologies AB + * Author: Peter Rosin + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Jean-Jacques Hiblot + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * The idle-as-is "state" is not an actual state that may be selected, it + * only implies that the state should not be changed. So, use that state + * as indication that the cached state of the multiplexer is unknown. + */ +#define MUX_CACHE_UNKNOWN MUX_IDLE_AS_IS + +/** + * mux_control_ops() - Get the mux_control ops. + * @dev: The client device. + * + * Return: A pointer to the 'mux_control_ops' of the device. + */ +static inline const struct mux_control_ops *mux_dev_ops(struct udevice *dev) +{ + return (const struct mux_control_ops *)dev->driver->ops; +} + +/** + * mux_control_set() - Set the state of the given mux controller. + * @mux: A multiplexer control + * @state: The new requested state. + * + * Return: 0 if OK, or a negative error code. + */ +static int mux_control_set(struct mux_control *mux, int state) +{ + int ret = mux_dev_ops(mux->dev)->set(mux, state); + + mux->cached_state = ret < 0 ? MUX_CACHE_UNKNOWN : state; + + return ret; +} + +unsigned int mux_control_states(struct mux_control *mux) +{ + return mux->states; +} + +/** + * __mux_control_select() - Select the given multiplexer state. + * @mux: The mux-control to request a change of state from. + * @state: The new requested state. + * + * Try to set the mux to the requested state. If not, try to revert if + * appropriate. + */ +static int __mux_control_select(struct mux_control *mux, int state) +{ + int ret; + + if (WARN_ON(state < 0 || state >= mux->states)) + return -EINVAL; + + if (mux->cached_state == state) + return 0; + + ret = mux_control_set(mux, state); + if (ret >= 0) + return 0; + + /* The mux update failed, try to revert if appropriate... */ + if (mux->idle_state != MUX_IDLE_AS_IS) + mux_control_set(mux, mux->idle_state); + + return ret; +} + +int mux_control_select(struct mux_control *mux, unsigned int state) +{ + int ret; + + if (mux->in_use) + return -EBUSY; + + ret = __mux_control_select(mux, state); + + if (ret < 0) + return ret; + + mux->in_use = true; + + return 0; +} + +int mux_control_deselect(struct mux_control *mux) +{ + int ret = 0; + + if (mux->idle_state != MUX_IDLE_AS_IS && + mux->idle_state != mux->cached_state) + ret = mux_control_set(mux, mux->idle_state); + + mux->in_use = false; + + return ret; +} + +static int mux_of_xlate_default(struct mux_chip *mux_chip, + struct ofnode_phandle_args *args, + struct mux_control **muxp) +{ + struct mux_control *mux; + int id; + + log_debug("%s(muxp=%p)\n", __func__, muxp); + + if (args->args_count > 1) { + debug("Invaild args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + id = args->args[0]; + else + id = 0; + + if (id >= mux_chip->controllers) { + dev_err(dev, "bad mux controller %u specified in %s\n", + id, ofnode_get_name(args->node)); + return -ERANGE; + } + + mux = &mux_chip->mux[id]; + mux->id = id; + *muxp = mux; + return 0; +} + +/** + * mux_get_by_indexed_prop() - Get a mux control by integer index + * @dev: The client device. + * @prop_name: Name of the device tree property. + * @index: The index of the mux to get + * @mux: A pointer to the 'mux_control' struct to initialize. + * + * Return: 0 of OK, -errno otherwise. + */ +static int mux_get_by_indexed_prop(struct udevice *dev, const char *prop_name, + int index, struct mux_control **mux) +{ + int ret; + struct ofnode_phandle_args args; + struct udevice *dev_mux; + const struct mux_control_ops *ops; + struct mux_chip *mux_chip; + + log_debug("%s(dev=%p, index=%d, mux=%p)\n", __func__, dev, index, mux); + + ret = dev_read_phandle_with_args(dev, prop_name, "#mux-control-cells", + 0, index, &args); + if (ret) { + debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n", + __func__, ret); + return ret; + } + + ret = uclass_get_device_by_ofnode(UCLASS_MUX, args.node, &dev_mux); + if (ret) { + debug("%s: uclass_get_device_by_ofnode failed: err=%d\n", + __func__, ret); + return ret; + } + + mux_chip = dev_get_uclass_priv(dev_mux); + + ops = mux_dev_ops(dev_mux); + if (ops->of_xlate) + ret = ops->of_xlate(mux_chip, &args, mux); + else + ret = mux_of_xlate_default(mux_chip, &args, mux); + if (ret) { + debug("of_xlate() failed: %d\n", ret); + return ret; + } + (*mux)->dev = dev_mux; + + return 0; +} + +int mux_get_by_index(struct udevice *dev, int index, struct mux_control **mux) +{ + return mux_get_by_indexed_prop(dev, "mux-controls", index, mux); +} + +int mux_control_get(struct udevice *dev, const char *name, + struct mux_control **mux) +{ + int index; + + debug("%s(dev=%p, name=%s, mux=%p)\n", __func__, dev, name, mux); + + index = dev_read_stringlist_search(dev, "mux-control-names", name); + if (index < 0) { + debug("fdt_stringlist_search() failed: %d\n", index); + return index; + } + + return mux_get_by_index(dev, index, mux); +} + +void mux_control_put(struct mux_control *mux) +{ + mux_control_deselect(mux); +} + +/** + * devm_mux_control_release() - Release the given managed mux. + * @dev: The client device. + * @res: Pointer to the mux to be released. + * + * This function is called by devres to release the mux. It reverses the + * effects of mux_control_get(). + */ +static void devm_mux_control_release(struct udevice *dev, void *res) +{ + mux_control_put(*(struct mux_control **)res); +} + +struct mux_control *devm_mux_control_get(struct udevice *dev, const char *id) +{ + int rc; + struct mux_control **mux; + + mux = devres_alloc(devm_mux_control_release, + sizeof(struct mux_control *), __GFP_ZERO); + if (unlikely(!mux)) + return ERR_PTR(-ENOMEM); + + rc = mux_control_get(dev, id, mux); + if (rc) + return ERR_PTR(rc); + + devres_add(dev, mux); + return *mux; +} + +int mux_alloc_controllers(struct udevice *dev, unsigned int controllers) +{ + int i; + struct mux_chip *mux_chip = dev_get_uclass_priv(dev); + + mux_chip->mux = devm_kmalloc(dev, + sizeof(struct mux_control) * controllers, + __GFP_ZERO); + if (!mux_chip->mux) + return -ENOMEM; + + mux_chip->controllers = controllers; + + for (i = 0; i < mux_chip->controllers; ++i) { + struct mux_control *mux = &mux_chip->mux[i]; + + mux->dev = dev; + mux->cached_state = MUX_CACHE_UNKNOWN; + mux->idle_state = MUX_IDLE_AS_IS; + mux->in_use = false; + mux->id = i; + } + + return 0; +} + +static int mux_uclass_post_probe(struct udevice *dev) +{ + int i, ret; + struct mux_chip *mux_chip = dev_get_uclass_priv(dev); + + /* Set all mux controllers to their idle state. */ + for (i = 0; i < mux_chip->controllers; ++i) { + struct mux_control *mux = &mux_chip->mux[i]; + + if (mux->idle_state == mux->cached_state) + continue; + + ret = mux_control_set(mux, mux->idle_state); + if (ret < 0) { + dev_err(&mux_chip->dev, "unable to set idle state\n"); + return ret; + } + } + return 0; +} + +UCLASS_DRIVER(mux) = { + .id = UCLASS_MUX, + .name = "mux", + .post_probe = mux_uclass_post_probe, + .per_device_auto_alloc_size = sizeof(struct mux_chip), +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 88f10c4622..17542de2f3 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -71,6 +71,7 @@ enum uclass_id { UCLASS_MMC, /* SD / MMC card or chip */ UCLASS_MOD_EXP, /* RSA Mod Exp device */ UCLASS_MTD, /* Memory Technology Device (MTD) device */ + UCLASS_MUX, /* Multiplexer device */ UCLASS_NOP, /* No-op devices */ UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */ UCLASS_NVME, /* NVM Express device */ diff --git a/include/dt-bindings/mux/mux.h b/include/dt-bindings/mux/mux.h new file mode 100644 index 0000000000..042719218d --- /dev/null +++ b/include/dt-bindings/mux/mux.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides constants for most Multiplexer bindings. + * + * Most Multiplexer bindings specify an idle state. In most cases, the + * the multiplexer can be left as is when idle, and in some cases it can + * disconnect the input/output and leave the multiplexer in a high + * impedance state. + */ + +#ifndef _DT_BINDINGS_MUX_MUX_H +#define _DT_BINDINGS_MUX_MUX_H + +#define MUX_IDLE_AS_IS (-1) +#define MUX_IDLE_DISCONNECT (-2) + +#endif diff --git a/include/mux-internal.h b/include/mux-internal.h new file mode 100644 index 0000000000..93e3a5cdd7 --- /dev/null +++ b/include/mux-internal.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Based on the linux multiplexer framework + * + * Copyright (C) 2017 Axentia Technologies AB + * Author: Peter Rosin + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Jean-Jacques Hiblot + */ + +#ifndef _MUX_INTERNAL_H +#define _MUX_INTERNAL_H + +/* See mux.h for background documentation. */ + +struct ofnode_phandle_args; + +/** + * struct mux_chip - Represents a chip holding mux controllers. + * @controllers: Number of mux controllers handled by the chip. + * @mux: Array of mux controllers that are handled. + * + * This a per-device uclass-private data. + */ +struct mux_chip { + unsigned int controllers; + struct mux_control *mux; +}; + +/** + * struct mux_control_ops - Mux controller operations for a mux chip. + * @set: Set the state of the given mux controller. + */ +struct mux_control_ops { + /** + * set - Apply a state to a multiplexer control + * + * @mux: A multiplexer control + * @return 0 if OK, or a negative error code. + */ + int (*set)(struct mux_control *mux, int state); + + /** + * of_xlate - Translate a client's device-tree (OF) multiplexer + * specifier. + * + * If this function pointer is set to NULL, the multiplexer core will + * use a default implementation, which assumes #mux-control-cells = <1> + * and that the DT cell contains a simple integer channel ID. + * + * @dev_mux: The multiplexer device. A single device may handle + * several multiplexer controls. + * @args: The multiplexer specifier values from device tree. + * @muxp: (out) A multiplexer control + * @return 0 if OK, or a negative error code. + */ + int (*of_xlate)(struct mux_chip *dev_mux, + struct ofnode_phandle_args *args, + struct mux_control **muxp); +}; + +/** + * struct mux_control - Represents a mux controller. + * @in_use: Whether the mux controller is in use or not. + * @dev: The client device. + * @cached_state: The current mux controller state, or -1 if none. + * @states: The number of mux controller states. + * @idle_state: The mux controller state to use when inactive, or one + * of MUX_IDLE_AS_IS and MUX_IDLE_DISCONNECT. + * @id: The index of the mux controller within the mux chip + * it is a part of. + * + * Mux drivers may only change @states and @idle_state, and may only do so + * between allocation and registration of the mux controller. Specifically, + * @cached_state is internal to the mux core and should never be written by + * mux drivers. + */ +struct mux_control { + bool in_use; + struct udevice *dev; + int cached_state; + unsigned int states; + int idle_state; + int id; +}; + +/** + * mux_control_get_index() - Get the index of the given mux controller + * @mux: The mux-control to get the index for. + * + * Return: The index of the mux controller within the mux chip the mux + * controller is a part of. + */ +static inline unsigned int mux_control_get_index(struct mux_control *mux) +{ + return mux->id; +} + +/** + * mux_alloc_controllers() - Allocate the given number of mux controllers. + * @dev: The client device. + * controllers: Number of controllers to allocate. + * + * Return: 0 of OK, -errno otherwise. + */ +int mux_alloc_controllers(struct udevice *dev, unsigned int controllers); + +#endif diff --git a/include/mux.h b/include/mux.h new file mode 100644 index 0000000000..85eb7d42fc --- /dev/null +++ b/include/mux.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Based on the linux multiplexer framework + * + * At its core, a multiplexer (or mux), also known as a data selector, is a + * device that selects between several analog or digital input signals and + * forwards it to a single output line. This notion can be extended to work + * with buses, like a I2C bus multiplexer for example. + * + * Copyright (C) 2017 Axentia Technologies AB + * Author: Peter Rosin + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Jean-Jacques Hiblot + */ + +#ifndef _MUX_H_ +#define _MUX_H_ + +#include +#include + +struct udevice; +struct mux_control; + +#if CONFIG_IS_ENABLED(MULTIPLEXER) +/** + * mux_control_states() - Query the number of multiplexer states. + * @mux: The mux-control to query. + * + * Return: The number of multiplexer states. + */ +unsigned int mux_control_states(struct mux_control *mux); + +/** + * mux_control_select() - Select the given multiplexer state. + * @mux: The mux-control to request a change of state from. + * @state: The new requested state. + * + * On successfully selecting the mux-control state, it will be locked until + * there is a call to mux_control_deselect(). If the mux-control is already + * selected when mux_control_select() is called, the function will indicate + * -EBUSY + * + * Therefore, make sure to call mux_control_deselect() when the operation is + * complete and the mux-control is free for others to use, but do not call + * mux_control_deselect() if mux_control_select() fails. + * + * Return: 0 when the mux-control state has the requested state or a negative + * errno on error. + */ +int __must_check mux_control_select(struct mux_control *mux, + unsigned int state); +#define mux_control_try_select(mux) mux_control_select(mux) + +/** + * mux_control_deselect() - Deselect the previously selected multiplexer state. + * @mux: The mux-control to deselect. + * + * It is required that a single call is made to mux_control_deselect() for + * each and every successful call made to either of mux_control_select() or + * mux_control_try_select(). + * + * Return: 0 on success and a negative errno on error. An error can only + * occur if the mux has an idle state. Note that even if an error occurs, the + * mux-control is unlocked and is thus free for the next access. + */ +int mux_control_deselect(struct mux_control *mux); + +/** + * mux_get_by_index() = Get a mux by integer index. + * @dev: The client device. + * @index: The index of the mux to get. + * @mux: A pointer to the 'mux_control' struct to initialize. + * + * This looks up and initializes a mux. The index is relative to the client + * device. + * + * Return: 0 if OK, or a negative error code. + */ +int mux_get_by_index(struct udevice *dev, int index, struct mux_control **mux); + +/** + * mux_control_get() - Get the mux-control for a device. + * @dev: The device that needs a mux-control. + * @mux_name: The name identifying the mux-control. + * @mux: A pointer to the mux-control pointer. + * + * Return: 0 of OK, or a negative error code. + */ +int mux_control_get(struct udevice *dev, const char *name, + struct mux_control **mux); + +/** + * mux_control_put() - Put away the mux-control for good. + * @mux: The mux-control to put away. + * + * mux_control_put() reverses the effects of mux_control_get(). + */ +void mux_control_put(struct mux_control *mux); + +/** + * devm_mux_control_get() - Get the mux-control for a device, with resource + * management. + * @dev: The device that needs a mux-control. + * @mux_name: The name identifying the mux-control. + * + * Return: Pointer to the mux-control, or an ERR_PTR with a negative errno. + */ +struct mux_control *devm_mux_control_get(struct udevice *dev, + const char *mux_name); +#else +unsigned int mux_control_states(struct mux_control *mux) +{ + return -ENOSYS; +} + +int __must_check mux_control_select(struct mux_control *mux, + unsigned int state) +{ + return -ENOSYS; +} + +#define mux_control_try_select(mux) mux_control_select(mux) + +int mux_control_deselect(struct mux_control *mux) +{ + return -ENOSYS; +} + +struct mux_control *mux_control_get(struct udevice *dev, const char *mux_name) +{ + return NULL; +} + +void mux_control_put(struct mux_control *mux) +{ +} + +struct mux_control *devm_mux_control_get(struct udevice *dev, + const char *mux_name) +{ + return NULL; +} +#endif + +#endif From patchwork Fri Oct 16 10:46:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383228 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=YhM50Zwn; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNC00tNCz9sTL for ; Fri, 16 Oct 2020 21:47:24 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E795A823F3; Fri, 16 Oct 2020 12:46:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="YhM50Zwn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C49F9823B7; Fri, 16 Oct 2020 12:46:49 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id DD254822D2 for ; Fri, 16 Oct 2020 12:46:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkiHE078279; Fri, 16 Oct 2020 05:46:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845204; bh=T6yatsXBBXm1RtzX+ibWMQfFYAXC0Nps/3iMZ/kfVqY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=YhM50Zwnqfn1ThNi33k5sJlU3Tol+MmhIOxZ41gdd5LtS9h2yDsVxFNqLWNiIx3Ta 6TaurjCVWjphLceuW6d4pApWOwpC6SYz/5boA4lVueEAxCwfi5C0N3suJmIWUrImep 9k+gvCSWhIpzEevCXZ9CKL3KcqI6EsZrAWxzC9rM= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAki6c115229 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:44 -0500 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:43 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:43 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSe016923; Fri, 16 Oct 2020 05:46:42 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 2/7] dm: board: complete the initialization of the muxes in initr_dm() Date: Fri, 16 Oct 2020 16:16:31 +0530 Message-ID: <20201016104636.14138-3-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Jean-Jacques Hiblot This will probe the multiplexer devices that have a "u-boot,mux-autoprobe" property. As a consequence they will be put in their idle state. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass Signed-off-by: Pratyush Yadav --- Notes: No changes in v4. common/board_r.c | 12 ++++++++++++ drivers/mux/mux-uclass.c | 23 +++++++++++++++++++++++ include/mux.h | 12 ++++++++++++ 3 files changed, 47 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 9b2fec701a..b9217b2e27 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -46,6 +46,7 @@ #include #endif #include +#include #include #include #include @@ -341,6 +342,17 @@ static int initr_dm_devices(void) return ret; } + if (IS_ENABLED(CONFIG_MULTIPLEXER)) { + /* + * Initialize the multiplexer controls to their default state. + * This must be done early as other drivers may unknowingly + * rely on it. + */ + ret = dm_mux_init(); + if (ret) + return ret; + } + return 0; } diff --git a/drivers/mux/mux-uclass.c b/drivers/mux/mux-uclass.c index 3c89e0a389..3dad466101 100644 --- a/drivers/mux/mux-uclass.c +++ b/drivers/mux/mux-uclass.c @@ -303,6 +303,29 @@ static int mux_uclass_post_probe(struct udevice *dev) return 0; } +int dm_mux_init(void) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + + ret = uclass_get(UCLASS_MUX, &uc); + if (ret < 0) { + log_debug("unable to get MUX uclass\n"); + return ret; + } + uclass_foreach_dev(dev, uc) { + if (dev_read_bool(dev, "u-boot,mux-autoprobe")) { + ret = device_probe(dev); + if (ret) + log_debug("unable to probe device %s\n", + dev->name); + } + } + + return 0; +} + UCLASS_DRIVER(mux) = { .id = UCLASS_MUX, .name = "mux", diff --git a/include/mux.h b/include/mux.h index 85eb7d42fc..23844f480a 100644 --- a/include/mux.h +++ b/include/mux.h @@ -109,6 +109,13 @@ void mux_control_put(struct mux_control *mux); */ struct mux_control *devm_mux_control_get(struct udevice *dev, const char *mux_name); +/** + * dm_mux_init() - Initialize the multiplexer controls to their default state. + * + * Return: 0 if OK, -errno otherwise. + */ +int dm_mux_init(void); + #else unsigned int mux_control_states(struct mux_control *mux) { @@ -142,6 +149,11 @@ struct mux_control *devm_mux_control_get(struct udevice *dev, { return NULL; } + +int dm_mux_init(void) +{ + return -ENOSYS; +} #endif #endif From patchwork Fri Oct 16 10:46:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383230 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=FCEQ/fRn; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNCN23PPz9sTL for ; Fri, 16 Oct 2020 21:47:44 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E8FCA82423; Fri, 16 Oct 2020 12:46:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="FCEQ/fRn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 15B0382351; Fri, 16 Oct 2020 12:46:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 622CE82351 for ; Fri, 16 Oct 2020 12:46:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkkZ6067536; Fri, 16 Oct 2020 05:46:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845206; bh=UAjIaCdf9I+18SHpu7FH9OsjTm7vPq+dwCoY7oqznI0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=FCEQ/fRnvtqyhkBpW3iopHhGYrG7otwEl7EYGNXtUHWikEPAVSCHW0MVC35eKPQen 50AVyijtoriyL45gwzrTrXquk1cxPVAVW959lyRnL4QLN6Oqnh+kZpVaLXBOY2fyH9 G9yyUGIaGHBRyDki0F8cW63Q6UZdThCfxnPH34BM= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAkko0115278 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:46 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:45 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:45 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSf016923; Fri, 16 Oct 2020 05:46:44 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 3/7] drivers: mux: mmio-based syscon mux controller Date: Fri, 16 Oct 2020 16:16:32 +0530 Message-ID: <20201016104636.14138-4-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Jean-Jacques Hiblot This adds a driver for mmio-based syscon multiplexers controlled by bitfields in a syscon register range. This is heavily based on the linux mmio-mux driver. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass Signed-off-by: Pratyush Yadav --- Notes: Changes in v4: - Make strings in log messages smaller to reduce memory footprint. drivers/mux/Kconfig | 14 +++++ drivers/mux/Makefile | 1 + drivers/mux/mmio.c | 141 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 drivers/mux/mmio.c diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index 35c1c5673c..f15ee4f833 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -8,4 +8,18 @@ config MULTIPLEXER controllers. It provides the same API as Linux and mux drivers should be portable with a minimum effort. +if MULTIPLEXER + +config MUX_MMIO + bool "MMIO register bitfield-controlled Multiplexer" + depends on MULTIPLEXER && SYSCON + help + MMIO register bitfield-controlled Multiplexer controller. + + The driver builds multiplexer controllers for bitfields in a syscon + register. For N bit wide bitfields, there will be 2^N possible + multiplexer states. + +endif + endmenu diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index 351e4363d3..78ebf04c7a 100644 --- a/drivers/mux/Makefile +++ b/drivers/mux/Makefile @@ -4,3 +4,4 @@ # Jean-Jacques Hiblot obj-$(CONFIG_$(SPL_)MULTIPLEXER) += mux-uclass.o +obj-$(CONFIG_$(SPL_)MUX_MMIO) += mmio.o diff --git a/drivers/mux/mmio.c b/drivers/mux/mmio.c new file mode 100644 index 0000000000..654fff26f7 --- /dev/null +++ b/drivers/mux/mmio.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MMIO register bitfield-controlled multiplexer driver + * Based on the linux mmio multiplexer driver + * + * Copyright (C) 2017 Pengutronix, Philipp Zabel + * Copyright (C) 2019 Texas Instrument, Jean-jacques Hiblot + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int mux_mmio_set(struct mux_control *mux, int state) +{ + struct regmap_field **fields = dev_get_priv(mux->dev); + + return regmap_field_write(fields[mux_control_get_index(mux)], state); +} + +static const struct mux_control_ops mux_mmio_ops = { + .set = mux_mmio_set, +}; + +static const struct udevice_id mmio_mux_of_match[] = { + { .compatible = "mmio-mux" }, + { /* sentinel */ }, +}; + +static int mmio_mux_probe(struct udevice *dev) +{ + struct regmap_field **fields; + struct mux_chip *mux_chip = dev_get_uclass_priv(dev); + struct regmap *regmap; + u32 *mux_reg_masks; + u32 *idle_states; + int num_fields; + int ret; + int i; + + regmap = syscon_node_to_regmap(dev_ofnode(dev->parent)); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(dev, "failed to get regmap: %d\n", ret); + return ret; + } + + num_fields = dev_read_size(dev, "mux-reg-masks"); + if (num_fields < 0) + return log_msg_ret("mux-reg-masks missing", -EINVAL); + + num_fields /= sizeof(u32); + if (num_fields == 0 || num_fields % 2) + ret = -EINVAL; + num_fields = num_fields / 2; + + ret = mux_alloc_controllers(dev, num_fields); + if (ret < 0) + return log_msg_ret("mux_alloc_controllers", ret); + + fields = devm_kmalloc(dev, num_fields * sizeof(*fields), __GFP_ZERO); + if (!fields) + return -ENOMEM; + dev->priv = fields; + + mux_reg_masks = devm_kmalloc(dev, num_fields * 2 * sizeof(u32), + __GFP_ZERO); + if (!mux_reg_masks) + return -ENOMEM; + + ret = dev_read_u32_array(dev, "mux-reg-masks", mux_reg_masks, + num_fields * 2); + if (ret < 0) + return log_msg_ret("mux-reg-masks read", ret); + + idle_states = devm_kmalloc(dev, num_fields * sizeof(u32), __GFP_ZERO); + if (!idle_states) + return -ENOMEM; + + ret = dev_read_u32_array(dev, "idle-states", idle_states, num_fields); + if (ret < 0) { + log_err("idle-states"); + devm_kfree(dev, idle_states); + idle_states = NULL; + } + + for (i = 0; i < num_fields; i++) { + struct mux_control *mux = &mux_chip->mux[i]; + struct reg_field field; + u32 reg, mask; + int bits; + + reg = mux_reg_masks[2 * i]; + mask = mux_reg_masks[2 * i + 1]; + + field.reg = reg; + field.msb = fls(mask) - 1; + field.lsb = ffs(mask) - 1; + + if (mask != GENMASK(field.msb, field.lsb)) + return log_msg_ret("invalid mask", -EINVAL); + + fields[i] = devm_regmap_field_alloc(dev, regmap, field); + if (IS_ERR(fields[i])) { + ret = PTR_ERR(fields[i]); + return log_msg_ret("regmap_field_alloc", ret); + } + + bits = 1 + field.msb - field.lsb; + mux->states = 1 << bits; + + if (!idle_states) + continue; + + if (idle_states[i] != MUX_IDLE_AS_IS && + idle_states[i] >= mux->states) + return log_msg_ret("idle-states range", -EINVAL); + + mux->idle_state = idle_states[i]; + } + + devm_kfree(dev, mux_reg_masks); + if (idle_states) + devm_kfree(dev, idle_states); + + return 0; +} + +U_BOOT_DRIVER(mmio_mux) = { + .name = "mmio-mux", + .id = UCLASS_MUX, + .of_match = mmio_mux_of_match, + .probe = mmio_mux_probe, + .ops = &mux_mmio_ops, +}; From patchwork Fri Oct 16 10:46:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383229 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=mSetd8T9; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNC80wkwz9sTL for ; Fri, 16 Oct 2020 21:47:32 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B6F868242B; Fri, 16 Oct 2020 12:46:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="mSetd8T9"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5652E82406; Fri, 16 Oct 2020 12:46:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E12DF81BD2 for ; Fri, 16 Oct 2020 12:46:49 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkmci067542; Fri, 16 Oct 2020 05:46:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845208; bh=2rGuykMVf53M70lNjMFnvM4/+wxHNFam3H67PzxXJHg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=mSetd8T9XvYo23Qx4jufLmlMd/l/UP2R1iTd8ileklQtoLIpkgRP/qx0QJ/Yjk+kM Xq9kiz40nIIFhWlyclFeY9ulX9r6r6JUbQMXdK5f5p35xYKjQ9UlqFPN7ri0I8DHDy 4WdJayLKRbN/9QPSrtafgM2udExkeSGVjRq5NC0o= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAkmjT115315 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:48 -0500 Received: from DFLE108.ent.ti.com (10.64.6.29) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:47 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:47 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSg016923; Fri, 16 Oct 2020 05:46:46 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 4/7] Kconfig: Increase the pre-relocation memory Date: Fri, 16 Oct 2020 16:16:33 +0530 Message-ID: <20201016104636.14138-5-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean The memory is close to full and adding a syscon node in test.dts makes it go over the limit and makes malloc() fail on startup. Signed-off-by: Pratyush Yadav Reviewed-by: Simon Glass --- Notes: New in v4. Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kconfig b/Kconfig index 520679f57e..b2165c1c49 100644 --- a/Kconfig +++ b/Kconfig @@ -196,7 +196,7 @@ config SYS_MALLOC_F_LEN hex "Size of malloc() pool before relocation" depends on SYS_MALLOC_F default 0x1000 if AM33XX - default 0x2800 if SANDBOX + default 0x4000 if SANDBOX default 0x2000 if (ARCH_IMX8 || ARCH_IMX8M || ARCH_MX7 || \ ARCH_MX7ULP || ARCH_MX6 || ARCH_MX5 || \ ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \ From patchwork Fri Oct 16 10:46:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383231 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=rHnuFJko; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNCb5yhpz9sTK for ; Fri, 16 Oct 2020 21:47:55 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2D5448241F; Fri, 16 Oct 2020 12:47:00 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="rHnuFJko"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BF8D982427; Fri, 16 Oct 2020 12:46:55 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id F0FC3823FC for ; Fri, 16 Oct 2020 12:46:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkoXN078306; Fri, 16 Oct 2020 05:46:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845210; bh=Xe1xw1GcC/mXU9W41tZpps+Mlgg0tsoJY5cFYS2bHlE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=rHnuFJkoyzRW4iqNnodYVAmzOx0iJm4iw2lrfgntvwWT3ISy3+T+yRwRLGJ7rghrO L49yPii5v9zoYATip31UrLwpcYuTcoAtkJ6jlIDxcowCqZsLURVbtBmumWWn2XwHQv H0QIzj4bmmRxIZVuu5EGKvgBEXemvWWB7GpOxLrU= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAkol0121798 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:50 -0500 Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:49 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:49 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSh016923; Fri, 16 Oct 2020 05:46:48 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 5/7] test: Add tests for the multiplexer framework Date: Fri, 16 Oct 2020 16:16:34 +0530 Message-ID: <20201016104636.14138-6-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Jean-Jacques Hiblot Provide tests to check the behavior of the multiplexer framework. Two sets of tests are added. One is using an emulated multiplexer driver that can be used to test basic functionality like select, deselect, etc. The other is using the mmio mux which adds tests specific to it. Signed-off-by: Jean-Jacques Hiblot Signed-off-by: Pratyush Yadav Reviewed-by: Simon Glass --- Notes: Changes in v4: - Add an emulated mux driver that makes it easier to test some basic functionality. It is used to test basic things like setting default state, and simple set/unset functionality. The MMIO test is still kept around for testing the mmio mux driver. - Add a node for the emulated mux driver in test.dts - Drop dm_test_mux_mmio_default_state(). This functionality is exercised by the emulated mux test. - Drop some unused includes from mux-mmio.c - s/DM_TESTF/UT_TESTF/g arch/sandbox/dts/test.dts | 33 +++++++++ configs/sandbox_defconfig | 2 + test/dm/Makefile | 2 + test/dm/mux-emul.c | 105 +++++++++++++++++++++++++++++ test/dm/mux-mmio.c | 138 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+) create mode 100644 test/dm/mux-emul.c create mode 100644 test/dm/mux-mmio.c diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index fa84b2c10f..70ccb4951a 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -3,6 +3,7 @@ #include #include #include +#include / { model = "sandbox"; @@ -133,6 +134,12 @@ interrupts-extended = <&irq 3 0>; acpi,name = "GHIJ"; phandle-value = <&gpio_c 10>, <0xFFFFFFFF 20>, <&gpio_a 30>; + + mux-controls = <&muxcontroller0 0>, <&muxcontroller0 1>, + <&muxcontroller0 2>, <&muxcontroller0 3>, + <&muxcontroller1>; + mux-control-names = "mux0", "mux1", "mux2", "mux3", "mux4"; + mux-syscon = <&syscon3>; }; junk { @@ -170,6 +177,9 @@ compatible = "denx,u-boot-fdt-test"; ping-expect = <3>; ping-add = <3>; + + mux-controls = <&muxcontroller0 0>; + mux-control-names = "mux0"; }; phy_provider0: gen_phy@0 { @@ -884,6 +894,29 @@ 0x58 8>; }; + syscon3: syscon@3 { + compatible = "simple-mfd", "syscon"; + reg = <0x000100 0x10>; + + muxcontroller0: a-mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + + mux-reg-masks = <0x0 0x30>, /* 0: reg 0x0, bits 5:4 */ + <0xc 0x1E>, /* 1: reg 0xc, bits 4:1 */ + <0x4 0xFF>; /* 2: reg 0x4, bits 7:0 */ + idle-states = , <0x02>, <0x73>; + u-boot,mux-autoprobe; + }; + }; + + muxcontroller1: emul-mux-controller { + compatible = "mux-emul"; + #mux-control-cells = <0>; + u-boot,mux-autoprobe; + idle-state = <0xabcd>; + }; + timer@0 { compatible = "sandbox,timer"; clock-frequency = <1000000>; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 6ac2919977..f3c4883032 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -179,6 +179,8 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_MULTIPLEXER=y +CONFIG_MUX_MMIO=y CONFIG_DM_ETH=y CONFIG_NVME=y CONFIG_PCI=y diff --git a/test/dm/Makefile b/test/dm/Makefile index e2b0798388..93484b48eb 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -57,6 +57,8 @@ obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_SMEM) += smem.o obj-$(CONFIG_DM_SPI) += spi.o obj-y += syscon.o +obj-$(CONFIG_MUX_MMIO) += mux-mmio.o +obj-$(CONFIG_MULTIPLEXER) += mux-emul.o obj-$(CONFIG_DM_USB) += usb.o obj-$(CONFIG_DM_PMIC) += pmic.o obj-$(CONFIG_DM_REGULATOR) += regulator.o diff --git a/test/dm/mux-emul.c b/test/dm/mux-emul.c new file mode 100644 index 0000000000..141fd4d908 --- /dev/null +++ b/test/dm/mux-emul.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ + * Pratyush Yadav + */ +#include +#include +#include +#include +#include +#include + +struct mux_emul_priv { + u32 state; +}; + +static int mux_emul_set(struct mux_control *mux, int state) +{ + struct mux_emul_priv *priv = dev_get_priv(mux->dev); + + priv->state = state; + return 0; +} + +static int mux_emul_probe(struct udevice *dev) +{ + struct mux_chip *mux_chip = dev_get_uclass_priv(dev); + struct mux_control *mux; + u32 idle_state; + int ret; + + ret = mux_alloc_controllers(dev, 1); + if (ret < 0) + return ret; + + mux = &mux_chip->mux[0]; + + ret = dev_read_u32(dev, "idle-state", &idle_state); + if (ret) + return ret; + + mux->idle_state = idle_state; + mux->states = 0x100000; + + return 0; +} + +static const struct mux_control_ops mux_emul_ops = { + .set = mux_emul_set, +}; + +static const struct udevice_id mux_emul_of_match[] = { + { .compatible = "mux-emul" }, + { /* sentinel */ }, +}; + +U_BOOT_DRIVER(emul_mux) = { + .name = "mux-emul", + .id = UCLASS_MUX, + .of_match = mux_emul_of_match, + .ops = &mux_emul_ops, + .probe = mux_emul_probe, + .priv_auto_alloc_size = sizeof(struct mux_emul_priv), +}; + +static int dm_test_mux_emul_default_state(struct unit_test_state *uts) +{ + struct udevice *dev; + struct mux_control *mux; + struct mux_emul_priv *priv; + + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test", + &dev)); + ut_assertok(mux_control_get(dev, "mux4", &mux)); + + priv = dev_get_priv(mux->dev); + + ut_asserteq(0xabcd, priv->state); + + return 0; +} +DM_TEST(dm_test_mux_emul_default_state, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_mux_emul_select_deselect(struct unit_test_state *uts) +{ + struct udevice *dev; + struct mux_control *mux; + struct mux_emul_priv *priv; + + gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test", + &dev)); + ut_assertok(mux_control_get(dev, "mux4", &mux)); + + priv = dev_get_priv(mux->dev); + + ut_assertok(mux_control_select(mux, 0x1234)); + ut_asserteq(priv->state, 0x1234); + + ut_assertok(mux_control_deselect(mux)); + ut_asserteq(priv->state, 0xabcd); + + return 0; +} +DM_TEST(dm_test_mux_emul_select_deselect, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/dm/mux-mmio.c b/test/dm/mux-mmio.c new file mode 100644 index 0000000000..fd353d8b15 --- /dev/null +++ b/test/dm/mux-mmio.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Jean-Jacques Hiblot + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int dm_test_mux_mmio_select(struct unit_test_state *uts) +{ + struct udevice *dev, *dev_b; + struct regmap *map; + struct mux_control *ctl0_a, *ctl0_b; + struct mux_control *ctl1; + struct mux_control *ctl_err; + u32 val; + int i; + + sandbox_set_enable_memio(true); + + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test", + &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "b-test", + &dev_b)); + map = syscon_regmap_lookup_by_phandle(dev, "mux-syscon"); + ut_assertok_ptr(map); + ut_assert(map); + + ut_assertok(mux_control_get(dev, "mux0", &ctl0_a)); + ut_assertok(mux_control_get(dev, "mux1", &ctl1)); + ut_asserteq(-ERANGE, mux_control_get(dev, "mux3", &ctl_err)); + ut_asserteq(-ENODATA, mux_control_get(dev, "dummy", &ctl_err)); + ut_assertok(mux_control_get(dev_b, "mux0", &ctl0_b)); + + for (i = 0; i < mux_control_states(ctl0_a); i++) { + /* Select a new state and verify the value in the regmap. */ + ut_assertok(mux_control_select(ctl0_a, i)); + ut_assertok(regmap_read(map, 0, &val)); + ut_asserteq(i, (val & 0x30) >> 4); + /* + * Deselect the mux and verify that the value in the regmap + * reflects the idle state (fixed to MUX_IDLE_AS_IS). + */ + ut_assertok(mux_control_deselect(ctl0_a)); + ut_assertok(regmap_read(map, 0, &val)); + ut_asserteq(i, (val & 0x30) >> 4); + } + + for (i = 0; i < mux_control_states(ctl1); i++) { + /* Select a new state and verify the value in the regmap. */ + ut_assertok(mux_control_select(ctl1, i)); + ut_assertok(regmap_read(map, 0xc, &val)); + ut_asserteq(i, (val & 0x1E) >> 1); + /* + * Deselect the mux and verify that the value in the regmap + * reflects the idle state (fixed to 2). + */ + ut_assertok(mux_control_deselect(ctl1)); + ut_assertok(regmap_read(map, 0xc, &val)); + ut_asserteq(2, (val & 0x1E) >> 1); + } + + /* Try unbalanced selection/deselection. */ + ut_assertok(mux_control_select(ctl0_a, 0)); + ut_asserteq(-EBUSY, mux_control_select(ctl0_a, 1)); + ut_asserteq(-EBUSY, mux_control_select(ctl0_a, 0)); + ut_assertok(mux_control_deselect(ctl0_a)); + + /* Try concurrent selection. */ + ut_assertok(mux_control_select(ctl0_a, 0)); + ut_assert(mux_control_select(ctl0_b, 0)); + ut_assertok(mux_control_deselect(ctl0_a)); + ut_assertok(mux_control_select(ctl0_b, 0)); + ut_assert(mux_control_select(ctl0_a, 0)); + ut_assertok(mux_control_deselect(ctl0_b)); + ut_assertok(mux_control_select(ctl0_a, 0)); + ut_assertok(mux_control_deselect(ctl0_a)); + + return 0; +} +DM_TEST(dm_test_mux_mmio_select, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test that managed API for mux work correctly */ +static int dm_test_devm_mux_mmio(struct unit_test_state *uts) +{ + struct udevice *dev, *dev_b; + struct mux_control *ctl0_a, *ctl0_b; + struct mux_control *ctl1; + struct mux_control *ctl_err; + + sandbox_set_enable_memio(true); + + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test", + &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "b-test", + &dev_b)); + + ctl0_a = devm_mux_control_get(dev, "mux0"); + ut_assertok_ptr(ctl0_a); + ut_assert(ctl0_a); + ctl1 = devm_mux_control_get(dev, "mux1"); + ut_assertok_ptr(ctl1); + ut_assert(ctl1); + ctl_err = devm_mux_control_get(dev, "mux3"); + ut_asserteq(-ERANGE, PTR_ERR(ctl_err)); + ctl_err = devm_mux_control_get(dev, "dummy"); + ut_asserteq(-ENODATA, PTR_ERR(ctl_err)); + + ctl0_b = devm_mux_control_get(dev_b, "mux0"); + ut_assertok_ptr(ctl0_b); + ut_assert(ctl0_b); + + /* Try concurrent selection. */ + ut_assertok(mux_control_select(ctl0_a, 0)); + ut_assert(mux_control_select(ctl0_b, 0)); + ut_assertok(mux_control_deselect(ctl0_a)); + ut_assertok(mux_control_select(ctl0_b, 0)); + ut_assert(mux_control_select(ctl0_a, 0)); + ut_assertok(mux_control_deselect(ctl0_b)); + + /* Remove one device and check that the mux is released. */ + ut_assertok(mux_control_select(ctl0_a, 0)); + ut_assert(mux_control_select(ctl0_b, 0)); + device_remove(dev, DM_REMOVE_NORMAL); + ut_assertok(mux_control_select(ctl0_b, 0)); + + device_remove(dev_b, DM_REMOVE_NORMAL); + return 0; +} +DM_TEST(dm_test_devm_mux_mmio, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); From patchwork Fri Oct 16 10:46:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383232 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=r+uSz1Ck; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCNCp5RdSz9sTK for ; Fri, 16 Oct 2020 21:48:06 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8118182437; Fri, 16 Oct 2020 12:47:01 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="r+uSz1Ck"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 959EE8241F; Fri, 16 Oct 2020 12:46:58 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4A4948241F for ; Fri, 16 Oct 2020 12:46:54 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkqIx078312; Fri, 16 Oct 2020 05:46:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845212; bh=lN8Izznkx747iqJyOZewm2wD+2M4qiHgzAcfXS5S3/g=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=r+uSz1CkX7Q9k5dFGFRlnp+uvFHvjwuB77mq2PD6xa0OpdPWkcDt7ET+tg8P4C7As j2v6xdgCI34XDotiJCkUbnEIOXP7yTIAgbjbEhXtDK2Er8VxzkSAlL04JKulybNSo4 ADXv2C9ktTAxv9m+BrxyLzbDc6UI8Z70/Uxy4Wc0= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAkqWG121815 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:52 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:51 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:51 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSi016923; Fri, 16 Oct 2020 05:46:50 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 6/7] cmd: Add a mux command Date: Fri, 16 Oct 2020 16:16:35 +0530 Message-ID: <20201016104636.14138-7-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean This command lets the user list, select, and deselect mux controllers introduced with the mux framework on the fly. It has 3 subcommands: list, select, and deselect. List: Lists all the mux present on the system. The muxes are listed for each chip. The chip is identified by its device name. Each chip can have a number of mux controllers. Each is listed in sequence and is assigned a sequential ID based on its position in the mux chip. It lists details like ID, whether the mux is currently selected or not, the current state, the idle state, and the number of states. A sample output would look something like: => mux list a-mux-controller: ID Selected Current State Idle State Num States 0 no unknown as-is 0x4 1 no 0x2 0x2 0x10 2 no 0x73 0x73 0x100 another-mux-controller: ID Selected Current State Idle State Num States 0 no 0x1 0x1 0x4 1 no 0x2 0x2 0x4 Select: Selects a given mux and puts it in the specified state. This subcommand takes 3 arguments: mux chip, mux ID, state to set the mux in. The arguments mux chip and mux ID are used to identify which mux needs to be selected, and then it is selected to the given state. The mux needs to be deselected before it can be selected again in another state. The state should be a hexadecimal number. For example: => mux list a-mux-controller: ID Selected Current State Idle State Num States 0 no 0x1 0x1 0x4 1 no 0x1 0x1 0x4 => mux select a-mux-controller 0 0x3 => mux list a-mux-controller: ID Selected Current State Idle State Num States 0 yes 0x3 0x1 0x4 1 no 0x1 0x1 0x4 Deselect: Deselects a given mux and puts it in its idle state. This subcommand takes 2 arguments: the mux chip and mux ID to identify which mux needs to be deselected. So in the above example, we can deselect mux 0 using: => mux deselect a-mux-controller 0 => mux list a-mux-controller: ID Selected Current State Idle State Num States 0 no 0x1 0x1 0x4 1 no 0x1 0x1 0x4 Signed-off-by: Pratyush Yadav Reviewed-by: Simon Glass --- Notes: Changes in v4: - Use spaces to print columns in 'mux list' instead of tabs. Tabs don't work well with ut_assert_nextline() because it calls membuff_readline() down the call chain and tells it to consider characters below the space character as EOL. This means ut_assert_nextline() can only assert for the next column not the next line if a command is using tabs. cmd/Kconfig | 6 ++ cmd/Makefile | 1 + cmd/mux.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 cmd/mux.c diff --git a/cmd/Kconfig b/cmd/Kconfig index a3166e4f31..a25d6d62d0 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1073,6 +1073,12 @@ config CMD_MTD help MTD commands support. +config CMD_MUX + bool "mux" + depends on MULTIPLEXER + help + List, select, and deselect mux controllers on the fly. + config CMD_NAND bool "nand" default y if NAND_SUNXI diff --git a/cmd/Makefile b/cmd/Makefile index 19a891633f..79a57b8482 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -104,6 +104,7 @@ obj-$(CONFIG_CMD_CLONE) += clone.o ifneq ($(CONFIG_CMD_NAND)$(CONFIG_CMD_SF),) obj-y += legacy-mtd-utils.o endif +obj-$(CONFIG_CMD_MUX) += mux.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NET) += net.o obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o diff --git a/cmd/mux.c b/cmd/mux.c new file mode 100644 index 0000000000..3a0839ec1f --- /dev/null +++ b/cmd/mux.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * List, select, and deselect mux controllers on the fly. + * + * Copyright (c) 2020 Texas Instruments Inc. + * Author: Pratyush Yadav + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define COLUMN_SIZE 16 + +/* + * Print a member of a column. The total size of the text printed, including + * trailing whitespace, will always be COLUMN_SIZE. + */ +#define PRINT_COLUMN(fmt, args...) do { \ + char buf[COLUMN_SIZE + 1]; \ + snprintf(buf, COLUMN_SIZE + 1, fmt, ##args); \ + printf("%-*s", COLUMN_SIZE, buf); \ +} while (0) + +/* + * Find a mux based on its device name in argv[1] and index in the chip in + * argv[2]. + */ +static struct mux_control *cmd_mux_find(char *const argv[]) +{ + struct udevice *dev; + struct mux_chip *chip; + int ret; + unsigned long id; + + ret = strict_strtoul(argv[2], 10, &id); + if (ret) + return ERR_PTR(ret); + + ret = uclass_get_device_by_name(UCLASS_MUX, argv[1], &dev); + if (ret) + return ERR_PTR(ret); + + chip = dev_get_uclass_priv(dev); + if (!chip) + return ERR_PTR(ret); + + if (id >= chip->controllers) + return ERR_PTR(-EINVAL); + + return &chip->mux[id]; +} + +/* + * Print the details of a mux. The columns printed correspond to: "Selected", + * "Current State", "Idle State", and "Num States". + */ +static void print_mux(struct mux_control *mux) +{ + PRINT_COLUMN("%s", mux->in_use ? "yes" : "no"); + + if (mux->cached_state == MUX_IDLE_AS_IS) + PRINT_COLUMN("%s", "unknown"); + else + PRINT_COLUMN("0x%x", mux->cached_state); + + if (mux->idle_state == MUX_IDLE_AS_IS) + PRINT_COLUMN("%s", "as-is"); + else if (mux->idle_state == MUX_IDLE_DISCONNECT) + PRINT_COLUMN("%s", "disconnect"); + else + PRINT_COLUMN("0x%x", mux->idle_state); + + PRINT_COLUMN("0x%x", mux->states); + + printf("\n"); +} + +static int do_mux_list(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + struct mux_chip *chip; + int j; + + for (uclass_first_device(UCLASS_MUX, &dev); + dev; + uclass_next_device(&dev)) { + chip = dev_get_uclass_priv(dev); + if (!chip) { + dev_err(dev, "can't find mux chip\n"); + continue; + } + + printf("%s:\n", dev->name); + + printf(" "); + PRINT_COLUMN("ID"); + PRINT_COLUMN("Selected"); + PRINT_COLUMN("Current State"); + PRINT_COLUMN("Idle State"); + PRINT_COLUMN("Num States"); + printf("\n"); + for (j = 0; j < chip->controllers; j++) { + printf(" "); + PRINT_COLUMN("%d", j); + print_mux(&chip->mux[j]); + } + printf("\n"); + } + + return 0; +} + +static int do_mux_select(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct mux_control *mux; + int ret; + unsigned long state; + + if (argc != 4) + return CMD_RET_USAGE; + + mux = cmd_mux_find(argv); + if (IS_ERR_OR_NULL(mux)) { + printf("Failed to find the specified mux\n"); + return CMD_RET_FAILURE; + } + + ret = strict_strtoul(argv[3], 16, &state); + if (ret) { + printf("Invalid state\n"); + return CMD_RET_FAILURE; + } + + ret = mux_control_select(mux, state); + if (ret) { + printf("Failed to select requested state\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_mux_deselect(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct mux_control *mux; + int ret; + + if (argc != 3) + return CMD_RET_USAGE; + + mux = cmd_mux_find(argv); + if (IS_ERR_OR_NULL(mux)) { + printf("Failed to find the specified mux\n"); + return CMD_RET_FAILURE; + } + + ret = mux_control_deselect(mux); + if (ret) { + printf("Failed to deselect mux\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static char mux_help_text[] = + "list - List all Muxes and their states\n" + "select - Select the given mux state\n" + "deselect - Deselect the given mux and reset it to its idle state"; + +U_BOOT_CMD_WITH_SUBCMDS(mux, "List, select, and deselect muxes", mux_help_text, + U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mux_list), + U_BOOT_SUBCMD_MKENT(select, 4, 0, do_mux_select), + U_BOOT_SUBCMD_MKENT(deselect, 3, 0, do_mux_deselect)); From patchwork Fri Oct 16 10:46:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1383233 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=jW+lXlfI; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CCND13NWkz9sTK for ; Fri, 16 Oct 2020 21:48:17 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9B6DB82443; Fri, 16 Oct 2020 12:47:03 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="jW+lXlfI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BF60782431; Fri, 16 Oct 2020 12:46:58 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id ED72E81BD2 for ; Fri, 16 Oct 2020 12:46:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 09GAksvn067555; Fri, 16 Oct 2020 05:46:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1602845214; bh=tu+da23BaI0VQ+YpVtJmMGmwScv8per1jszkq7cthRo=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=jW+lXlfIFrQYXi4bwmwxR4jostmK8VJkgOwABuYSOKwi+6lIX23GW4J9XGvFUFA3O yyQabfqysMTbU8Bw3xKxm69Ux23G3rzgxaWMCQxLV/6Vgi2WjCfAkfPZ6TqVvf03yo +mZtk5+DwjY5dpx0YjRiwo8K6kofPDU2rurQIdqk= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 09GAksEM121859 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Oct 2020 05:46:54 -0500 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 16 Oct 2020 05:46:53 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 16 Oct 2020 05:46:53 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 09GAkbSj016923; Fri, 16 Oct 2020 05:46:52 -0500 From: Pratyush Yadav To: Tom Rini CC: Pratyush Yadav , , Simon Glass , Vignesh Raghavendra Subject: [PATCH v4 7/7] test: mux-cmd: Add tests for the 'mux' command Date: Fri, 16 Oct 2020 16:16:36 +0530 Message-ID: <20201016104636.14138-8-p.yadav@ti.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016104636.14138-1-p.yadav@ti.com> References: <20201016104636.14138-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Tests tests run the three mux subcommands: list, select, and deselect, and verify that the commands do what we expect. Signed-off-by: Pratyush Yadav Reviewed-by: Simon Glass --- Notes: New in v4. configs/sandbox_defconfig | 1 + test/dm/Makefile | 1 + test/dm/mux-cmd.c | 177 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 test/dm/mux-cmd.c diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index f3c4883032..e573ae075b 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -55,6 +55,7 @@ CONFIG_CMD_GPT_RENAME=y CONFIG_CMD_IDE=y CONFIG_CMD_I2C=y CONFIG_CMD_LSBLK=y +CONFIG_CMD_MUX=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_READ=y diff --git a/test/dm/Makefile b/test/dm/Makefile index 93484b48eb..8b3d77e34e 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -34,6 +34,7 @@ obj-y += irq.o obj-$(CONFIG_LED) += led.o obj-$(CONFIG_DM_MAILBOX) += mailbox.o obj-$(CONFIG_DM_MMC) += mmc.o +obj-$(CONFIG_CMD_MUX) += mux-cmd.o obj-y += fdtdec.o obj-y += ofnode.o obj-y += ofread.o diff --git a/test/dm/mux-cmd.c b/test/dm/mux-cmd.c new file mode 100644 index 0000000000..11c237b5da --- /dev/null +++ b/test/dm/mux-cmd.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Texas Instruments Inc. + * Pratyush Yadav + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 + +/* Test 'mux list' */ +static int dm_test_cmd_mux_list(struct unit_test_state *uts) +{ + char str[BUF_SIZE], *tok; + struct udevice *dev; + struct mux_chip *chip; + struct mux_control *mux; + int i; + unsigned long val; + + sandbox_set_enable_memio(true); + + ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", + &dev)); + chip = dev_get_uclass_priv(dev); + ut_assertnonnull(chip); + + run_command("mux list", 0); + ut_assert_nextline("a-mux-controller:"); + + /* + * Check the table header to make sure we are not out of sync with the + * code in the command. If we are, catch it early. + */ + console_record_readline(str, BUF_SIZE); + tok = strtok(str, " "); + ut_asserteq_str("ID", tok); + + tok = strtok(NULL, " "); + ut_asserteq_str("Selected", tok); + + tok = strtok(NULL, " "); + ut_asserteq_str("Current", tok); + tok = strtok(NULL, " "); + ut_asserteq_str("State", tok); + + tok = strtok(NULL, " "); + ut_asserteq_str("Idle", tok); + tok = strtok(NULL, " "); + ut_asserteq_str("State", tok); + + tok = strtok(NULL, " "); + ut_asserteq_str("Num", tok); + tok = strtok(NULL, " "); + ut_asserteq_str("States", tok); + + for (i = 0; i < chip->controllers; i++) { + mux = &chip->mux[i]; + + console_record_readline(str, BUF_SIZE); + + /* + * Check if the ID printed matches with the ID of the chip we + * have. + */ + tok = strtok(str, " "); + ut_assertok(strict_strtoul(tok, 10, &val)); + ut_asserteq(i, val); + + /* Check if mux selection state matches. */ + tok = strtok(NULL, " "); + if (mux->in_use) { + ut_asserteq_str("yes", tok); + } else { + ut_asserteq_str("no", tok); + } + + /* Check if the current state matches. */ + tok = strtok(NULL, " "); + if (mux->cached_state == MUX_IDLE_AS_IS) { + ut_asserteq_str("unknown", tok); + } else { + ut_assertok(strict_strtoul(tok, 16, &val)); + ut_asserteq(mux->cached_state, val); + } + + /* Check if the idle state matches */ + tok = strtok(NULL, " "); + if (mux->idle_state == MUX_IDLE_AS_IS) { + ut_asserteq_str("as-is", tok); + } else { + ut_assertok(strict_strtoul(tok, 16, &val)); + ut_asserteq(mux->idle_state, val); + } + + /* Check if the number of states matches */ + tok = strtok(NULL, " "); + ut_assertok(strict_strtoul(tok, 16, &val)); + ut_asserteq(mux->states, val); + } + + return 0; +} +DM_TEST(dm_test_cmd_mux_list, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_cmd_mux_select(struct unit_test_state *uts) +{ + struct udevice *dev; + struct mux_chip *chip; + struct mux_control *mux; + char cmd[BUF_SIZE]; + unsigned int i, state; + + sandbox_set_enable_memio(true); + + ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", + &dev)); + chip = dev_get_uclass_priv(dev); + ut_assertnonnull(chip); + + srand(get_ticks() + rand()); + for (i = 0; i < chip->controllers; i++) { + mux = &chip->mux[i]; + + state = rand() % mux->states; + + snprintf(cmd, BUF_SIZE, "mux select a-mux-controller %x %x", i, + state); + run_command(cmd, 0); + ut_asserteq(!!mux->in_use, true); + ut_asserteq(state, mux->cached_state); + + ut_assertok(mux_control_deselect(mux)); + } + + return 0; +} +DM_TEST(dm_test_cmd_mux_select, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_cmd_mux_deselect(struct unit_test_state *uts) +{ + struct udevice *dev; + struct mux_chip *chip; + struct mux_control *mux; + char cmd[BUF_SIZE]; + unsigned int i, state; + + sandbox_set_enable_memio(true); + + ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller", + &dev)); + chip = dev_get_uclass_priv(dev); + ut_assertnonnull(chip); + + srand(get_ticks() + rand()); + for (i = 0; i < chip->controllers; i++) { + mux = &chip->mux[i]; + + state = rand() % mux->states; + ut_assertok(mux_control_select(mux, state)); + + snprintf(cmd, BUF_SIZE, "mux deselect a-mux-controller %d", i); + run_command(cmd, 0); + ut_asserteq(!!mux->in_use, false); + } + + return 0; +} +DM_TEST(dm_test_cmd_mux_deselect, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);