blob: da2bfd5f596deda9206c57455bd5a18c14aef6c7 [file] [log] [blame]
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -07001/*
Subhash Jadavanibe096032017-03-23 12:55:25 -07002 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include "ufshcd.h"
15#include "ufs_quirks.h"
16
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070017static struct ufs_card_fix ufs_fixups[] = {
18 /* UFS cards deviations table */
19 UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ),
20 UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
21 UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS),
22 UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
23 UFS_DEVICE_NO_FASTAUTO),
Kyle Yan65be4a52016-10-31 15:05:00 -070024 UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL,
25 UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE),
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070026 UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG",
27 UFS_DEVICE_QUIRK_PA_TACTIVATE),
28 UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG",
29 UFS_DEVICE_QUIRK_PA_TACTIVATE),
Kyle Yan65be4a52016-10-31 15:05:00 -070030 UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL,
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070031 UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME),
Kyle Yan65be4a52016-10-31 15:05:00 -070032 UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ),
Subhash Jadavanibe096032017-03-23 12:55:25 -070033 UFS_FIX(UFS_VENDOR_SKHYNIX, "hB8aL1",
34 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
35 UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8aL1",
36 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
37 UFS_FIX(UFS_VENDOR_SKHYNIX, "hD8aL1",
38 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
39 UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8aM1",
40 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
41 UFS_FIX(UFS_VENDOR_SKHYNIX, "h08aM1",
42 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
43 UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8GL1",
44 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
45 UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8HL1",
46 UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH),
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070047
48 END_FIX
49};
50
Subhash Jadavani344c16c2016-12-15 17:09:35 -080051void ufs_advertise_fixup_device(struct ufs_hba *hba)
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070052{
53 int err;
Michal' Potomski833ea2a2017-05-31 15:25:11 +053054 u8 str_desc_buf[QUERY_DESC_MAX_SIZE + 1];
Subhash Jadavani344c16c2016-12-15 17:09:35 -080055 char *model;
56 struct ufs_card_fix *f;
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070057
Subhash Jadavani344c16c2016-12-15 17:09:35 -080058 model = kmalloc(MAX_MODEL_LEN + 1, GFP_KERNEL);
59 if (!model)
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070060 goto out;
61
Michal' Potomski833ea2a2017-05-31 15:25:11 +053062 memset(str_desc_buf, 0, QUERY_DESC_MAX_SIZE);
Subhash Jadavani344c16c2016-12-15 17:09:35 -080063 err = ufshcd_read_string_desc(hba, hba->dev_info.i_product_name,
Michal' Potomski833ea2a2017-05-31 15:25:11 +053064 str_desc_buf, QUERY_DESC_MAX_SIZE, ASCII_STD);
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070065 if (err)
66 goto out;
67
Michal' Potomski833ea2a2017-05-31 15:25:11 +053068 str_desc_buf[QUERY_DESC_MAX_SIZE] = '\0';
Subhash Jadavani344c16c2016-12-15 17:09:35 -080069 strlcpy(model, (str_desc_buf + QUERY_DESC_HDR_SIZE),
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070070 min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET],
71 MAX_MODEL_LEN));
72 /* Null terminate the model string */
Subhash Jadavani344c16c2016-12-15 17:09:35 -080073 model[MAX_MODEL_LEN] = '\0';
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070074
75 for (f = ufs_fixups; f->quirk; f++) {
76 /* if same wmanufacturerid */
Subhash Jadavani344c16c2016-12-15 17:09:35 -080077 if (((f->w_manufacturer_id ==
78 hba->dev_info.w_manufacturer_id) ||
79 (f->w_manufacturer_id == UFS_ANY_VENDOR)) &&
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070080 /* and same model */
Subhash Jadavani344c16c2016-12-15 17:09:35 -080081 (STR_PRFX_EQUAL(f->model, model) ||
82 !strcmp(f->model, UFS_ANY_MODEL)))
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070083 /* update quirks */
Subhash Jadavani4f0df17b2016-12-16 13:19:27 -080084 hba->dev_info.quirks |= f->quirk;
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070085 }
86out:
Subhash Jadavani344c16c2016-12-15 17:09:35 -080087 kfree(model);
Subhash Jadavanicce6fbc2016-08-11 11:35:26 -070088}