Received: by 10.223.164.202 with SMTP id h10csp2509110wrb; Mon, 27 Nov 2017 18:54:13 -0800 (PST) X-Google-Smtp-Source: AGs4zMZodQwo2fYdm5mwFQx5Nid27/wJZXEzT+WDnagRsFX6Cty0qpWNr4GsDCCHK3qlbceVwjuV X-Received: by 10.84.193.129 with SMTP id f1mr9020207pld.363.1511837653164; Mon, 27 Nov 2017 18:54:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511837653; cv=none; d=google.com; s=arc-20160816; b=CyA0EpRP/lem/Y8zZkbyDcGAxcuJsuEzEe2jikXU3p9W/+sMWqfEwvuLmQEJvUIsQP UXMGS8NzxiKjvYkfOb3xX48eFkJJSZNQA1AwtXvBIIyB9PTLaMm6J5zNYypArXe/WU18 BT/cTjcxVyuO22ElDWP3pDxTdDLe/q5creGwJxtvRp0Y7JOUDsLKBYuvUeq4cIm0ziKN P6XSdohF2XYxgQeIU7g3OipWNB5a8An6QYkCQrPKHCH8NJPGhNRFSIUFx32yKdMgMWTA GMgO5MdOGYQd7r9EC3GvHivLjotE/Y6wDZ7dWDeoCvhVbrf7J3TZ/ea85d3wzgRfHIvS 1QWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :content-language:accept-language:in-reply-to:references:message-id :date:thread-index:thread-topic:subject:cc:to:from:ironport-phdr :dkim-signature:arc-authentication-results; bh=nhcNBc33Zup1sTdJYQOvyJQPbrf7M80YltWd70dxDg0=; b=Ur9+YPZUlQYljPoV/aFZth81ZL3eDjQGNEyTBQpvh+2v/5wVKDko6sVQ2DsZ5xK/+T 3wYWlIEUaf7eE3mXgD1TCM5fUV10AocyfcuTVCQrqlbRTbyBliOSMXu3asJoZyKwfiiy hoyTMtBqfeqlvyIkyVm6lTBCTm+CxSKFVNBlaQnWbihGF1GNzxpJw/HMd5yeNtweJHQB H7h4100l4f4J1KlfWSe3D22eOT+FedmQDN0i87A6fAl+1ATGa5qhK/KMpmGXaF8C3QEK pQ1mRP/Ux+nIVqx+M0D82Mx8iFzGmvalGmtypwjU+6LMA4QlNAvak91pxUUOGrgspmtz ZOGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@dell.com header.s=smtpout header.b=DUNKEg5B; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=dell.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s15si24133257pgc.789.2017.11.27.18.54.01; Mon, 27 Nov 2017 18:54:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@dell.com header.s=smtpout header.b=DUNKEg5B; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=dell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753614AbdK1Cwt (ORCPT + 78 others); Mon, 27 Nov 2017 21:52:49 -0500 Received: from esa3.dell-outbound.iphmx.com ([68.232.153.94]:20811 "EHLO esa3.dell-outbound.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753580AbdK1Cwr (ORCPT ); Mon, 27 Nov 2017 21:52:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=dell.com; i=@dell.com; q=dns/txt; s=smtpout; t=1511837031; x=1543373031; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=siziW/yXeJSzLPsoIEgOJUAtyvjSMP2d2k5M3Dx/pxw=; b=DUNKEg5Bb31Jv/izDa9YQ3+m+IPzJEUhzmPqxjS9UHoynhvd+ri7BPdU j3XxDYqgltbBB6H43eXoU9hE9J9EhR65aDIu8djC0Qps1cZnv/NxoA7TQ GbyyKVZ7P7stfWo3kmCdX3wJVt2KMZVu0705LodCxbUL3NNR7vwlNHFeo w=; IronPort-PHdr: =?us-ascii?q?9a23=3AGqEyAxUBiacyIrM45vsVW6VYv77V8LGtZVwlr6E/?= =?us-ascii?q?grcLSJyIuqrYbBGDt8tkgFKBZ4jH8fUM07OQ6PGwHzRYqb+681k6OKRWUBEEjc?= =?us-ascii?q?hE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRo?= =?us-ascii?q?LerpBIHSk9631+ev8JHPfglEnjSwbLdxIRmssQndqtQdjJd/JKo21hbHuGZDdf?= =?us-ascii?q?5MxWNvK1KTnhL86dm18ZV+7SleuO8v+tBZX6nicKs2UbJXDDI9M2Ao/8LrrgXM?= =?us-ascii?q?TRGO5nQHTGoblAdDDhXf4xH7WpfxtTb6tvZ41SKHM8D6Uaw4VDK/5KptVRTmij?= =?us-ascii?q?oINyQh/W/XlMJ+kb5brhyiqRxxwYHUYZ2aOvVxca7GYdMaXGhBUtpNWyBdH4+x?= =?us-ascii?q?aZYEAeobPeZfqonwv1wDowGgCgm2HuPuyiVEiX3r3aIg1eQsChzJ0xIkH9IKqn?= =?us-ascii?q?jbsNL1NKILXO2z0aLGwzLDb/ZM1jf87ojFah8hofeRXb5qdsrR00YvGgXYhVuT?= =?us-ascii?q?sYzoJzKY2+cXv2SF4edsS/ijh3Mnpgx/uDSj2Nsgh4fRio4I1lzI7zh1zJorKd?= =?us-ascii?q?GiVUJ3fN6pHIFOuyyVOYZ6Wt4uTm5mtSog17ELuJ+2cDIJxZkn3RLTdeCLfomO?= =?us-ascii?q?7xn+TuieOy14i2hgeL+nghay9lWvxfPkW8mv1VZKsjJFkt7RtnARzxDT6taISv?= =?us-ascii?q?96/kq5xzmPzBrc5+FeLU8pi6XbL5ohzqc3lpoOrUTMBSj2mFjwjKCLaEko4Omo?= =?us-ascii?q?6/znYrXjqZ6QLZN7igb7Mqg2m8y/B/o3MhQWUmWa+umwzqPv8EPnTLlQk/E7kq?= =?us-ascii?q?fUvIrEKcgHqKO1GwpV3Zwi6xa7ATemytMYnXwfIVxfZh2HlZLpOlHULP/6EPew?= =?us-ascii?q?mVKsnSx2yP/YOr3hBo/BIWTEkLfkZbp98VJTyBIvzdBD4JJZErUBIPP1Wk/su9?= =?us-ascii?q?3UFxw5PBKuw+bhFtp90pgTWXyAAqCHKqPeq1yI6fw1I+mKeoAVvCzxK/8/5/7h?= =?us-ascii?q?3jcFngpJZ7So6pUabn+QBPlvJ16YZTznhdJHGmFc+kJqRfbshHWLSzhfbTC+Uv?= =?us-ascii?q?R4rmU0Eo+pDofrQoGrnayP2zq9EpRKZ2dATFeWHiG7WZ+DXqJYUC+ION4noyEN?= =?us-ascii?q?U5CtRoslkxqpsVmpmPJcMuPI93hA5trY399v6riLmA=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2E3AABozhxah8uZ6ERcGQEBAQEBAQEBA?= =?us-ascii?q?QEBAQcBAQEBAYQSEIEVB44YjxSBfZZtEIIBCh+BYoM6AoR0PxgBAQEBAQEBAQE?= =?us-ascii?q?BAhABAQEKCwkIKC+COCIRSFgBAQEBAQEjAg1dAQEBAQMaAQxSDAQCAQgRBAEBK?= =?us-ascii?q?AdGCQgCBAENBQgBihmoeTqKegEBAQEBAQEBAgEBAQEBAQEBAQEBHQkBgzCCB4M?= =?us-ascii?q?9AYMrgUmBW4E9HwUMMYVSBZJDjzBTi1yJJ5NXjW2FIYMsgTofggpvgncJgkkQD?= =?us-ascii?q?IFnd4kOgRQBAQE?= X-IPAS-Result: =?us-ascii?q?A2E3AABozhxah8uZ6ERcGQEBAQEBAQEBAQEBAQcBAQEBAYQ?= =?us-ascii?q?SEIEVB44YjxSBfZZtEIIBCh+BYoM6AoR0PxgBAQEBAQEBAQEBAhABAQEKCwkIK?= =?us-ascii?q?C+COCIRSFgBAQEBAQEjAg1dAQEBAQMaAQxSDAQCAQgRBAEBKAdGCQgCBAENBQg?= =?us-ascii?q?BihmoeTqKegEBAQEBAQEBAgEBAQEBAQEBAQEBHQkBgzCCB4M9AYMrgUmBW4E9H?= =?us-ascii?q?wUMMYVSBZJDjzBTi1yJJ5NXjW2FIYMsgTofggpvgncJgkkQDIFnd4kOgRQBAQE?= Received: from esa5.dell-outbound2.iphmx.com ([68.232.153.203]) by esa3.dell-outbound.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2017 20:43:48 -0600 From: Received: from ausc60pc101.us.dell.com ([143.166.85.206]) by esa5.dell-outbound2.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Nov 2017 08:47:48 +0600 X-LoopCount0: from 10.166.135.98 X-IronPort-AV: E=Sophos;i="5.44,466,1505797200"; d="scan'208";a="1183623394" X-DLP: DLP_GlobalPCIDSS To: , , CC: , , Subject: RE: [PATCH v7,2/2] misc: rtsx: Add support for RTS5260 Thread-Topic: [PATCH v7,2/2] misc: rtsx: Add support for RTS5260 Thread-Index: AQHTZ1KM41ePvK7Kz0CRwU4CtnnbV6MpF/eg Date: Tue, 28 Nov 2017 02:52:39 +0000 Message-ID: <8fe09bd00a224b81874b795ef19bf400@KULX13MDC111.APAC.DELL.COM> References: <1511768195-23204-1-git-send-email-rui_feng@realsil.com.cn> In-Reply-To: <1511768195-23204-1-git-send-email-rui_feng@realsil.com.cn> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.102.115.243] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Greg. The patches have been tested basing on V4.15-rc1 successfully. The sdcard function is working well. Tested-by: Perry Yuan Perry=A0 Yuan Dell | Client Software Group | Firmware Principal Engineer -----Original Message----- From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-owner@vger.ke= rnel.org] On Behalf Of rui_feng@realsil.com.cn Sent: Monday, November 27, 2017 3:37 PM To: arnd@arndb.de; gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org; ricky_wu@realtek.com; bristot@redhat.com;= Rui Feng Subject: [PATCH v7,2/2] misc: rtsx: Add support for RTS5260 From: Rui Feng Add support for new chip rts5260. In order to support rts5260, the definitions of some internal registers and= workflow have to be modified and are different from its predecessors and O= CP function is added for RTS5260. So we need this patch to ensure RTS5260 c= an work. Signed-off-by: Rui Feng Reviewed-by: Daniel Bristot de Oliveira --- drivers/misc/cardreader/Kconfig | 2 +- drivers/misc/cardreader/Makefile | 2 +- drivers/misc/cardreader/rts5260.c | 748 +++++++++++++++++++++++++++++++++= ++++ drivers/misc/cardreader/rts5260.h | 45 +++ drivers/misc/cardreader/rtsx= _pcr.c | 123 +++++- drivers/misc/cardreader/rtsx_pcr.h | 10 + include/linux/rtsx_pci.h | 234 +++++++++++- 7 files changed, 1157 insertions(+), 7 deletions(-) create mode 100644 dr= ivers/misc/cardreader/rts5260.c create mode 100644 drivers/misc/cardreader= /rts5260.h diff --git a/drivers/misc/cardreader/Kconfig b/drivers/misc/cardreader/Kcon= fig index e7d835a..69e815e 100644 --- a/drivers/misc/cardreader/Kconfig +++ b/drivers/misc/cardreader/Kconfig @@ -4,7 +4,7 @@ config MISC_RTSX_PCI select MFD_CORE help This supports for Realtek PCI-Express card reader including rts5209, - rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411. + rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260. Realtek card readers support access to many types of memory cards, such as Memory Stick, Memory Stick Pro, Secure Digital and MultiMediaCard. diff --git a/drivers/misc/cardreader/Makefile b/drivers/misc/cardreader/Mak= efile index 78337b2..9fabfcc 100644 --- a/drivers/misc/cardreader/Makefile +++ b/drivers/misc/cardreader/Makefile @@ -1,4 +1,4 @@ -rtsx_pci-objs :=3D rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5= 249.o +rtsx_pci-objs :=3D rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o=20 +rts5249.o rts5260.o =20 obj-$(CONFIG_MISC_RTSX_PCI) +=3D rtsx_pci.o obj-$(CONFIG_MISC_RTSX_USB) +=3D rtsx_usb.o diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rt= s5260.c new file mode 100644 index 0000000..3b30864 --- /dev/null +++ b/drivers/misc/cardreader/rts5260.c @@ -0,0 +1,748 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify=20 +it + * under the terms of the GNU General Public License as published by=20 +the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License=20 +along + * with this program; if not, see . + * + * Author: + * Steven FENG + * Rui FENG + * Wei WANG + */ + +#include +#include +#include + +#include "rts5260.h" +#include "rtsx_pcr.h" + +static u8 rts5260_get_ic_version(struct rtsx_pcr *pcr) { + u8 val; + + rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val); + return val & IC_VERSION_MASK; +} + +static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage) { + u8 driving_3v3[6][3] =3D { + {0x94, 0x94, 0x94}, + {0x11, 0x11, 0x18}, + {0x55, 0x55, 0x5C}, + {0x94, 0x94, 0x94}, + {0x94, 0x94, 0x94}, + {0xFF, 0xFF, 0xFF}, + }; + u8 driving_1v8[6][3] =3D { + {0x9A, 0x89, 0x89}, + {0xC4, 0xC4, 0xC4}, + {0x3C, 0x3C, 0x3C}, + {0x9B, 0x99, 0x99}, + {0x9A, 0x89, 0x89}, + {0xFE, 0xFE, 0xFE}, + }; + u8 (*driving)[3], drive_sel; + + if (voltage =3D=3D OUTPUT_3V3) { + driving =3D driving_3v3; + drive_sel =3D pcr->sd30_drive_sel_3v3; + } else { + driving =3D driving_1v8; + drive_sel =3D pcr->sd30_drive_sel_1v8; + } + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, + 0xFF, driving[drive_sel][0]); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, + 0xFF, driving[drive_sel][1]); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, + 0xFF, driving[drive_sel][2]); +} + +static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) { + u32 reg; + + rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); + pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); + + if (!rtsx_vendor_setting_valid(reg)) { + pcr_dbg(pcr, "skip fetch vendor setting\n"); + return; + } + + pcr->aspm_en =3D rtsx_reg_to_aspm(reg); + pcr->sd30_drive_sel_1v8 =3D rtsx_reg_to_sd30_drive_sel_1v8(reg); + pcr->card_drive_sel &=3D 0x3F; + pcr->card_drive_sel |=3D rtsx_reg_to_card_drive_sel(reg); + + rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); + pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); + pcr->sd30_drive_sel_3v3 =3D rtsx_reg_to_sd30_drive_sel_3v3(reg); + if (rtsx_reg_check_reverse_socket(reg)) + pcr->flags |=3D PCR_REVERSE_SOCKET; +} + +static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8=20 +pm_state) { + /* Set relink_time to 0 */ + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0); + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0); + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, + RELINK_TIME_MASK, 0); + + if (pm_state =3D=3D HOST_ENTER_S3) + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, + D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); + + rtsx_pci_write_register(pcr, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN);=20 +} + +static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr) { + return rtsx_pci_write_register(pcr, OLT_LED_CTL, + LED_SHINE_MASK, LED_SHINE_EN); +} + +static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr) { + return rtsx_pci_write_register(pcr, OLT_LED_CTL, + LED_SHINE_MASK, LED_SHINE_DISABLE); +} + +static int rts5260_turn_on_led(struct rtsx_pcr *pcr) { + return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0, + RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_ON); } + +static int rts5260_turn_off_led(struct rtsx_pcr *pcr) { + return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0, + RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_OFF); } + +/* SD Pull Control Enable: + * SD_DAT[3:0] =3D=3D> pull up + * SD_CD =3D=3D> pull up + * SD_WP =3D=3D> pull up + * SD_CMD =3D=3D> pull up + * SD_CLK =3D=3D> pull down + */ +static const u32 rts5260_sd_pull_ctl_enable_tbl[] =3D { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA), + 0, +}; + +/* SD Pull Control Disable: + * SD_DAT[3:0] =3D=3D> pull down + * SD_CD =3D=3D> pull up + * SD_WP =3D=3D> pull down + * SD_CMD =3D=3D> pull down + * SD_CLK =3D=3D> pull down + */ +static const u32 rts5260_sd_pull_ctl_disable_tbl[] =3D { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), + 0, +}; + +/* MS Pull Control Enable: + * MS CD =3D=3D> pull up + * others =3D=3D> pull down + */ +static const u32 rts5260_ms_pull_ctl_enable_tbl[] =3D { + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +/* MS Pull Control Disable: + * MS CD =3D=3D> pull up + * others =3D=3D> pull down + */ +static const u32 rts5260_ms_pull_ctl_disable_tbl[] =3D { + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr) { + rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK + | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); + rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); + + return 0; +} + +static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card) { + int err =3D 0; + struct rtsx_cr_option *option =3D &pcr->option; + + if (option->ocp_en) + rtsx_pci_enable_ocp(pcr); + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, + DV331812_VDD1, DV331812_VDD1); + err =3D rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); + if (err < 0) + return err; + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0, + RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1, + LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, + DV331812_POWERON, DV331812_POWERON); + err =3D rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); + + msleep(20); + + if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 || + pcr->extra_caps & EXTRA_CAPS_SD_SDR104) + sd_set_sample_push_timing_sd30(pcr); + + /* Initialize SD_CFG1 register */ + rtsx_pci_write_register(pcr, SD_CFG1, 0xFF, + SD_CLK_DIVIDE_128 | SD_20_MODE); + + rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL, + 0xFF, SD20_RX_POS_EDGE); + rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, 0xFF, 0); + rtsx_pci_write_register(pcr, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + + /* Reset SD_CFG3 register */ + rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, 0); + rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG, + SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 | + SD30_CLK_STOP_CFG0, 0); + + rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0); + + return err; +} + +static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8=20 +voltage) { + switch (voltage) { + case OUTPUT_3V3: + rtsx_pci_write_register(pcr, LDO_CONFIG2, + DV331812_VDD1, DV331812_VDD1); + rtsx_pci_write_register(pcr, LDO_DV18_CFG, + DV331812_MASK, DV331812_33); + rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0); + break; + case OUTPUT_1V8: + rtsx_pci_write_register(pcr, LDO_CONFIG2, + DV331812_VDD1, DV331812_VDD1); + rtsx_pci_write_register(pcr, LDO_DV18_CFG, + DV331812_MASK, DV331812_17); + rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, + SD_IO_USING_1V8); + break; + default: + return -EINVAL; + } + + /* set pad drive */ + rtsx_pci_init_cmd(pcr); + rts5260_fill_driving(pcr, voltage); + return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); } + +static void rts5260_stop_cmd(struct rtsx_pcr *pcr) { + rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); + rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); + rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0, + RTS5260_DMA_RST | RTS5260_ADMA3_RST, + RTS5260_DMA_RST | RTS5260_ADMA3_RST); + rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH); } + +static void rts5260_card_before_power_off(struct rtsx_pcr *pcr) { + struct rtsx_cr_option *option =3D &pcr->option; + + rts5260_stop_cmd(pcr); + rts5260_switch_output_voltage(pcr, OUTPUT_3V3); + + if (option->ocp_en) + rtsx_pci_disable_ocp(pcr); +} + +static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card) { + int err =3D 0; + + rts5260_card_before_power_off(pcr); + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1, + LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, + DV331812_POWERON, DV331812_POWEROFF); + err =3D rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); + + return err; +} + +static void rts5260_init_ocp(struct rtsx_pcr *pcr) { + struct rtsx_cr_option *option =3D &pcr->option; + + if (option->ocp_en) { + u8 mask, val; + + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, + RTS5260_DVCC_OCP_EN | + RTS5260_DVCC_OCP_CL_EN, + RTS5260_DVCC_OCP_EN | + RTS5260_DVCC_OCP_CL_EN); + rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, + RTS5260_DVIO_OCP_EN | + RTS5260_DVIO_OCP_CL_EN, + RTS5260_DVIO_OCP_EN | + RTS5260_DVIO_OCP_CL_EN); + + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, + RTS5260_DVCC_OCP_THD_MASK, + option->sd_400mA_ocp_thd); + + rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, + RTS5260_DVIO_OCP_THD_MASK, + RTS5260_DVIO_OCP_THD_350); + + rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG, + RTS5260_DV331812_OCP_THD_MASK, + RTS5260_DV331812_OCP_THD_210); + + mask =3D SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK; + val =3D pcr->hw_param.ocp_glitch; + rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val); + + rtsx_pci_enable_ocp(pcr); + } else { + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, + RTS5260_DVCC_OCP_EN | + RTS5260_DVCC_OCP_CL_EN, 0); + rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, + RTS5260_DVIO_OCP_EN | + RTS5260_DVIO_OCP_CL_EN, 0); + } +} + +static void rts5260_enable_ocp(struct rtsx_pcr *pcr) { + u8 val =3D 0; + + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0); + + val =3D SD_OCP_INT_EN | SD_DETECT_EN; + val |=3D SDVIO_OCP_INT_EN | SDVIO_DETECT_EN; + rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); + rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, + DV3318_DETECT_EN | DV3318_OCP_INT_EN, + DV3318_DETECT_EN | DV3318_OCP_INT_EN); } + +static void rts5260_disable_ocp(struct rtsx_pcr *pcr) { + u8 mask =3D 0; + + mask =3D SD_OCP_INT_EN | SD_DETECT_EN; + mask |=3D SDVIO_OCP_INT_EN | SDVIO_DETECT_EN; + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); + rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, + DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0); + + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, + OC_POWER_DOWN); +} + +int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val) { + return rtsx_pci_read_register(pcr, REG_OCPSTAT, val); } + +int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val) { + return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val); } + +void rts5260_clear_ocpstat(struct rtsx_pcr *pcr) { + u8 mask =3D 0; + u8 val =3D 0; + + mask =3D SD_OCP_INT_CLR | SD_OC_CLR; + mask |=3D SDVIO_OCP_INT_CLR | SDVIO_OC_CLR; + val =3D SD_OCP_INT_CLR | SD_OC_CLR; + val |=3D SDVIO_OCP_INT_CLR | SDVIO_OC_CLR; + + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); + rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, + DV3318_OCP_INT_CLR | DV3318_OCP_CLR, + DV3318_OCP_INT_CLR | DV3318_OCP_CLR); + udelay(10); + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); + rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, + DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0); } + +void rts5260_process_ocp(struct rtsx_pcr *pcr) { + if (!pcr->option.ocp_en) + return; + + rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); + rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2); + if (pcr->card_exist & SD_EXIST) + sd_power_off_card3v3(pcr); + else if (pcr->card_exist & MS_EXIST) + ms_power_off_card3v3(pcr); + + if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) { + if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER | + SDVIO_OC_NOW | SDVIO_OC_EVER)) || + (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) + rtsx_pci_clear_ocpstat(pcr); + pcr->ocp_stat =3D 0; + pcr->ocp_stat2 =3D 0; + } + + if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER | + SDVIO_OC_NOW | SDVIO_OC_EVER)) || + (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) { + if (pcr->card_exist & SD_EXIST) + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); + else if (pcr->card_exist & MS_EXIST) + rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0); + } +} + +int rts5260_init_hw(struct rtsx_pcr *pcr) { + int err; + + rtsx_pci_init_ocp(pcr); + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1, + AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE); + /* Rest L1SUB Config */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CLK_FORCE_CTL, + CLK_PM_EN, CLK_PM_EN); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWD_SUSPEND_EN, 0xFF, 0xFF); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + PWR_GATE_EN, PWR_GATE_EN); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, REG_VREF, + PWD_SUSPND_EN, PWD_SUSPND_EN); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RBCTL, + U_AUTO_DMA_EN_MASK, U_AUTO_DMA_DISABLE); + + if (pcr->flags & PCR_REVERSE_SOCKET) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0); + else + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, + OBFF_EN_MASK, OBFF_DISABLE); + + err =3D rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); + if (err < 0) + return err; + + return 0; +} + +static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) { + int lss_l1_1, lss_l1_2; + + lss_l1_1 =3D rtsx_check_dev_flag(pcr, ASPM_L1_1_EN) + | rtsx_check_dev_flag(pcr, PM_L1_1_EN); + lss_l1_2 =3D rtsx_check_dev_flag(pcr, ASPM_L1_2_EN) + | rtsx_check_dev_flag(pcr, PM_L1_2_EN); + + if (lss_l1_2) { + pcr_dbg(pcr, "Set parameters for L1.2."); + rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, + 0xFF, PCIE_L1_2_EN); + rtsx_pci_write_register(pcr, PWR_FE_CTL, + 0xFF, PCIE_L1_2_PD_FE_EN); + } else if (lss_l1_1) { + pcr_dbg(pcr, "Set parameters for L1.1."); + rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, + 0xFF, PCIE_L1_1_EN); + rtsx_pci_write_register(pcr, PWR_FE_CTL, + 0xFF, PCIE_L1_1_PD_FE_EN); + } else { + pcr_dbg(pcr, "Set parameters for L1."); + rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, + 0xFF, PCIE_L1_0_EN); + rtsx_pci_write_register(pcr, PWR_FE_CTL, + 0xFF, PCIE_L1_0_PD_FE_EN); + } + + rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE, + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); + rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE, + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE, + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE, + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); + rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE, + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); + /*Option cut APHY*/ + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0, + 0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT); + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1, + 0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT); + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2, + 0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT); + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3, + 0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT); + /*CDR DEC*/ + rtsx_pci_write_register(pcr, PWC_CDR, 0xFF, PWC_CDR_DEFAULT); + /*PWMPFM*/ + rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE, + 0xFF, CFG_LP_FPWM_VALUE_DEFAULT); + /*No Power Saving WA*/ + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_MISC_RET_VALUE, + 0xFF, CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT); +} + +static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) { + struct rtsx_cr_option *option =3D &pcr->option; + u32 lval; + + rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_5260, &lval); + + if (lval & ASPM_L1_1_EN_MASK) + rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); + + if (lval & ASPM_L1_2_EN_MASK) + rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); + + if (lval & PM_L1_1_EN_MASK) + rtsx_set_dev_flag(pcr, PM_L1_1_EN); + + if (lval & PM_L1_2_EN_MASK) + rtsx_set_dev_flag(pcr, PM_L1_2_EN); + + rts5260_pwr_saving_setting(pcr); + + if (option->ltr_en) { + u16 val; + + pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); + if (val & PCI_EXP_DEVCTL2_LTR_EN) { + option->ltr_enabled =3D true; + option->ltr_active =3D true; + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); + } else { + option->ltr_enabled =3D false; + } + } + + if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN + | PM_L1_1_EN | PM_L1_2_EN)) + option->force_clkreq_0 =3D false; + else + option->force_clkreq_0 =3D true; +} + +static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) { + struct rtsx_cr_option *option =3D &pcr->option; + + /* Set mcu_cnt to 7 to ensure data can be sampled properly */ + rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); + rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D); + + rts5260_init_from_cfg(pcr); + + /* force no MDIO*/ + rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4, + 0xFF, RTS5260_MIMO_DISABLE); + /*Modify SDVCC Tune Default Parameters!*/ + rtsx_pci_write_register(pcr, LDO_VCC_CFG0, + RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); + + rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); + + rts5260_init_hw(pcr); + + /* + * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced + * to drive low, and we forcibly request clock. + */ + if (option->force_clkreq_0) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); + else + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); + + return 0; +} + +void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable) { + struct rtsx_cr_option *option =3D &pcr->option; + u8 val =3D 0; + + if (pcr->aspm_enabled =3D=3D enable) + return; + + if (option->dev_aspm_mode =3D=3D DEV_ASPM_DYNAMIC) { + if (enable) + val =3D pcr->aspm_en; + rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL, + ASPM_MASK_NEG, val); + } else if (option->dev_aspm_mode =3D=3D DEV_ASPM_BACKDOOR) { + u8 mask =3D FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0; + + if (!enable) + val =3D FORCE_ASPM_CTL0; + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); + } + + pcr->aspm_enabled =3D enable; +} + +static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int=20 +active) { + struct rtsx_cr_option *option =3D &pcr->option; + u32 interrupt =3D rtsx_pci_readl(pcr, RTSX_BIPR); + int card_exist =3D (interrupt & SD_EXIST) | (interrupt & MS_EXIST); + int aspm_L1_1, aspm_L1_2; + u8 val =3D 0; + + aspm_L1_1 =3D rtsx_check_dev_flag(pcr, ASPM_L1_1_EN); + aspm_L1_2 =3D rtsx_check_dev_flag(pcr, ASPM_L1_2_EN); + + if (active) { + /* run, latency: 60us */ + if (aspm_L1_1) + val =3D option->ltr_l1off_snooze_sspwrgate; + } else { + /* l1off, latency: 300us */ + if (aspm_L1_2) + val =3D option->ltr_l1off_sspwrgate; + } + + if (aspm_L1_1 || aspm_L1_2) { + if (rtsx_check_dev_flag(pcr, + LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) { + if (card_exist) + val &=3D ~L1OFF_MBIAS2_EN_5250; + else + val |=3D L1OFF_MBIAS2_EN_5250; + } + } + rtsx_set_l1off_sub(pcr, val); +} + +static const struct pcr_ops rts5260_pcr_ops =3D { + .fetch_vendor_settings =3D rtsx_base_fetch_vendor_settings, + .turn_on_led =3D rts5260_turn_on_led, + .turn_off_led =3D rts5260_turn_off_led, + .extra_init_hw =3D rts5260_extra_init_hw, + .enable_auto_blink =3D rtsx_base_enable_auto_blink, + .disable_auto_blink =3D rtsx_base_disable_auto_blink, + .card_power_on =3D rts5260_card_power_on, + .card_power_off =3D rts5260_card_power_off, + .switch_output_voltage =3D rts5260_switch_output_voltage, + .force_power_down =3D rtsx_base_force_power_down, + .stop_cmd =3D rts5260_stop_cmd, + .set_aspm =3D rts5260_set_aspm, + .set_l1off_cfg_sub_d0 =3D rts5260_set_l1off_cfg_sub_d0, + .enable_ocp =3D rts5260_enable_ocp, + .disable_ocp =3D rts5260_disable_ocp, + .init_ocp =3D rts5260_init_ocp, + .process_ocp =3D rts5260_process_ocp, + .get_ocpstat =3D rts5260_get_ocpstat, + .clear_ocpstat =3D rts5260_clear_ocpstat, }; + +void rts5260_init_params(struct rtsx_pcr *pcr) { + struct rtsx_cr_option *option =3D &pcr->option; + struct rtsx_hw_param *hw_param =3D &pcr->hw_param; + + pcr->extra_caps =3D EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; + pcr->num_slots =3D 2; + + pcr->flags =3D 0; + pcr->card_drive_sel =3D RTSX_CARD_DRIVE_DEFAULT; + pcr->sd30_drive_sel_1v8 =3D CFG_DRIVER_TYPE_B; + pcr->sd30_drive_sel_3v3 =3D CFG_DRIVER_TYPE_B; + pcr->aspm_en =3D ASPM_L1_EN; + pcr->tx_initial_phase =3D SET_CLOCK_PHASE(1, 29, 16); + pcr->rx_initial_phase =3D SET_CLOCK_PHASE(24, 6, 5); + + pcr->ic_version =3D rts5260_get_ic_version(pcr); + pcr->sd_pull_ctl_enable_tbl =3D rts5260_sd_pull_ctl_enable_tbl; + pcr->sd_pull_ctl_disable_tbl =3D rts5260_sd_pull_ctl_disable_tbl; + pcr->ms_pull_ctl_enable_tbl =3D rts5260_ms_pull_ctl_enable_tbl; + pcr->ms_pull_ctl_disable_tbl =3D rts5260_ms_pull_ctl_disable_tbl; + + pcr->reg_pm_ctrl3 =3D RTS524A_PM_CTRL3; + + pcr->ops =3D &rts5260_pcr_ops; + + option->dev_flags =3D (LTR_L1SS_PWR_GATE_CHECK_CARD_EN + | LTR_L1SS_PWR_GATE_EN); + option->ltr_en =3D true; + + /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */ + option->ltr_active_latency =3D LTR_ACTIVE_LATENCY_DEF; + option->ltr_idle_latency =3D LTR_IDLE_LATENCY_DEF; + option->ltr_l1off_latency =3D LTR_L1OFF_LATENCY_DEF; + option->dev_aspm_mode =3D DEV_ASPM_DYNAMIC; + option->l1_snooze_delay =3D L1_SNOOZE_DELAY_DEF; + option->ltr_l1off_sspwrgate =3D LTR_L1OFF_SSPWRGATE_5250_DEF; + option->ltr_l1off_snooze_sspwrgate =3D + LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; + + option->ocp_en =3D 1; + if (option->ocp_en) + hw_param->interrupt_en |=3D SD_OC_INT_EN; + hw_param->ocp_glitch =3D SD_OCP_GLITCH_10M | SDVIO_OCP_GLITCH_800U; + option->sd_400mA_ocp_thd =3D RTS5260_DVCC_OCP_THD_550; + option->sd_800mA_ocp_thd =3D RTS5260_DVCC_OCP_THD_970; } diff --git a/drivers/misc/cardreader/rts5260.h b/drivers/misc/cardreader/rt= s5260.h new file mode 100644 index 0000000..53a1411 --- /dev/null +++ b/drivers/misc/cardreader/rts5260.h @@ -0,0 +1,45 @@ +#ifndef __RTS5260_H__ +#define __RTS5260_H__ + +#define RTS5260_DVCC_CTRL 0xFF73 +#define RTS5260_DVCC_OCP_EN (0x01 << 7) +#define RTS5260_DVCC_OCP_THD_MASK (0x07 << 4) +#define RTS5260_DVCC_POWERON (0x01 << 3) +#define RTS5260_DVCC_OCP_CL_EN (0x01 << 2) + +#define RTS5260_DVIO_CTRL 0xFF75 +#define RTS5260_DVIO_OCP_EN (0x01 << 7) +#define RTS5260_DVIO_OCP_THD_MASK (0x07 << 4) +#define RTS5260_DVIO_POWERON (0x01 << 3) +#define RTS5260_DVIO_OCP_CL_EN (0x01 << 2) + +#define RTS5260_DV331812_CFG 0xFF71 +#define RTS5260_DV331812_OCP_EN (0x01 << 7) +#define RTS5260_DV331812_OCP_THD_MASK (0x07 << 4) +#define RTS5260_DV331812_POWERON (0x01 << 3) +#define RTS5260_DV331812_SEL (0x01 << 2) +#define RTS5260_DV331812_VDD1 (0x01 << 2) +#define RTS5260_DV331812_VDD2 (0x00 << 2) + +#define RTS5260_DV331812_OCP_THD_120 (0x00 << 4) +#define RTS5260_DV331812_OCP_THD_140 (0x01 << 4) +#define RTS5260_DV331812_OCP_THD_160 (0x02 << 4) +#define RTS5260_DV331812_OCP_THD_180 (0x03 << 4) +#define RTS5260_DV331812_OCP_THD_210 (0x04 << 4) +#define RTS5260_DV331812_OCP_THD_240 (0x05 << 4) +#define RTS5260_DV331812_OCP_THD_270 (0x06 << 4) +#define RTS5260_DV331812_OCP_THD_300 (0x07 << 4) + +#define RTS5260_DVIO_OCP_THD_250 (0x00 << 4) +#define RTS5260_DVIO_OCP_THD_300 (0x01 << 4) +#define RTS5260_DVIO_OCP_THD_350 (0x02 << 4) +#define RTS5260_DVIO_OCP_THD_400 (0x03 << 4) +#define RTS5260_DVIO_OCP_THD_450 (0x04 << 4) +#define RTS5260_DVIO_OCP_THD_500 (0x05 << 4) +#define RTS5260_DVIO_OCP_THD_550 (0x06 << 4) +#define RTS5260_DVIO_OCP_THD_600 (0x07 << 4) + +#define RTS5260_DVCC_OCP_THD_550 (0x00 << 4) +#define RTS5260_DVCC_OCP_THD_970 (0x05 << 4) + +#endif diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/r= tsx_pcr.c index b60bd2a..99adc67 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -62,6 +62,7 @@ { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { 0, } }; =20 @@ -334,6 +335,9 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8= addr, u16 *val) =20 void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) { + if (pcr->ops->stop_cmd) + return pcr->ops->stop_cmd(pcr); + rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); =20 @@ -826,7 +830,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigne= d int card_clock, return err; =20 /* Wait SSC clock stable */ - udelay(10); + udelay(SSC_CLOCK_STABLE_WAIT); err =3D rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); if (err < 0) return err; @@ -963,6 +967,20 @@ static void rtsx_pci_card_detect(struct work_struct *w= ork) pcr->slots[RTSX_MS_CARD].p_dev); } =20 +void rtsx_pci_process_ocp(struct rtsx_pcr *pcr) { + if (pcr->ops->process_ocp) + pcr->ops->process_ocp(pcr); +} + +int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr) { + if (pcr->option.ocp_en) + rtsx_pci_process_ocp(pcr); + + return 0; +} + static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) { struct rtsx_pcr *pcr =3D dev_id; @@ -987,6 +1005,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) =20 int_reg &=3D (pcr->bier | 0x7FFFFF); =20 + if (int_reg & SD_OC_INT) + rtsx_pci_process_ocp_interrupt(pcr); + if (int_reg & SD_INT) { if (int_reg & SD_EXIST) { pcr->card_inserted |=3D SD_EXIST; @@ -1119,6 +1140,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr= , u8 pm_state) } #endif =20 +void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr) { + u8 val =3D SD_OCP_INT_EN | SD_DETECT_EN; + + if (pcr->ops->enable_ocp) + pcr->ops->enable_ocp(pcr); + else + rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); + +} + +void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr) { + u8 mask =3D SD_OCP_INT_EN | SD_DETECT_EN; + + if (pcr->ops->disable_ocp) + pcr->ops->disable_ocp(pcr); + else + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); } + +void rtsx_pci_init_ocp(struct rtsx_pcr *pcr) { + if (pcr->ops->init_ocp) { + pcr->ops->init_ocp(pcr); + } else { + struct rtsx_cr_option *option =3D &(pcr->option); + + if (option->ocp_en) { + u8 val =3D option->sd_400mA_ocp_thd; + + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0); + rtsx_pci_write_register(pcr, REG_OCPPARA1, + SD_OCP_TIME_MASK, SD_OCP_TIME_800); + rtsx_pci_write_register(pcr, REG_OCPPARA2, + SD_OCP_THD_MASK, val); + rtsx_pci_write_register(pcr, REG_OCPGLITCH, + SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch); + rtsx_pci_enable_ocp(pcr); + } else { + /* OC power down */ + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, + OC_POWER_DOWN); + } + } +} + +int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val) { + if (pcr->ops->get_ocpstat) + return pcr->ops->get_ocpstat(pcr, val); + else + return rtsx_pci_read_register(pcr, REG_OCPSTAT, val); } + +void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr) { + if (pcr->ops->clear_ocpstat) { + pcr->ops->clear_ocpstat(pcr); + } else { + u8 mask =3D SD_OCP_INT_CLR | SD_OC_CLR; + u8 val =3D SD_OCP_INT_CLR | SD_OC_CLR; + + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); + } +} + +int sd_power_off_card3v3(struct rtsx_pcr *pcr) { + rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN | + MS_CLK_EN | SD40_CLK_EN, 0); + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); + + rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); + + msleep(50); + + rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD); + + return 0; +} + +int ms_power_off_card3v3(struct rtsx_pcr *pcr) { + rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN | + MS_CLK_EN | SD40_CLK_EN, 0); + + rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD); + + rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0); + rtsx_pci_card_power_off(pcr, RTSX_MS_CARD); + + return 0; +} + static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) { int err; @@ -1189,6 +1306,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) case PID_5250: case PID_524A: case PID_525A: + case PID_5260: rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1); break; default: @@ -1265,6 +1383,9 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) case 0x5286: rtl8402_init_params(pcr); break; + case 0x5260: + rts5260_init_params(pcr); + break; } =20 pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n", diff --git a/drivers/mi= sc/cardreader/rtsx_pcr.h b/drivers/misc/cardreader/rtsx_pcr.h index b0691c9..c544e35 100644 --- a/drivers/misc/cardreader/rtsx_pcr.h +++ b/drivers/misc/cardreader/rtsx_pcr.h @@ -44,6 +44,8 @@ #define ASPM_MASK_NEG 0xFC #define MASK_8_BIT_DEF 0xFF =20 +#define SSC_CLOCK_STABLE_WAIT 130 + int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);= int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)= ; =20 @@ -57,6 +59,7 @@ void rts524a_init_params(struct rtsx_pcr *pcr); void rts525a_init_params(= struct rtsx_pcr *pcr); void rtl8411b_init_params(struct rtsx_pcr *pcr); +void rts5260_init_params(struct rtsx_pcr *pcr); =20 static inline u8 map_sd_drive(int idx) { @@ -99,5 +102,12 @@ static inline u8 map_sd_drive(int idx) int rtsx_gops_p= m_reset(struct rtsx_pcr *pcr); int rtsx_set_ltr_latency(struct rtsx_pcr *p= cr, u32 latency); int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val); +void rtsx_pci_init_ocp(struct rtsx_pcr *pcr); void=20 +rtsx_pci_disable_ocp(struct rtsx_pcr *pcr); void=20 +rtsx_pci_enable_ocp(struct rtsx_pcr *pcr); int=20 +rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val); void=20 +rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr); int=20 +sd_power_off_card3v3(struct rtsx_pcr *pcr); int=20 +ms_power_off_card3v3(struct rtsx_pcr *pcr); =20 #endif diff --git a/include/linux/rtsx_pci.h b/include/linux/rtsx_pci.h index 82ab= ac7..a44670e 100644 --- a/include/linux/rtsx_pci.h +++ b/include/linux/rtsx_pci.h @@ -203,6 +203,7 @@ #define SD_DDR_MODE 0x04 #define SD_30_MODE 0x08 #define SD_CLK_DIVIDE_MASK 0xC0 +#define SD_MODE_SELECT_MASK 0x0C #define SD_CFG2 0xFDA1 #define SD_CALCULATE_CRC7 0x00 #define SD_NO_CALCULATE_CRC7 0x80 @@ -226,6 +227,7 @@ #define SD_RSP_TYPE_R6 0x01 #define SD_RSP_TYPE_R7 0x01 #define SD_CFG3 0xFDA2 +#define SD30_CLK_END_EN 0x10 #define SD_RSP_80CLK_TIMEOUT_EN 0x01 =20 #define SD_STAT1 0xFDA3 @@ -309,6 +311,12 @@ =20 #define SD_DATA_STATE 0xFDB6 #define SD_DATA_IDLE 0x80 +#define REG_SD_STOP_SDCLK_CFG 0xFDB8 +#define SD30_CLK_STOP_CFG_EN 0x04 +#define SD30_CLK_STOP_CFG1 0x02 +#define SD30_CLK_STOP_CFG0 0x01 +#define REG_PRE_RW_MODE 0xFD70 +#define EN_INFINITE_MODE 0x01 =20 #define SRCTL 0xFC13 =20 @@ -434,6 +442,7 @@ #define CARD_CLK_EN 0xFD69 #define SD_CLK_EN 0x04 #define MS_CLK_EN 0x08 +#define SD40_CLK_EN 0x10 #define SDIO_CTRL 0xFD6B #define CD_PAD_CTL 0xFD73 #define CD_DISABLE_MASK 0x07 @@ -453,8 +462,8 @@ #define FPDCTL 0xFC00 #define SSC_POWER_DOWN 0x01 #define SD_OC_POWER_DOWN 0x02 -#define ALL_POWER_DOWN 0x07 -#define OC_POWER_DOWN 0x06 +#define ALL_POWER_DOWN 0x03 +#define OC_POWER_DOWN 0x02 #define PDINFO 0xFC01 =20 #define CLK_CTL 0xFC02 @@ -490,6 +499,9 @@ =20 #define FPGA_PULL_CTL 0xFC1D #define OLT_LED_CTL 0xFC1E +#define LED_SHINE_MASK 0x08 +#define LED_SHINE_EN 0x08 +#define LED_SHINE_DISABLE 0x00 #define GPIO_CTL 0xFC1F =20 #define LDO_CTL 0xFC1E @@ -511,7 +523,11 @@ #define BPP_LDO_ON 0x00 #define BPP_LDO_SUSPEND 0x02 #define BPP_LDO_OFF 0x03 +#define EFUSE_CTL 0xFC30 +#define EFUSE_ADD 0xFC31 #define SYS_VER 0xFC32 +#define EFUSE_DATAL 0xFC34 +#define EFUSE_DATAH 0xFC35 =20 #define CARD_PULL_CTL1 0xFD60 #define CARD_PULL_CTL2 0xFD61 @@ -553,6 +569,9 @@ #define RBBC1 0xFE2F #define RBDAT 0xFE30 #define RBCTL 0xFE34 +#define U_AUTO_DMA_EN_MASK 0x20 +#define U_AUTO_DMA_DISABLE 0x00 +#define RB_FLUSH 0x80 #define CFGADDR0 0xFE35 #define CFGADDR1 0xFE36 #define CFGDATA0 0xFE37 @@ -581,6 +600,8 @@ #define LTR_LATENCY_MODE_HW 0 #define LTR_LATENCY_MODE_SW BIT(6) #define OBFF_CFG 0xFE4C +#define OBFF_EN_MASK 0x03 +#define OBFF_DISABLE 0x00 =20 #define CDRESUMECTL 0xFE52 #define WAKE_SEL_CTL 0xFE54 @@ -595,6 +616,7 @@ #define FORCE_ASPM_L0_EN 0x01 #define FORCE_ASPM_NO_ASPM 0x00 #define PM_CLK_FORCE_CTL 0xFE58 +#define CLK_PM_EN 0x01 #define FUNC_FORCE_CTL 0xFE59 #define FUNC_FORCE_UPME_XMT_DBG 0x02 #define PERST_GLITCH_WIDTH 0xFE5C @@ -620,14 +642,23 @@ #define LDO_PWR_SEL 0xFE78 =20 #define L1SUB_CONFIG1 0xFE8D +#define AUX_CLK_ACTIVE_SEL_MASK 0x01 +#define MAC_CKSW_DONE 0x00 #define L1SUB_CONFIG2 0xFE8E #define L1SUB_AUTO_CFG 0x02 #define L1SUB_CONFIG3 0xFE8F #define L1OFF_MBIAS2_EN_5250 BIT(7) =20 #define DUMMY_REG_RESET_0 0xFE90 +#define IC_VERSION_MASK 0x0F =20 +#define REG_VREF 0xFE97 +#define PWD_SUSPND_EN 0x10 +#define RTS5260_DMA_RST_CTL_0 0xFEBF +#define RTS5260_DMA_RST 0x80 +#define RTS5260_ADMA3_RST 0x40 #define AUTOLOAD_CFG_BASE 0xFF00 +#define RELINK_TIME_MASK 0x01 #define PETXCFG 0xFF03 #define FORCE_CLKREQ_DELINK_MASK BIT(7) #define FORCE_CLKREQ_LOW 0x80 @@ -667,15 +698,24 @@ #define LDO_DV18_CFG 0xFF70 #define LDO_DV18_SR_MASK 0xC0 #define LDO_DV18_SR_DF 0x40 +#define DV331812_MASK 0x70 +#define DV331812_33 0x70 +#define DV331812_17 0x30 =20 #define LDO_CONFIG2 0xFF71 #define LDO_D3318_MASK 0x07 #define LDO_D3318_33V 0x07 #define LDO_D3318_18V 0x02 +#define DV331812_VDD1 0x04 +#define DV331812_POWERON 0x08 +#define DV331812_POWEROFF 0x00 =20 #define LDO_VCC_CFG0 0xFF72 #define LDO_VCC_LMTVTH_MASK 0x30 #define LDO_VCC_LMTVTH_2A 0x10 +/*RTS5260*/ +#define RTS5260_DVCC_TUNE_MASK 0x70 +#define RTS5260_DVCC_33 0x70 =20 #define LDO_VCC_CFG1 0xFF73 #define LDO_VCC_REF_TUNE_MASK 0x30 @@ -684,6 +724,10 @@ #define LDO_VCC_1V8 0x04 #define LDO_VCC_3V3 0x07 #define LDO_VCC_LMT_EN 0x08 +/*RTS5260*/ +#define LDO_POW_SDVDD1_MASK 0x08 +#define LDO_POW_SDVDD1_ON 0x08 +#define LDO_POW_SDVDD1_OFF 0x00 =20 #define LDO_VIO_CFG 0xFF75 #define LDO_VIO_SR_MASK 0xC0 @@ -711,6 +755,160 @@ #define SD_VIO_LDO_1V8 0x40 #define SD_VIO_LDO_3V3 0x70 =20 +#define RTS5260_AUTOLOAD_CFG4 0xFF7F +#define RTS5260_MIMO_DISABLE 0x8A + +#define RTS5260_REG_GPIO_CTL0 0xFC1A +#define RTS5260_REG_GPIO_MASK 0x01 +#define RTS5260_REG_GPIO_ON 0x01 +#define RTS5260_REG_GPIO_OFF 0x00 + +#define PWR_GLOBAL_CTRL 0xF200 +#define PCIE_L1_2_EN 0x0C +#define PCIE_L1_1_EN 0x0A +#define PCIE_L1_0_EN 0x09 +#define PWR_FE_CTL 0xF201 +#define PCIE_L1_2_PD_FE_EN 0x0C +#define PCIE_L1_1_PD_FE_EN 0x0A +#define PCIE_L1_0_PD_FE_EN 0x09 +#define CFG_PCIE_APHY_OFF_0 0xF204 +#define CFG_PCIE_APHY_OFF_0_DEFAULT 0xBF +#define CFG_PCIE_APHY_OFF_1 0xF205 +#define CFG_PCIE_APHY_OFF_1_DEFAULT 0xFF +#define CFG_PCIE_APHY_OFF_2 0xF206 +#define CFG_PCIE_APHY_OFF_2_DEFAULT 0x01 +#define CFG_PCIE_APHY_OFF_3 0xF207 +#define CFG_PCIE_APHY_OFF_3_DEFAULT 0x00 +#define CFG_L1_0_PCIE_MAC_RET_VALUE 0xF20C +#define CFG_L1_0_PCIE_DPHY_RET_VALUE 0xF20E +#define CFG_L1_0_SYS_RET_VALUE 0xF210 +#define CFG_L1_0_CRC_MISC_RET_VALUE 0xF212 +#define CFG_L1_0_CRC_SD30_RET_VALUE 0xF214 +#define CFG_L1_0_CRC_SD40_RET_VALUE 0xF216 +#define CFG_LP_FPWM_VALUE 0xF219 +#define CFG_LP_FPWM_VALUE_DEFAULT 0x18 +#define PWC_CDR 0xF253 +#define PWC_CDR_DEFAULT 0x03 +#define CFG_L1_0_RET_VALUE_DEFAULT 0x1B +#define CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT 0x0C + +/* OCPCTL */ +#define SD_DETECT_EN 0x08 +#define SD_OCP_INT_EN 0x04 +#define SD_OCP_INT_CLR 0x02 +#define SD_OC_CLR 0x01 + +#define SDVIO_DETECT_EN (1 << 7) +#define SDVIO_OCP_INT_EN (1 << 6) +#define SDVIO_OCP_INT_CLR (1 << 5) +#define SDVIO_OC_CLR (1 << 4) + +/* OCPSTAT */ +#define SD_OCP_DETECT 0x08 +#define SD_OC_NOW 0x04 +#define SD_OC_EVER 0x02 + +#define SDVIO_OC_NOW (1 << 6) +#define SDVIO_OC_EVER (1 << 5) + +#define REG_OCPCTL 0xFD6A +#define REG_OCPSTAT 0xFD6E +#define REG_OCPGLITCH 0xFD6C +#define REG_OCPPARA1 0xFD6B +#define REG_OCPPARA2 0xFD6D + +/* rts5260 DV3318 OCP-related registers */ +#define REG_DV3318_OCPCTL 0xFD89 +#define DV3318_OCP_TIME_MASK 0xF0 +#define DV3318_DETECT_EN 0x08 +#define DV3318_OCP_INT_EN 0x04 +#define DV3318_OCP_INT_CLR 0x02 +#define DV3318_OCP_CLR 0x01 + +#define REG_DV3318_OCPSTAT 0xFD8A +#define DV3318_OCP_GlITCH_TIME_MASK 0xF0 +#define DV3318_OCP_DETECT 0x08 +#define DV3318_OCP_NOW 0x04 +#define DV3318_OCP_EVER 0x02 + +#define SD_OCP_GLITCH_MASK 0x0F + +/* OCPPARA1 */ +#define SDVIO_OCP_TIME_60 0x00 +#define SDVIO_OCP_TIME_100 0x10 +#define SDVIO_OCP_TIME_200 0x20 +#define SDVIO_OCP_TIME_400 0x30 +#define SDVIO_OCP_TIME_600 0x40 +#define SDVIO_OCP_TIME_800 0x50 +#define SDVIO_OCP_TIME_1100 0x60 +#define SDVIO_OCP_TIME_MASK 0x70 + +#define SD_OCP_TIME_60 0x00 +#define SD_OCP_TIME_100 0x01 +#define SD_OCP_TIME_200 0x02 +#define SD_OCP_TIME_400 0x03 +#define SD_OCP_TIME_600 0x04 +#define SD_OCP_TIME_800 0x05 +#define SD_OCP_TIME_1100 0x06 +#define SD_OCP_TIME_MASK 0x07 + +/* OCPPARA2 */ +#define SDVIO_OCP_THD_190 0x00 +#define SDVIO_OCP_THD_250 0x10 +#define SDVIO_OCP_THD_320 0x20 +#define SDVIO_OCP_THD_380 0x30 +#define SDVIO_OCP_THD_440 0x40 +#define SDVIO_OCP_THD_500 0x50 +#define SDVIO_OCP_THD_570 0x60 +#define SDVIO_OCP_THD_630 0x70 +#define SDVIO_OCP_THD_MASK 0x70 + +#define SD_OCP_THD_450 0x00 +#define SD_OCP_THD_550 0x01 +#define SD_OCP_THD_650 0x02 +#define SD_OCP_THD_750 0x03 +#define SD_OCP_THD_850 0x04 +#define SD_OCP_THD_950 0x05 +#define SD_OCP_THD_1050 0x06 +#define SD_OCP_THD_1150 0x07 +#define SD_OCP_THD_MASK 0x07 + +#define SDVIO_OCP_GLITCH_MASK 0xF0 +#define SDVIO_OCP_GLITCH_NONE 0x00 +#define SDVIO_OCP_GLITCH_50U 0x10 +#define SDVIO_OCP_GLITCH_100U 0x20 +#define SDVIO_OCP_GLITCH_200U 0x30 +#define SDVIO_OCP_GLITCH_600U 0x40 +#define SDVIO_OCP_GLITCH_800U 0x50 +#define SDVIO_OCP_GLITCH_1M 0x60 +#define SDVIO_OCP_GLITCH_2M 0x70 +#define SDVIO_OCP_GLITCH_3M 0x80 +#define SDVIO_OCP_GLITCH_4M 0x90 +#define SDVIO_OCP_GLIVCH_5M 0xA0 +#define SDVIO_OCP_GLITCH_6M 0xB0 +#define SDVIO_OCP_GLITCH_7M 0xC0 +#define SDVIO_OCP_GLITCH_8M 0xD0 +#define SDVIO_OCP_GLITCH_9M 0xE0 +#define SDVIO_OCP_GLITCH_10M 0xF0 + +#define SD_OCP_GLITCH_MASK 0x0F +#define SD_OCP_GLITCH_NONE 0x00 +#define SD_OCP_GLITCH_50U 0x01 +#define SD_OCP_GLITCH_100U 0x02 +#define SD_OCP_GLITCH_200U 0x03 +#define SD_OCP_GLITCH_600U 0x04 +#define SD_OCP_GLITCH_800U 0x05 +#define SD_OCP_GLITCH_1M 0x06 +#define SD_OCP_GLITCH_2M 0x07 +#define SD_OCP_GLITCH_3M 0x08 +#define SD_OCP_GLITCH_4M 0x09 +#define SD_OCP_GLIVCH_5M 0x0A +#define SD_OCP_GLITCH_6M 0x0B +#define SD_OCP_GLITCH_7M 0x0C +#define SD_OCP_GLITCH_8M 0x0D +#define SD_OCP_GLITCH_9M 0x0E +#define SD_OCP_GLITCH_10M 0x0F + /* Phy register */ #define PHY_PCR 0x00 #define PHY_PCR_FORCE_CODE 0xB000 @@ -857,6 +1055,7 @@ =20 #define PCR_ASPM_SETTING_REG1 0x160 #define PCR_ASPM_SETTING_REG2 0x168 +#define PCR_ASPM_SETTING_5260 0x178 =20 #define PCR_SETTING_REG1 0x724 #define PCR_SETTING_REG2 0x814 @@ -890,6 +1089,7 @@ struct pcr_ops { int (*conv_clk_and_div_n)(int clk, int dir); void (*fetch_vendor_settings)(struct rtsx_pcr *pcr); void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state); + void (*stop_cmd)(struct rtsx_pcr *pcr); =20 void (*set_aspm)(struct rtsx_pcr *pcr, bool enable); int (*set_ltr_latency)(struct rtsx_pcr *pcr, u32 latency); @@ -897,6 +109= 7,12 @@ struct pcr_ops { void (*set_l1off_cfg_sub_d0)(struct rtsx_pcr *pcr, int active); void (*full_on)(struct rtsx_pcr *pcr); void (*power_saving)(struct rtsx_pcr *pcr); + void (*enable_ocp)(struct rtsx_pcr *pcr); + void (*disable_ocp)(struct rtsx_pcr *pcr); + void (*init_ocp)(struct rtsx_pcr *pcr); + void (*process_ocp)(struct rtsx_pcr *pcr); + int (*get_ocpstat)(struct rtsx_pcr *pcr, u8 *val); + void (*clear_ocpstat)(struct rtsx_pcr *pcr); }; =20 enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; @@ -935,6 +1141,9 @@ enum= dev_aspm_mode { * @l1_snooze_delay: l1 snooze delay * @ltr_l1off_sspwrgate: ltr l1off sspwrgate * @ltr_l1off_snooze_sspwrgate: ltr l1off snooze sspwrgate + * @ocp_en: enable ocp flag + * @sd_400mA_ocp_thd: 400mA ocp thd + * @sd_800mA_ocp_thd: 800mA ocp thd */ struct rtsx_cr_option { u32 dev_flags; @@ -949,6 +1158,19 @@ struct rtsx_cr_option { u32 l1_snooze_delay; u8 ltr_l1off_sspwrgate; u8 ltr_l1off_snooze_sspwrgate; + bool ocp_en; + u8 sd_400mA_ocp_thd; + u8 sd_800mA_ocp_thd; +}; + +/* + * struct rtsx_hw_param - card reader hardware param + * @interrupt_en: indicate which interrutp enable + * @ocp_glitch: ocp glitch time + */ +struct rtsx_hw_param { + u32 interrupt_en; + u8 ocp_glitch; }; =20 #define rtsx_set_dev_flag(cr, flag) \ @@ -963,6 +1185,7 @@ struct rtsx_pcr { unsigned int id; int pcie_cap; struct rtsx_cr_option option; + struct rtsx_hw_param hw_param; =20 /* pci resources */ unsigned long addr; @@ -1042,12 +1265,15 @@ struct rtsx_pcr { struct rtsx_slot *slots; =20 u8 dma_error_count; + u8 ocp_stat; + u8 ocp_stat2; }; =20 #define PID_524A 0x524A -#define PID_5249 0x5249 -#define PID_5250 0x5250 +#define PID_5249 0x5249 +#define PID_5250 0x5250 #define PID_525A 0x525A +#define PID_5260 0x5260 =20 #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device =3D=3D (pid)) #define PCI_VID(pcr) ((pcr)->pci->vendor) -- 1.9.1 From 1585203966543511953@xxx Mon Nov 27 07:38:29 +0000 2017 X-GM-THRID: 1585203966543511953 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread