From patchwork Mon Jul 8 11:32:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Connolly X-Patchwork-Id: 811187 Delivered-To: patch@linaro.org Received: by 2002:adf:a199:0:b0:367:895a:4699 with SMTP id u25csp2687318wru; Mon, 8 Jul 2024 04:33:24 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXHkoueBwhbBQViTDYppkUpZllHY+YBUJn+6nPH8PMivE8iNemoYRO9ATYGomMWwNiRI97V3k2jabauZZTtsJ6D X-Google-Smtp-Source: AGHT+IGYvD6ibcLesEWpe7wAvHdrcMTcEtVeiBn9Xm6mryxVxSKRGT416O47PAdH1dhuJ6r0VKGK X-Received: by 2002:a05:6402:2747:b0:57a:33a5:9b71 with SMTP id 4fb4d7f45d1cf-58e5c8269e4mr10596711a12.33.1720438404625; Mon, 08 Jul 2024 04:33:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720438404; cv=none; d=google.com; s=arc-20160816; b=Z6w6NL+qYwVslQXWzVh6WR0BDbXyYMLUpuNb/NCcP7vGtPN/k59m0OmaD+qH45P9eS xUzSu8wZsLleBJPsUPS174hRa+Chnk80T9B1uH1q3fk/C3ruQnMLe+7L64CJfjMnFVKT iXtzlpww5cmZoIfXYE/oMdF5HCQ7I87GpJfP5cC/UJu7i/rQrNx/sVLnWc1utGW/TdqU cM6L0yn7T+n+qn4WKHx+nP+0QcgQcz4GyCqGhJk1uvg+fKYx7lmxcWBJgnnEWKS1jLo4 IJZMUWY5PZmwLynOzoyoA1NkGGqdS/AHmkHKNhnFNPpem8C6uopNNzJ7rXULqxMtxG7Q J/tA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:cc:to:in-reply-to:references :message-id:content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=qvkoZcQ7OJD8CXSX3t0Cqg2dNoEjO5pN9QkaEuTXc8w=; fh=/XivWHF+vo8fEJZkIifbJJS5exQ4Pz1Cdxakj2MFy4s=; b=ZZvTFCs9KtzGeWt1qzKf6uVBAd8PmUUk8etsqQk5ll21KhU9hT1Gj/0T4FPnvxFPYV a63jaUoUWM8Adi+sF+HhbPbMUvyfgtheEpZXZA7N6PMDHsLkCrwRndUOYa7V8DtRVRJy ma1m6iUzF5ix9FnCZ1PC44GqLX871gK2DUUFGHstfl8zc8XgMRLrpnWUl52fzKIp7GwP RagNugBmR5nJERwa6IkbL1fi+P3Rj7QAHKeuZ9GdPCN3RjrjHAisOeX6bosoEwZpVeoC Dug29Q+eMuuecs+U239GTtUQ+9cxL7paXMUffj3bkHL0sK7YzBL56rk3SGzIcIt0YB3W essg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VvAGYQCP; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id 4fb4d7f45d1cf-58c028764fasi6587943a12.546.2024.07.08.04.33.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:24 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VvAGYQCP; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D49B7886F3; Mon, 8 Jul 2024 13:33:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="VvAGYQCP"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0E5FA886DB; Mon, 8 Jul 2024 13:33:10 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 10128886AF for ; Mon, 8 Jul 2024 13:33:08 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=caleb.connolly@linaro.org Received: by mail-ed1-x529.google.com with SMTP id 4fb4d7f45d1cf-57cf8880f95so4795574a12.3 for ; Mon, 08 Jul 2024 04:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1720438387; x=1721043187; darn=lists.denx.de; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=qvkoZcQ7OJD8CXSX3t0Cqg2dNoEjO5pN9QkaEuTXc8w=; b=VvAGYQCPeuoyVk+EXSRdG8Ac6VpCcSFGi7zWvniRsuiL+Y4iDW2DG8IrGGQnnEzQVu AsM03YoQ2F3K/Ok47u2hZBx6dRAGoXZwr1nF8BLwSQZqBX280BN5VwuLDWrKmTJFXM+3 /jcwSA163ljPP6Fs0PXYQByXupWvYurZC2IFoBFkD+9s2x8kUWlmHCxEX03i8Cbege4j WnAVdjiPZURpR6gswzq50CnTYRrrebsGo4N4EbGlgjrM81KNkBIp3kObWwtTvAhSHr+e q8Z+72CYB/rsXE0KKaTl2IA5YsYUhP2o5SeixpW1+Fpe4xMRwuoE7LQhladxiNGP2fC/ /cjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720438387; x=1721043187; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qvkoZcQ7OJD8CXSX3t0Cqg2dNoEjO5pN9QkaEuTXc8w=; b=vHLwTxmeHuT128GasyyGD8EjKDD7z0JHPUB7C4dYf6R0aYF4nz6/9B0/bmuY1rEN99 KsL02XnL74KTJ1ZV94KYoCOf6ciYdQ62vtqztcnn5PPIpdHnbMC7EjXrDbABPIDIellx JKWsHWNJbmIkfQirwgFc5xvaUBFfiXjLLat0rylsAj3KB+3axBlBeOEmibFVEVcYZeic kb7xKHOgkPAiVRKE1lx587WP/L3oPuLrMhKnmGum5kG6pdfgl22/iCAlC5D9Fi+HuP6G /a7hwSxhGd9uv3mgGQPIVdOY52CPxMGj7AS6Dtuoakl0dHI0t85IDhfUI/kobeeN/ls9 KGSw== X-Gm-Message-State: AOJu0YwYVL4DpfBS7oPmX5BViSybck9YnLHAh7proBcnSCaissz6FVPI Ix60kVanujq861CpAIxQZw5kHk6sSgJnuoYoQpN82b2fvBIE/eAjRHzJdgoETNEXI2mVXYKeExJ DXpE= X-Received: by 2002:a17:906:605:b0:a6f:ddb3:bf2b with SMTP id a640c23a62f3a-a77ba48e721mr800451766b.41.1720438387143; Mon, 08 Jul 2024 04:33:07 -0700 (PDT) Received: from [192.168.0.113] ([2a02:8109:aa0d:be00::18f8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a77c9925463sm303628466b.69.2024.07.08.04.33.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:06 -0700 (PDT) From: Caleb Connolly Date: Mon, 08 Jul 2024 13:32:53 +0200 Subject: [PATCH v2 1/4] linux/bitmap.h: add bitmap_empty helper MIME-Version: 1.0 Message-Id: <20240708-b4-qcom-rpmh-v2-1-8bc765606e56@linaro.org> References: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> In-Reply-To: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> To: Tom Rini , Caleb Connolly , Neil Armstrong , Sumit Garg , Jaehoon Chung Cc: u-boot@lists.denx.de, u-boot-qcom@groups.io X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=882; i=caleb.connolly@linaro.org; h=from:subject:message-id; bh=z6XvfLGv5QyURxvw0REJ2jitM49N/Q7K6mgwTQZxddM=; b=owEBbQKS/ZANAwAIAQWDMSsZX2S2AcsmYgBmi85wLPq+1QG+jhRm6dp+wxvc5LZUnte1wHclN MynYWkwIc2JAjMEAAEIAB0WIQS2UaFGPGq+0GkMVc0FgzErGV9ktgUCZovOcAAKCRAFgzErGV9k tmOREACbs1kX9S77/R28BH32B4epkHRt4LGtorVwIWs3ges0KZoAqdCnYsgTpru0jAKCoYfTVWG k71Lud4nY8woMGfonpxqiUIQaJCA4xpnywW0/AnNGiIKudJozP4f5RtExGtZDuamQzJK/V0Y8jM tobW2SpVn9P+YC3KRi9RhPh1RAGYZwzfBL3v+BRwQZAwWuvsPGP2WdhqjzA4z0SoS5nRAX06CWw xshs2nFor2+n0eNJViYoy9TWEXiCEof9EnxjW993LU5sVVQjqqmFNWa/2eb0BdqkYPZRXAtisqk sldEXmR+E4zIGMY9CmDQMitGY0oCvo0iZpkvXh59oXKRhGpmrZjcj9eTiQw9Svs1SxD2bK4U8G6 Ge+HzDJGRW3/SOBc6WjI3Jpy0U1S2cD/0BOzXiP69n2vRxEy+1hlaX39uZqxxYg63NOxrSHQKsb bELk8qfGKevh0OvB+iVKghf6QdI+sfcJ+DwNVRvKmcfgBa0N4Q5X+gPRKMV3qILEUQPNkQWgkd+ v3mxueklHFrvS40NpYCIcMgZZMR8Yy3XTTZtt3N5fm9Fq/0mAikc0lO86R2OCk836bDcz4yCHuQ Fpnm9D7zqGhNRx0o5KqnrEwvdCSQDMcW6hyu0TiaS+uLhv94MI3oZcrmb++jAz0+n8HhPBw0Q+u xprPu9zRI5chx+A== X-Developer-Key: i=caleb.connolly@linaro.org; a=openpgp; fpr=83B24DA7FE145076BC38BB250CD904EB673A7C47 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.8 at phobos.denx.de X-Virus-Status: Clean Import this function from Linux. Signed-off-by: Caleb Connolly --- include/linux/bitmap.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 0a8503af9f14..40ca2212cb40 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -195,8 +195,16 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) memset(dst, 0xff, len); } } +static inline bool bitmap_empty(const unsigned long *src, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + return !(*src & BITMAP_LAST_WORD_MASK(nbits)); + + return find_first_bit(src, nbits) == nbits; +} + static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, unsigned int nbits) { if (small_const_nbits(nbits)) From patchwork Mon Jul 8 11:32:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Connolly X-Patchwork-Id: 811189 Delivered-To: patch@linaro.org Received: by 2002:adf:a199:0:b0:367:895a:4699 with SMTP id u25csp2687461wru; Mon, 8 Jul 2024 04:33:45 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVi3JnA/scdtpz+RiWvnJTJHC8iusOuT3Ix8hZK3GhkDo/FjwRYoYDS/EL+2uqUxJnc3ZmxfmeoTUo1HjflIIkO X-Google-Smtp-Source: AGHT+IFP87UtAFmDpzhk46Ul90MII260bPyiL1FnPBhK0jV7D3pd6aX9wZFqhC2coTQ9d5GVHWLq X-Received: by 2002:a17:906:fcd9:b0:a6f:4d6b:c779 with SMTP id a640c23a62f3a-a77ba7e1ac4mr685716466b.52.1720438425309; Mon, 08 Jul 2024 04:33:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720438425; cv=none; d=google.com; s=arc-20160816; b=oEn/VMoIFzubW6Et53vnR3O/p09vXEazReBhSf2Yizu4YWE9G4Is2IcUQssZuEzi1p 0eyefBj1OuVMm9FkY9YF/HtduNNppsxsqdvkRr5BuLuone1LYGb94jpgoO7IuWWeN3YJ rvRyl0up6PmCDSh93QjUG4ylu7IoDEtJ4CuJKVWK+LI/8zEW/NwNfuJf/jhWXABKaK2h Qp029h6a61ac7vqrq5W3M9LHIgnGaUgF+Muz8UYsK4E+/zzA9Vwff7vuw0ii8Bei5YnB hZBRJCpZZSLS5cIF2PmfhqUxR/N7SmqxL/W1Aq23yd1ypyAEcu7smRsWyYZQhT0cuxaU 6emA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:cc:to:in-reply-to:references :message-id:content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=1uFfKAf15FxhHpA2O1ii8PCNKbpxpSKEjmqNOdVSSFc=; fh=/XivWHF+vo8fEJZkIifbJJS5exQ4Pz1Cdxakj2MFy4s=; b=nV0l8ySx3P3yu+wdP65gUTzVszx231RnnFacn0KpKVriI7RqtIxcXAQbJXo05zSJ9f y4bWqrL/thorPMAJG84PLHKgMw7T5JozWvjk2nlNLhM6P5l235Fkl4z84Qd/rb9djMp8 7NgOwF5DWa1EQ8k1y2BBV3icw8/4PPhNSseQlca0oNtYxWTv4H5aUryG1wWODTr3zzZQ 7bedyEheIiz9QLiRaHeE1e6FpDnajDlMkdGOtHoxTGoNFDiyVxnlPE6XXII8UkjZzAqh UTvYDkAuzvWFxGEJ716i1JRkBGlRoTZ6GoE3vcEmvkGXK9/U6CpuYLKOgddunsPmlRhX NxoQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EycFQzJB; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id a640c23a62f3a-a72aaef603dsi1071273266b.147.2024.07.08.04.33.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:45 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EycFQzJB; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A7D2188707; Mon, 8 Jul 2024 13:33:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="EycFQzJB"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2C67388271; Mon, 8 Jul 2024 13:33:13 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D6506884CC for ; Mon, 8 Jul 2024 13:33:09 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=caleb.connolly@linaro.org Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-a77e5929033so209768466b.0 for ; Mon, 08 Jul 2024 04:33:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1720438389; x=1721043189; darn=lists.denx.de; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1uFfKAf15FxhHpA2O1ii8PCNKbpxpSKEjmqNOdVSSFc=; b=EycFQzJBB8SVyIOjr9Or4Ju2zlSocrOUv7fH9M8OXgBxZLZfndKmrjZlHu31nZCVIq TJ2GemmKwjJwqdhSVa++IEZgc4ahI1zhtakZaM7KqC2MaPN4s4fmXWzSjQD1hZbi4zef +BRfvt+8dhb164t6d6vNscq7gkfE3MZVla8gRIPynbSk9UErFf1h7y/1K6DejeeJMniv CPwHaQpKtYXTHcf2xyks+c/nKxxqvRhZnzcBZET5NHaeOkkDfKiERzFFErV2OYOMjE+l OXuwvVcWSlDMNsxw6pEloGEduKAAM9s9gATwSkEC6jN8v1oJ+J3cw4IUFKDbFpMqMIE8 yVWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720438389; x=1721043189; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1uFfKAf15FxhHpA2O1ii8PCNKbpxpSKEjmqNOdVSSFc=; b=C50cNh7shyGGxkiHr/rF/hcMzT3sEyemPJttiU4z6cQ6xWWKkAeR6hdkkHw+kLdoKR gIxXlrtT6n6q3uOSk4ROgzxXiU70Z5x83CjiirMFS/hiyC+zBpjwSdb7TDpY6HWx2DTf LjgOJprM2RXDjzsBhVdlnQOVw5cqug8xy8Zu0mwBPRew4tdlgVxLFw0memCMcegYIRG/ quKv6hurgXz+FaynfqBx20iM9Q3VWlJ6bqe2eUuShClPwX3BAx9zD+SYYEKkccRZs6Wj hkVYVatJZJbtsG4R9uPYCEesJqiHJcv0qlUy3BQlToFyGNzVybw9Z2PXHZLR94awZjoi aMOQ== X-Gm-Message-State: AOJu0YxG2vHBZbrlXbiiw71+/1rZPUbbM0FKQqM5+VZDQjtSNR6TGyWS mmJMIdS4GU4bKUqr/LeyiEb6bzw98ccFyioGLG7nf7NFZjYIZ4XhVbcf9cJ5eGYQz5wZu/1Imzu 81Mw= X-Received: by 2002:a17:906:5acd:b0:a6f:51d8:1963 with SMTP id a640c23a62f3a-a77ba70e622mr828786466b.43.1720438388431; Mon, 08 Jul 2024 04:33:08 -0700 (PDT) Received: from [192.168.0.113] ([2a02:8109:aa0d:be00::18f8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a77c9925463sm303628466b.69.2024.07.08.04.33.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:07 -0700 (PDT) From: Caleb Connolly Date: Mon, 08 Jul 2024 13:32:54 +0200 Subject: [PATCH v2 2/4] soc: qcom: rpmh and cmd-db drivers MIME-Version: 1.0 Message-Id: <20240708-b4-qcom-rpmh-v2-2-8bc765606e56@linaro.org> References: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> In-Reply-To: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> To: Tom Rini , Caleb Connolly , Neil Armstrong , Sumit Garg , Jaehoon Chung Cc: u-boot@lists.denx.de, u-boot-qcom@groups.io X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=45038; i=caleb.connolly@linaro.org; h=from:subject:message-id; bh=ohkrqlRvwIN9S6KoECFHzQZ8KikyhsB+l7SqUSmolWc=; b=owEBbQKS/ZANAwAIAQWDMSsZX2S2AcsmYgBmi85w2CQTxIEzoUbIDfpMmUWyokRlS4nvmqdID mlwhZqyOAyJAjMEAAEIAB0WIQS2UaFGPGq+0GkMVc0FgzErGV9ktgUCZovOcAAKCRAFgzErGV9k tro9D/9I7yyitQ2/IU5z6BkWU5JwUYUJ6bwxtsGbFY+NPmiG9WLmxchlAOApV2PL6V3/hYJn6wA U5/qM5jQTd6G3ni7UzONes+njgV0Oiu5NEfxFOCnxSzk87SM31QAiHdjxG9f5uJ3bEH627YNMip wK6PmTM0nu1iVTx43RRpuYyzEtekPVDlSqsvWCNCceOHyWqhypjUujpZxxZSYvXdBrBRCqa5CmQ 01EfePOjuo/bTINjb3JpfPEihaOfz1GsRl+GW/noC5n6IfKLiCFxWh7kcO9+bywJDWseSis8hfM KqbLxo6BCZPwUw1mTqbrsuMR+Gn6nEe2sln6LXdeF+nOyxVqncwP5z8f5LlGL2lMtQUG5DkU7us sbh4aXuU9DILcbaObm0QRA+vM1Ss+4FzcajBiyu8jTAyXSoSmtorr3PkEvh+5lcEqh/ZzP285i/ 992X8reD2BPtkT8DAwqHzvr5NU/7uFJGlxiLuv7yhFkQ2F1eHmdNGosnJ71RWezPyYKREgWf3U8 Vxa2b61V5Ui0ucUtdsC/3bVbNhlfmvAd4aitxebQwhY5uG2va36+4iajHxsxg0SYdIfYkCV6fSY vIuLRpb+CV+V+nxqS+MN11LbmtSlZ5jKXyN4xQPi9gQxQw0b5e3ywJw618iUR1/HWNWafc5ndU4 +LRMKaBpuTE7SAw== X-Developer-Key: i=caleb.connolly@linaro.org; a=openpgp; fpr=83B24DA7FE145076BC38BB250CD904EB673A7C47 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.8 at phobos.denx.de X-Virus-Status: Clean Introduce two Qualcomm SoC drivers, the RPMh and cmd-db. RPMh is a the name for the second generation Resource Power Management hub on Qualcomm SoCs. Most core regulators have to be controlled via this hub. The cmd-db is a region of memory which contains offsets and data about how to communicate with the RPMh. Tested-by: Neil Armstrong # on SM8550 & SM8^%) Signed-off-by: Caleb Connolly --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/qcom/Kconfig | 25 ++ drivers/soc/qcom/Makefile | 4 + drivers/soc/qcom/cmd-db.c | 261 ++++++++++++++++ drivers/soc/qcom/rpmh-internal.h | 141 +++++++++ drivers/soc/qcom/rpmh-rsc.c | 628 +++++++++++++++++++++++++++++++++++++++ drivers/soc/qcom/rpmh.c | 112 +++++++ include/soc/qcom/cmd-db.h | 42 +++ include/soc/qcom/rpmh.h | 29 ++ include/soc/qcom/tcs.h | 78 +++++ 11 files changed, 1322 insertions(+) diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index cee506fe4747..8ef408d9ba1b 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -47,8 +47,9 @@ config SOC_XILINX_VERSAL_NET Enable this option to select SoC device id driver for Xilinx Versal NET. This allows other drivers to verify the SoC familiy & revision using matching SoC attributes. +source "drivers/soc/qcom/Kconfig" source "drivers/soc/samsung/Kconfig" source "drivers/soc/ti/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 5ec89a053165..abcc8a88950f 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -4,8 +4,9 @@ obj-$(CONFIG_SOC_AMD_VERSAL2) += soc_amd_versal2.o obj-$(CONFIG_SOC_SAMSUNG) += samsung/ obj-$(CONFIG_SOC_TI) += ti/ +obj-$(CONFIG_SOC_QCOM) += qcom/ obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o obj-$(CONFIG_SANDBOX) += soc_sandbox.o obj-$(CONFIG_SOC_XILINX_ZYNQMP) += soc_xilinx_zynqmp.o diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig new file mode 100644 index 000000000000..a0872c5b3c83 --- /dev/null +++ b/drivers/soc/qcom/Kconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0+ + +menuconfig SOC_QCOM + bool "Qualcomm SOC drivers support" + help + Say Y here if you want to enable Qualcomm SOC drivers support. + +if SOC_QCOM + +config QCOM_COMMAND_DB + bool "Qualcomm Command DB" + help + Command DB queries shared memory by key string for shared system + resources. Platform drivers that require to set state of a shared + resource on a RPM-hardened platform must use this database to get + SoC specific identifier and information for the shared resources. + +config QCOM_RPMH + bool "Qualcomm RPMh support" + depends on QCOM_COMMAND_DB + help + Say y here to support the Qualcomm RPMh (resource peripheral manager) + if you need to control regulators on Qualcomm platforms, say y here. + +endif # SOC_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile new file mode 100644 index 000000000000..4fca569cfb77 --- /dev/null +++ b/drivers/soc/qcom/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o +obj-$(CONFIG_QCOM_RPMH) += rpmh-rsc.o rpmh.o diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c new file mode 100644 index 000000000000..62f1479bda09 --- /dev/null +++ b/drivers/soc/qcom/cmd-db.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Ltd. + */ + +#define pr_fmt(fmt) "cmd-db: " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NUM_PRIORITY 2 +#define MAX_SLV_ID 8 +#define SLAVE_ID_MASK 0x7 +#define SLAVE_ID_SHIFT 16 + +/** + * struct entry_header: header for each entry in cmddb + * + * @id: resource's identifier + * @priority: unused + * @addr: the address of the resource + * @len: length of the data + * @offset: offset from :@data_offset, start of the data + */ +struct entry_header { + u8 id[8]; + __le32 priority[NUM_PRIORITY]; + __le32 addr; + __le16 len; + __le16 offset; +}; + +/** + * struct rsc_hdr: resource header information + * + * @slv_id: id for the resource + * @header_offset: entry's header at offset from the end of the cmd_db_header + * @data_offset: entry's data at offset from the end of the cmd_db_header + * @cnt: number of entries for HW type + * @version: MSB is major, LSB is minor + * @reserved: reserved for future use. + */ +struct rsc_hdr { + __le16 slv_id; + __le16 header_offset; + __le16 data_offset; + __le16 cnt; + __le16 version; + __le16 reserved[3]; +}; + +/** + * struct cmd_db_header: The DB header information + * + * @version: The cmd db version + * @magic: constant expected in the database + * @header: array of resources + * @checksum: checksum for the header. Unused. + * @reserved: reserved memory + * @data: driver specific data + */ +struct cmd_db_header { + __le32 version; + u8 magic[4]; + struct rsc_hdr header[MAX_SLV_ID]; + __le32 checksum; + __le32 reserved; + u8 data[]; +}; + +/** + * DOC: Description of the Command DB database. + * + * At the start of the command DB memory is the cmd_db_header structure. + * The cmd_db_header holds the version, checksum, magic key as well as an + * array for header for each slave (depicted by the rsc_header). Each h/w + * based accelerator is a 'slave' (shared resource) and has slave id indicating + * the type of accelerator. The rsc_header is the header for such individual + * slaves of a given type. The entries for each of these slaves begin at the + * rsc_hdr.header_offset. In addition each slave could have auxiliary data + * that may be needed by the driver. The data for the slave starts at the + * entry_header.offset to the location pointed to by the rsc_hdr.data_offset. + * + * Drivers have a stringified key to a slave/resource. They can query the slave + * information and get the slave id and the auxiliary data and the length of the + * data. Using this information, they can format the request to be sent to the + * h/w accelerator and request a resource state. + */ + +static const u8 CMD_DB_MAGIC[] = { 0xdb, 0x30, 0x03, 0x0c }; + +static bool cmd_db_magic_matches(const struct cmd_db_header *header) +{ + const u8 *magic = header->magic; + + return memcmp(magic, CMD_DB_MAGIC, ARRAY_SIZE(CMD_DB_MAGIC)) == 0; +} + +static struct cmd_db_header *cmd_db_header; + +static inline const void *rsc_to_entry_header(const struct rsc_hdr *hdr) +{ + u16 offset = le16_to_cpu(hdr->header_offset); + + return cmd_db_header->data + offset; +} + +static inline void * +rsc_offset(const struct rsc_hdr *hdr, const struct entry_header *ent) +{ + u16 offset = le16_to_cpu(hdr->data_offset); + u16 loffset = le16_to_cpu(ent->offset); + + return cmd_db_header->data + offset + loffset; +} + +static int cmd_db_get_header(const char *id, const struct entry_header **eh, + const struct rsc_hdr **rh) +{ + const struct rsc_hdr *rsc_hdr; + const struct entry_header *ent; + int i, j; + u8 query[sizeof(ent->id)] __nonstring; + + /* + * Pad out query string to same length as in DB. NOTE: the output + * query string is not necessarily '\0' terminated if it bumps up + * against the max size. That's OK and expected. + */ + strncpy(query, id, sizeof(query)); + + for (i = 0; i < MAX_SLV_ID; i++) { + rsc_hdr = &cmd_db_header->header[i]; + if (!rsc_hdr->slv_id) + break; + + ent = rsc_to_entry_header(rsc_hdr); + for (j = 0; j < le16_to_cpu(rsc_hdr->cnt); j++, ent++) { + if (strncmp(ent->id, query, sizeof(ent->id)) == 0) { + if (eh) + *eh = ent; + if (rh) + *rh = rsc_hdr; + return 0; + } + } + } + + return -ENODEV; +} + +/** + * cmd_db_read_addr() - Query command db for resource id address. + * + * @id: resource id to query for address + * + * Return: resource address on success, 0 on error + * + * This is used to retrieve resource address based on resource + * id. + */ +u32 cmd_db_read_addr(const char *id) +{ + int ret; + const struct entry_header *ent; + + ret = cmd_db_get_header(id, &ent, NULL); + + return ret < 0 ? 0 : le32_to_cpu(ent->addr); +} +EXPORT_SYMBOL(cmd_db_read_addr); + +/** + * cmd_db_read_aux_data() - Query command db for aux data. + * + * @id: Resource to retrieve AUX Data on + * @len: size of data buffer returned + * + * Return: pointer to data on success, error pointer otherwise + */ +const void *cmd_db_read_aux_data(const char *id, size_t *len) +{ + int ret; + const struct entry_header *ent; + const struct rsc_hdr *rsc_hdr; + + ret = cmd_db_get_header(id, &ent, &rsc_hdr); + if (ret) + return ERR_PTR(ret); + + if (len) + *len = le16_to_cpu(ent->len); + + return rsc_offset(rsc_hdr, ent); +} +EXPORT_SYMBOL(cmd_db_read_aux_data); + +/** + * cmd_db_read_slave_id - Get the slave ID for a given resource address + * + * @id: Resource id to query the DB for version + * + * Return: cmd_db_hw_type enum on success, CMD_DB_HW_INVALID on error + */ +enum cmd_db_hw_type cmd_db_read_slave_id(const char *id) +{ + int ret; + const struct entry_header *ent; + u32 addr; + + ret = cmd_db_get_header(id, &ent, NULL); + if (ret < 0) + return CMD_DB_HW_INVALID; + + addr = le32_to_cpu(ent->addr); + return (addr >> SLAVE_ID_SHIFT) & SLAVE_ID_MASK; +} +EXPORT_SYMBOL(cmd_db_read_slave_id); + +int cmd_db_init(void) +{ + void __iomem *base; + ofnode rmem, node; + + if (cmd_db_header) + return 0; + + rmem = ofnode_path("/reserved-memory"); + ofnode_for_each_subnode(node, rmem) { + if (ofnode_device_is_compatible(node, "qcom,cmd-db")) + goto found; + } + + log_err("%s: Failed to find cmd-db node\n", __func__); + return -ENOENT; +found: + debug("%s(%s)\n", __func__, ofnode_get_name(node)); + + base = (void __iomem *)ofnode_get_addr(node); + if ((fdt_addr_t)base == FDT_ADDR_T_NONE) { + log_err("%s: Failed to read base address\n", __func__); + return -ENOENT; + } + + cmd_db_header = base; + if (!cmd_db_magic_matches(cmd_db_header)) { + log_err("%s: Invalid Command DB Magic\n", __func__); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(cmd_db_init); diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h new file mode 100644 index 000000000000..9dbb1c51cc35 --- /dev/null +++ b/drivers/soc/qcom/rpmh-internal.h @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + */ + +#ifndef __RPM_INTERNAL_H__ +#define __RPM_INTERNAL_H__ + +#include +#include + +#define TCS_TYPE_NR 4 +#define MAX_CMDS_PER_TCS 16 +#define MAX_TCS_PER_TYPE 3 +#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR) +#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE) + +#define USEC_PER_SEC 1000000UL + +struct rsc_drv; + +/** + * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests + * to the controller + * + * @drv: The controller. + * @type: Type of the TCS in this group - active, sleep, wake. + * @mask: Mask of the TCSes relative to all the TCSes in the RSC. + * @offset: Start of the TCS group relative to the TCSes in the RSC. + * @num_tcs: Number of TCSes in this type. + * @ncpt: Number of commands in each TCS. + * @req: Requests that are sent from the TCS; only used for ACTIVE_ONLY + * transfers (could be on a wake/sleep TCS if we are borrowing for + * an ACTIVE_ONLY transfer). + * Start: grab drv->lock, set req, set tcs_in_use, drop drv->lock, + * trigger + * End: get irq, access req, + * grab drv->lock, clear tcs_in_use, drop drv->lock + * @slots: Indicates which of @cmd_addr are occupied; only used for + * SLEEP / WAKE TCSs. Things are tightly packed in the + * case that (ncpt < MAX_CMDS_PER_TCS). That is if ncpt = 2 and + * MAX_CMDS_PER_TCS = 16 then bit[2] = the first bit in 2nd TCS. + */ +struct tcs_group { + struct rsc_drv *drv; + int type; + u32 mask; + u32 offset; + int num_tcs; + int ncpt; + const struct tcs_request *req[MAX_TCS_PER_TYPE]; + DECLARE_BITMAP(slots, MAX_TCS_SLOTS); +}; + +/** + * struct rpmh_request: the message to be sent to rpmh-rsc + * + * @msg: the request + * @cmd: the payload that will be part of the @msg + * @completion: triggered when request is done + * @dev: the device making the request + * @needs_free: check to free dynamically allocated request object + */ +struct rpmh_request { + struct tcs_request msg; + struct tcs_cmd cmd[MAX_RPMH_PAYLOAD]; + const struct udevice *dev; + bool needs_free; +}; + +/** + * struct rpmh_ctrlr: our representation of the controller + * + * @cache: the list of cached requests + * @cache_lock: synchronize access to the cache data + * @dirty: was the cache updated since flush + * @batch_cache: Cache sleep and wake requests sent as batch + */ +struct rpmh_ctrlr { + struct list_head cache; + bool dirty; + struct list_head batch_cache; +}; + +struct rsc_ver { + u32 major; + u32 minor; +}; + +/** + * struct rsc_drv: the Direct Resource Voter (DRV) of the + * Resource State Coordinator controller (RSC) + * + * @name: Controller identifier. + * @base: Start address of the DRV registers in this controller. + * @tcs_base: Start address of the TCS registers in this controller. + * @id: Instance id in the controller (Direct Resource Voter). + * @num_tcs: Number of TCSes in this DRV. + * @rsc_pm: CPU PM notifier for controller. + * Used when solver mode is not present. + * @cpus_in_pm: Number of CPUs not in idle power collapse. + * Used when solver mode and "power-domains" is not present. + * @genpd_nb: PM Domain notifier for cluster genpd notifications. + * @tcs: TCS groups. + * @tcs_in_use: S/W state of the TCS; only set for ACTIVE_ONLY + * transfers, but might show a sleep/wake TCS in use if + * it was borrowed for an active_only transfer. You + * must hold the lock in this struct (AKA drv->lock) in + * order to update this. + * @lock: Synchronize state of the controller. If RPMH's cache + * lock will also be held, the order is: drv->lock then + * cache_lock. + * @tcs_wait: Wait queue used to wait for @tcs_in_use to free up a + * slot + * @client: Handle to the DRV's client. + * @dev: RSC device. + */ +struct rsc_drv { + const char *name; + void __iomem *base; + void __iomem *tcs_base; + int id; + int num_tcs; + struct tcs_group tcs[TCS_TYPE_NR]; + DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR); + struct rpmh_ctrlr client; + struct udevice *dev; + struct rsc_ver ver; + u32 *regs; +}; + +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg); +int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, + const struct tcs_request *msg); +void rpmh_rsc_invalidate(struct rsc_drv *drv); +void rpmh_rsc_write_next_wakeup(struct rsc_drv *drv); + +int rpmh_rsc_wait_for_resp(struct rsc_drv *drv, int tcs_id); +int rpmh_flush(struct rpmh_ctrlr *ctrlr); + +#endif /* __RPM_INTERNAL_H__ */ diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c new file mode 100644 index 000000000000..1f8428c415a1 --- /dev/null +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -0,0 +1,628 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Ltd. + */ + +#define pr_fmt(fmt) "rpmh-rsc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "rpmh-internal.h" + +#include +#include + +#define RSC_DRV_ID 0 + +#define MAJOR_VER_MASK 0xFF +#define MAJOR_VER_SHIFT 16 +#define MINOR_VER_MASK 0xFF +#define MINOR_VER_SHIFT 8 + +enum { + RSC_DRV_TCS_OFFSET, + RSC_DRV_CMD_OFFSET, + DRV_SOLVER_CONFIG, + DRV_PRNT_CHLD_CONFIG, + RSC_DRV_IRQ_ENABLE, + RSC_DRV_IRQ_STATUS, + RSC_DRV_IRQ_CLEAR, + RSC_DRV_CMD_WAIT_FOR_CMPL, + RSC_DRV_CONTROL, + RSC_DRV_STATUS, + RSC_DRV_CMD_ENABLE, + RSC_DRV_CMD_MSGID, + RSC_DRV_CMD_ADDR, + RSC_DRV_CMD_DATA, + RSC_DRV_CMD_STATUS, + RSC_DRV_CMD_RESP_DATA, +}; + +/* DRV HW Solver Configuration Information Register */ +#define DRV_HW_SOLVER_MASK 1 +#define DRV_HW_SOLVER_SHIFT 24 + +/* DRV TCS Configuration Information Register */ +#define DRV_NUM_TCS_MASK 0x3F +#define DRV_NUM_TCS_SHIFT 6 +#define DRV_NCPT_MASK 0x1F +#define DRV_NCPT_SHIFT 27 + +/* Offsets for CONTROL TCS Registers */ +#define RSC_DRV_CTL_TCS_DATA_HI 0x38 +#define RSC_DRV_CTL_TCS_DATA_HI_MASK 0xFFFFFF +#define RSC_DRV_CTL_TCS_DATA_HI_VALID BIT(31) +#define RSC_DRV_CTL_TCS_DATA_LO 0x40 +#define RSC_DRV_CTL_TCS_DATA_LO_MASK 0xFFFFFFFF +#define RSC_DRV_CTL_TCS_DATA_SIZE 32 + +#define TCS_AMC_MODE_ENABLE BIT(16) +#define TCS_AMC_MODE_TRIGGER BIT(24) + +/* TCS CMD register bit mask */ +#define CMD_MSGID_LEN 8 +#define CMD_MSGID_RESP_REQ BIT(8) +#define CMD_MSGID_WRITE BIT(16) +#define CMD_STATUS_ISSUED BIT(8) +#define CMD_STATUS_COMPL BIT(16) + +/* + * Here's a high level overview of how all the registers in RPMH work + * together: + * + * - The main rpmh-rsc address is the base of a register space that can + * be used to find overall configuration of the hardware + * (DRV_PRNT_CHLD_CONFIG). Also found within the rpmh-rsc register + * space are all the TCS blocks. The offset of the TCS blocks is + * specified in the device tree by "qcom,tcs-offset" and used to + * compute tcs_base. + * - TCS blocks come one after another. Type, count, and order are + * specified by the device tree as "qcom,tcs-config". + * - Each TCS block has some registers, then space for up to 16 commands. + * Note that though address space is reserved for 16 commands, fewer + * might be present. See ncpt (num cmds per TCS). + * + * Here's a picture: + * + * +---------------------------------------------------+ + * |RSC | + * | ctrl | + * | | + * | Drvs: | + * | +-----------------------------------------------+ | + * | |DRV0 | | + * | | ctrl/config | | + * | | IRQ | | + * | | | | + * | | TCSes: | | + * | | +------------------------------------------+ | | + * | | |TCS0 | | | | | | | | | | | | | | | + * | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | +------------------------------------------+ | | + * | | |TCS1 | | | | | | | | | | | | | | | + * | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | +------------------------------------------+ | | + * | | |TCS2 | | | | | | | | | | | | | | | + * | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15| | | + * | | | | | | | | | | | | | | | | | | + * | | +------------------------------------------+ | | + * | | ...... | | + * | +-----------------------------------------------+ | + * | +-----------------------------------------------+ | + * | |DRV1 | | + * | | (same as DRV0) | | + * | +-----------------------------------------------+ | + * | ...... | + * +---------------------------------------------------+ + */ + +static u32 rpmh_rsc_reg_offset_ver_2_7[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 20, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x10, + [RSC_DRV_CONTROL] = 0x14, + [RSC_DRV_STATUS] = 0x18, + [RSC_DRV_CMD_ENABLE] = 0x1C, + [RSC_DRV_CMD_MSGID] = 0x30, + [RSC_DRV_CMD_ADDR] = 0x34, + [RSC_DRV_CMD_DATA] = 0x38, + [RSC_DRV_CMD_STATUS] = 0x3C, + [RSC_DRV_CMD_RESP_DATA] = 0x40, +}; + +static u32 rpmh_rsc_reg_offset_ver_3_0[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 24, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20, + [RSC_DRV_CONTROL] = 0x24, + [RSC_DRV_STATUS] = 0x28, + [RSC_DRV_CMD_ENABLE] = 0x2C, + [RSC_DRV_CMD_MSGID] = 0x34, + [RSC_DRV_CMD_ADDR] = 0x38, + [RSC_DRV_CMD_DATA] = 0x3C, + [RSC_DRV_CMD_STATUS] = 0x40, + [RSC_DRV_CMD_RESP_DATA] = 0x44, +}; + +static inline void __iomem * +tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id) +{ + return drv->tcs_base + drv->regs[RSC_DRV_TCS_OFFSET] * tcs_id + reg; +} + +static inline void __iomem * +tcs_cmd_addr(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +{ + return tcs_reg_addr(drv, reg, tcs_id) + drv->regs[RSC_DRV_CMD_OFFSET] * cmd_id; +} + +static u32 read_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id) +{ + return readl_relaxed(tcs_reg_addr(drv, reg, tcs_id)); +} + +static void write_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id, + int cmd_id, u32 data) +{ + void __iomem *addr = tcs_cmd_addr(drv, reg, tcs_id, cmd_id); + + debug("tcs(m): %d cmd(n): %d addr: %#x data: %#x\n", + tcs_id, cmd_id, reg, data); + writel_relaxed(data, addr); +} + +static void write_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id, + u32 data) +{ + void __iomem *addr = tcs_reg_addr(drv, reg, tcs_id); + + debug("tcs(m): %d addr: %#x data: %#x\n", + tcs_id, reg, data); + writel_relaxed(data, addr); +} + +static void write_tcs_reg_sync(const struct rsc_drv *drv, int reg, int tcs_id, + u32 data) +{ + int i; + void __iomem *addr = tcs_reg_addr(drv, reg, tcs_id); + + debug("tcs(m): %d addr: %#x data: %#x\n", + tcs_id, reg, data); + + writel(data, addr); + + /* + * Wait until we read back the same value. Use a counter rather than + * ktime for timeout since this may be called after timekeeping stops. + */ + for (i = 0; i < USEC_PER_SEC; i++) { + if (readl(addr) == data) + return; + udelay(1); + } + log_err("error writing %#x to %d:%#x\n", + data, tcs_id, reg); +} + +/** + * tcs_invalidate() - Invalidate all TCSes of the given type (sleep or wake). + * @drv: The RSC controller. + * @type: SLEEP_TCS or WAKE_TCS + * + * This will clear the "slots" variable of the given tcs_group and also + * tell the hardware to forget about all entries. + * + * The caller must ensure that no other RPMH actions are happening when this + * function is called, since otherwise the device may immediately become + * used again even before this function exits. + */ +static void tcs_invalidate(struct rsc_drv *drv, int type) +{ + int m; + struct tcs_group *tcs = &drv->tcs[type]; + + /* Caller ensures nobody else is running so no lock */ + if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) + return; + + for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], m, 0); + + bitmap_zero(tcs->slots, MAX_TCS_SLOTS); +} + +/** + * rpmh_rsc_invalidate() - Invalidate sleep and wake TCSes. + * @drv: The RSC controller. + * + * The caller must ensure that no other RPMH actions are happening when this + * function is called, since otherwise the device may immediately become + * used again even before this function exits. + */ +void rpmh_rsc_invalidate(struct rsc_drv *drv) +{ + tcs_invalidate(drv, SLEEP_TCS); + tcs_invalidate(drv, WAKE_TCS); +} + +/** + * rpmh_rsc_wait_for_resp() - Spin until we get a response from the rpmh + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * + * This is for ACTIVE_ONLY transfers (which are the only ones we support in + * u-boot). As we don't support interrupts, we just spin on the IRQ_STATUS + * register until the bit is set to confirm that the TCS TX is done. + */ +int rpmh_rsc_wait_for_resp(struct rsc_drv *drv, int tcs_id) +{ + u32 reg; + int i; + + reg = drv->regs[RSC_DRV_IRQ_STATUS]; + + debug("waiting for response to tcs %d\n", tcs_id); + + for (i = 0; i < 5 * USEC_PER_SEC; i++) { + if (readl(tcs_reg_addr(drv, reg, tcs_id)) & BIT(tcs_id)) + break; + udelay(1); + } + + if (i == 5 * USEC_PER_SEC) { + log_err("timeout waiting\n"); + return -ETIMEDOUT; + } + + writel_relaxed(BIT(tcs_id), drv->tcs_base + drv->regs[RSC_DRV_IRQ_CLEAR]); + + return 0; +} + +/** + * __tcs_buffer_write() - Write to TCS hardware from a request; don't trigger. + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @cmd_id: The index within the TCS to start writing. + * @msg: The message we want to send, which will contain several addr/data + * pairs to program (but few enough that they all fit in one TCS). + * + * This is used for all types of transfers (active, sleep, and wake). + */ +static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, + const struct tcs_request *msg) +{ + u32 msgid; + u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE; + u32 cmd_enable = 0; + struct tcs_cmd *cmd; + int i, j; + + /* u-boot: get a response to ensure everything is golden before continuing */ + cmd_msgid |= CMD_MSGID_RESP_REQ; + + for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) { + cmd = &msg->cmds[i]; + cmd_enable |= BIT(j); + msgid = cmd_msgid; + /* + * Additionally, if the cmd->wait is set, make the command + * response reqd even if the overall request was fire-n-forget. + */ + msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0; + + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); + debug("tcs(m): %d [%s] cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d\n", + tcs_id, msg->state == RPMH_ACTIVE_ONLY_STATE ? "active" : "?", j, msgid, + cmd->addr, cmd->data, cmd->wait); + } + + cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id); + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable); +} + +/** + * __tcs_set_trigger() - Start xfer on a TCS or unset trigger on a borrowed TCS + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @trigger: If true then untrigger/retrigger. If false then just untrigger. + * + * In the normal case we only ever call with "trigger=true" to start a + * transfer. That will un-trigger/disable the TCS from the last transfer + * then trigger/enable for this transfer. + * + * If we borrowed a wake TCS for an active-only transfer we'll also call + * this function with "trigger=false" to just do the un-trigger/disable + * before using the TCS for wake purposes again. + * + * Note that the AP is only in charge of triggering active-only transfers. + * The AP never triggers sleep/wake values using this function. + */ +static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) +{ + u32 enable; + u32 reg = drv->regs[RSC_DRV_CONTROL]; + + /* + * HW req: Clear the DRV_CONTROL and enable TCS again + * While clearing ensure that the AMC mode trigger is cleared + * and then the mode enable is cleared. + */ + enable = read_tcs_reg(drv, reg, tcs_id); + enable &= ~TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable &= ~TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + + if (trigger) { + /* Enable the AMC mode on the TCS and then trigger the TCS */ + enable = TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable |= TCS_AMC_MODE_TRIGGER; + write_tcs_reg(drv, reg, tcs_id, enable); + } +} + +/** + * get_tcs_for_msg() - Get the tcs_group used to send the given message. + * @drv: The RSC controller. + * @msg: The message we want to send. + * + * This is normally pretty straightforward except if we are trying to send + * an ACTIVE_ONLY message but don't have any active_only TCSes. + * + * Return: A pointer to a tcs_group or an ERR_PTR. + */ +static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, + const struct tcs_request *msg) +{ + if (msg->state != RPMH_ACTIVE_ONLY_STATE) { + log_err("WARN: only ACTIVE_ONLY state supported\n"); + return ERR_PTR(-EINVAL); + } + + return &drv->tcs[ACTIVE_TCS]; +} + +/** + * rpmh_rsc_send_data() - Write / trigger active-only message. + * @drv: The controller. + * @msg: The data to be sent. + * + * NOTES: + * - This is only used for "ACTIVE_ONLY" since the limitations of this + * function don't make sense for sleep/wake cases. + * - To do the transfer, we will grab a whole TCS for ourselves--we don't + * try to share. If there are none available we'll wait indefinitely + * for a free one. + * - This function will not wait for the commands to be finished, only for + * data to be programmed into the RPMh. See rpmh_tx_done() which will + * be called when the transfer is fully complete. + * - This function must be called with interrupts enabled. If the hardware + * is busy doing someone else's transfer we need that transfer to fully + * finish so that we can have the hardware, and to fully finish it needs + * the interrupt handler to run. If the interrupts is set to run on the + * active CPU this can never happen if interrupts are disabled. + * + * Return: 0 on success, -EINVAL on error. + */ +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) +{ + struct tcs_group *tcs; + int tcs_id; + unsigned long flags; + + tcs = get_tcs_for_msg(drv, msg); + if (IS_ERR(tcs)) + return PTR_ERR(tcs); + + spin_lock_irqsave(&drv->lock, flags); + + /* u-boot is single-threaded, always use the first TCS as we'll never conflict */ + tcs_id = tcs->offset; + + tcs->req[tcs_id - tcs->offset] = msg; + generic_set_bit(tcs_id, drv->tcs_in_use); + if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) { + /* + * Clear previously programmed WAKE commands in selected + * repurposed TCS to avoid triggering them. tcs->slots will be + * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() + */ + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); + } + spin_unlock_irqrestore(&drv->lock, flags); + + /* + * These two can be done after the lock is released because: + * - We marked "tcs_in_use" under lock. + * - Once "tcs_in_use" has been marked nobody else could be writing + * to these registers until the interrupt goes off. + * - The interrupt can't go off until we trigger w/ the last line + * of __tcs_set_trigger() below. + */ + __tcs_buffer_write(drv, tcs_id, 0, msg); + __tcs_set_trigger(drv, tcs_id, true); + + rpmh_rsc_wait_for_resp(drv, tcs_id); + + return 0; +} + +static int rpmh_probe_tcs_config(struct udevice *dev, struct rsc_drv *drv) +{ + struct tcs_type_config { + u32 type; + u32 n; + } tcs_cfg[TCS_TYPE_NR] = { { 0 } }; + ofnode dn = dev_ofnode(dev); + u32 config, max_tcs, ncpt, offset; + int i, ret, n, st = 0; + struct tcs_group *tcs; + + ret = ofnode_read_u32(dn, "qcom,tcs-offset", &offset); + if (ret) + return ret; + drv->tcs_base = drv->base + offset; + + config = readl_relaxed(drv->base + drv->regs[DRV_PRNT_CHLD_CONFIG]); + + max_tcs = config; + max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id); + max_tcs = max_tcs >> (DRV_NUM_TCS_SHIFT * drv->id); + + ncpt = config & (DRV_NCPT_MASK << DRV_NCPT_SHIFT); + ncpt = ncpt >> DRV_NCPT_SHIFT; + + n = ofnode_read_u32_array(dn, "qcom,tcs-config", (u32 *)tcs_cfg, 2 * TCS_TYPE_NR); + if (n < 0) { + log_err("RPMh: %s: error reading qcom,tcs-config %d\n", dev->name, n); + return n; + } + + for (i = 0; i < TCS_TYPE_NR; i++) { + if (tcs_cfg[i].n > MAX_TCS_PER_TYPE) + return -EINVAL; + } + + for (i = 0; i < TCS_TYPE_NR; i++) { + tcs = &drv->tcs[tcs_cfg[i].type]; + if (tcs->drv) + return -EINVAL; + tcs->drv = drv; + tcs->type = tcs_cfg[i].type; + tcs->num_tcs = tcs_cfg[i].n; + tcs->ncpt = ncpt; + + if (!tcs->num_tcs || tcs->type == CONTROL_TCS) + continue; + + if (st + tcs->num_tcs > max_tcs || + st + tcs->num_tcs >= BITS_PER_BYTE * sizeof(tcs->mask)) + return -EINVAL; + + tcs->mask = ((1 << tcs->num_tcs) - 1) << st; + tcs->offset = st; + st += tcs->num_tcs; + } + + drv->num_tcs = st; + + return 0; +} + +static int rpmh_rsc_bind(struct udevice *dev) +{ + int ret; + + ret = cmd_db_init(); + if (ret) + return ret; + + return dm_scan_fdt_dev(dev); +} + +static int rpmh_rsc_probe(struct udevice *dev) +{ + ofnode dn = dev_ofnode(dev); + struct rsc_drv *drv; + char drv_id[10] = {0}; + int ret; + u32 rsc_id; + + drv = dev_get_priv(dev); + + ret = ofnode_read_u32(dn, "qcom,drv-id", &drv->id); + if (ret) + return ret; + + drv->name = ofnode_get_property(dn, "label", NULL); + if (!drv->name) + drv->name = dev->name; + + snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id); + drv->base = (void __iomem *)dev_read_addr_name(dev, drv_id); + if (IS_ERR(drv->base)) + return PTR_ERR(drv->base); + + rsc_id = readl_relaxed(drv->base + RSC_DRV_ID); + drv->ver.major = rsc_id & (MAJOR_VER_MASK << MAJOR_VER_SHIFT); + drv->ver.major >>= MAJOR_VER_SHIFT; + drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT); + drv->ver.minor >>= MINOR_VER_SHIFT; + + if (drv->ver.major == 3) + drv->regs = rpmh_rsc_reg_offset_ver_3_0; + else + drv->regs = rpmh_rsc_reg_offset_ver_2_7; + + ret = rpmh_probe_tcs_config(dev, drv); + if (ret) + return ret; + + spin_lock_init(&drv->lock); + init_waitqueue_head(&drv->tcs_wait); + bitmap_zero(drv->tcs_in_use, MAX_TCS_NR); + + /* Enable the active TCS to send requests immediately */ + writel_relaxed(drv->tcs[ACTIVE_TCS].mask, + drv->tcs_base + drv->regs[RSC_DRV_IRQ_ENABLE]); + + spin_lock_init(&drv->client.cache_lock); + INIT_LIST_HEAD(&drv->client.cache); + INIT_LIST_HEAD(&drv->client.batch_cache); + + dev_set_drvdata(dev, drv); + drv->dev = dev; + + log_debug("RPMh: %s: v%d.%d\n", dev->name, drv->ver.major, drv->ver.minor); + + return ret; +} + +static const struct udevice_id qcom_rpmh_ids[] = { + { .compatible = "qcom,rpmh-rsc" }, + { } +}; + +U_BOOT_DRIVER(qcom_rpmh_rsc) = { + .name = "qcom_rpmh_rsc", + .id = UCLASS_MISC, + .priv_auto = sizeof(struct rsc_drv), + .probe = rpmh_rsc_probe, + .bind = rpmh_rsc_bind, + .of_match = qcom_rpmh_ids, + /* rpmh is under CLUSTER_PD which we don't support */ + .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, +}; diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c new file mode 100644 index 000000000000..fc881c21e3e3 --- /dev/null +++ b/drivers/soc/qcom/rpmh.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + */ + +#define pr_fmt(fmt) "rpmh: " fmt + +#include +#include +#include +#include +#include + +#include + +#include "rpmh-internal.h" + +#define RPMH_TIMEOUT_MS msecs_to_jiffies(10000) + +#define DEFINE_RPMH_MSG_ONSTACK(device, s, name) \ + struct rpmh_request name = { \ + .msg = { \ + .state = s, \ + .cmds = name.cmd, \ + .num_cmds = 0, \ + }, \ + .cmd = { { 0 } }, \ + .dev = device, \ + .needs_free = false, \ + } + +#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client) + +static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct udevice *dev) +{ + struct rsc_drv *drv = (struct rsc_drv *)dev_get_priv(dev->parent); + + if (!drv) { + log_err("BUG: no RPMh driver for %s (parent %s)\n", dev->name, dev->parent->name); + BUG(); + } + + return &drv->client; +} + +/** + * __rpmh_write: Cache and send the RPMH request + * + * @dev: The device making the request + * @state: Active/Sleep request type + * @rpm_msg: The data that needs to be sent (cmds). + * + * Cache the RPMH request and send if the state is ACTIVE_ONLY. + * SLEEP/WAKE_ONLY requests are not sent to the controller at + * this time. Use rpmh_flush() to send them to the controller. + */ +static int __rpmh_write(const struct udevice *dev, enum rpmh_state state, + struct rpmh_request *rpm_msg) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); + + debug("rpmh_write: %s, %d\n", dev->name, state); + + if (state != RPMH_ACTIVE_ONLY_STATE) { + log_err("WARN: only ACTIVE_ONLY state supported\n"); + return -EINVAL; + } + + return rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg); +} + +static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ + if (!cmd || !n || n > MAX_RPMH_PAYLOAD) + return -EINVAL; + + memcpy(req->cmd, cmd, n * sizeof(*cmd)); + + req->msg.state = state; + req->msg.cmds = req->cmd; + req->msg.num_cmds = n; + + debug("rpmh_msg: %d, %d cmds [first %#x/%#x]\n", state, n, cmd->addr, cmd->data); + + return 0; +} + +/** + * rpmh_write: Write a set of RPMH commands and block until response + * + * @dev: The device making the request + * @state: Active/sleep set + * @cmd: The payload data + * @n: The number of elements in @cmd + * + * May sleep. Do not call from atomic contexts. + */ +int rpmh_write(const struct udevice *dev, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ + DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg); + int ret; + + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + ret = __rpmh_write(dev, state, &rpm_msg); + + return ret; +} diff --git a/include/soc/qcom/cmd-db.h b/include/soc/qcom/cmd-db.h new file mode 100644 index 000000000000..d5dfe7917c10 --- /dev/null +++ b/include/soc/qcom/cmd-db.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ + +#ifndef __QCOM_COMMAND_DB_H__ +#define __QCOM_COMMAND_DB_H__ + +#include +#include + +enum cmd_db_hw_type { + CMD_DB_HW_INVALID = 0, + CMD_DB_HW_MIN = 3, + CMD_DB_HW_ARC = CMD_DB_HW_MIN, + CMD_DB_HW_VRM = 4, + CMD_DB_HW_BCM = 5, + CMD_DB_HW_MAX = CMD_DB_HW_BCM, + CMD_DB_HW_ALL = 0xff, +}; + +#if IS_ENABLED(CONFIG_QCOM_COMMAND_DB) +u32 cmd_db_read_addr(const char *resource_id); + +const void *cmd_db_read_aux_data(const char *resource_id, size_t *len); + +enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id); + +int cmd_db_init(void); + +#else +static inline u32 cmd_db_read_addr(const char *resource_id) +{ return 0; } + +static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len) +{ return ERR_PTR(-ENODEV); } + +static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id) +{ return -ENODEV; } + +static inline int cmd_db_ready(void) +{ return -ENODEV; } +#endif /* CONFIG_QCOM_COMMAND_DB */ +#endif /* __QCOM_COMMAND_DB_H__ */ diff --git a/include/soc/qcom/rpmh.h b/include/soc/qcom/rpmh.h new file mode 100644 index 000000000000..eb7c067cc5fd --- /dev/null +++ b/include/soc/qcom/rpmh.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + */ + +#ifndef __SOC_QCOM_RPMH_H__ +#define __SOC_QCOM_RPMH_H__ + +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_QCOM_RPMH) +int rpmh_write(const struct udevice *dev, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n); + +#else + +static inline int rpmh_write(const struct udevice *dev, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 n) +{ return -ENODEV; } + +#endif /* CONFIG_QCOM_RPMH */ + +/* u-boot: no multithreading */ +#define rpmh_write_async(dev, state, cmd, n) rpmh_write(dev, state, cmd, n) + +#endif /* __SOC_QCOM_RPMH_H__ */ diff --git a/include/soc/qcom/tcs.h b/include/soc/qcom/tcs.h new file mode 100644 index 000000000000..c8d28b052f1d --- /dev/null +++ b/include/soc/qcom/tcs.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __SOC_QCOM_TCS_H__ +#define __SOC_QCOM_TCS_H__ + +#define MAX_RPMH_PAYLOAD 16 + +/** + * rpmh_state: state for the request + * + * RPMH_SLEEP_STATE: State of the resource when the processor subsystem + * is powered down. There is no client using the + * resource actively. + * RPMH_WAKE_ONLY_STATE: Resume resource state to the value previously + * requested before the processor was powered down. + * RPMH_ACTIVE_ONLY_STATE: Active or AMC mode requests. Resource state + * is aggregated immediately. + */ +enum rpmh_state { + RPMH_SLEEP_STATE, + RPMH_WAKE_ONLY_STATE, + RPMH_ACTIVE_ONLY_STATE, +}; + +/** + * struct tcs_cmd: an individual request to RPMH. + * + * @addr: the address of the resource slv_id:18:16 | offset:0:15 + * @data: the resource state request + * @wait: ensure that this command is complete before returning. + * Setting "wait" here only makes sense during rpmh_write_batch() for + * active-only transfers, this is because: + * rpmh_write() - Always waits. + * (DEFINE_RPMH_MSG_ONSTACK will set .wait_for_compl) + * rpmh_write_async() - Never waits. + * (There's no request completion callback) + */ +struct tcs_cmd { + u32 addr; + u32 data; + u32 wait; +}; + +/** + * struct tcs_request: A set of tcs_cmds sent together in a TCS + * + * @state: state for the request. + * @num_cmds: the number of @cmds in this request + * @cmds: an array of tcs_cmds + */ +struct tcs_request { + enum rpmh_state state; + u32 num_cmds; + struct tcs_cmd *cmds; +}; + +#define BCM_TCS_CMD_COMMIT_SHFT 30 +#define BCM_TCS_CMD_COMMIT_MASK 0x40000000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20000000 +#define BCM_TCS_CMD_VOTE_X_SHFT 14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT 0 +#define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000 + +/* Construct a Bus Clock Manager (BCM) specific TCS command */ +#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ + (((commit) << BCM_TCS_CMD_COMMIT_SHFT) | \ + ((valid) << BCM_TCS_CMD_VALID_SHFT) | \ + ((cpu_to_le32(vote_x) & \ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) | \ + ((cpu_to_le32(vote_y) & \ + BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT)) + +#endif /* __SOC_QCOM_TCS_H__ */ From patchwork Mon Jul 8 11:32:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Connolly X-Patchwork-Id: 811188 Delivered-To: patch@linaro.org Received: by 2002:adf:a199:0:b0:367:895a:4699 with SMTP id u25csp2687378wru; Mon, 8 Jul 2024 04:33:34 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWt7OMIVLoQgeS7fNFBfS11JCrNI8fBaa7TJ2VWhtCNJvJe1R51cIbC+RciHqRF12mOJl6JAnzLYThAfWxHouFq X-Google-Smtp-Source: AGHT+IHhv/AXA7yKnRcnigVlt/+YewsuwcurEAMy5uRoA9lg2GG4oagsun9XByTfeKsN1QGWbXX5 X-Received: by 2002:a17:907:1c18:b0:a77:f1c8:7cb7 with SMTP id a640c23a62f3a-a77f1c87fa2mr275388666b.73.1720438414692; Mon, 08 Jul 2024 04:33:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720438414; cv=none; d=google.com; s=arc-20160816; b=pzyY3lYZjpywnJAXZjuTZ6RNllUAOLt6lV4Emj47rckuFSu7x57ra6DOv3KhF1I6Na 7Kev/MISviJQfzVZlTJB3raJ/88Fo3Uu/4IcYnFzKhwo/eeDgBxIBQrOXDsKU8yUZdzb 7JIW2CsdA8IXDxiKdZzLy1B6PyN2pAxLxzy7uUSR6Ts1b3S+jahvoc0avHy83UVp1aSR p/1oQ4aY338jDVY7CzXsVNfiq5Y8dVypeCyL/FFvFkuXB6r6waa9ENVr085XI+0qPJL0 2Ut7xfA/4E6GyWg/SpMeGuD4dhLcSUl4YWIHFJEFEfe2xstH86BTMVVON3FPwH/f7FEd tFvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:cc:to:in-reply-to:references :message-id:content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=8+RxeoDY23U098AbtdRBsqVy8mCCokuEc6na2mW89QI=; fh=/XivWHF+vo8fEJZkIifbJJS5exQ4Pz1Cdxakj2MFy4s=; b=y+YTJtLPCAeaakB6Mdivj5B2LnZBJtedcdrZ0rVh/q+FlJ6toAm//JTRYb0LcUZ/5k CTsJimgaRqsPuDcadqWnYlqjS6RGJhmDaC8IMveJDeZOmyLwrdiE29alSMMVNMRj0D1b tWDaP/GJDaD3G6ji6k6NWYvcRqLLQBEkAf3Ue3s1AqM7bkZlPS/VXUKt+uBVwAOzHhTu I1JKJT9dC7l8fLVdKkMu9T2jODPRzHX4hq5UMXT1wVCItNn38mqcx8tbYXTwN4IHrpRR 0Qp6CwLroH5b3ffTELSr8b1jjYTkFndSezCM86ho1xhuo3yZ8i4mcBgkKQHNswRcTKk/ M65Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="c/sS1xgy"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id a640c23a62f3a-a77e31d5cb3si260364566b.922.2024.07.08.04.33.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:34 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="c/sS1xgy"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 467EA884CC; Mon, 8 Jul 2024 13:33:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="c/sS1xgy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EC01E88271; Mon, 8 Jul 2024 13:33:12 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8D939886AF for ; Mon, 8 Jul 2024 13:33:10 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=caleb.connolly@linaro.org Received: by mail-ej1-x631.google.com with SMTP id a640c23a62f3a-a77e85cb9b4so151857766b.0 for ; Mon, 08 Jul 2024 04:33:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1720438390; x=1721043190; darn=lists.denx.de; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=8+RxeoDY23U098AbtdRBsqVy8mCCokuEc6na2mW89QI=; b=c/sS1xgyHWR704LnzZS51+ZgaU6V5r+gBRBYLvKYYPpCfT1iZg6Qqx8zZOqPD+oA2h IoAVB4K7eLCjdpIqEa/M/53Hd5vujHo30zSUkWrGTsNtw15FcxRZGEbul8gh83x1QrwH 0Bb98T7r6471KEy3NuyffM0aYeviFm3gz5WDv7pa45NZeieFRD1jVFA3eosdNRTlqctw sF6J2uePSpQ9wBBu8yc4HV1Am03KGYcZxm4iWLQTaAWdLDZnZParkzUoLbu0rF7YFrwe 5x9eiQSFUwj+mxlJubZiOq3NZwd3r0GIJNN0QEdeXqYZ76v+naqVqhVQvMnVx84CfVO9 nVBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720438390; x=1721043190; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8+RxeoDY23U098AbtdRBsqVy8mCCokuEc6na2mW89QI=; b=YuNW4gUm7AwtI+SKDI58oit4zskE8TutVGPsWiSSZhTZxZTEMOamID7UMMPj5dHPgJ rODrZ+FqPXrB1fBzxSbXSKkZ7yeYtsrmQgjzbHAJP1KI0qho+z5zpC3wWRP6hCBNL7Nv KsRb03XLY9xUqcygf8ynIJzCBfFotS9pXQIJBpTX/FxMbQ48J3dBPeWdUuw4VxstOou5 HFP7Z7tpRUUw109pTK+Zgd2uAL3GjP3RdGQ1mIMJciSLtcSRV+SgU2f5RR5apGioGYkp dY51TDuypFjKlDoWzqOFxfxWLHwjtBSjG+Qt0Khenv0boyCWB68tSmhA3La98LWFryrB M+KQ== X-Gm-Message-State: AOJu0YxaQ5udrOtFHQK+fda6VDa9hTcSeRUBQrp6KZM/FT3Lq1szhrrp XdQ7C6e+lqlwo/ibv8dQUHNZjpiQoPXerOP1vV6gZ2GModAMxSmrCxWL3GLhRzNEGK8P0x08Zi6 xls8= X-Received: by 2002:a17:906:eb56:b0:a6f:b715:6cd9 with SMTP id a640c23a62f3a-a77ba70a7ddmr769685366b.56.1720438389469; Mon, 08 Jul 2024 04:33:09 -0700 (PDT) Received: from [192.168.0.113] ([2a02:8109:aa0d:be00::18f8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a77c9925463sm303628466b.69.2024.07.08.04.33.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:09 -0700 (PDT) From: Caleb Connolly Date: Mon, 08 Jul 2024 13:32:55 +0200 Subject: [PATCH v2 3/4] power: regulator: add qcom-rpmh-regulator MIME-Version: 1.0 Message-Id: <20240708-b4-qcom-rpmh-v2-3-8bc765606e56@linaro.org> References: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> In-Reply-To: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> To: Tom Rini , Caleb Connolly , Neil Armstrong , Sumit Garg , Jaehoon Chung Cc: u-boot@lists.denx.de, u-boot-qcom@groups.io X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=18340; i=caleb.connolly@linaro.org; h=from:subject:message-id; bh=12Z5km0pLk4CJ8ivJ1W8gj0/OEPY9fyAiBdVhCdiU7o=; b=owEBbQKS/ZANAwAIAQWDMSsZX2S2AcsmYgBmi85wnO039d/qB1m6518bcx6lDWtIdSWzgKxrc /6rZJy2mZGJAjMEAAEIAB0WIQS2UaFGPGq+0GkMVc0FgzErGV9ktgUCZovOcAAKCRAFgzErGV9k tnM/D/oCQwAHmHLLJjX3WH0Jtd2RZacY51pRmsPHG0Cb47HWTQgLX7KUvqBPTyQXlAM0fh5tRzP aYnse6k+UuYCd2OIoo346IzEg+W/0xy4jUYPpnpwU+NTS82Yr0aSdSFUpBW5C5tvRGk/rpF7uLV a6Yqb9VMeXhoyjFJO58QAkPEkU7aGE5Trqcgb78I2Xd43wtvaWyTgg18aJgSelTJU5OrGlEei9i Do/SIn6pXbsZluftpBQX6KyaN6IBeRAflEowG/RteAmwdr+4cMtNyqcik1RqunXiPAE9QjncDW/ XP/A0WAhrS2gDN+aezJ22VwOOBeDC2j9dsttaYaTgaB0vxLRpQIpgNzyJ+Fx36ZwnEIVyts2YRq /HK6rmPN446OjOyCCJRXW6XLSn+Q74w9PY8HH9YytnxYeWZjUQrQpixrXj/evj6IU4TVyoGQeQX h8PnmmuJS20iB7RYL0gNndEAvTTS+J8xPd0Y/0nN9YIgzyaQTYyvx/Bqfe3ASq/qNC4DQxC2Iqd 4NjZ0KqV+XUUQZGsM6Anobc/o/Mv1TA4Kf2AFIDvupDeFymEvk56hIufBwIpPFiXNoV1+bKzttE LldoNmqPisSnoKyjemBBwSYhcysKV+8f2yMaQ8bNNSkID0XHrkwBCVxdn6df/gemPZP8BRmC0kt 4J4aK55LTCaJ3EA== X-Developer-Key: i=caleb.connolly@linaro.org; a=openpgp; fpr=83B24DA7FE145076BC38BB250CD904EB673A7C47 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.8 at phobos.denx.de X-Virus-Status: Clean Add a regulator driver for controlling the PMIC rails via the RPMh on Qualcomm platforms. This driver is restricted to only know about rails which are required by u-boot. Signed-off-by: Caleb Connolly --- drivers/power/regulator/Kconfig | 8 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/qcom-rpmh-regulator.c | 536 ++++++++++++++++++++++++++ 3 files changed, 545 insertions(+) diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 102ec7bc5f89..bc061c20d75e 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -215,8 +215,16 @@ config DM_REGULATOR_GPIO This config enables implementation of driver-model regulator uclass features for gpio regulators. The driver implements get/set for voltage value. +config DM_REGULATOR_QCOM_RPMH + bool "Enable driver model for Qualcomm RPMh regulator" + depends on DM_REGULATOR && QCOM_RPMH + ---help--- + Enable support for the Qualcomm RPMh regulator. The driver + implements get/set api for a limited set of regulators used + by u-boot. + config SPL_DM_REGULATOR_GPIO bool "Enable Driver Model for GPIO REGULATOR in SPL" depends on DM_REGULATOR_GPIO && SPL_GPIO select SPL_DM_REGULATOR_COMMON diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index f79932d83307..56a527612b74 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -20,8 +20,9 @@ obj-$(CONFIG_$(SPL_)REGULATOR_PWM) += pwm_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_FAN53555) += fan53555.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_COMMON) += regulator_common.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o +obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o obj-$(CONFIG_$(SPL_TPL_)REGULATOR_RK8XX) += rk8xx.o obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c new file mode 100644 index 000000000000..7ddd6e3d21bf --- /dev/null +++ b/drivers/power/regulator/qcom-rpmh-regulator.c @@ -0,0 +1,536 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/** + * enum rpmh_regulator_type - supported RPMh accelerator types + * @VRM: RPMh VRM accelerator which supports voting on enable, voltage, + * and mode of LDO, SMPS, and BOB type PMIC regulators. + * @XOB: RPMh XOB accelerator which supports voting on the enable state + * of PMIC regulators. + */ +enum rpmh_regulator_type { + VRM, + XOB, +}; + +enum rpmh_regulator_mode { + REGULATOR_MODE_RETENTION, + REGULATOR_MODE_LPM, + REGULATOR_MODE_AUTO, + REGULATOR_MODE_HPM, +}; + +#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0 +#define RPMH_REGULATOR_REG_ENABLE 0x4 +#define RPMH_REGULATOR_REG_VRM_MODE 0x8 + +#define PMIC4_LDO_MODE_RETENTION 4 +#define PMIC4_LDO_MODE_LPM 5 +#define PMIC4_LDO_MODE_HPM 7 + +#define PMIC4_SMPS_MODE_RETENTION 4 +#define PMIC4_SMPS_MODE_PFM 5 +#define PMIC4_SMPS_MODE_AUTO 6 +#define PMIC4_SMPS_MODE_PWM 7 + +#define PMIC4_BOB_MODE_PASS 0 +#define PMIC4_BOB_MODE_PFM 1 +#define PMIC4_BOB_MODE_AUTO 2 +#define PMIC4_BOB_MODE_PWM 3 + +#define PMIC5_LDO_MODE_RETENTION 3 +#define PMIC5_LDO_MODE_LPM 4 +#define PMIC5_LDO_MODE_HPM 7 + +#define PMIC5_SMPS_MODE_RETENTION 3 +#define PMIC5_SMPS_MODE_PFM 4 +#define PMIC5_SMPS_MODE_AUTO 6 +#define PMIC5_SMPS_MODE_PWM 7 + +#define PMIC5_BOB_MODE_PASS 2 +#define PMIC5_BOB_MODE_PFM 4 +#define PMIC5_BOB_MODE_AUTO 6 +#define PMIC5_BOB_MODE_PWM 7 + +/** + * struct linear_range - table of selector - value pairs + * + * Define a lookup-table for range of values. Intended to help when looking + * for a register value matching certaing physical measure (like voltage). + * Usable when increment of one in register always results a constant increment + * of the physical measure (like voltage). + * + * @min: Lowest value in range + * @min_sel: Lowest selector for range + * @max_sel: Highest selector for range + * @step: Value step size + */ +struct linear_range { + unsigned int min; + unsigned int min_sel; + unsigned int max_sel; + unsigned int step; +}; + +/* Initialize struct linear_range for regulators */ +#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \ +{ \ + .min = _min_uV, \ + .min_sel = _min_sel, \ + .max_sel = _max_sel, \ + .step = _step_uV, \ +} + +/** + * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations + * @regulator_type: RPMh accelerator type used to manage this + * regulator + * @ops: Pointer to regulator ops callback structure + * @voltage_range: The single range of voltages supported by this + * PMIC regulator type + * @n_voltages: The number of unique voltage set points defined + * by voltage_range + * @hpm_min_load_uA: Minimum load current in microamps that requires + * high power mode (HPM) operation. This is used + * for LDO hardware type regulators only. + * @pmic_mode_map: Array indexed by regulator framework mode + * containing PMIC hardware modes. Must be large + * enough to index all framework modes supported + * by this regulator hardware type. + * @of_map_mode: Maps an RPMH_REGULATOR_MODE_* mode value defined + * in device tree to a regulator framework mode + */ +struct rpmh_vreg_hw_data { + enum rpmh_regulator_type regulator_type; + const struct dm_regulator_ops *ops; + struct linear_range voltage_range; + int n_voltages; + int hpm_min_load_uA; + struct dm_regulator_mode *pmic_mode_map; + int n_modes; + unsigned int (*of_map_mode)(unsigned int mode); +}; + +/** + * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a + * single regulator device + * @dev: Device pointer for the top-level PMIC RPMh + * regulator parent device. This is used as a + * handle in RPMh write requests. + * @addr: Base address of the regulator resource within + * an RPMh accelerator + * @rdesc: Regulator descriptor + * @hw_data: PMIC regulator configuration data for this RPMh + * regulator + * @always_wait_for_ack: Boolean flag indicating if a request must always + * wait for an ACK from RPMh before continuing even + * if it corresponds to a strictly lower power + * state (e.g. enabled --> disabled). + * @enabled: Flag indicating if the regulator is enabled or + * not + * @bypassed: Boolean indicating if the regulator is in + * bypass (pass-through) mode or not. This is + * only used by BOB rpmh-regulator resources. + * @uv: Selector used for get_voltage_sel() and + * set_value() callbacks + * @mode: RPMh VRM regulator current framework mode + */ +struct rpmh_vreg { + struct udevice *dev; + u32 addr; + const struct rpmh_vreg_hw_data *hw_data; + bool always_wait_for_ack; + + int enabled; + bool bypassed; + int uv; + int mode; +}; + +/** + * struct rpmh_vreg_init_data - initialization data for an RPMh regulator + * @name: Name for the regulator which also corresponds + * to the device tree subnode name of the regulator + * @resource_name: RPMh regulator resource name format string. + * This must include exactly one field: '%s' which + * is filled at run-time with the PMIC ID provided + * by device tree property qcom,pmic-id. Example: + * "ldo%s1" for RPMh resource "ldoa1". + * @supply_name: Parent supply regulator name + * @hw_data: Configuration data for this PMIC regulator type + */ +struct rpmh_vreg_init_data { + const char *name; + const char *resource_name; + const char *supply_name; + const struct rpmh_vreg_hw_data *hw_data; +}; + +/** + * rpmh_regulator_send_request() - send the request to RPMh + * @vreg: Pointer to the RPMh regulator + * @cmd: Pointer to the RPMh command to send + * @wait_for_ack: Boolean indicating if execution must wait until the + * request has been acknowledged as complete + * + * Return: 0 on success, errno on failure + */ +static int rpmh_regulator_send_request(struct rpmh_vreg *vreg, + const struct tcs_cmd *cmd, bool wait_for_ack) +{ + int ret; + + if (wait_for_ack || vreg->always_wait_for_ack) + ret = rpmh_write(vreg->dev->parent, RPMH_ACTIVE_ONLY_STATE, cmd, 1); + else + ret = rpmh_write_async(vreg->dev->parent, RPMH_ACTIVE_ONLY_STATE, cmd, 1); + + return ret; +} + +static int _rpmh_regulator_vrm_set_value(struct udevice *rdev, + int uv, bool wait_for_ack) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + struct tcs_cmd cmd = { + .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE, + }; + int ret; + unsigned int selector; + + selector = (uv - vreg->hw_data->voltage_range.min) / vreg->hw_data->voltage_range.step; + cmd.data = DIV_ROUND_UP(vreg->hw_data->voltage_range.min + + selector * vreg->hw_data->voltage_range.step, 1000); + + ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack); + if (!ret) + vreg->uv = cmd.data * 1000; + + return ret; +} + +static int rpmh_regulator_vrm_set_value(struct udevice *rdev, + int uv) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + + debug("%s: set_value %d (current %d)\n", rdev->name, uv, vreg->uv); + + if (vreg->enabled == -EINVAL) { + /* + * Cache the voltage and send it later when the regulator is + * enabled or disabled. + */ + vreg->uv = uv; + return 0; + } + + return _rpmh_regulator_vrm_set_value(rdev, uv, + uv > vreg->uv); +} + +static int rpmh_regulator_vrm_get_value(struct udevice *rdev) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + + debug("%s: get_value %d\n", rdev->name, vreg->uv); + + return vreg->uv; +} + +static int rpmh_regulator_is_enabled(struct udevice *rdev) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + + debug("%s: is_enabled %d\n", rdev->name, vreg->enabled); + + return vreg->enabled > 0; +} + +static int rpmh_regulator_set_enable_state(struct udevice *rdev, + bool enable) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + struct tcs_cmd cmd = { + .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE, + .data = enable, + }; + int ret; + + debug("%s: set_enable %d (current %d)\n", rdev->name, enable, + vreg->enabled); + + if (vreg->enabled == -EINVAL && + vreg->uv != -ENOTRECOVERABLE) { + ret = _rpmh_regulator_vrm_set_value(rdev, + vreg->uv, true); + if (ret < 0) + return ret; + } + + ret = rpmh_regulator_send_request(vreg, &cmd, enable); + if (!ret) + vreg->enabled = enable; + + return ret; +} + +static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg, + unsigned int mode, bool bypassed) +{ + struct tcs_cmd cmd = { + .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE, + }; + struct dm_regulator_mode *pmic_mode; + int i; + + if (mode > REGULATOR_MODE_HPM) + return -EINVAL; + + for (i = 0; i < vreg->hw_data->n_modes; i++) { + pmic_mode = &vreg->hw_data->pmic_mode_map[i]; + if (pmic_mode->id == mode) + break; + } + if (pmic_mode->id != mode) { + printf("Invalid mode %d\n", mode); + return -EINVAL; + } + + if (bypassed) + cmd.data = PMIC4_BOB_MODE_PASS; + else + cmd.data = pmic_mode->id; + + return rpmh_regulator_send_request(vreg, &cmd, true); +} + +static int rpmh_regulator_vrm_set_mode(struct udevice *rdev, + int mode) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + int ret; + + debug("%s: set_mode %d (current %d)\n", rdev->name, mode, vreg->mode); + + if (mode == vreg->mode) + return 0; + + ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed); + if (!ret) + vreg->mode = mode; + + return ret; +} + +static int rpmh_regulator_vrm_get_mode(struct udevice *rdev) +{ + struct rpmh_vreg *vreg = dev_get_priv(rdev); + + debug("%s: get_mode %d\n", rdev->name, vreg->mode); + + return vreg->mode; +} + +static const struct dm_regulator_ops rpmh_regulator_vrm_drms_ops = { + .get_value = rpmh_regulator_vrm_get_value, + .set_value = rpmh_regulator_vrm_set_value, + .set_enable = rpmh_regulator_set_enable_state, + .get_enable = rpmh_regulator_is_enabled, + .set_mode = rpmh_regulator_vrm_set_mode, + .get_mode = rpmh_regulator_vrm_get_mode, +}; + +static struct dm_regulator_mode pmic_mode_map_pmic5_ldo[] = { + { + .id = REGULATOR_MODE_RETENTION, + .register_value = PMIC5_LDO_MODE_RETENTION, + .name = "PMIC5_LDO_MODE_RETENTION" + }, { + .id = REGULATOR_MODE_LPM, + .register_value = PMIC5_LDO_MODE_LPM, + .name = "PMIC5_LDO_MODE_LPM" + }, { + .id = REGULATOR_MODE_HPM, + .register_value = PMIC5_LDO_MODE_HPM, + .name = "PMIC5_LDO_MODE_HPM" + }, +}; + +static const struct rpmh_vreg_hw_data pmic5_pldo_lv = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000), + .n_voltages = 63, + .hpm_min_load_uA = 10000, + .pmic_mode_map = pmic_mode_map_pmic5_ldo, +}; + +static const struct rpmh_vreg_hw_data pmic5_pldo = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000), + .n_voltages = 256, + .hpm_min_load_uA = 10000, + .pmic_mode_map = pmic_mode_map_pmic5_ldo, + .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo), +}; + +#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \ +{ \ + .name = _name, \ + .resource_name = _resource_name, \ + .hw_data = _hw_data, \ + .supply_name = _supply_name, \ +} + +static const struct rpmh_vreg_init_data pm8150_vreg_data[] = { + RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"), +}; + +static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = { + RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo_lv, "vdd-l1-l8"), + RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l7-l11"), + {} +}; + +/* probe an individual regulator */ +static int rpmh_regulator_probe(struct udevice *dev) +{ + const struct rpmh_vreg_init_data *init_data; + struct rpmh_vreg *priv; + struct dm_regulator_uclass_plat *plat_data; + + init_data = (const struct rpmh_vreg_init_data *)dev_get_driver_data(dev); + priv = dev_get_priv(dev); + plat_data = dev_get_uclass_plat(dev); + + priv->dev = dev; + priv->addr = cmd_db_read_addr(dev->name); + if (!priv->addr) { + dev_err(dev, "Failed to read RPMh address for %s\n", dev->name); + return -ENODEV; + } + + priv->hw_data = init_data->hw_data; + priv->enabled = -EINVAL; + priv->uv = -ENOTRECOVERABLE; + if (ofnode_read_u32(dev_ofnode(dev), "regulator-initial-mode", &priv->mode)) + priv->mode = -EINVAL; + + plat_data->mode = priv->hw_data->pmic_mode_map; + plat_data->mode_count = priv->hw_data->n_modes; + + return 0; +} + +/* for non-drm, xob, or bypass regulators add additional driver definitions */ +U_BOOT_DRIVER(rpmh_regulator_drm) = { + .name = "rpmh_regulator_drm", + .id = UCLASS_REGULATOR, + .probe = rpmh_regulator_probe, + .priv_auto = sizeof(struct rpmh_vreg), + .ops = &rpmh_regulator_vrm_drms_ops, +}; + +/* This driver intentionally only supports a subset of the available regulators. + * This function checks to see if a given regulator node in DT matches a regulator + * defined in the driver. + */ +static const struct rpmh_vreg_init_data * +vreg_get_init_data(const struct rpmh_vreg_init_data *init_data, ofnode node) +{ + const struct rpmh_vreg_init_data *data; + + for (data = init_data; data->name; data++) { + if (!strcmp(data->name, ofnode_get_name(node))) + return data; + } + + return NULL; +} + +static int rpmh_regulators_bind(struct udevice *dev) +{ + const struct rpmh_vreg_init_data *init_data, *data; + const char *pmic_id; + char *name; + struct driver *drv; + ofnode node; + int ret; + size_t namelen; + + init_data = (const struct rpmh_vreg_init_data *)dev_get_driver_data(dev); + if (!init_data) { + dev_err(dev, "No RPMh regulator init data\n"); + return -ENODEV; + } + + pmic_id = ofnode_read_string(dev_ofnode(dev), "qcom,pmic-id"); + if (!pmic_id) { + dev_err(dev, "No PMIC ID\n"); + return -ENODEV; + } + + drv = lists_driver_lookup_name("rpmh_regulator_drm"); + + ofnode_for_each_subnode(node, dev_ofnode(dev)) { + data = vreg_get_init_data(init_data, node); + if (!data) + continue; + + /* %s is replaced with pmic_id, so subtract 2, then add 1 for the null terminator */ + namelen = strlen(data->resource_name) + strlen(pmic_id) - 1; + name = devm_kzalloc(dev, namelen, GFP_KERNEL); + ret = snprintf(name, namelen, data->resource_name, pmic_id); + if (ret < 0 || ret >= namelen) { + dev_err(dev, "Failed to create RPMh regulator name\n"); + return -ENOMEM; + } + + ret = device_bind_with_driver_data(dev, drv, name, (ulong)data, + node, NULL); + if (ret < 0) { + dev_err(dev, "Failed to bind RPMh regulator %s: %d\n", name, ret); + return ret; + } + } + + return 0; +} + +static const struct udevice_id rpmh_regulator_ids[] = { + { + .compatible = "qcom,pm8150-rpmh-regulators", + .data = (ulong)pm8150_vreg_data, + }, + { + .compatible = "qcom,pm8150l-rpmh-regulators", + .data = (ulong)pm8150l_vreg_data, + }, + { /* sentinal */ }, +}; + +/* Driver for a 'bank' of regulators. This creates devices for each + * individual regulator + */ +U_BOOT_DRIVER(rpmh_regulators) = { + .name = "rpmh_regulators", + .id = UCLASS_MISC, + .bind = rpmh_regulators_bind, + .of_match = rpmh_regulator_ids, + .ops = &rpmh_regulator_vrm_drms_ops, +}; From patchwork Mon Jul 8 11:32:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Connolly X-Patchwork-Id: 811190 Delivered-To: patch@linaro.org Received: by 2002:adf:a199:0:b0:367:895a:4699 with SMTP id u25csp2687537wru; Mon, 8 Jul 2024 04:33:57 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUHsTiNTf5JQAf1q8u4XxLuf+/kg7jNr0NGm0A1NFqWWOWwgpqLtYJaocjokH0pY8mE5qWsZV88nGpnT6nTl8hB X-Google-Smtp-Source: AGHT+IEmV8rIZa3bgTuIGQnTx0liEjv/MWfJC/oPxcOurNcpnRaqpHympuoHCHt/YHMVF1imAbOm X-Received: by 2002:a17:906:378a:b0:a77:bfcb:24fa with SMTP id a640c23a62f3a-a77bfcb2553mr907701566b.25.1720438436967; Mon, 08 Jul 2024 04:33:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720438436; cv=none; d=google.com; s=arc-20160816; b=H9VpF8PYPqsPkqS0VrExC9YMNU5wIlmeqJYSQdCRO5pKDP0EsRfZBaRLiN3SZaUPrI 3ClNUuYILp0soWpr7dP6wZOmh/zcBPOCOQiH3PDaSh/Pvz+7o5O+ZLt333pibg3Symtf 2cgWxCxYUJvZotWj3ANgoK8Mr0cQKzE4HjqEUhceyal4iRQv/c7MbvhEuptZE9zw6cUj ENEUv6Bry1uEsfsmJ0yVw+7fpw9OHCXZf4dcPg7fSq9OQ5ZXI4bOS/QfT022XZQvhXDJ ErJVQdx5tTqjwlOSiWIOK3y107VTg45lKJVLklDK58qUx+VFFGQZdgtu/AM0AmYtW6gJ AK3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:cc:to:in-reply-to:references :message-id:content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=nIIvJbrAbNJRYWo+J18YgLbk7RXm9zDJv7nP2Beyq5g=; fh=/XivWHF+vo8fEJZkIifbJJS5exQ4Pz1Cdxakj2MFy4s=; b=R2aN8u75LXXj1McKxAuNWOXaKBk5uAfDtviqYnbDwFguMw5fx+HZGD67s3Xf+X4ujk ehaCuyS7Le4qv+oJHKleiYdhqF2H0EMdSHpgvT8zxOLXOwl7SCBzQHeF9PFCGiHw9XCt 7fPtPJQv46MUA/gNCY29xBp0+xUufzwZCIPKTxsZK/5hxd8WyRdz47R8Tx59BqJzelzb BnLDPsguCMNij4TYNUnwxZhKcvWghQiBCvyoI90LIiSq12jiPTinprWPK8y0X8aZnOQG pzK1osuBkM34MY5YzQdCGwC2+ZSE7AdVvy6mcZPAH32APbkR5WPtZLeSIJ4JadomqZ2V zo1g==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=w6sGY1nw; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id a640c23a62f3a-a77cba483d5si369170966b.222.2024.07.08.04.33.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:56 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=w6sGY1nw; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1A756886DB; Mon, 8 Jul 2024 13:33:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="w6sGY1nw"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D459788703; Mon, 8 Jul 2024 13:33:14 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, UPPERCASE_50_75 autolearn=no autolearn_force=no version=3.4.2 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7A065886E8 for ; Mon, 8 Jul 2024 13:33:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=caleb.connolly@linaro.org Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-a77cc73d35fso455910766b.0 for ; Mon, 08 Jul 2024 04:33:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1720438391; x=1721043191; darn=lists.denx.de; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=nIIvJbrAbNJRYWo+J18YgLbk7RXm9zDJv7nP2Beyq5g=; b=w6sGY1nwNhpadq+qILH41q6dZ/3FOvKcO4Ae1hsCL/ocTPkhRqr4HezpfDTus+D24c oFL3tg2vXQ9I/4ciM42b/PvMOhEZemkzVs7Gzn1cHq+IwPZeyGWEzthV1iiTYbSQldrQ 0QEoOMgTO3jluxbpjAaOAn6Zc6+Fia0ig8GsGQDEl+TrLeUcmQEkXEo3uzkobwVJCVij rzekf8+mKo0GkCc3HeEMGznWdTZRpgvsV4t4PqJUOgd18J6vVyx157Z4/1C9p7G1COMJ QfoIY89l1xwWtKhBdCuMbDphkDKkj2rDHjfpkgXKiJ1tHhWSU2wXfibtqG7mc3J+G5To Y+qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720438391; x=1721043191; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nIIvJbrAbNJRYWo+J18YgLbk7RXm9zDJv7nP2Beyq5g=; b=Rx+dqi0EoEggYs719dlkn9OI3WKIeSXOg4Z9tlNtk1MpdaqPq/DitAfyK0JRXFXFlX eLFV/pJ7P0lF19BKDA+4FL2aoQRz0HcV6oQ5hf2whvKbs3iP0KWgFm4Ay7bTakYLntQJ 2rp2fBbVj6aptYLpgA7c0nbIAPrIeFTpHl3/aUJmimr3Kl8hZeML3L0FFmcKUSUk5jju lacioHiheACgIR+xm1v10j69tX8kBhF1a/YLhr3ZUwqTt5tS7eZnVvwXbmJRIUgj6cdi OQfp2xuwzu3iXOVR88Dw22sHSlUqsNjNLxMfVFID2tqWmANmCEKZ8ERJ9i/gftOrlJLk dV3g== X-Gm-Message-State: AOJu0Yyc/N4LpO7WPT7IFq1D9vzCOnFyP7KLrYp5I5bLvWB2c/cCRq1b uI4SXBch0W+6wDriDIdzsKktQ6k957GW5WZjqknwj4wrbKfKBoj/Mc4vxDhqUBFf2dfIZuvd1Nh g3/c= X-Received: by 2002:a17:906:2bc2:b0:a77:dd70:a161 with SMTP id a640c23a62f3a-a77dd70a6d8mr604558966b.10.1720438390782; Mon, 08 Jul 2024 04:33:10 -0700 (PDT) Received: from [192.168.0.113] ([2a02:8109:aa0d:be00::18f8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a77c9925463sm303628466b.69.2024.07.08.04.33.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jul 2024 04:33:10 -0700 (PDT) From: Caleb Connolly Date: Mon, 08 Jul 2024 13:32:56 +0200 Subject: [PATCH v2 4/4] qcom_defconfig: enable rpmh regulators MIME-Version: 1.0 Message-Id: <20240708-b4-qcom-rpmh-v2-4-8bc765606e56@linaro.org> References: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> In-Reply-To: <20240708-b4-qcom-rpmh-v2-0-8bc765606e56@linaro.org> To: Tom Rini , Caleb Connolly , Neil Armstrong , Sumit Garg , Jaehoon Chung Cc: u-boot@lists.denx.de, u-boot-qcom@groups.io X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1022; i=caleb.connolly@linaro.org; h=from:subject:message-id; bh=gRFw9sllDNNt4nSyWXUL+01p1obRypQjKFtWQBwneRw=; b=owEBbQKS/ZANAwAIAQWDMSsZX2S2AcsmYgBmi85wl461iyakkFwvvG+IZdicpOTSKg5BvK4h6 iyuCGisOTCJAjMEAAEIAB0WIQS2UaFGPGq+0GkMVc0FgzErGV9ktgUCZovOcAAKCRAFgzErGV9k tmniD/4+YR+2MwjDRZdsfuOXksr7jXMQJRkio985rsaGbOkGrU3PeZD++W8l92onkLUYWXdv0EX QWasrB+63bm2AwtfNz+ptEnJkicvESCCNPFo9xDwJr3NPSagrnfWXDHJxW7lhnwJSseM3uWMFyx 50idHel4O/Bgg3sMflzMl4kdAdj7w8elZBmLjM1H46fKc61ZhS+Fm5Q6JCu91e2buACkfmi5RHu IUL/oNBEltKCjP2GqGkX8uvdp2ddUlZTLIARZRrr587iXXsuHvQHMZUtiqFnnKXcnUs9y7q/avA vlzi3++teV+cWgZ5k+m5zgj9237mX/Tp+kGfG0wdYnuVRZ/cXD4z9Y9vKtu6O069O8IrA1v/Rw9 /LbwP0M3fTRpnd3TuJf96M7khBWecUIADgRIOg9pKJZ2j8zVeRxOaji8XN1j8VUu8kTzw1NchTA 5+op45trj5sRGYqdO2chcFndwydneUXn/fZsoTYeNCl6Nm7YQsgOF6jY4CBAkUd1l7MOEFTa8DR jyL08RDaHJXCsDqMH9nCKeYP9jtyNGAvvZfDz1dOz4iWHxGaXeTID5Ct7AVdtWF/tgfD2WBy7+O 4DU+QBw3WsPLfVtfgzSTkASMnrVxOG/yENB4N2WhSutiAd/qugYWFyTV8aCUDj5+WNbhvfmQdSv YH3p5FftW24YBtw== X-Developer-Key: i=caleb.connolly@linaro.org; a=openpgp; fpr=83B24DA7FE145076BC38BB250CD904EB673A7C47 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.8 at phobos.denx.de X-Virus-Status: Clean Enable RPMh, cmd-db, and RPMh regulators. Additionally enable CMD_REGULATOR for debugging. Signed-off-by: Caleb Connolly --- configs/qcom_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index 60a8e38cc6bb..8a55bb9af708 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -35,8 +35,9 @@ CONFIG_CMD_UFS=y CONFIG_CMD_USB=y CONFIG_CMD_CAT=y CONFIG_CMD_BMP=y CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_REGULATOR=y CONFIG_CMD_LOG=y CONFIG_OF_LIVE=y CONFIG_BUTTON_QCOM_PMIC=y CONFIG_CLK=y @@ -90,11 +91,15 @@ CONFIG_PINCTRL_QCOM_SM8650=y CONFIG_DM_PMIC=y CONFIG_PMIC_QCOM=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_QCOM_RPMH=y CONFIG_SCSI=y CONFIG_MSM_SERIAL=y CONFIG_MSM_GENI_SERIAL=y +CONFIG_SOC_QCOM=y +CONFIG_QCOM_COMMAND_DB=y +CONFIG_QCOM_RPMH=y CONFIG_SPMI_MSM=y CONFIG_SYSINFO=y CONFIG_SYSINFO_SMBIOS=y CONFIG_USB=y