summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm (follow)
Commit message (Collapse)AuthorAge
...
| * | | | | | | drm/msm: Refactor GPU IOMMUJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Very soon we will be adding support for secure domains and so a bit of refactoring is needed the GPU IOMMU code: * Add support for directly probing the context bank device at create instead of at attach. This makes it a little bit easier to directly associate a mmu device with a specific context bank. * Specify the domain type at create time. Add a new domain type MSM_DOMAIN_USER to associate the user domain with the gfx3d_user context bank. Also add MSM_DOMAIN_DEFAULT with no context bank for legacy devices (read MDP4) with only one context bank to attach to the parent device. Adding a domain type saves us from having to create N entry points for each domain type. Note that dynamic domains stay with their own initalization function. This is because dynamic domains are cloned from the parent domain so the semantics are too different to try to smash into the generic functions. Change-Id: Ic0dedbad41692e776cddc72cda653ae637f9ec77 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: Finish consolidating the address space codeJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Now that the SMMU/IOMMU differences have been resolved the only delta between the SMMU and the IOMMU address space implementations is the actual address space allocation which we can work around by assuming the caller doesn't want address generation if they specify the same start and end address (i.e. 0). With that optimization we can get rid of the address space sub functions and a bunch of otherwise duplicated code. Change-Id: Ic0dedbaddef0fcd3a8f39e30f95c71245d84f111 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: Get rid of the MMU ->map_dma_buf and ->unmap_dma_buf funcsJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Finish consolidating the MMU map and unmap operations into a single function. By passing in the meta token to map/unmap the specific SMMU operations can make a local decision as to which function to call. Change-Id: Ic0dedbad52aac6ed1317411b2667755794d1818f Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: Consoldate mmu ->map and mmu ->map_sgJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For all intents and purposes the mmu ->map function has used a scatter gather list for some time. Drop the pretense and just make both the SMMU and IOMMU flavors use the sg flavor of their respective iommu API functions. As a result we can drop the map_sg hooks in the SMMU driver and get rid of a considerable amount of re-invented wheels in the IOMMU driver. Change-Id: Ic0dedbadc4724c8ae389892fb85610435c5c08cf Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: Set IOMMU flags in the IOMMU specific codeJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Pass the bo flags all the way down to the iommu map code and translate into the IOMMU flags right before mapping. This crosses the streams a bit by moving BO level knowledge all the way down into the MMU driver but it removes IOMMU specific knowledge from the address space level which will be important when the address space code for the GPU and the display are merged into one. Change-Id: Ic0dedbad256f8986658bbe50fc2e2bd4051b7a7c Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: return -EFAULT if copy_from_user() failsDan Carpenter2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | copy_from_user_inatomic() is actually a local function that returns -EFAULT or positive values on error. Otherwise copy_from_user() returns the number of bytes remaining to be copied. We want to return -EFAULT here. I removed an unlikely() because we just did a copy_from_user() so I don't think it can possibly make a difference. Change-Id: Ic0dedbad3437020c12053b6d93276a4dd24a577a Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Rob Clark <robdclark@gmail.com> Git-commit: 21c42da18ef128ca8fb4cc4ead888f5c61e3916a Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [jcrouse@codeaurora.org: fix minor merge conflict and checkpatch errors] Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
| * | | | | | | drm/msm: Safely skip holes in the counter group listsJordan Crouse2017-04-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For backwards compatibility the counter group list has some built in gaps that return NULL when queried. Make sure that all the functions that query the list are able to handle a NULL pointer. Change-Id: Ic0dedbadd10ccf3a3b9b1f1b035a46a4f7ee8493 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | | | | | | Merge "drm/msm: Add PLL_DELTA property to HDMI connector"Linux Build Service Account2017-05-01
|\ \ \ \ \ \ \ \ | |_|_|_|_|_|/ / |/| | | | | | |
| * | | | | | | drm/msm: Add PLL_DELTA property to HDMI connectorRay Zhang2017-04-24
| | |_|_|_|/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Clock recovery needs to update HDMI clock in order to compensate the clock drift, so add a connector property named as PLL_DELTA to support it. Meanwhile add a node in debugfs to expose this functionality. CRs-Fixed: 2015827 Change-Id: Ifdc7134b33102f112a8e3c659fae6a017ff11461 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | | | | Merge "drm/msm: Add explicit sync operations"Linux Build Service Account2017-04-28
|\ \ \ \ \ \ \ | | |/ / / / / | |/| / / / / | |_|/ / / / |/| | | | |
| * | | | | drm/msm: Add explicit sync operationsJordan Crouse2017-04-26
| |/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add sync operations to give the user more control over the behavior of cached buffers. Change-Id: Ic0dedbad67e19a6b30b2cc5f6b2c7bbe52c2b708 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* / / / / drm/msm: Enable per cmdstream profiling for the userSharat Masetty2017-04-24
|/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user provides a profile buffer identified with a buffer type MSM_SUBMIT_CMD_PROFILE_BUF, then the driver records the kernel clock time and gpu ticks at the time of cmdstream submission, and the GPU records the ticks just before the start of the cmdstream execution and right after the end of the cmdstream execution. Change-Id: Ic6298ec5919b18e976ae089ffb0860b8165ce4f3 Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
* | | | Merge "drm/msm/sde: remove redundant CRTC event caching"Linux Build Service Account2017-04-13
|\ \ \ \
| * | | | drm/msm/sde: remove redundant CRTC event cachingAbhinav Kumar2017-04-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently both sde_crtc_atomic_begin() and sde_crtc_atomic_flush() add the CRTC state event to the cached sde_crtc->event. This has a potential NULL ptr issue in the case of vblank event firing in between sde_crtc_atomic_begin() and sde_crtc_atomic_flush() because the upstream DRM vblank API send_vblank_event() doesn't consider the case when the VBLANK interrupt could have already freed any pending vblank events. Remove the caching from sde_crtc_atomic_begin() to avoid this condition. Also make sure that a page_flip event was indeed submitted before signaling the complete_flip() by setting a PENDING_FLIP flag right after HW flush. Change-Id: Ib201d2851e57bf22ec1f00814fc2e4dd2f35bfa1 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | | | | Merge "drm/msm: Re-trigger preemption upon command completion"Linux Build Service Account2017-04-12
|\ \ \ \ \
| * | | | | drm/msm: Re-trigger preemption upon command completionSharat Masetty2017-04-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Trigger preemption from the interrupt handler. This allows us to aggressively change ringbuffers especially to lower priority ones and finish working on pending commands. Change-Id: Ic05213f3d02b1bb7400461edd0d19e38d5b01ec2 Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
* | | | | | Merge "drm/msm: add HDMI debugfs support to show edid modes"Linux Build Service Account2017-04-12
|\ \ \ \ \ \
| * | | | | | drm/msm: add HDMI debugfs support to show edid modesAbhinav Kumar2017-04-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Extend the HDMI debugfs interface to show the EDID modes and also the extracted information from various data blocks of the EDID. Change-Id: I7cb7dbea290ec822e994c79430c6c2dbb39abc33 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | | | | | | Merge "drm/msm: Add DRM EDID parser for external displays"Linux Build Service Account2017-04-12
|\| | | | | | | |/ / / / / |/| | | | |
| * | | | | drm/msm: Add DRM EDID parser for external displaysAbhinav Kumar2017-04-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add DRM EDID parser support for external displays using MSM chipsets. Change-Id: I066c4faac4db31dc548b2de1090deac26cb395c7 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
| * | | | | drm/msm: add support for enabling scrambling featureAbhinav Kumar2017-04-10
| | |_|/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To support 4k@60fps resolution through HDMI, enable scrambler feature from HDMI controller and communicate it with sink device through DDC. Change-Id: I17750db358df58499303ef9d735bf3301b02a7c1 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | | | | Merge "drm/msm: fix the display type string in SDE HDMI driver"Linux Build Service Account2017-04-11
|\ \ \ \ \ | |_|/ / / |/| | | |
| * | | | drm/msm: fix the display type string in SDE HDMI driverAbhinav Kumar2017-04-05
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is a mismatch in the display type string between userspace and HDMI driver causing the userspace to not correctly detect the display configuration. Fix the string to align the userspace and driver. Change-Id: Ibb59fde833cb0be743b337fcb857c81bcbb37266 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* / / / drm/msm: Fix gmem range settingKasin Li2017-04-08
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | GMEM IOVA range is intend to start from 0x100000, But currently it is initialized with RANGE_MIN_LO:RANGE_MIN_LO. It makes GMEM IOVA start from 0. Change-Id: I6028c076c32d861303cbec1c6ad168d8494e094c Signed-off-by: Kasin Li <donglil@codeaurora.org>
* | | drm/msm: Add performance counter trackingJordan Crouse2017-03-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adreno GPUs have a certain number of fixed performance counters most of which can be programmed to a large number of different items (countables). A centralized database in the kernel is needed to make the most efficient use of counters across processes. Add performance counter tracking and APIs to allow applications to reserve performance counters by requesting a group ID and a countable (countables differ from block to block). The kernel will check to see if an active counter is already selected for that countable or if a new one should be assigned. Different processes can share the same counter if they both need the same countable. Counters are reserved with DRM_IOCTL_MSM_COUNTER_GET which returns a counter ID for the reserved counter and the hi/lo offset of the counter register. The reserving application can either read the counter from within a PM4 stream or it can use the group ID and counter ID and read the value of the counter with DRM_MSM_COUNTER_READ. After the counter is no longer needed DRM_IOCTL_MSM_COUNTER_PUT returns it and it can be released for other countables if no other processes are sharing it. Reservations are tracked for each process and cleaned up if the process dies without putting back the counters. Change-Id: Ic0dedbadc45e85ab0063331b39ca6f3289523038 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | drm/msm: Remove ringbuffer restriction from idleJordan Crouse2017-03-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove the check in a5xx_idle() to see if idle is being called on the current ring. a5xx_idle() is to used make sure the commands in the specified ring have completed and it is entirely reasonably to expect that a ring switch might need to be executed first. Change-Id: Ic0dedbadf45c7f624093efae72f3a9d75dc6857d Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | drm/msm: Update registers for performance countersJordan Crouse2017-03-29
| | | | | | | | | | | | | | | | | | | | | | | | Update a5xx rnddb database to add some VBIF registers for clearing and enabling performance counters. Change-Id: Ic0dedbada994e916527e8c44e2cf0a20115985a9 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | drm/msm: Take the mutex before calling msm_gem_new_implJordan Crouse2017-03-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Amongst its other duties, msm_gem_new_impl adds the newly created GEM object to the shared inactive list which may also be actively modifiying the list during submission. All the paths to modify the list are protected by the mutex except for the one through msm_gem_import which can end up causing list corruption. Change-Id: Ic0dedbad6b68d4d3db726e0d598d4d21af4b328c Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | Merge "ARM: dts: msm: Enable dma-coherent property for GPU"Linux Build Service Account2017-03-21
|\ \ \
| * | | drm/msm: Enable I/O coherence for CPU cached buffersSushmita Susheelendra2017-03-10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This makes buffers allocated as cached on the CPU to be coherent with the GPU. With this, the GPU is able to snoop into the CPU's caches to get the data. If the data is not present in any of the CPU's caches, it is fetched from main memory. This avoids the need for CPU cache maintenance operations in software. Change-Id: I5fd4df0182a4b4c36528904d9e4bb35221da0053 Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org>
* | | | drm/msm: Remove DRM_MSM_NUM_IOCTLSJordan Crouse2017-03-07
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | The ioctl array is sparsely populated but the compiler will make sure that it is sufficiently sized for all the values that we have so we can safely use ARRAY_SIZE() instead of having a constantly changing #define in the uapi header. Change-Id: Ic0dedbad39f30abb8ce340289089d2f3a5f6fe36 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* / / drm/msm/sde: fix color component order for UBWC formatsAbhinav Kumar2017-03-03
|/ / | | | | | | | | | | | | | | | | | | | | For UBWC formats color component order should be independent of endianness. Fix the component order for UBWC formats based on above requirement for SDE driver. Change-Id: I054049105d3af99c5496328819ffef7d0eb9610a Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | Merge "drm/msm: Revert "drm/msm/sde: fix color component order""Linux Build Service Account2017-02-27
|\ \
| * | drm/msm: Revert "drm/msm/sde: fix color component order"Abhinav Kumar2017-02-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit <c3e05abca5fabd7580be1378c5165a8b8f523f98> (<drm/msm/sde: fix color component order>). Color component order is specific to the rendering framework as well. This change reverts the commit mentioned above to take other frameworks into account which have different endianness. Change-Id: Ic3135d5742dd4cf999f2d7271fc56ee46c74a353 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | | Merge "msm: ext_display: move ext_display out of FB driver"Linux Build Service Account2017-02-26
|\ \ \
| * | | msm: ext_display: move ext_display out of FB driverRay Zhang2017-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make ext_display a standalone module independent of framebuffer driver, so that it could be shared by various drivers such as framebuffer and KMS. CRs-Fixed: 2010135 Change-Id: I336c556cbfbd66d3cb3467acaea038d5d3651f67 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | drm/msm: do not trigger HPD work in non-pluggable caseRay Zhang2017-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In HDMI non-pluggable case, it's supposed that there will not be hotplug events, so ignore the HPD interrupt and do not schedule the HPD work. CRs-Fixed: 2010135 Change-Id: I72b9c3fb0f831ddab4be0545c37cd9189d4afa41 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | drm/msm: update edid block for audio codecRay Zhang2017-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Audio codec needs audio extension block data in EDID, so add support for providing this information in ops registered by the audio driver. CRs-Fixed: 2010135 Change-Id: Ic1b389872171d5faade38d5ff484be065a9dc489 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | drm/msm: add HPD notification and acknowledge supportRay Zhang2017-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In HPD case the HDMI driver communicate with external display module by specific notification and acknowledge interfaces. Add this support to enable the communication. CRs-Fixed: 2010135 Change-Id: I24ac1e0f0cb1e3946e2a53e4bf72bafbd84e4395 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | drm/msm: enable hdmi audio function for sdeRay Zhang2017-02-26
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | Register ext_disp and provide audio codec ops. This enables HDMI audio functionality for DRM driver. CRs-Fixed: 2010135 Change-Id: Ide661456ab42bf6a8f13359819e39317f439a255 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | Merge "drm/msm: add hdmi audio support for sde kms"Linux Build Service Account2017-02-26
|\ \ \
| * | | drm/msm: add hdmi audio support for sde kmsRay Zhang2017-02-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add the specific audio driver for SDE HDMI including audio ACR and InfoFrame programming. CRs-Fixed: 2010135 Change-Id: I24a76e4f41aad976d5215b68f6f7f00d1bbb3de0 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
| * | | drm/msm: add info frame configuration for hdmi controllerJin Li2017-02-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When HDMI controller is configured as non-DVI with CEA mode, SDE driver needs to program AVI, VSIF and SPD information into HW to generate correct info frame. CRs-Fixed: 2010135 Change-Id: Ib218761c63b13aa229fc24519ceb9ccd0bd34ce2 Signed-off-by: Jin Li <jinl@codeaurora.org> Signed-off-by: Ray Zhang <rayz@codeaurora.org>
| * | | drm/msm: add sde hdmi bridge implementationRay Zhang2017-02-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add a private HDMI bridge implementation for SDE. This is intended to support new HDMI features specific to SDE driver. CRs-Fixed: 2010135 Change-Id: I0269b1ff79d8be4f48643a9e4e904427791ac1ac Signed-off-by: Ray Zhang <rayz@codeaurora.org>
* | | | drm/msm: Add BACKLIGHT_CLASS_DEVICE as a dependencyJordan Crouse2017-02-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | One of the SDE files requires BACKLIGHT_CLASS_DEVICE so make sure it gets selected in the Kconfig. Change-Id: Ic0dedbadc5bca3ea536d94d54e3683d656bd4aba Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | | Merge "drm/msm: mdp5: Correctly return ERR_PTR for mdp5_cfg_init"Linux Build Service Account2017-02-23
|\ \ \ \
| * | | | drm/msm: mdp5: Correctly return ERR_PTR for mdp5_cfg_initJordan Crouse2017-02-09
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The caller for mdp5_cfg_init expects a valid pointer or a ERR_PTR encoded error. Returning NULL leads to a kernel oops. Change-Id: Ic0dedbad44e37bdbc458fad6713d42ab249428d8 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
* | | | | Merge "drm/msm: add support for 5V HPD pin for msm8998"Linux Build Service Account2017-02-23
|\ \ \ \ \ | | |/ / / | |/| | |
| * | | | drm/msm: add support for 5V HPD pin for msm8998Abhinav Kumar2017-02-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | msm8998 needs an additional 5V pin to be enabled to power the HPD circuit. This change enables the support for this pin. Change-Id: I42f91265ce56ff5505e3d9c2382858fe6c1be52b Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
* | | | | Merge "drm/msm: enable hpd event support for hdmi display"Linux Build Service Account2017-02-23
|\| | | |