diff options
author | Micky Ching <micky_ching@realsil.com.cn> | 2015-02-25 00:50:14 -0500 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2015-03-03 11:41:20 -0500 |
commit | 663c425f2c8d87a433629f09c5afd0af7e7e550c (patch) | |
tree | 37bfe278669642440cb5cf05d605f93b66435ec3 | |
parent | 19f3bd548f2750a8a7e4e6d2f25fdc5f8e2c3ee9 (diff) |
mfd: rtsx: Add support for rts524A
add support for new chip rts524A.
Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r-- | drivers/mfd/rts5249.c | 186 | ||||
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 25 | ||||
-rw-r--r-- | drivers/mfd/rtsx_pcr.h | 7 | ||||
-rw-r--r-- | include/linux/mfd/rtsx_pci.h | 132 |
4 files changed, 318 insertions, 32 deletions
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c index 3c77058a70d2..32be803b5327 100644 --- a/drivers/mfd/rts5249.c +++ b/drivers/mfd/rts5249.c | |||
@@ -65,15 +65,17 @@ static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage) | |||
65 | 0xFF, driving[drive_sel][2]); | 65 | 0xFF, driving[drive_sel][2]); |
66 | } | 66 | } |
67 | 67 | ||
68 | static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr) | 68 | static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) |
69 | { | 69 | { |
70 | u32 reg; | 70 | u32 reg; |
71 | 71 | ||
72 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); | 72 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); |
73 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); | 73 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); |
74 | 74 | ||
75 | if (!rtsx_vendor_setting_valid(reg)) | 75 | if (!rtsx_vendor_setting_valid(reg)) { |
76 | pcr_dbg(pcr, "skip fetch vendor setting\n"); | ||
76 | return; | 77 | return; |
78 | } | ||
77 | 79 | ||
78 | pcr->aspm_en = rtsx_reg_to_aspm(reg); | 80 | pcr->aspm_en = rtsx_reg_to_aspm(reg); |
79 | pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg); | 81 | pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg); |
@@ -87,7 +89,7 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr) | |||
87 | pcr->flags |= PCR_REVERSE_SOCKET; | 89 | pcr->flags |= PCR_REVERSE_SOCKET; |
88 | } | 90 | } |
89 | 91 | ||
90 | static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) | 92 | static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) |
91 | { | 93 | { |
92 | /* Set relink_time to 0 */ | 94 | /* Set relink_time to 0 */ |
93 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0); | 95 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0); |
@@ -95,7 +97,8 @@ static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) | |||
95 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0); | 97 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0); |
96 | 98 | ||
97 | if (pm_state == HOST_ENTER_S3) | 99 | if (pm_state == HOST_ENTER_S3) |
98 | rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10); | 100 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, |
101 | D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); | ||
99 | 102 | ||
100 | rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03); | 103 | rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03); |
101 | } | 104 | } |
@@ -104,6 +107,8 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) | |||
104 | { | 107 | { |
105 | rtsx_pci_init_cmd(pcr); | 108 | rtsx_pci_init_cmd(pcr); |
106 | 109 | ||
110 | /* Rest L1SUB Config */ | ||
111 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00); | ||
107 | /* Configure GPIO as output */ | 112 | /* Configure GPIO as output */ |
108 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02); | 113 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02); |
109 | /* Reset ASPM state to default value */ | 114 | /* Reset ASPM state to default value */ |
@@ -189,27 +194,27 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr) | |||
189 | PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12); | 194 | PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12); |
190 | } | 195 | } |
191 | 196 | ||
192 | static int rts5249_turn_on_led(struct rtsx_pcr *pcr) | 197 | static int rtsx_base_turn_on_led(struct rtsx_pcr *pcr) |
193 | { | 198 | { |
194 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02); | 199 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02); |
195 | } | 200 | } |
196 | 201 | ||
197 | static int rts5249_turn_off_led(struct rtsx_pcr *pcr) | 202 | static int rtsx_base_turn_off_led(struct rtsx_pcr *pcr) |
198 | { | 203 | { |
199 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00); | 204 | return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00); |
200 | } | 205 | } |
201 | 206 | ||
202 | static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr) | 207 | static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr) |
203 | { | 208 | { |
204 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08); | 209 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08); |
205 | } | 210 | } |
206 | 211 | ||
207 | static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr) | 212 | static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr) |
208 | { | 213 | { |
209 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00); | 214 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00); |
210 | } | 215 | } |
211 | 216 | ||
212 | static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card) | 217 | static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card) |
213 | { | 218 | { |
214 | int err; | 219 | int err; |
215 | 220 | ||
@@ -236,7 +241,7 @@ static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card) | |||
236 | return 0; | 241 | return 0; |
237 | } | 242 | } |
238 | 243 | ||
239 | static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card) | 244 | static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card) |
240 | { | 245 | { |
241 | rtsx_pci_init_cmd(pcr); | 246 | rtsx_pci_init_cmd(pcr); |
242 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, | 247 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, |
@@ -246,22 +251,35 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card) | |||
246 | return rtsx_pci_send_cmd(pcr, 100); | 251 | return rtsx_pci_send_cmd(pcr, 100); |
247 | } | 252 | } |
248 | 253 | ||
249 | static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | 254 | static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
250 | { | 255 | { |
251 | int err; | 256 | int err; |
257 | u16 append; | ||
252 | 258 | ||
253 | if (voltage == OUTPUT_3V3) { | 259 | switch (voltage) { |
254 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24); | 260 | case OUTPUT_3V3: |
261 | err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK, | ||
262 | PHY_TUNE_VOLTAGE_3V3); | ||
255 | if (err < 0) | 263 | if (err < 0) |
256 | return err; | 264 | return err; |
257 | } else if (voltage == OUTPUT_1V8) { | 265 | break; |
258 | err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02); | 266 | case OUTPUT_1V8: |
267 | append = PHY_TUNE_D18_1V8; | ||
268 | if (CHK_PCI_PID(pcr, 0x5249)) { | ||
269 | err = rtsx_pci_update_phy(pcr, PHY_BACR, | ||
270 | PHY_BACR_BASIC_MASK, 0); | ||
271 | if (err < 0) | ||
272 | return err; | ||
273 | append = PHY_TUNE_D18_1V7; | ||
274 | } | ||
275 | |||
276 | err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK, | ||
277 | append); | ||
259 | if (err < 0) | 278 | if (err < 0) |
260 | return err; | 279 | return err; |
261 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24); | 280 | break; |
262 | if (err < 0) | 281 | default: |
263 | return err; | 282 | pcr_dbg(pcr, "unknown output voltage %d\n", voltage); |
264 | } else { | ||
265 | return -EINVAL; | 283 | return -EINVAL; |
266 | } | 284 | } |
267 | 285 | ||
@@ -272,17 +290,17 @@ static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
272 | } | 290 | } |
273 | 291 | ||
274 | static const struct pcr_ops rts5249_pcr_ops = { | 292 | static const struct pcr_ops rts5249_pcr_ops = { |
275 | .fetch_vendor_settings = rts5249_fetch_vendor_settings, | 293 | .fetch_vendor_settings = rtsx_base_fetch_vendor_settings, |
276 | .extra_init_hw = rts5249_extra_init_hw, | 294 | .extra_init_hw = rts5249_extra_init_hw, |
277 | .optimize_phy = rts5249_optimize_phy, | 295 | .optimize_phy = rts5249_optimize_phy, |
278 | .turn_on_led = rts5249_turn_on_led, | 296 | .turn_on_led = rtsx_base_turn_on_led, |
279 | .turn_off_led = rts5249_turn_off_led, | 297 | .turn_off_led = rtsx_base_turn_off_led, |
280 | .enable_auto_blink = rts5249_enable_auto_blink, | 298 | .enable_auto_blink = rtsx_base_enable_auto_blink, |
281 | .disable_auto_blink = rts5249_disable_auto_blink, | 299 | .disable_auto_blink = rtsx_base_disable_auto_blink, |
282 | .card_power_on = rts5249_card_power_on, | 300 | .card_power_on = rtsx_base_card_power_on, |
283 | .card_power_off = rts5249_card_power_off, | 301 | .card_power_off = rtsx_base_card_power_off, |
284 | .switch_output_voltage = rts5249_switch_output_voltage, | 302 | .switch_output_voltage = rtsx_base_switch_output_voltage, |
285 | .force_power_down = rts5249_force_power_down, | 303 | .force_power_down = rtsx_base_force_power_down, |
286 | }; | 304 | }; |
287 | 305 | ||
288 | /* SD Pull Control Enable: | 306 | /* SD Pull Control Enable: |
@@ -356,4 +374,116 @@ void rts5249_init_params(struct rtsx_pcr *pcr) | |||
356 | pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl; | 374 | pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl; |
357 | pcr->ms_pull_ctl_enable_tbl = rts5249_ms_pull_ctl_enable_tbl; | 375 | pcr->ms_pull_ctl_enable_tbl = rts5249_ms_pull_ctl_enable_tbl; |
358 | pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl; | 376 | pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl; |
377 | |||
378 | pcr->reg_pm_ctrl3 = PM_CTRL3; | ||
379 | } | ||
380 | |||
381 | static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val) | ||
382 | { | ||
383 | addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr; | ||
384 | |||
385 | return __rtsx_pci_write_phy_register(pcr, addr, val); | ||
359 | } | 386 | } |
387 | |||
388 | static int rts524a_read_phy(struct rtsx_pcr *pcr, u8 addr, u16 *val) | ||
389 | { | ||
390 | addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr; | ||
391 | |||
392 | return __rtsx_pci_read_phy_register(pcr, addr, val); | ||
393 | } | ||
394 | |||
395 | static int rts524a_optimize_phy(struct rtsx_pcr *pcr) | ||
396 | { | ||
397 | int err; | ||
398 | |||
399 | err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, | ||
400 | D3_DELINK_MODE_EN, 0x00); | ||
401 | if (err < 0) | ||
402 | return err; | ||
403 | |||
404 | rtsx_pci_write_phy_register(pcr, PHY_PCR, | ||
405 | PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 | | ||
406 | PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 | PHY_PCR_RSSI_EN); | ||
407 | rtsx_pci_write_phy_register(pcr, PHY_SSCCR3, | ||
408 | PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY); | ||
409 | |||
410 | if (is_version(pcr, 0x524A, IC_VER_A)) { | ||
411 | rtsx_pci_write_phy_register(pcr, PHY_SSCCR3, | ||
412 | PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY); | ||
413 | rtsx_pci_write_phy_register(pcr, PHY_SSCCR2, | ||
414 | PHY_SSCCR2_PLL_NCODE | PHY_SSCCR2_TIME0 | | ||
415 | PHY_SSCCR2_TIME2_WIDTH); | ||
416 | rtsx_pci_write_phy_register(pcr, PHY_ANA1A, | ||
417 | PHY_ANA1A_TXR_LOOPBACK | PHY_ANA1A_RXT_BIST | | ||
418 | PHY_ANA1A_TXR_BIST | PHY_ANA1A_REV); | ||
419 | rtsx_pci_write_phy_register(pcr, PHY_ANA1D, | ||
420 | PHY_ANA1D_DEBUG_ADDR); | ||
421 | rtsx_pci_write_phy_register(pcr, PHY_DIG1E, | ||
422 | PHY_DIG1E_REV | PHY_DIG1E_D0_X_D1 | | ||
423 | PHY_DIG1E_RX_ON_HOST | PHY_DIG1E_RCLK_REF_HOST | | ||
424 | PHY_DIG1E_RCLK_TX_EN_KEEP | | ||
425 | PHY_DIG1E_RCLK_TX_TERM_KEEP | | ||
426 | PHY_DIG1E_RCLK_RX_EIDLE_ON | PHY_DIG1E_TX_TERM_KEEP | | ||
427 | PHY_DIG1E_RX_TERM_KEEP | PHY_DIG1E_TX_EN_KEEP | | ||
428 | PHY_DIG1E_RX_EN_KEEP); | ||
429 | } | ||
430 | |||
431 | rtsx_pci_write_phy_register(pcr, PHY_ANA08, | ||
432 | PHY_ANA08_RX_EQ_DCGAIN | PHY_ANA08_SEL_RX_EN | | ||
433 | PHY_ANA08_RX_EQ_VAL | PHY_ANA08_SCP | PHY_ANA08_SEL_IPI); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int rts524a_extra_init_hw(struct rtsx_pcr *pcr) | ||
439 | { | ||
440 | rts5249_extra_init_hw(pcr); | ||
441 | |||
442 | rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, | ||
443 | FORCE_ASPM_L1_EN, FORCE_ASPM_L1_EN); | ||
444 | rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0); | ||
445 | rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_LMT_EN, | ||
446 | LDO_VCC_LMT_EN); | ||
447 | rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); | ||
448 | if (is_version(pcr, 0x524A, IC_VER_A)) { | ||
449 | rtsx_pci_write_register(pcr, LDO_DV18_CFG, | ||
450 | LDO_DV18_SR_MASK, LDO_DV18_SR_DF); | ||
451 | rtsx_pci_write_register(pcr, LDO_VCC_CFG1, | ||
452 | LDO_VCC_REF_TUNE_MASK, LDO_VCC_REF_1V2); | ||
453 | rtsx_pci_write_register(pcr, LDO_VIO_CFG, | ||
454 | LDO_VIO_REF_TUNE_MASK, LDO_VIO_REF_1V2); | ||
455 | rtsx_pci_write_register(pcr, LDO_VIO_CFG, | ||
456 | LDO_VIO_SR_MASK, LDO_VIO_SR_DF); | ||
457 | rtsx_pci_write_register(pcr, LDO_DV12S_CFG, | ||
458 | LDO_REF12_TUNE_MASK, LDO_REF12_TUNE_DF); | ||
459 | rtsx_pci_write_register(pcr, SD40_LDO_CTL1, | ||
460 | SD40_VIO_TUNE_MASK, SD40_VIO_TUNE_1V7); | ||
461 | } | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static const struct pcr_ops rts524a_pcr_ops = { | ||
467 | .write_phy = rts524a_write_phy, | ||
468 | .read_phy = rts524a_read_phy, | ||
469 | .fetch_vendor_settings = rtsx_base_fetch_vendor_settings, | ||
470 | .extra_init_hw = rts524a_extra_init_hw, | ||
471 | .optimize_phy = rts524a_optimize_phy, | ||
472 | .turn_on_led = rtsx_base_turn_on_led, | ||
473 | .turn_off_led = rtsx_base_turn_off_led, | ||
474 | .enable_auto_blink = rtsx_base_enable_auto_blink, | ||
475 | .disable_auto_blink = rtsx_base_disable_auto_blink, | ||
476 | .card_power_on = rtsx_base_card_power_on, | ||
477 | .card_power_off = rtsx_base_card_power_off, | ||
478 | .switch_output_voltage = rtsx_base_switch_output_voltage, | ||
479 | .force_power_down = rtsx_base_force_power_down, | ||
480 | }; | ||
481 | |||
482 | void rts524a_init_params(struct rtsx_pcr *pcr) | ||
483 | { | ||
484 | rts5249_init_params(pcr); | ||
485 | |||
486 | pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3; | ||
487 | pcr->ops = &rts524a_pcr_ops; | ||
488 | } | ||
489 | |||
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 81b9c2c2e0f1..e6d97adcc825 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -58,6 +58,7 @@ static const struct pci_device_id rtsx_pci_ids[] = { | |||
58 | { PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 58 | { PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
59 | { PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 59 | { PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
60 | { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 60 | { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
61 | { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | ||
61 | { 0, } | 62 | { 0, } |
62 | }; | 63 | }; |
63 | 64 | ||
@@ -142,7 +143,7 @@ int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data) | |||
142 | } | 143 | } |
143 | EXPORT_SYMBOL_GPL(rtsx_pci_read_register); | 144 | EXPORT_SYMBOL_GPL(rtsx_pci_read_register); |
144 | 145 | ||
145 | int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) | 146 | int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) |
146 | { | 147 | { |
147 | int err, i, finished = 0; | 148 | int err, i, finished = 0; |
148 | u8 tmp; | 149 | u8 tmp; |
@@ -174,9 +175,17 @@ int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) | |||
174 | 175 | ||
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
178 | |||
179 | int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) | ||
180 | { | ||
181 | if (pcr->ops->write_phy) | ||
182 | return pcr->ops->write_phy(pcr, addr, val); | ||
183 | |||
184 | return __rtsx_pci_write_phy_register(pcr, addr, val); | ||
185 | } | ||
177 | EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register); | 186 | EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register); |
178 | 187 | ||
179 | int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) | 188 | int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) |
180 | { | 189 | { |
181 | int err, i, finished = 0; | 190 | int err, i, finished = 0; |
182 | u16 data; | 191 | u16 data; |
@@ -222,6 +231,14 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) | |||
222 | 231 | ||
223 | return 0; | 232 | return 0; |
224 | } | 233 | } |
234 | |||
235 | int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) | ||
236 | { | ||
237 | if (pcr->ops->read_phy) | ||
238 | return pcr->ops->read_phy(pcr, addr, val); | ||
239 | |||
240 | return __rtsx_pci_read_phy_register(pcr, addr, val); | ||
241 | } | ||
225 | EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register); | 242 | EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register); |
226 | 243 | ||
227 | void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) | 244 | void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) |
@@ -1093,6 +1110,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | |||
1093 | rts5249_init_params(pcr); | 1110 | rts5249_init_params(pcr); |
1094 | break; | 1111 | break; |
1095 | 1112 | ||
1113 | case 0x524A: | ||
1114 | rts524a_init_params(pcr); | ||
1115 | break; | ||
1116 | |||
1096 | case 0x5287: | 1117 | case 0x5287: |
1097 | rtl8411b_init_params(pcr); | 1118 | rtl8411b_init_params(pcr); |
1098 | break; | 1119 | break; |
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h index fe2bbb67defc..e7daf6f54b83 100644 --- a/drivers/mfd/rtsx_pcr.h +++ b/drivers/mfd/rtsx_pcr.h | |||
@@ -27,12 +27,19 @@ | |||
27 | #define MIN_DIV_N_PCR 80 | 27 | #define MIN_DIV_N_PCR 80 |
28 | #define MAX_DIV_N_PCR 208 | 28 | #define MAX_DIV_N_PCR 208 |
29 | 29 | ||
30 | #define RTS524A_PME_FORCE_CTL 0xFF78 | ||
31 | #define RTS524A_PM_CTRL3 0xFF7E | ||
32 | |||
33 | int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val); | ||
34 | int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val); | ||
35 | |||
30 | void rts5209_init_params(struct rtsx_pcr *pcr); | 36 | void rts5209_init_params(struct rtsx_pcr *pcr); |
31 | void rts5229_init_params(struct rtsx_pcr *pcr); | 37 | void rts5229_init_params(struct rtsx_pcr *pcr); |
32 | void rtl8411_init_params(struct rtsx_pcr *pcr); | 38 | void rtl8411_init_params(struct rtsx_pcr *pcr); |
33 | void rtl8402_init_params(struct rtsx_pcr *pcr); | 39 | void rtl8402_init_params(struct rtsx_pcr *pcr); |
34 | void rts5227_init_params(struct rtsx_pcr *pcr); | 40 | void rts5227_init_params(struct rtsx_pcr *pcr); |
35 | void rts5249_init_params(struct rtsx_pcr *pcr); | 41 | void rts5249_init_params(struct rtsx_pcr *pcr); |
42 | void rts524a_init_params(struct rtsx_pcr *pcr); | ||
36 | void rtl8411b_init_params(struct rtsx_pcr *pcr); | 43 | void rtl8411b_init_params(struct rtsx_pcr *pcr); |
37 | 44 | ||
38 | static inline u8 map_sd_drive(int idx) | 45 | static inline u8 map_sd_drive(int idx) |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 33cc63ced99e..754a18d4203a 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
@@ -577,8 +577,16 @@ | |||
577 | 577 | ||
578 | #define CDRESUMECTL 0xFE52 | 578 | #define CDRESUMECTL 0xFE52 |
579 | #define WAKE_SEL_CTL 0xFE54 | 579 | #define WAKE_SEL_CTL 0xFE54 |
580 | #define PCLK_CTL 0xFE55 | ||
581 | #define PCLK_MODE_SEL 0x20 | ||
580 | #define PME_FORCE_CTL 0xFE56 | 582 | #define PME_FORCE_CTL 0xFE56 |
583 | |||
581 | #define ASPM_FORCE_CTL 0xFE57 | 584 | #define ASPM_FORCE_CTL 0xFE57 |
585 | #define FORCE_ASPM_CTL0 0x10 | ||
586 | #define FORCE_ASPM_VAL_MASK 0x03 | ||
587 | #define FORCE_ASPM_L1_EN 0x02 | ||
588 | #define FORCE_ASPM_L0_EN 0x01 | ||
589 | #define FORCE_ASPM_NO_ASPM 0x00 | ||
582 | #define PM_CLK_FORCE_CTL 0xFE58 | 590 | #define PM_CLK_FORCE_CTL 0xFE58 |
583 | #define FUNC_FORCE_CTL 0xFE59 | 591 | #define FUNC_FORCE_CTL 0xFE59 |
584 | #define PERST_GLITCH_WIDTH 0xFE5C | 592 | #define PERST_GLITCH_WIDTH 0xFE5C |
@@ -590,7 +598,8 @@ | |||
590 | #define HOST_ENTER_S3 2 | 598 | #define HOST_ENTER_S3 2 |
591 | 599 | ||
592 | #define SDIO_CFG 0xFE70 | 600 | #define SDIO_CFG 0xFE70 |
593 | 601 | #define PM_EVENT_DEBUG 0xFE71 | |
602 | #define PME_DEBUG_0 0x08 | ||
594 | #define NFTS_TX_CTRL 0xFE72 | 603 | #define NFTS_TX_CTRL 0xFE72 |
595 | 604 | ||
596 | #define PWR_GATE_CTRL 0xFE75 | 605 | #define PWR_GATE_CTRL 0xFE75 |
@@ -602,12 +611,19 @@ | |||
602 | #define PWD_SUSPEND_EN 0xFE76 | 611 | #define PWD_SUSPEND_EN 0xFE76 |
603 | #define LDO_PWR_SEL 0xFE78 | 612 | #define LDO_PWR_SEL 0xFE78 |
604 | 613 | ||
614 | #define L1SUB_CONFIG1 0xFE8D | ||
615 | #define L1SUB_CONFIG2 0xFE8E | ||
616 | #define L1SUB_AUTO_CFG 0x02 | ||
617 | #define L1SUB_CONFIG3 0xFE8F | ||
618 | |||
605 | #define DUMMY_REG_RESET_0 0xFE90 | 619 | #define DUMMY_REG_RESET_0 0xFE90 |
606 | 620 | ||
607 | #define AUTOLOAD_CFG_BASE 0xFF00 | 621 | #define AUTOLOAD_CFG_BASE 0xFF00 |
608 | #define PETXCFG 0xFF03 | 622 | #define PETXCFG 0xFF03 |
609 | 623 | ||
610 | #define PM_CTRL1 0xFF44 | 624 | #define PM_CTRL1 0xFF44 |
625 | #define CD_RESUME_EN_MASK 0xF0 | ||
626 | |||
611 | #define PM_CTRL2 0xFF45 | 627 | #define PM_CTRL2 0xFF45 |
612 | #define PM_CTRL3 0xFF46 | 628 | #define PM_CTRL3 0xFF46 |
613 | #define SDIO_SEND_PME_EN 0x80 | 629 | #define SDIO_SEND_PME_EN 0x80 |
@@ -628,6 +644,61 @@ | |||
628 | #define IMAGE_FLAG_ADDR0 0xCE80 | 644 | #define IMAGE_FLAG_ADDR0 0xCE80 |
629 | #define IMAGE_FLAG_ADDR1 0xCE81 | 645 | #define IMAGE_FLAG_ADDR1 0xCE81 |
630 | 646 | ||
647 | #define RREF_CFG 0xFF6C | ||
648 | #define RREF_VBGSEL_MASK 0x38 | ||
649 | #define RREF_VBGSEL_1V25 0x28 | ||
650 | |||
651 | #define OOBS_CONFIG 0xFF6E | ||
652 | #define OOBS_AUTOK_DIS 0x80 | ||
653 | #define OOBS_VAL_MASK 0x1F | ||
654 | |||
655 | #define LDO_DV18_CFG 0xFF70 | ||
656 | #define LDO_DV18_SR_MASK 0xC0 | ||
657 | #define LDO_DV18_SR_DF 0x40 | ||
658 | |||
659 | #define LDO_CONFIG2 0xFF71 | ||
660 | #define LDO_D3318_MASK 0x07 | ||
661 | #define LDO_D3318_33V 0x07 | ||
662 | #define LDO_D3318_18V 0x02 | ||
663 | |||
664 | #define LDO_VCC_CFG0 0xFF72 | ||
665 | #define LDO_VCC_LMTVTH_MASK 0x30 | ||
666 | #define LDO_VCC_LMTVTH_2A 0x10 | ||
667 | |||
668 | #define LDO_VCC_CFG1 0xFF73 | ||
669 | #define LDO_VCC_REF_TUNE_MASK 0x30 | ||
670 | #define LDO_VCC_REF_1V2 0x20 | ||
671 | #define LDO_VCC_TUNE_MASK 0x07 | ||
672 | #define LDO_VCC_1V8 0x04 | ||
673 | #define LDO_VCC_3V3 0x07 | ||
674 | #define LDO_VCC_LMT_EN 0x08 | ||
675 | |||
676 | #define LDO_VIO_CFG 0xFF75 | ||
677 | #define LDO_VIO_SR_MASK 0xC0 | ||
678 | #define LDO_VIO_SR_DF 0x40 | ||
679 | #define LDO_VIO_REF_TUNE_MASK 0x30 | ||
680 | #define LDO_VIO_REF_1V2 0x20 | ||
681 | #define LDO_VIO_TUNE_MASK 0x07 | ||
682 | #define LDO_VIO_1V7 0x03 | ||
683 | #define LDO_VIO_1V8 0x04 | ||
684 | #define LDO_VIO_3V3 0x07 | ||
685 | |||
686 | #define LDO_DV12S_CFG 0xFF76 | ||
687 | #define LDO_REF12_TUNE_MASK 0x18 | ||
688 | #define LDO_REF12_TUNE_DF 0x10 | ||
689 | #define LDO_D12_TUNE_MASK 0x07 | ||
690 | #define LDO_D12_TUNE_DF 0x04 | ||
691 | |||
692 | #define LDO_AV12S_CFG 0xFF77 | ||
693 | #define LDO_AV12S_TUNE_MASK 0x07 | ||
694 | #define LDO_AV12S_TUNE_DF 0x04 | ||
695 | |||
696 | #define SD40_LDO_CTL1 0xFE7D | ||
697 | #define SD40_VIO_TUNE_MASK 0x70 | ||
698 | #define SD40_VIO_TUNE_1V7 0x30 | ||
699 | #define SD_VIO_LDO_1V8 0x40 | ||
700 | #define SD_VIO_LDO_3V3 0x70 | ||
701 | |||
631 | /* Phy register */ | 702 | /* Phy register */ |
632 | #define PHY_PCR 0x00 | 703 | #define PHY_PCR 0x00 |
633 | #define PHY_PCR_FORCE_CODE 0xB000 | 704 | #define PHY_PCR_FORCE_CODE 0xB000 |
@@ -641,6 +712,10 @@ | |||
641 | #define PHY_RCR1 0x02 | 712 | #define PHY_RCR1 0x02 |
642 | #define PHY_RCR1_ADP_TIME_4 0x0400 | 713 | #define PHY_RCR1_ADP_TIME_4 0x0400 |
643 | #define PHY_RCR1_VCO_COARSE 0x001F | 714 | #define PHY_RCR1_VCO_COARSE 0x001F |
715 | #define PHY_SSCCR2 0x02 | ||
716 | #define PHY_SSCCR2_PLL_NCODE 0x0A00 | ||
717 | #define PHY_SSCCR2_TIME0 0x001C | ||
718 | #define PHY_SSCCR2_TIME2_WIDTH 0x0003 | ||
644 | 719 | ||
645 | #define PHY_RCR2 0x03 | 720 | #define PHY_RCR2 0x03 |
646 | #define PHY_RCR2_EMPHASE_EN 0x8000 | 721 | #define PHY_RCR2_EMPHASE_EN 0x8000 |
@@ -649,6 +724,9 @@ | |||
649 | #define PHY_RCR2_FREQSEL_12 0x0040 | 724 | #define PHY_RCR2_FREQSEL_12 0x0040 |
650 | #define PHY_RCR2_CDR_SC_12P 0x0010 | 725 | #define PHY_RCR2_CDR_SC_12P 0x0010 |
651 | #define PHY_RCR2_CALIB_LATE 0x0002 | 726 | #define PHY_RCR2_CALIB_LATE 0x0002 |
727 | #define PHY_SSCCR3 0x03 | ||
728 | #define PHY_SSCCR3_STEP_IN 0x2740 | ||
729 | #define PHY_SSCCR3_CHECK_DELAY 0x0008 | ||
652 | 730 | ||
653 | #define PHY_RTCR 0x04 | 731 | #define PHY_RTCR 0x04 |
654 | #define PHY_RDR 0x05 | 732 | #define PHY_RDR 0x05 |
@@ -663,6 +741,16 @@ | |||
663 | #define PHY_TUNE_TUNED18 0x01C0 | 741 | #define PHY_TUNE_TUNED18 0x01C0 |
664 | #define PHY_TUNE_TUNED12 0X0020 | 742 | #define PHY_TUNE_TUNED12 0X0020 |
665 | #define PHY_TUNE_TUNEA12 0x0004 | 743 | #define PHY_TUNE_TUNEA12 0x0004 |
744 | #define PHY_TUNE_VOLTAGE_MASK 0xFC3F | ||
745 | #define PHY_TUNE_VOLTAGE_3V3 0x03C0 | ||
746 | #define PHY_TUNE_D18_1V8 0x0100 | ||
747 | #define PHY_TUNE_D18_1V7 0x0080 | ||
748 | #define PHY_ANA08 0x08 | ||
749 | #define PHY_ANA08_RX_EQ_DCGAIN 0x5000 | ||
750 | #define PHY_ANA08_SEL_RX_EN 0x0400 | ||
751 | #define PHY_ANA08_RX_EQ_VAL 0x03C0 | ||
752 | #define PHY_ANA08_SCP 0x0020 | ||
753 | #define PHY_ANA08_SEL_IPI 0x0004 | ||
666 | 754 | ||
667 | #define PHY_IMR 0x09 | 755 | #define PHY_IMR 0x09 |
668 | #define PHY_BPCR 0x0A | 756 | #define PHY_BPCR 0x0A |
@@ -678,6 +766,7 @@ | |||
678 | #define PHY_HOST_CLK_CTRL 0x0F | 766 | #define PHY_HOST_CLK_CTRL 0x0F |
679 | #define PHY_DMR 0x10 | 767 | #define PHY_DMR 0x10 |
680 | #define PHY_BACR 0x11 | 768 | #define PHY_BACR 0x11 |
769 | #define PHY_BACR_BASIC_MASK 0xFFF3 | ||
681 | #define PHY_IER 0x12 | 770 | #define PHY_IER 0x12 |
682 | #define PHY_BCSR 0x13 | 771 | #define PHY_BCSR 0x13 |
683 | #define PHY_BPR 0x14 | 772 | #define PHY_BPR 0x14 |
@@ -698,12 +787,19 @@ | |||
698 | #define PHY_REV_STOP_CLKWR 0x0004 | 787 | #define PHY_REV_STOP_CLKWR 0x0004 |
699 | 788 | ||
700 | #define PHY_FLD0 0x1A | 789 | #define PHY_FLD0 0x1A |
790 | #define PHY_ANA1A 0x1A | ||
791 | #define PHY_ANA1A_TXR_LOOPBACK 0x2000 | ||
792 | #define PHY_ANA1A_RXT_BIST 0x0500 | ||
793 | #define PHY_ANA1A_TXR_BIST 0x0040 | ||
794 | #define PHY_ANA1A_REV 0x0006 | ||
701 | #define PHY_FLD1 0x1B | 795 | #define PHY_FLD1 0x1B |
702 | #define PHY_FLD2 0x1C | 796 | #define PHY_FLD2 0x1C |
703 | #define PHY_FLD3 0x1D | 797 | #define PHY_FLD3 0x1D |
704 | #define PHY_FLD3_TIMER_4 0x0800 | 798 | #define PHY_FLD3_TIMER_4 0x0800 |
705 | #define PHY_FLD3_TIMER_6 0x0020 | 799 | #define PHY_FLD3_TIMER_6 0x0020 |
706 | #define PHY_FLD3_RXDELINK 0x0004 | 800 | #define PHY_FLD3_RXDELINK 0x0004 |
801 | #define PHY_ANA1D 0x1D | ||
802 | #define PHY_ANA1D_DEBUG_ADDR 0x0004 | ||
707 | 803 | ||
708 | #define PHY_FLD4 0x1E | 804 | #define PHY_FLD4 0x1E |
709 | #define PHY_FLD4_FLDEN_SEL 0x4000 | 805 | #define PHY_FLD4_FLDEN_SEL 0x4000 |
@@ -713,7 +809,18 @@ | |||
713 | #define PHY_FLD4_BER_COUNT 0x00E0 | 809 | #define PHY_FLD4_BER_COUNT 0x00E0 |
714 | #define PHY_FLD4_BER_TIMER 0x000A | 810 | #define PHY_FLD4_BER_TIMER 0x000A |
715 | #define PHY_FLD4_BER_CHK_EN 0x0001 | 811 | #define PHY_FLD4_BER_CHK_EN 0x0001 |
716 | 812 | #define PHY_DIG1E 0x1E | |
813 | #define PHY_DIG1E_REV 0x4000 | ||
814 | #define PHY_DIG1E_D0_X_D1 0x1000 | ||
815 | #define PHY_DIG1E_RX_ON_HOST 0x0800 | ||
816 | #define PHY_DIG1E_RCLK_REF_HOST 0x0400 | ||
817 | #define PHY_DIG1E_RCLK_TX_EN_KEEP 0x0040 | ||
818 | #define PHY_DIG1E_RCLK_TX_TERM_KEEP 0x0020 | ||
819 | #define PHY_DIG1E_RCLK_RX_EIDLE_ON 0x0010 | ||
820 | #define PHY_DIG1E_TX_TERM_KEEP 0x0008 | ||
821 | #define PHY_DIG1E_RX_TERM_KEEP 0x0004 | ||
822 | #define PHY_DIG1E_TX_EN_KEEP 0x0002 | ||
823 | #define PHY_DIG1E_RX_EN_KEEP 0x0001 | ||
717 | #define PHY_DUM_REG 0x1F | 824 | #define PHY_DUM_REG 0x1F |
718 | 825 | ||
719 | #define PCR_SETTING_REG1 0x724 | 826 | #define PCR_SETTING_REG1 0x724 |
@@ -729,6 +836,8 @@ struct pcr_handle { | |||
729 | }; | 836 | }; |
730 | 837 | ||
731 | struct pcr_ops { | 838 | struct pcr_ops { |
839 | int (*write_phy)(struct rtsx_pcr *pcr, u8 addr, u16 val); | ||
840 | int (*read_phy)(struct rtsx_pcr *pcr, u8 addr, u16 *val); | ||
732 | int (*extra_init_hw)(struct rtsx_pcr *pcr); | 841 | int (*extra_init_hw)(struct rtsx_pcr *pcr); |
733 | int (*optimize_phy)(struct rtsx_pcr *pcr); | 842 | int (*optimize_phy)(struct rtsx_pcr *pcr); |
734 | int (*turn_on_led)(struct rtsx_pcr *pcr); | 843 | int (*turn_on_led)(struct rtsx_pcr *pcr); |
@@ -823,6 +932,8 @@ struct rtsx_pcr { | |||
823 | const struct pcr_ops *ops; | 932 | const struct pcr_ops *ops; |
824 | enum PDEV_STAT state; | 933 | enum PDEV_STAT state; |
825 | 934 | ||
935 | u16 reg_pm_ctrl3; | ||
936 | |||
826 | int num_slots; | 937 | int num_slots; |
827 | struct rtsx_slot *slots; | 938 | struct rtsx_slot *slots; |
828 | }; | 939 | }; |
@@ -830,6 +941,10 @@ struct rtsx_pcr { | |||
830 | #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) | 941 | #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) |
831 | #define PCI_VID(pcr) ((pcr)->pci->vendor) | 942 | #define PCI_VID(pcr) ((pcr)->pci->vendor) |
832 | #define PCI_PID(pcr) ((pcr)->pci->device) | 943 | #define PCI_PID(pcr) ((pcr)->pci->device) |
944 | #define is_version(pcr, pid, ver) \ | ||
945 | (CHK_PCI_PID(pcr, pid) && (pcr)->ic_version == (ver)) | ||
946 | #define pcr_dbg(pcr, fmt, arg...) \ | ||
947 | dev_dbg(&(pcr)->pci->dev, fmt, ##arg) | ||
833 | 948 | ||
834 | #define SDR104_PHASE(val) ((val) & 0xFF) | 949 | #define SDR104_PHASE(val) ((val) & 0xFF) |
835 | #define SDR50_PHASE(val) (((val) >> 8) & 0xFF) | 950 | #define SDR50_PHASE(val) (((val) >> 8) & 0xFF) |
@@ -899,4 +1014,17 @@ static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val) | |||
899 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val); | 1014 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val); |
900 | } | 1015 | } |
901 | 1016 | ||
1017 | static inline int rtsx_pci_update_phy(struct rtsx_pcr *pcr, u8 addr, | ||
1018 | u16 mask, u16 append) | ||
1019 | { | ||
1020 | int err; | ||
1021 | u16 val; | ||
1022 | |||
1023 | err = rtsx_pci_read_phy_register(pcr, addr, &val); | ||
1024 | if (err < 0) | ||
1025 | return err; | ||
1026 | |||
1027 | return rtsx_pci_write_phy_register(pcr, addr, (val & mask) | append); | ||
1028 | } | ||
1029 | |||
902 | #endif | 1030 | #endif |