mpc10x_common.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /*
  2. * arch/ppc/syslib/mpc10x_common.c
  3. *
  4. * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
  5. * Mem ctlr, EPIC, etc.
  6. *
  7. * Author: Mark A. Greer
  8. * mgreer@mvista.com
  9. *
  10. * 2001 (c) MontaVista, Software, Inc. This file is licensed under
  11. * the terms of the GNU General Public License version 2. This program
  12. * is licensed "as is" without any warranty of any kind, whether express
  13. * or implied.
  14. */
  15. /*
  16. * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
  17. */
  18. #include <linux/kernel.h>
  19. #include <linux/init.h>
  20. #include <linux/pci.h>
  21. #include <linux/slab.h>
  22. #include <linux/serial_8250.h>
  23. #include <linux/fsl_devices.h>
  24. #include <linux/device.h>
  25. #include <asm/byteorder.h>
  26. #include <asm/io.h>
  27. #include <asm/irq.h>
  28. #include <asm/uaccess.h>
  29. #include <asm/machdep.h>
  30. #include <asm/pci-bridge.h>
  31. #include <asm/open_pic.h>
  32. #include <asm/mpc10x.h>
  33. #include <asm/ppc_sys.h>
  34. #ifdef CONFIG_MPC10X_OPENPIC
  35. #ifdef CONFIG_EPIC_SERIAL_MODE
  36. #define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5)
  37. #else
  38. #define EPIC_IRQ_BASE 5
  39. #endif
  40. #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS)
  41. #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS)
  42. #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS)
  43. #else
  44. #define MPC10X_I2C_IRQ -1
  45. #define MPC10X_DMA0_IRQ -1
  46. #define MPC10X_DMA1_IRQ -1
  47. #endif
  48. static struct fsl_i2c_platform_data mpc10x_i2c_pdata = {
  49. .device_flags = 0,
  50. };
  51. static struct plat_serial8250_port serial_platform_data[] = {
  52. { },
  53. };
  54. struct platform_device ppc_sys_platform_devices[] = {
  55. [MPC10X_IIC1] = {
  56. .name = "fsl-i2c",
  57. .id = 1,
  58. .dev.platform_data = &mpc10x_i2c_pdata,
  59. .num_resources = 2,
  60. .resource = (struct resource[]) {
  61. {
  62. .start = MPC10X_EUMB_I2C_OFFSET,
  63. .end = MPC10X_EUMB_I2C_OFFSET +
  64. MPC10X_EUMB_I2C_SIZE - 1,
  65. .flags = IORESOURCE_MEM,
  66. },
  67. {
  68. .flags = IORESOURCE_IRQ
  69. },
  70. },
  71. },
  72. [MPC10X_DMA0] = {
  73. .name = "fsl-dma",
  74. .id = 0,
  75. .num_resources = 2,
  76. .resource = (struct resource[]) {
  77. {
  78. .start = MPC10X_EUMB_DMA_OFFSET + 0x10,
  79. .end = MPC10X_EUMB_DMA_OFFSET + 0x1f,
  80. .flags = IORESOURCE_MEM,
  81. },
  82. {
  83. .flags = IORESOURCE_IRQ,
  84. },
  85. },
  86. },
  87. [MPC10X_DMA1] = {
  88. .name = "fsl-dma",
  89. .id = 1,
  90. .num_resources = 2,
  91. .resource = (struct resource[]) {
  92. {
  93. .start = MPC10X_EUMB_DMA_OFFSET + 0x20,
  94. .end = MPC10X_EUMB_DMA_OFFSET + 0x2f,
  95. .flags = IORESOURCE_MEM,
  96. },
  97. {
  98. .flags = IORESOURCE_IRQ,
  99. },
  100. },
  101. },
  102. [MPC10X_DMA1] = {
  103. .name = "fsl-dma",
  104. .id = 1,
  105. .num_resources = 2,
  106. .resource = (struct resource[]) {
  107. {
  108. .start = MPC10X_EUMB_DMA_OFFSET + 0x20,
  109. .end = MPC10X_EUMB_DMA_OFFSET + 0x2f,
  110. .flags = IORESOURCE_MEM,
  111. },
  112. {
  113. .flags = IORESOURCE_IRQ,
  114. },
  115. },
  116. },
  117. [MPC10X_DUART] = {
  118. .name = "serial8250",
  119. .id = 0,
  120. .dev.platform_data = serial_platform_data,
  121. },
  122. };
  123. /* We use the PCI ID to match on */
  124. struct ppc_sys_spec *cur_ppc_sys_spec;
  125. struct ppc_sys_spec ppc_sys_specs[] = {
  126. {
  127. .ppc_sys_name = "8245",
  128. .mask = 0xFFFFFFFF,
  129. .value = MPC10X_BRIDGE_8245,
  130. .num_devices = 4,
  131. .device_list = (enum ppc_sys_devices[])
  132. {
  133. MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, MPC10X_DUART,
  134. },
  135. },
  136. {
  137. .ppc_sys_name = "8240",
  138. .mask = 0xFFFFFFFF,
  139. .value = MPC10X_BRIDGE_8240,
  140. .num_devices = 3,
  141. .device_list = (enum ppc_sys_devices[])
  142. {
  143. MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
  144. },
  145. },
  146. {
  147. .ppc_sys_name = "107",
  148. .mask = 0xFFFFFFFF,
  149. .value = MPC10X_BRIDGE_107,
  150. .num_devices = 3,
  151. .device_list = (enum ppc_sys_devices[])
  152. {
  153. MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
  154. },
  155. },
  156. { /* default match */
  157. .ppc_sys_name = "",
  158. .mask = 0x00000000,
  159. .value = 0x00000000,
  160. },
  161. };
  162. /* Set resources to match bridge memory map */
  163. void __init
  164. mpc10x_bridge_set_resources(int map, struct pci_controller *hose)
  165. {
  166. switch (map) {
  167. case MPC10X_MEM_MAP_A:
  168. pci_init_resource(&hose->io_resource,
  169. 0x00000000,
  170. 0x3f7fffff,
  171. IORESOURCE_IO,
  172. "PCI host bridge");
  173. pci_init_resource (&hose->mem_resources[0],
  174. 0xc0000000,
  175. 0xfeffffff,
  176. IORESOURCE_MEM,
  177. "PCI host bridge");
  178. break;
  179. case MPC10X_MEM_MAP_B:
  180. pci_init_resource(&hose->io_resource,
  181. 0x00000000,
  182. 0x00bfffff,
  183. IORESOURCE_IO,
  184. "PCI host bridge");
  185. pci_init_resource (&hose->mem_resources[0],
  186. 0x80000000,
  187. 0xfcffffff,
  188. IORESOURCE_MEM,
  189. "PCI host bridge");
  190. break;
  191. default:
  192. printk("mpc10x_bridge_set_resources: "
  193. "Invalid map specified\n");
  194. if (ppc_md.progress)
  195. ppc_md.progress("mpc10x:exit1", 0x100);
  196. }
  197. }
  198. /*
  199. * Do some initialization and put the EUMB registers at the specified address
  200. * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set).
  201. *
  202. * The EPIC is not on the 106, only the 8240 and 107.
  203. */
  204. int __init
  205. mpc10x_bridge_init(struct pci_controller *hose,
  206. uint current_map,
  207. uint new_map,
  208. uint phys_eumb_base)
  209. {
  210. int host_bridge, picr1, picr1_bit, i;
  211. ulong pci_config_addr, pci_config_data;
  212. u_char pir, byte;
  213. if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100);
  214. /* Set up for current map so we can get at config regs */
  215. switch (current_map) {
  216. case MPC10X_MEM_MAP_A:
  217. setup_indirect_pci(hose,
  218. MPC10X_MAPA_CNFG_ADDR,
  219. MPC10X_MAPA_CNFG_DATA);
  220. break;
  221. case MPC10X_MEM_MAP_B:
  222. setup_indirect_pci(hose,
  223. MPC10X_MAPB_CNFG_ADDR,
  224. MPC10X_MAPB_CNFG_DATA);
  225. break;
  226. default:
  227. printk("mpc10x_bridge_init: %s\n",
  228. "Invalid current map specified");
  229. if (ppc_md.progress)
  230. ppc_md.progress("mpc10x:exit1", 0x100);
  231. return -1;
  232. }
  233. /* Make sure it's a supported bridge */
  234. early_read_config_dword(hose,
  235. 0,
  236. PCI_DEVFN(0,0),
  237. PCI_VENDOR_ID,
  238. &host_bridge);
  239. switch (host_bridge) {
  240. case MPC10X_BRIDGE_106:
  241. case MPC10X_BRIDGE_8240:
  242. case MPC10X_BRIDGE_107:
  243. case MPC10X_BRIDGE_8245:
  244. break;
  245. default:
  246. if (ppc_md.progress)
  247. ppc_md.progress("mpc10x:exit2", 0x100);
  248. return -1;
  249. }
  250. switch (new_map) {
  251. case MPC10X_MEM_MAP_A:
  252. MPC10X_SETUP_HOSE(hose, A);
  253. pci_config_addr = MPC10X_MAPA_CNFG_ADDR;
  254. pci_config_data = MPC10X_MAPA_CNFG_DATA;
  255. picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A;
  256. break;
  257. case MPC10X_MEM_MAP_B:
  258. MPC10X_SETUP_HOSE(hose, B);
  259. pci_config_addr = MPC10X_MAPB_CNFG_ADDR;
  260. pci_config_data = MPC10X_MAPB_CNFG_DATA;
  261. picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B;
  262. break;
  263. default:
  264. printk("mpc10x_bridge_init: %s\n",
  265. "Invalid new map specified");
  266. if (ppc_md.progress)
  267. ppc_md.progress("mpc10x:exit3", 0x100);
  268. return -1;
  269. }
  270. /* Make bridge use the 'new_map', if not already usng it */
  271. if (current_map != new_map) {
  272. early_read_config_dword(hose,
  273. 0,
  274. PCI_DEVFN(0,0),
  275. MPC10X_CFG_PICR1_REG,
  276. &picr1);
  277. picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) |
  278. picr1_bit;
  279. early_write_config_dword(hose,
  280. 0,
  281. PCI_DEVFN(0,0),
  282. MPC10X_CFG_PICR1_REG,
  283. picr1);
  284. asm volatile("sync");
  285. /* Undo old mappings & map in new cfg data/addr regs */
  286. iounmap((void *)hose->cfg_addr);
  287. iounmap((void *)hose->cfg_data);
  288. setup_indirect_pci(hose,
  289. pci_config_addr,
  290. pci_config_data);
  291. }
  292. /* Setup resources to match map */
  293. mpc10x_bridge_set_resources(new_map, hose);
  294. /*
  295. * Want processor accesses of 0xFDxxxxxx to be mapped
  296. * to PCI memory space at 0x00000000. Do not want
  297. * host bridge to respond to PCI memory accesses of
  298. * 0xFDxxxxxx. Do not want host bridge to respond
  299. * to PCI memory addresses 0xFD000000-0xFDFFFFFF;
  300. * want processor accesses from 0x000A0000-0x000BFFFF
  301. * to be forwarded to system memory.
  302. *
  303. * Only valid if not in agent mode and using MAP B.
  304. */
  305. if (new_map == MPC10X_MEM_MAP_B) {
  306. early_read_config_byte(hose,
  307. 0,
  308. PCI_DEVFN(0,0),
  309. MPC10X_CFG_MAPB_OPTIONS_REG,
  310. &byte);
  311. byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE |
  312. MPC10X_CFG_MAPB_OPTIONS_PCICH |
  313. MPC10X_CFG_MAPB_OPTIONS_PROCCH);
  314. if (host_bridge != MPC10X_BRIDGE_106) {
  315. byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE;
  316. }
  317. early_write_config_byte(hose,
  318. 0,
  319. PCI_DEVFN(0,0),
  320. MPC10X_CFG_MAPB_OPTIONS_REG,
  321. byte);
  322. }
  323. if (host_bridge != MPC10X_BRIDGE_106) {
  324. early_read_config_byte(hose,
  325. 0,
  326. PCI_DEVFN(0,0),
  327. MPC10X_CFG_PIR_REG,
  328. &pir);
  329. if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) {
  330. printk("Host bridge in Agent mode\n");
  331. /* Read or Set LMBAR & PCSRBAR? */
  332. }
  333. /* Set base addr of the 8240/107 EUMB. */
  334. early_write_config_dword(hose,
  335. 0,
  336. PCI_DEVFN(0,0),
  337. MPC10X_CFG_EUMBBAR,
  338. phys_eumb_base);
  339. #ifdef CONFIG_MPC10X_OPENPIC
  340. /* Map EPIC register part of EUMB into vitual memory - PCORE
  341. uses an i8259 instead of EPIC. */
  342. OpenPIC_Addr =
  343. ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
  344. MPC10X_EUMB_EPIC_SIZE);
  345. #endif
  346. }
  347. #ifdef CONFIG_MPC10X_STORE_GATHERING
  348. mpc10x_enable_store_gathering(hose);
  349. #else
  350. mpc10x_disable_store_gathering(hose);
  351. #endif
  352. /* setup platform devices for MPC10x bridges */
  353. identify_ppc_sys_by_id (host_bridge);
  354. for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
  355. unsigned int dev_id = cur_ppc_sys_spec->device_list[i];
  356. ppc_sys_fixup_mem_resource(&ppc_sys_platform_devices[dev_id],
  357. phys_eumb_base);
  358. }
  359. /* IRQ's are determined at runtime */
  360. ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ;
  361. ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ;
  362. ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ;
  363. ppc_sys_platform_devices[MPC10X_DMA0].resource[1].end = MPC10X_DMA0_IRQ;
  364. ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ;
  365. ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ;
  366. /*
  367. * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative
  368. * PCI reads may return stale data so turn off.
  369. */
  370. if ((host_bridge == MPC10X_BRIDGE_8240)
  371. || (host_bridge == MPC10X_BRIDGE_8245)
  372. || (host_bridge == MPC10X_BRIDGE_107)) {
  373. early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
  374. MPC10X_CFG_PICR1_REG, &picr1);
  375. picr1 &= ~MPC10X_CFG_PICR1_SPEC_PCI_RD;
  376. early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
  377. MPC10X_CFG_PICR1_REG, picr1);
  378. }
  379. /*
  380. * 8241/8245 erratum 28: PCI reads from local memory may return
  381. * stale data. Workaround by setting PICR2[0] to disable copyback
  382. * optimization. Oddly, the latest available user manual for the
  383. * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd.
  384. */
  385. if (host_bridge == MPC10X_BRIDGE_8245) {
  386. u32 picr2;
  387. early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
  388. MPC10X_CFG_PICR2_REG, &picr2);
  389. picr2 |= MPC10X_CFG_PICR2_COPYBACK_OPT;
  390. early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
  391. MPC10X_CFG_PICR2_REG, picr2);
  392. }
  393. if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100);
  394. return 0;
  395. }
  396. /*
  397. * Need to make our own PCI config space access macros because
  398. * mpc10x_get_mem_size() is called before the data structures are set up for
  399. * the 'early_xxx' and 'indirect_xxx' routines to work.
  400. * Assumes bus 0.
  401. */
  402. #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr))
  403. #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val))
  404. #define MPC10X_PCI_OP(rw, size, type, op, mask) \
  405. static void \
  406. mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \
  407. { \
  408. out_be32(cfg_addr, \
  409. ((offset & 0xfc) << 24) | (devfn << 16) \
  410. | (0 << 8) | 0x80); \
  411. MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \
  412. return; \
  413. }
  414. MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
  415. MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
  416. #if 0 /* Not used */
  417. MPC10X_PCI_OP(write, byte, u8, out_8, 3)
  418. MPC10X_PCI_OP(read, word, u16 *, in_le16, 2)
  419. MPC10X_PCI_OP(write, word, u16, out_le16, 2)
  420. MPC10X_PCI_OP(write, dword, u32, out_le32, 0)
  421. #endif
  422. /*
  423. * Read the memory controller registers to determine the amount of memory in
  424. * the system. This assumes that the firmware has correctly set up the memory
  425. * controller registers.
  426. */
  427. unsigned long __init
  428. mpc10x_get_mem_size(uint mem_map)
  429. {
  430. uint *config_addr, *config_data, val;
  431. ulong start, end, total, offset;
  432. int i;
  433. u_char bank_enables;
  434. switch (mem_map) {
  435. case MPC10X_MEM_MAP_A:
  436. config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR;
  437. config_data = (uint *)MPC10X_MAPA_CNFG_DATA;
  438. break;
  439. case MPC10X_MEM_MAP_B:
  440. config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR;
  441. config_data = (uint *)MPC10X_MAPB_CNFG_DATA;
  442. break;
  443. default:
  444. return 0;
  445. }
  446. mpc10x_read_config_byte(config_addr,
  447. config_data,
  448. PCI_DEVFN(0,0),
  449. MPC10X_MCTLR_MEM_BANK_ENABLES,
  450. &bank_enables);
  451. total = 0;
  452. for (i=0; i<8; i++) {
  453. if (bank_enables & (1 << i)) {
  454. offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
  455. mpc10x_read_config_dword(config_addr,
  456. config_data,
  457. PCI_DEVFN(0,0),
  458. offset,
  459. &val);
  460. start = (val >> ((i & 3) << 3)) & 0xff;
  461. offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
  462. mpc10x_read_config_dword(config_addr,
  463. config_data,
  464. PCI_DEVFN(0,0),
  465. offset,
  466. &val);
  467. val = (val >> ((i & 3) << 3)) & 0x03;
  468. start = (val << 28) | (start << 20);
  469. offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
  470. mpc10x_read_config_dword(config_addr,
  471. config_data,
  472. PCI_DEVFN(0,0),
  473. offset,
  474. &val);
  475. end = (val >> ((i & 3) << 3)) & 0xff;
  476. offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
  477. mpc10x_read_config_dword(config_addr,
  478. config_data,
  479. PCI_DEVFN(0,0),
  480. offset,
  481. &val);
  482. val = (val >> ((i & 3) << 3)) & 0x03;
  483. end = (val << 28) | (end << 20) | 0xfffff;
  484. total += (end - start + 1);
  485. }
  486. }
  487. return total;
  488. }
  489. int __init
  490. mpc10x_enable_store_gathering(struct pci_controller *hose)
  491. {
  492. uint picr1;
  493. early_read_config_dword(hose,
  494. 0,
  495. PCI_DEVFN(0,0),
  496. MPC10X_CFG_PICR1_REG,
  497. &picr1);
  498. picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN;
  499. early_write_config_dword(hose,
  500. 0,
  501. PCI_DEVFN(0,0),
  502. MPC10X_CFG_PICR1_REG,
  503. picr1);
  504. return 0;
  505. }
  506. int __init
  507. mpc10x_disable_store_gathering(struct pci_controller *hose)
  508. {
  509. uint picr1;
  510. early_read_config_dword(hose,
  511. 0,
  512. PCI_DEVFN(0,0),
  513. MPC10X_CFG_PICR1_REG,
  514. &picr1);
  515. picr1 &= ~MPC10X_CFG_PICR1_ST_GATH_EN;
  516. early_write_config_dword(hose,
  517. 0,
  518. PCI_DEVFN(0,0),
  519. MPC10X_CFG_PICR1_REG,
  520. picr1);
  521. return 0;
  522. }
  523. #ifdef CONFIG_MPC10X_OPENPIC
  524. void __init mpc10x_set_openpic(void)
  525. {
  526. /* Map external IRQs */
  527. openpic_set_sources(0, EPIC_IRQ_BASE, OpenPIC_Addr + 0x10200);
  528. /* Skip reserved space and map i2c and DMA Ch[01] */
  529. openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020);
  530. /* Skip reserved space and map Message Unit Interrupt (I2O) */
  531. openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0);
  532. openpic_init(NUM_8259_INTERRUPTS);
  533. }
  534. #endif