1efa56239SAndrew Jeffery // SPDX-License-Identifier: GPL-2.0-or-later 2efa56239SAndrew Jeffery /* Copyright (C) 2019 IBM Corp. */ 3efa56239SAndrew Jeffery 4efa56239SAndrew Jeffery /* Pieces to enable drivers to implement the .set callback */ 5efa56239SAndrew Jeffery 6efa56239SAndrew Jeffery #include "pinmux-aspeed.h" 7efa56239SAndrew Jeffery 88c4407deSYueHaibing static const char *const aspeed_pinmux_ips[] = { 9efa56239SAndrew Jeffery [ASPEED_IP_SCU] = "SCU", 10efa56239SAndrew Jeffery [ASPEED_IP_GFX] = "GFX", 11efa56239SAndrew Jeffery [ASPEED_IP_LPC] = "LPC", 12efa56239SAndrew Jeffery }; 13efa56239SAndrew Jeffery 14efa56239SAndrew Jeffery static inline void aspeed_sig_desc_print_val( 15efa56239SAndrew Jeffery const struct aspeed_sig_desc *desc, bool enable, u32 rv) 16efa56239SAndrew Jeffery { 17efa56239SAndrew Jeffery pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n", 18efa56239SAndrew Jeffery aspeed_pinmux_ips[desc->ip], desc->reg, 19efa56239SAndrew Jeffery desc->mask, enable ? desc->enable : desc->disable, 20efa56239SAndrew Jeffery (rv & desc->mask) >> __ffs(desc->mask), rv); 21efa56239SAndrew Jeffery } 22efa56239SAndrew Jeffery 23efa56239SAndrew Jeffery /** 24*333944c7SSouptick Joarder * aspeed_sig_desc_eval() - Query the enabled or disabled state of a signal 25*333944c7SSouptick Joarder * descriptor. 26efa56239SAndrew Jeffery * 27efa56239SAndrew Jeffery * @desc: The signal descriptor of interest 28efa56239SAndrew Jeffery * @enabled: True to query the enabled state, false to query disabled state 29efa56239SAndrew Jeffery * @map: The IP block's regmap instance 30efa56239SAndrew Jeffery * 31efa56239SAndrew Jeffery * Return: 1 if the descriptor's bitfield is configured to the state 32efa56239SAndrew Jeffery * selected by @enabled, 0 if not, and less than zero if an unrecoverable 33efa56239SAndrew Jeffery * failure occurred 34efa56239SAndrew Jeffery * 35efa56239SAndrew Jeffery * Evaluation of descriptor state is non-trivial in that it is not a binary 36efa56239SAndrew Jeffery * outcome: The bitfields can be greater than one bit in size and thus can take 37efa56239SAndrew Jeffery * a value that is neither the enabled nor disabled state recorded in the 38efa56239SAndrew Jeffery * descriptor (typically this means a different function to the one of interest 39efa56239SAndrew Jeffery * is enabled). Thus we must explicitly test for either condition as required. 40efa56239SAndrew Jeffery */ 41efa56239SAndrew Jeffery int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, 42efa56239SAndrew Jeffery bool enabled, struct regmap *map) 43efa56239SAndrew Jeffery { 44efa56239SAndrew Jeffery int ret; 45efa56239SAndrew Jeffery unsigned int raw; 46efa56239SAndrew Jeffery u32 want; 47efa56239SAndrew Jeffery 48efa56239SAndrew Jeffery if (!map) 49efa56239SAndrew Jeffery return -ENODEV; 50efa56239SAndrew Jeffery 51efa56239SAndrew Jeffery ret = regmap_read(map, desc->reg, &raw); 52efa56239SAndrew Jeffery if (ret) 53efa56239SAndrew Jeffery return ret; 54efa56239SAndrew Jeffery 55efa56239SAndrew Jeffery aspeed_sig_desc_print_val(desc, enabled, raw); 56efa56239SAndrew Jeffery want = enabled ? desc->enable : desc->disable; 57efa56239SAndrew Jeffery 58efa56239SAndrew Jeffery return ((raw & desc->mask) >> __ffs(desc->mask)) == want; 59efa56239SAndrew Jeffery } 60efa56239SAndrew Jeffery 61efa56239SAndrew Jeffery /** 62efa56239SAndrew Jeffery * Query the enabled or disabled state for a mux function's signal on a pin 63efa56239SAndrew Jeffery * 64efa56239SAndrew Jeffery * @ctx: The driver context for the pinctrl IP 65efa56239SAndrew Jeffery * @expr: An expression controlling the signal for a mux function on a pin 66efa56239SAndrew Jeffery * @enabled: True to query the enabled state, false to query disabled state 67efa56239SAndrew Jeffery * 68efa56239SAndrew Jeffery * Return: 1 if the expression composed by @enabled evaluates true, 0 if not, 69efa56239SAndrew Jeffery * and less than zero if an unrecoverable failure occurred. 70efa56239SAndrew Jeffery * 71efa56239SAndrew Jeffery * A mux function is enabled or disabled if the function's signal expression 72efa56239SAndrew Jeffery * for each pin in the function's pin group evaluates true for the desired 73efa56239SAndrew Jeffery * state. An signal expression evaluates true if all of its associated signal 74efa56239SAndrew Jeffery * descriptors evaluate true for the desired state. 75efa56239SAndrew Jeffery * 76efa56239SAndrew Jeffery * If an expression's state is described by more than one bit, either through 77efa56239SAndrew Jeffery * multi-bit bitfields in a single signal descriptor or through multiple signal 78efa56239SAndrew Jeffery * descriptors of a single bit then it is possible for the expression to be in 79efa56239SAndrew Jeffery * neither the enabled nor disabled state. Thus we must explicitly test for 80efa56239SAndrew Jeffery * either condition as required. 81efa56239SAndrew Jeffery */ 82c1432423SAndrew Jeffery int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx, 83efa56239SAndrew Jeffery const struct aspeed_sig_expr *expr, bool enabled) 84efa56239SAndrew Jeffery { 85efa56239SAndrew Jeffery int ret; 86c1432423SAndrew Jeffery int i; 87c1432423SAndrew Jeffery 88c1432423SAndrew Jeffery if (ctx->ops->eval) 89c1432423SAndrew Jeffery return ctx->ops->eval(ctx, expr, enabled); 90efa56239SAndrew Jeffery 91efa56239SAndrew Jeffery for (i = 0; i < expr->ndescs; i++) { 92efa56239SAndrew Jeffery const struct aspeed_sig_desc *desc = &expr->descs[i]; 93efa56239SAndrew Jeffery 94efa56239SAndrew Jeffery ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]); 95efa56239SAndrew Jeffery if (ret <= 0) 96efa56239SAndrew Jeffery return ret; 97efa56239SAndrew Jeffery } 98efa56239SAndrew Jeffery 99efa56239SAndrew Jeffery return 1; 100efa56239SAndrew Jeffery } 101