diff options
| -rw-r--r-- | drivers/spi/spi-pl022.c | 59 | ||||
| -rw-r--r-- | include/linux/amba/bus.h | 5 |
2 files changed, 63 insertions, 1 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 7f13f3f7198b..d0741b2eabb4 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -82,6 +82,7 @@ | |||
| 82 | #define SSP_MIS(r) (r + 0x01C) | 82 | #define SSP_MIS(r) (r + 0x01C) |
| 83 | #define SSP_ICR(r) (r + 0x020) | 83 | #define SSP_ICR(r) (r + 0x020) |
| 84 | #define SSP_DMACR(r) (r + 0x024) | 84 | #define SSP_DMACR(r) (r + 0x024) |
| 85 | #define SSP_CSR(r) (r + 0x030) /* vendor extension */ | ||
| 85 | #define SSP_ITCR(r) (r + 0x080) | 86 | #define SSP_ITCR(r) (r + 0x080) |
| 86 | #define SSP_ITIP(r) (r + 0x084) | 87 | #define SSP_ITIP(r) (r + 0x084) |
| 87 | #define SSP_ITOP(r) (r + 0x088) | 88 | #define SSP_ITOP(r) (r + 0x088) |
| @@ -198,6 +199,12 @@ | |||
| 198 | #define SSP_DMACR_MASK_TXDMAE (0x1UL << 1) | 199 | #define SSP_DMACR_MASK_TXDMAE (0x1UL << 1) |
| 199 | 200 | ||
| 200 | /* | 201 | /* |
| 202 | * SSP Chip Select Control Register - SSP_CSR | ||
| 203 | * (vendor extension) | ||
| 204 | */ | ||
| 205 | #define SSP_CSR_CSVALUE_MASK (0x1FUL << 0) | ||
| 206 | |||
| 207 | /* | ||
| 201 | * SSP Integration Test control Register - SSP_ITCR | 208 | * SSP Integration Test control Register - SSP_ITCR |
| 202 | */ | 209 | */ |
| 203 | #define SSP_ITCR_MASK_ITEN (0x1UL << 0) | 210 | #define SSP_ITCR_MASK_ITEN (0x1UL << 0) |
| @@ -313,6 +320,7 @@ enum ssp_writing { | |||
| 313 | * @extended_cr: 32 bit wide control register 0 with extra | 320 | * @extended_cr: 32 bit wide control register 0 with extra |
| 314 | * features and extra features in CR1 as found in the ST variants | 321 | * features and extra features in CR1 as found in the ST variants |
| 315 | * @pl023: supports a subset of the ST extensions called "PL023" | 322 | * @pl023: supports a subset of the ST extensions called "PL023" |
| 323 | * @internal_cs_ctrl: supports chip select control register | ||
| 316 | */ | 324 | */ |
| 317 | struct vendor_data { | 325 | struct vendor_data { |
| 318 | int fifodepth; | 326 | int fifodepth; |
| @@ -321,6 +329,7 @@ struct vendor_data { | |||
| 321 | bool extended_cr; | 329 | bool extended_cr; |
| 322 | bool pl023; | 330 | bool pl023; |
| 323 | bool loopback; | 331 | bool loopback; |
| 332 | bool internal_cs_ctrl; | ||
| 324 | }; | 333 | }; |
| 325 | 334 | ||
| 326 | /** | 335 | /** |
| @@ -440,9 +449,32 @@ static void null_cs_control(u32 command) | |||
| 440 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); | 449 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); |
| 441 | } | 450 | } |
| 442 | 451 | ||
| 452 | /** | ||
| 453 | * internal_cs_control - Control chip select signals via SSP_CSR. | ||
| 454 | * @pl022: SSP driver private data structure | ||
| 455 | * @command: select/delect the chip | ||
| 456 | * | ||
| 457 | * Used on controller with internal chip select control via SSP_CSR register | ||
| 458 | * (vendor extension). Each of the 5 LSB in the register controls one chip | ||
| 459 | * select signal. | ||
| 460 | */ | ||
| 461 | static void internal_cs_control(struct pl022 *pl022, u32 command) | ||
| 462 | { | ||
| 463 | u32 tmp; | ||
| 464 | |||
| 465 | tmp = readw(SSP_CSR(pl022->virtbase)); | ||
| 466 | if (command == SSP_CHIP_SELECT) | ||
| 467 | tmp &= ~BIT(pl022->cur_cs); | ||
| 468 | else | ||
| 469 | tmp |= BIT(pl022->cur_cs); | ||
| 470 | writew(tmp, SSP_CSR(pl022->virtbase)); | ||
| 471 | } | ||
| 472 | |||
| 443 | static void pl022_cs_control(struct pl022 *pl022, u32 command) | 473 | static void pl022_cs_control(struct pl022 *pl022, u32 command) |
| 444 | { | 474 | { |
| 445 | if (gpio_is_valid(pl022->cur_cs)) | 475 | if (pl022->vendor->internal_cs_ctrl) |
| 476 | internal_cs_control(pl022, command); | ||
| 477 | else if (gpio_is_valid(pl022->cur_cs)) | ||
| 446 | gpio_set_value(pl022->cur_cs, command); | 478 | gpio_set_value(pl022->cur_cs, command); |
| 447 | else | 479 | else |
| 448 | pl022->cur_chip->cs_control(command); | 480 | pl022->cur_chip->cs_control(command); |
| @@ -2122,6 +2154,9 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2122 | if (platform_info->num_chipselect && platform_info->chipselects) { | 2154 | if (platform_info->num_chipselect && platform_info->chipselects) { |
| 2123 | for (i = 0; i < num_cs; i++) | 2155 | for (i = 0; i < num_cs; i++) |
| 2124 | pl022->chipselects[i] = platform_info->chipselects[i]; | 2156 | pl022->chipselects[i] = platform_info->chipselects[i]; |
| 2157 | } else if (pl022->vendor->internal_cs_ctrl) { | ||
| 2158 | for (i = 0; i < num_cs; i++) | ||
| 2159 | pl022->chipselects[i] = i; | ||
| 2125 | } else if (IS_ENABLED(CONFIG_OF)) { | 2160 | } else if (IS_ENABLED(CONFIG_OF)) { |
| 2126 | for (i = 0; i < num_cs; i++) { | 2161 | for (i = 0; i < num_cs; i++) { |
| 2127 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | 2162 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); |
| @@ -2352,6 +2387,7 @@ static struct vendor_data vendor_arm = { | |||
| 2352 | .extended_cr = false, | 2387 | .extended_cr = false, |
| 2353 | .pl023 = false, | 2388 | .pl023 = false, |
| 2354 | .loopback = true, | 2389 | .loopback = true, |
| 2390 | .internal_cs_ctrl = false, | ||
| 2355 | }; | 2391 | }; |
| 2356 | 2392 | ||
| 2357 | static struct vendor_data vendor_st = { | 2393 | static struct vendor_data vendor_st = { |
| @@ -2361,6 +2397,7 @@ static struct vendor_data vendor_st = { | |||
| 2361 | .extended_cr = true, | 2397 | .extended_cr = true, |
| 2362 | .pl023 = false, | 2398 | .pl023 = false, |
| 2363 | .loopback = true, | 2399 | .loopback = true, |
| 2400 | .internal_cs_ctrl = false, | ||
| 2364 | }; | 2401 | }; |
| 2365 | 2402 | ||
| 2366 | static struct vendor_data vendor_st_pl023 = { | 2403 | static struct vendor_data vendor_st_pl023 = { |
| @@ -2370,6 +2407,17 @@ static struct vendor_data vendor_st_pl023 = { | |||
| 2370 | .extended_cr = true, | 2407 | .extended_cr = true, |
| 2371 | .pl023 = true, | 2408 | .pl023 = true, |
| 2372 | .loopback = false, | 2409 | .loopback = false, |
| 2410 | .internal_cs_ctrl = false, | ||
| 2411 | }; | ||
| 2412 | |||
| 2413 | static struct vendor_data vendor_lsi = { | ||
| 2414 | .fifodepth = 8, | ||
| 2415 | .max_bpw = 16, | ||
| 2416 | .unidir = false, | ||
| 2417 | .extended_cr = false, | ||
| 2418 | .pl023 = false, | ||
| 2419 | .loopback = true, | ||
| 2420 | .internal_cs_ctrl = true, | ||
| 2373 | }; | 2421 | }; |
| 2374 | 2422 | ||
| 2375 | static struct amba_id pl022_ids[] = { | 2423 | static struct amba_id pl022_ids[] = { |
| @@ -2403,6 +2451,15 @@ static struct amba_id pl022_ids[] = { | |||
| 2403 | .mask = 0xffffffff, | 2451 | .mask = 0xffffffff, |
| 2404 | .data = &vendor_st_pl023, | 2452 | .data = &vendor_st_pl023, |
| 2405 | }, | 2453 | }, |
| 2454 | { | ||
| 2455 | /* | ||
| 2456 | * PL022 variant that has a chip select control register whih | ||
| 2457 | * allows control of 5 output signals nCS[0:4]. | ||
| 2458 | */ | ||
| 2459 | .id = 0x000b6022, | ||
| 2460 | .mask = 0x000fffff, | ||
| 2461 | .data = &vendor_lsi, | ||
| 2462 | }, | ||
| 2406 | { 0, 0 }, | 2463 | { 0, 0 }, |
| 2407 | }; | 2464 | }; |
| 2408 | 2465 | ||
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index fdd7e1b61f60..c324f5700d1a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h | |||
| @@ -44,10 +44,15 @@ struct amba_driver { | |||
| 44 | const struct amba_id *id_table; | 44 | const struct amba_id *id_table; |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * Constants for the designer field of the Peripheral ID register. When bit 7 | ||
| 49 | * is set to '1', bits [6:0] should be the JEP106 manufacturer identity code. | ||
| 50 | */ | ||
| 47 | enum amba_vendor { | 51 | enum amba_vendor { |
| 48 | AMBA_VENDOR_ARM = 0x41, | 52 | AMBA_VENDOR_ARM = 0x41, |
| 49 | AMBA_VENDOR_ST = 0x80, | 53 | AMBA_VENDOR_ST = 0x80, |
| 50 | AMBA_VENDOR_QCOM = 0x51, | 54 | AMBA_VENDOR_QCOM = 0x51, |
| 55 | AMBA_VENDOR_LSI = 0xb6, | ||
| 51 | }; | 56 | }; |
| 52 | 57 | ||
| 53 | extern struct bus_type amba_bustype; | 58 | extern struct bus_type amba_bustype; |
