From patchwork Wed Sep 10 14:40:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anders Berg X-Patchwork-Id: 4878371 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3E72FC0338 for ; Wed, 10 Sep 2014 14:40:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D6C692017A for ; Wed, 10 Sep 2014 14:40:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4EADF20149 for ; Wed, 10 Sep 2014 14:40:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752156AbaIJOkq (ORCPT ); Wed, 10 Sep 2014 10:40:46 -0400 Received: from exprod7og128.obsmtp.com ([64.18.2.121]:35185 "EHLO exprod7og128.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751726AbaIJOko (ORCPT ); Wed, 10 Sep 2014 10:40:44 -0400 Received: from mail-qg0-f44.google.com ([209.85.192.44]) (using TLSv1) by exprod7ob128.postini.com ([64.18.6.12]) with SMTP ID DSNKVBBi7CqyMcOaQRyLsSSGjjgmMoV5qZRn@postini.com; Wed, 10 Sep 2014 07:40:44 PDT Received: by mail-qg0-f44.google.com with SMTP id f51so7198177qge.31 for ; Wed, 10 Sep 2014 07:40:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=xWrUDoZDCgYos5E0zYohB5Qs/L7fDoDfWNLkIPU2Tu0=; b=DONUZf1Cbs77iC6C8C98pj5ISDX7QiMf+9E6zHKzitzjTo2BsQsOr4dAFB/1ncXqPO dn5Nl18jKARW8HqMA9Cxv/Q0ZoTPrBK/5BwbHkf8f/PUB9zKHXFtkA93u/IG7hvPsyfc PrQYtXHYPG+lZbVSAytdMk3q03WWOqe/iyhqpScqeAdqKFlKfW9lUV2yiuGcv5FCCMIo dV2mvEvslVMkPhfO7eR86z7lEL6YebINY1l2hanTotMcUwE/N/yc48QxpSvYb64e14AB 6fiDDT9Kp7EyoxPp5G1KMNmNFjmHLjXHf3U4vqNv4dmcS6Q91gLgvjwv5zLN/R8GWV26 XQ4Q== X-Gm-Message-State: ALoCoQlYxaAqNQJ9HEh+ZQyd9Dc9I3g2Y5Fg80zS9nyPCEoX2o8qevyM9VwGLKCcLE3rkd7Zx3o0ydMSNy1AspXkNrgZlZqMoTIBuT4LUC1KhZVvT+c00uaO7hUfbIl88v0Jtxc3oiOHA21vNyNXm2JRTUG/u9gOHQ== X-Received: by 10.140.108.200 with SMTP id j66mr61295820qgf.43.1410360043707; Wed, 10 Sep 2014 07:40:43 -0700 (PDT) X-Received: by 10.140.108.200 with SMTP id j66mr61295781qgf.43.1410360043493; Wed, 10 Sep 2014 07:40:43 -0700 (PDT) Received: from swsaberg01.lsi.com ([213.121.150.226]) by mx.google.com with ESMTPSA id o92sm6461564qgd.0.2014.09.10.07.40.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 Sep 2014 07:40:43 -0700 (PDT) From: Anders Berg To: Mark Brown , Linus Walleij Cc: linux-arm-kernel@lists.infradead.org, linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, Anders Berg Subject: [PATCH] spi: pl022: Add support for chip select extension Date: Wed, 10 Sep 2014 16:40:30 +0200 Message-Id: <1410360030-26634-1-git-send-email-anders.berg@avagotech.com> X-Mailer: git-send-email 1.9.1 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-9.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for a extended PL022 which has an extra register for controlling up to five chip select signals. This controller is found on the AXM5516 SoC. Unfortunately the PrimeCell identification registers are identical to a standard ARM PL022. To work around this, the peripheral ID must be overridden in the device tree using the "arm,primecell-periphid" property with the value 0x000b6022. Signed-off-by: Anders Berg --- drivers/spi/spi-pl022.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 1189cfd..b395489 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -82,6 +82,7 @@ #define SSP_MIS(r) (r + 0x01C) #define SSP_ICR(r) (r + 0x020) #define SSP_DMACR(r) (r + 0x024) +#define SSP_CSR(r) (r + 0x030) /* vendor extension */ #define SSP_ITCR(r) (r + 0x080) #define SSP_ITIP(r) (r + 0x084) #define SSP_ITOP(r) (r + 0x088) @@ -198,6 +199,12 @@ #define SSP_DMACR_MASK_TXDMAE (0x1UL << 1) /* + * SSP Chip Select Control Register - SSP_CSR + * (vendor extension) + */ +#define SSP_CSR_CSVALUE_MASK (0x1FUL << 0) + +/* * SSP Integration Test control Register - SSP_ITCR */ #define SSP_ITCR_MASK_ITEN (0x1UL << 0) @@ -313,6 +320,7 @@ enum ssp_writing { * @extended_cr: 32 bit wide control register 0 with extra * features and extra features in CR1 as found in the ST variants * @pl023: supports a subset of the ST extensions called "PL023" + * @internal_cs_ctrl: supports chip select control register */ struct vendor_data { int fifodepth; @@ -321,6 +329,7 @@ struct vendor_data { bool extended_cr; bool pl023; bool loopback; + bool internal_cs_ctrl; }; /** @@ -440,9 +449,32 @@ static void null_cs_control(u32 command) pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); } +/** + * internal_cs_control - Control chip select signals via SSP_CSR. + * @pl022: SSP driver private data structure + * @command: select/delect the chip + * + * Used on controller with internal chip select control via SSP_CSR register + * (vendor extension). Each of the 5 LSB in the register controls one chip + * select signal. + */ +static void internal_cs_control(struct pl022 *pl022, u32 command) +{ + u32 tmp; + + tmp = readw(SSP_CSR(pl022->virtbase)); + if (command == SSP_CHIP_SELECT) + tmp &= ~BIT(pl022->cur_cs); + else + tmp |= BIT(pl022->cur_cs); + writew(tmp, SSP_CSR(pl022->virtbase)); +} + static void pl022_cs_control(struct pl022 *pl022, u32 command) { - if (gpio_is_valid(pl022->cur_cs)) + if (pl022->vendor->internal_cs_ctrl) + internal_cs_control(pl022, command); + else if (gpio_is_valid(pl022->cur_cs)) gpio_set_value(pl022->cur_cs, command); else pl022->cur_chip->cs_control(command); @@ -2118,6 +2150,9 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) if (platform_info->num_chipselect && platform_info->chipselects) { for (i = 0; i < num_cs; i++) pl022->chipselects[i] = platform_info->chipselects[i]; + } else if (pl022->vendor->internal_cs_ctrl) { + for (i = 0; i < num_cs; i++) + pl022->chipselects[i] = i; } else if (IS_ENABLED(CONFIG_OF)) { for (i = 0; i < num_cs; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); @@ -2347,6 +2382,7 @@ static struct vendor_data vendor_arm = { .extended_cr = false, .pl023 = false, .loopback = true, + .internal_cs_ctrl = false, }; static struct vendor_data vendor_st = { @@ -2356,6 +2392,7 @@ static struct vendor_data vendor_st = { .extended_cr = true, .pl023 = false, .loopback = true, + .internal_cs_ctrl = false, }; static struct vendor_data vendor_st_pl023 = { @@ -2365,6 +2402,17 @@ static struct vendor_data vendor_st_pl023 = { .extended_cr = true, .pl023 = true, .loopback = false, + .internal_cs_ctrl = false, +}; + +static struct vendor_data vendor_lsi = { + .fifodepth = 8, + .max_bpw = 16, + .unidir = false, + .extended_cr = false, + .pl023 = false, + .loopback = true, + .internal_cs_ctrl = true, }; static struct amba_id pl022_ids[] = { @@ -2398,6 +2446,15 @@ static struct amba_id pl022_ids[] = { .mask = 0xffffffff, .data = &vendor_st_pl023, }, + { + /* + * PL022 variant that has a chip select control register whih + * allows control of 5 output signals nCS[0:4]. + */ + .id = 0x000b6022, + .mask = 0x000fffff, + .data = &vendor_lsi, + }, { 0, 0 }, };