mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-12 23:33:55 +08:00
drm-misc-next for 5.16:
UAPI Changes: Cross-subsystem Changes: Core Changes: - fbdev: Fix double-free, Remove unused scrolling acceleration - locking: improve logging for contented locks without backoff - dma-buf: Add dma_resv_for_each_fence iterator, and conversion of users Driver Changes: - nouveau: Various code style improvements - bridge: HPD improvements for lt9611uxc, eDP aux-bus support for ps8640, lvds-codec data-mapping selection support - panels: Vivax TPC-9150, Innolux G070Y2-T02, LOGIC Technologies LTTD800480070-L2RT, Sharp LS060T1SX01, -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCYWgczwAKCRDj7w1vZxhR xTwlAP9uzjFJqG22inn1fchteZMTvJG0JxLjdO9l6ORUMzsj/AD/SNC1MYAuUv3Y /McjFrd1C2yVvKfdmI+21SsY2q95sAE= =AwQ7 -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2021-10-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for 5.16: UAPI Changes: Cross-subsystem Changes: Core Changes: - fbdev: Fix double-free, Remove unused scrolling acceleration - locking: improve logging for contented locks without backoff - dma-buf: Add dma_resv_for_each_fence iterator, and conversion of users Driver Changes: - nouveau: Various code style improvements - bridge: HPD improvements for lt9611uxc, eDP aux-bus support for ps8640, lvds-codec data-mapping selection support - panels: Vivax TPC-9150, Innolux G070Y2-T02, LOGIC Technologies LTTD800480070-L2RT, Sharp LS060T1SX01, Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20211014120452.2wicnt6hobu3kbwb@gilmour
This commit is contained in:
commit
5275a99e35
@ -49,11 +49,26 @@ properties:
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description: |
|
||||
For LVDS encoders, port 0 is the parallel input
|
||||
For LVDS decoders, port 0 is the LVDS input
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-mapping:
|
||||
enum:
|
||||
- jeida-18
|
||||
- jeida-24
|
||||
- vesa-24
|
||||
description: |
|
||||
The color signals mapping order. See details in
|
||||
Documentation/devicetree/bindings/display/panel/lvds.yaml
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: |
|
||||
@ -71,6 +86,22 @@ properties:
|
||||
|
||||
power-supply: true
|
||||
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: lvds-decoder
|
||||
then:
|
||||
properties:
|
||||
ports:
|
||||
properties:
|
||||
port@0:
|
||||
properties:
|
||||
endpoint:
|
||||
properties:
|
||||
data-mapping: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ports
|
||||
|
@ -40,6 +40,9 @@ properties:
|
||||
vdd33-supply:
|
||||
description: Regulator for 3.3V digital core power.
|
||||
|
||||
aux-bus:
|
||||
$ref: /schemas/display/dp-aux-bus.yaml#
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
@ -98,7 +101,21 @@ examples:
|
||||
reg = <1>;
|
||||
ps8640_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
aux-bus {
|
||||
panel {
|
||||
compatible = "boe,nv133fhm-n62";
|
||||
power-supply = <&pp3300_dx_edp>;
|
||||
backlight = <&backlight>;
|
||||
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&ps8640_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -166,6 +166,8 @@ properties:
|
||||
- innolux,at070tn92
|
||||
# Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD panel
|
||||
- innolux,g070y2-l01
|
||||
# Innolux G070Y2-T02 7" WVGA (800x480) TFT LCD TTL panel
|
||||
- innolux,g070y2-t02
|
||||
# Innolux Corporation 10.1" G101ICE-L01 WXGA (1280x800) LVDS panel
|
||||
- innolux,g101ice-l01
|
||||
# Innolux Corporation 12.1" WXGA (1280x800) TFT LCD panel
|
||||
@ -309,6 +311,8 @@ properties:
|
||||
- urt,umsh-8596md-11t
|
||||
- urt,umsh-8596md-19t
|
||||
- urt,umsh-8596md-20t
|
||||
# Vivax TPC-9150 tablet 9.0" WSVGA TFT LCD panel
|
||||
- vivax,tpc9150-panel
|
||||
# VXT 800x480 color TFT LCD panel
|
||||
- vxt,vl050-8048nt-c01
|
||||
# Winstar Display Corporation 3.5" QVGA (320x240) TFT LCD panel
|
||||
@ -317,6 +321,7 @@ properties:
|
||||
- yes-optoelectronics,ytc700tlag-05-201c
|
||||
|
||||
backlight: true
|
||||
ddc-i2c-bus: true
|
||||
enable-gpios: true
|
||||
port: true
|
||||
power-supply: true
|
||||
|
@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/sharp,ls060t1sx01.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sharp Microelectronics 6.0" FullHD TFT LCD panel
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryskov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sharp,ls060t1sx01
|
||||
|
||||
reg: true
|
||||
backlight: true
|
||||
reset-gpios: true
|
||||
port: true
|
||||
|
||||
avdd-supply:
|
||||
description: handle of the regulator that provides the positive supply voltage
|
||||
avee-supply:
|
||||
description: handle of the regulator that provides the negative supply voltage
|
||||
vddi-supply:
|
||||
description: handle of the regulator that provides the I/O supply voltage
|
||||
vddh-supply:
|
||||
description: handle of the regulator that provides the analog supply voltage
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "sharp,ls060t1sx01";
|
||||
reg = <0>;
|
||||
avdd-supply = <&pm8941_l22>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&pm8916_gpios 25 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1264,6 +1264,8 @@ patternProperties:
|
||||
description: Vitesse Semiconductor Corporation
|
||||
"^vivante,.*":
|
||||
description: Vivante Corporation
|
||||
"^vivax,.*":
|
||||
description: Vivax brand by M SAN Grupa d.o.o.
|
||||
"^vocore,.*":
|
||||
description: VoCore Studio
|
||||
"^voipac,.*":
|
||||
|
@ -314,16 +314,19 @@ Level: Advanced
|
||||
Garbage collect fbdev scrolling acceleration
|
||||
--------------------------------------------
|
||||
|
||||
Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode =
|
||||
SCROLL_REDRAW. There's a ton of code this will allow us to remove:
|
||||
Scroll acceleration has been disabled in fbcon. Now it works as the old
|
||||
SCROLL_REDRAW mode. A ton of code was removed in fbcon.c and the hook bmove was
|
||||
removed from fbcon_ops.
|
||||
Remaining tasks:
|
||||
|
||||
- lots of code in fbcon.c
|
||||
|
||||
- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called
|
||||
- a bunch of the hooks in fbcon_ops could be removed or simplified by calling
|
||||
directly instead of the function table (with a switch on p->rotate)
|
||||
|
||||
- fb_copyarea is unused after this, and can be deleted from all drivers
|
||||
|
||||
- after that, fb_copyarea can be deleted from fb_ops in include/linux/fb.h as
|
||||
well as cfb_copyarea
|
||||
|
||||
Note that not all acceleration code can be deleted, since clearing and cursor
|
||||
support is still accelerated, which might be good candidates for further
|
||||
deletion projects.
|
||||
|
@ -209,19 +209,14 @@ static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
|
||||
dma_fence_put(fence);
|
||||
}
|
||||
|
||||
static bool dma_buf_poll_shared(struct dma_resv *resv,
|
||||
static bool dma_buf_poll_add_cb(struct dma_resv *resv, bool write,
|
||||
struct dma_buf_poll_cb_t *dcb)
|
||||
{
|
||||
struct dma_resv_list *fobj = dma_resv_shared_list(resv);
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int i, r;
|
||||
int r;
|
||||
|
||||
if (!fobj)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < fobj->shared_count; ++i) {
|
||||
fence = rcu_dereference_protected(fobj->shared[i],
|
||||
dma_resv_held(resv));
|
||||
dma_resv_for_each_fence(&cursor, resv, write, fence) {
|
||||
dma_fence_get(fence);
|
||||
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
|
||||
if (!r)
|
||||
@ -232,24 +227,6 @@ static bool dma_buf_poll_shared(struct dma_resv *resv,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dma_buf_poll_excl(struct dma_resv *resv,
|
||||
struct dma_buf_poll_cb_t *dcb)
|
||||
{
|
||||
struct dma_fence *fence = dma_resv_excl_fence(resv);
|
||||
int r;
|
||||
|
||||
if (!fence)
|
||||
return false;
|
||||
|
||||
dma_fence_get(fence);
|
||||
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
|
||||
if (!r)
|
||||
return true;
|
||||
dma_fence_put(fence);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
||||
{
|
||||
struct dma_buf *dmabuf;
|
||||
@ -282,8 +259,7 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
||||
spin_unlock_irq(&dmabuf->poll.lock);
|
||||
|
||||
if (events & EPOLLOUT) {
|
||||
if (!dma_buf_poll_shared(resv, dcb) &&
|
||||
!dma_buf_poll_excl(resv, dcb))
|
||||
if (!dma_buf_poll_add_cb(resv, true, dcb))
|
||||
/* No callback queued, wake up any other waiters */
|
||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
||||
else
|
||||
@ -303,7 +279,7 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
||||
spin_unlock_irq(&dmabuf->poll.lock);
|
||||
|
||||
if (events & EPOLLIN) {
|
||||
if (!dma_buf_poll_excl(resv, dcb))
|
||||
if (!dma_buf_poll_add_cb(resv, false, dcb))
|
||||
/* No callback queued, wake up any other waiters */
|
||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
||||
else
|
||||
@ -1356,10 +1332,9 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct dma_buf *buf_obj;
|
||||
struct dma_buf_attachment *attach_obj;
|
||||
struct dma_resv *robj;
|
||||
struct dma_resv_list *fobj;
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int count = 0, attach_count, shared_count, i;
|
||||
int count = 0, attach_count;
|
||||
size_t size = 0;
|
||||
int ret;
|
||||
|
||||
@ -1386,21 +1361,10 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||
file_inode(buf_obj->file)->i_ino,
|
||||
buf_obj->name ?: "");
|
||||
|
||||
robj = buf_obj->resv;
|
||||
fence = dma_resv_excl_fence(robj);
|
||||
if (fence)
|
||||
seq_printf(s, "\tExclusive fence: %s %s %ssignalled\n",
|
||||
fence->ops->get_driver_name(fence),
|
||||
fence->ops->get_timeline_name(fence),
|
||||
dma_fence_is_signaled(fence) ? "" : "un");
|
||||
|
||||
fobj = rcu_dereference_protected(robj->fence,
|
||||
dma_resv_held(robj));
|
||||
shared_count = fobj ? fobj->shared_count : 0;
|
||||
for (i = 0; i < shared_count; i++) {
|
||||
fence = rcu_dereference_protected(fobj->shared[i],
|
||||
dma_resv_held(robj));
|
||||
seq_printf(s, "\tShared fence: %s %s %ssignalled\n",
|
||||
dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
|
||||
seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
|
||||
dma_resv_iter_is_exclusive(&cursor) ?
|
||||
"Exclusive" : "Shared",
|
||||
fence->ops->get_driver_name(fence),
|
||||
fence->ops->get_timeline_name(fence),
|
||||
dma_fence_is_signaled(fence) ? "" : "un");
|
||||
|
@ -333,10 +333,14 @@ static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor)
|
||||
{
|
||||
cursor->seq = read_seqcount_begin(&cursor->obj->seq);
|
||||
cursor->index = -1;
|
||||
if (cursor->all_fences)
|
||||
cursor->shared_count = 0;
|
||||
if (cursor->all_fences) {
|
||||
cursor->fences = dma_resv_shared_list(cursor->obj);
|
||||
else
|
||||
if (cursor->fences)
|
||||
cursor->shared_count = cursor->fences->shared_count;
|
||||
} else {
|
||||
cursor->fences = NULL;
|
||||
}
|
||||
cursor->is_restarted = true;
|
||||
}
|
||||
|
||||
@ -363,7 +367,7 @@ static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor)
|
||||
continue;
|
||||
|
||||
} else if (!cursor->fences ||
|
||||
cursor->index >= cursor->fences->shared_count) {
|
||||
cursor->index >= cursor->shared_count) {
|
||||
cursor->fence = NULL;
|
||||
break;
|
||||
|
||||
@ -423,6 +427,57 @@ struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor)
|
||||
}
|
||||
EXPORT_SYMBOL(dma_resv_iter_next_unlocked);
|
||||
|
||||
/**
|
||||
* dma_resv_iter_first - first fence from a locked dma_resv object
|
||||
* @cursor: cursor to record the current position
|
||||
*
|
||||
* Return the first fence in the dma_resv object while holding the
|
||||
* &dma_resv.lock.
|
||||
*/
|
||||
struct dma_fence *dma_resv_iter_first(struct dma_resv_iter *cursor)
|
||||
{
|
||||
struct dma_fence *fence;
|
||||
|
||||
dma_resv_assert_held(cursor->obj);
|
||||
|
||||
cursor->index = 0;
|
||||
if (cursor->all_fences)
|
||||
cursor->fences = dma_resv_shared_list(cursor->obj);
|
||||
else
|
||||
cursor->fences = NULL;
|
||||
|
||||
fence = dma_resv_excl_fence(cursor->obj);
|
||||
if (!fence)
|
||||
fence = dma_resv_iter_next(cursor);
|
||||
|
||||
cursor->is_restarted = true;
|
||||
return fence;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_resv_iter_first);
|
||||
|
||||
/**
|
||||
* dma_resv_iter_next - next fence from a locked dma_resv object
|
||||
* @cursor: cursor to record the current position
|
||||
*
|
||||
* Return the next fences from the dma_resv object while holding the
|
||||
* &dma_resv.lock.
|
||||
*/
|
||||
struct dma_fence *dma_resv_iter_next(struct dma_resv_iter *cursor)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
dma_resv_assert_held(cursor->obj);
|
||||
|
||||
cursor->is_restarted = false;
|
||||
if (!cursor->fences || cursor->index >= cursor->fences->shared_count)
|
||||
return NULL;
|
||||
|
||||
idx = cursor->index++;
|
||||
return rcu_dereference_protected(cursor->fences->shared[idx],
|
||||
dma_resv_held(cursor->obj));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_resv_iter_next);
|
||||
|
||||
/**
|
||||
* dma_resv_copy_fences - Copy all fences from src to dst.
|
||||
* @dst: the destination reservation object
|
||||
@ -448,10 +503,8 @@ int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
|
||||
dma_resv_list_free(list);
|
||||
dma_fence_put(excl);
|
||||
|
||||
if (cursor.fences) {
|
||||
unsigned int cnt = cursor.fences->shared_count;
|
||||
|
||||
list = dma_resv_list_alloc(cnt);
|
||||
if (cursor.shared_count) {
|
||||
list = dma_resv_list_alloc(cursor.shared_count);
|
||||
if (!list) {
|
||||
dma_resv_iter_end(&cursor);
|
||||
return -ENOMEM;
|
||||
@ -522,7 +575,7 @@ int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl,
|
||||
if (fence_excl)
|
||||
dma_fence_put(*fence_excl);
|
||||
|
||||
count = cursor.fences ? cursor.fences->shared_count : 0;
|
||||
count = cursor.shared_count;
|
||||
count += fence_excl ? 0 : 1;
|
||||
|
||||
/* Eventually re-allocate the array */
|
||||
|
@ -100,6 +100,21 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
|
||||
This has the potential to use a lot of memory and print some very
|
||||
large kernel messages. If in doubt, say "N".
|
||||
|
||||
config DRM_DEBUG_MODESET_LOCK
|
||||
bool "Enable backtrace history for lock contention"
|
||||
depends on STACKTRACE_SUPPORT
|
||||
depends on DEBUG_KERNEL
|
||||
depends on EXPERT
|
||||
select STACKDEPOT
|
||||
default y if DEBUG_WW_MUTEX_SLOWPATH
|
||||
help
|
||||
Enable debug tracing of failures to gracefully handle drm modeset lock
|
||||
contention. A history of each drm modeset lock path hitting -EDEADLK
|
||||
will be saved until gracefully handled, and the backtrace will be
|
||||
printed when attempting to lock a contended lock.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_FBDEV_EMULATION
|
||||
bool "Enable legacy fbdev support for your modesetting driver"
|
||||
depends on DRM
|
||||
|
@ -167,9 +167,10 @@ static void lt9611uxc_hpd_work(struct work_struct *work)
|
||||
struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work);
|
||||
bool connected;
|
||||
|
||||
if (lt9611uxc->connector.dev)
|
||||
drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
|
||||
else {
|
||||
if (lt9611uxc->connector.dev) {
|
||||
if (lt9611uxc->connector.dev->mode_config.funcs)
|
||||
drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
|
||||
} else {
|
||||
|
||||
mutex_lock(<9611uxc->ocm_lock);
|
||||
connected = lt9611uxc->hdmi_connected;
|
||||
@ -339,6 +340,8 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lt9611uxc->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
drm_connector_helper_add(<9611uxc->connector,
|
||||
<9611uxc_bridge_connector_helper_funcs);
|
||||
ret = drm_connector_init(bridge->dev, <9611uxc->connector,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
@ -22,6 +23,7 @@ struct lvds_codec {
|
||||
struct regulator *vcc;
|
||||
struct gpio_desc *powerdown_gpio;
|
||||
u32 connector_type;
|
||||
unsigned int bus_format;
|
||||
};
|
||||
|
||||
static inline struct lvds_codec *to_lvds_codec(struct drm_bridge *bridge)
|
||||
@ -74,12 +76,50 @@ static const struct drm_bridge_funcs funcs = {
|
||||
.disable = lvds_codec_disable,
|
||||
};
|
||||
|
||||
#define MAX_INPUT_SEL_FORMATS 1
|
||||
static u32 *
|
||||
lvds_codec_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts)
|
||||
{
|
||||
struct lvds_codec *lvds_codec = to_lvds_codec(bridge);
|
||||
u32 *input_fmts;
|
||||
|
||||
*num_input_fmts = 0;
|
||||
|
||||
input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
|
||||
GFP_KERNEL);
|
||||
if (!input_fmts)
|
||||
return NULL;
|
||||
|
||||
input_fmts[0] = lvds_codec->bus_format;
|
||||
*num_input_fmts = MAX_INPUT_SEL_FORMATS;
|
||||
|
||||
return input_fmts;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs funcs_decoder = {
|
||||
.attach = lvds_codec_attach,
|
||||
.enable = lvds_codec_enable,
|
||||
.disable = lvds_codec_disable,
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_get_input_bus_fmts = lvds_codec_atomic_get_input_bus_fmts,
|
||||
};
|
||||
|
||||
static int lvds_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *panel_node;
|
||||
struct device_node *bus_node;
|
||||
struct drm_panel *panel;
|
||||
struct lvds_codec *lvds_codec;
|
||||
const char *mapping;
|
||||
int ret;
|
||||
|
||||
lvds_codec = devm_kzalloc(dev, sizeof(*lvds_codec), GFP_KERNEL);
|
||||
if (!lvds_codec)
|
||||
@ -119,13 +159,47 @@ static int lvds_codec_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(lvds_codec->panel_bridge))
|
||||
return PTR_ERR(lvds_codec->panel_bridge);
|
||||
|
||||
lvds_codec->bridge.funcs = &funcs;
|
||||
|
||||
/*
|
||||
* Decoder input LVDS format is a property of the decoder chip or even
|
||||
* its strapping. Handle data-mapping the same way lvds-panel does. In
|
||||
* case data-mapping is not present, do nothing, since there are still
|
||||
* legacy bindings which do not specify this property.
|
||||
*/
|
||||
if (lvds_codec->connector_type != DRM_MODE_CONNECTOR_LVDS) {
|
||||
bus_node = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
|
||||
if (!bus_node) {
|
||||
dev_dbg(dev, "bus DT node not found\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = of_property_read_string(bus_node, "data-mapping",
|
||||
&mapping);
|
||||
of_node_put(bus_node);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "missing 'data-mapping' DT property\n");
|
||||
} else {
|
||||
if (!strcmp(mapping, "jeida-18")) {
|
||||
lvds_codec->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
|
||||
} else if (!strcmp(mapping, "jeida-24")) {
|
||||
lvds_codec->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
|
||||
} else if (!strcmp(mapping, "vesa-24")) {
|
||||
lvds_codec->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
|
||||
} else {
|
||||
dev_err(dev, "invalid 'data-mapping' DT property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
lvds_codec->bridge.funcs = &funcs_decoder;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The panel_bridge bridge is attached to the panel's of_node,
|
||||
* but we need a bridge attached to our of_node for our user
|
||||
* to look up.
|
||||
*/
|
||||
lvds_codec->bridge.of_node = dev->of_node;
|
||||
lvds_codec->bridge.funcs = &funcs;
|
||||
drm_bridge_add(&lvds_codec->bridge);
|
||||
|
||||
platform_set_drvdata(pdev, lvds_codec);
|
||||
|
@ -939,6 +939,40 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
|
||||
drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0);
|
||||
}
|
||||
|
||||
static u32 *nwl_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts)
|
||||
{
|
||||
u32 *input_fmts, input_fmt;
|
||||
|
||||
*num_input_fmts = 0;
|
||||
|
||||
switch (output_fmt) {
|
||||
/* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
|
||||
case MEDIA_BUS_FMT_FIXED:
|
||||
input_fmt = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_RGB888_1X24:
|
||||
case MEDIA_BUS_FMT_RGB666_1X18:
|
||||
case MEDIA_BUS_FMT_RGB565_1X16:
|
||||
input_fmt = output_fmt;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
|
||||
if (!input_fmts)
|
||||
return NULL;
|
||||
input_fmts[0] = input_fmt;
|
||||
*num_input_fmts = 1;
|
||||
|
||||
return input_fmts;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
@ -946,6 +980,7 @@ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
|
||||
.atomic_check = nwl_dsi_bridge_atomic_check,
|
||||
.atomic_enable = nwl_dsi_bridge_atomic_enable,
|
||||
.atomic_disable = nwl_dsi_bridge_atomic_disable,
|
||||
.atomic_get_input_bus_fmts = nwl_bridge_atomic_get_input_bus_fmts,
|
||||
.mode_set = nwl_dsi_bridge_mode_set,
|
||||
.mode_valid = nwl_dsi_bridge_mode_valid,
|
||||
.attach = nwl_dsi_bridge_attach,
|
||||
|
@ -288,6 +288,19 @@ err_dsi_attach:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sn65dsi83_detach(struct drm_bridge *bridge)
|
||||
{
|
||||
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
|
||||
|
||||
if (!ctx->dsi)
|
||||
return;
|
||||
|
||||
mipi_dsi_detach(ctx->dsi);
|
||||
mipi_dsi_device_unregister(ctx->dsi);
|
||||
drm_bridge_remove(&ctx->bridge);
|
||||
ctx->dsi = NULL;
|
||||
}
|
||||
|
||||
static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
{
|
||||
@ -583,6 +596,7 @@ sn65dsi83_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
|
||||
static const struct drm_bridge_funcs sn65dsi83_funcs = {
|
||||
.attach = sn65dsi83_attach,
|
||||
.detach = sn65dsi83_detach,
|
||||
.atomic_pre_enable = sn65dsi83_atomic_pre_enable,
|
||||
.atomic_enable = sn65dsi83_atomic_enable,
|
||||
.atomic_disable = sn65dsi83_atomic_disable,
|
||||
@ -697,9 +711,6 @@ static int sn65dsi83_remove(struct i2c_client *client)
|
||||
{
|
||||
struct sn65dsi83 *ctx = i2c_get_clientdata(client);
|
||||
|
||||
mipi_dsi_detach(ctx->dsi);
|
||||
mipi_dsi_device_unregister(ctx->dsi);
|
||||
drm_bridge_remove(&ctx->bridge);
|
||||
of_node_put(ctx->host_node);
|
||||
|
||||
return 0;
|
||||
|
@ -625,6 +625,8 @@ int drm_connector_register_all(struct drm_device *dev)
|
||||
*
|
||||
* In contrast to the other drm_get_*_name functions this one here returns a
|
||||
* const pointer and hence is threadsafe.
|
||||
*
|
||||
* Returns: connector status string
|
||||
*/
|
||||
const char *drm_get_connector_status_name(enum drm_connector_status status)
|
||||
{
|
||||
@ -707,7 +709,7 @@ __drm_connector_put_safe(struct drm_connector *conn)
|
||||
* drm_connector_list_iter_next - return next connector
|
||||
* @iter: connector_list iterator
|
||||
*
|
||||
* Returns the next connector for @iter, or NULL when the list walk has
|
||||
* Returns: the next connector for @iter, or NULL when the list walk has
|
||||
* completed.
|
||||
*/
|
||||
struct drm_connector *
|
||||
@ -780,6 +782,8 @@ static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
|
||||
*
|
||||
* Note you could abuse this and return something out of bounds, but that
|
||||
* would be a caller error. No unscrubbed user data should make it here.
|
||||
*
|
||||
* Returns: string describing an enumerated subpixel property
|
||||
*/
|
||||
const char *drm_get_subpixel_order_name(enum subpixel_order order)
|
||||
{
|
||||
@ -809,6 +813,9 @@ static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
|
||||
* Store the supported bus formats in display info structure.
|
||||
* See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
|
||||
* a full list of available formats.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_display_info_set_bus_formats(struct drm_display_info *info,
|
||||
const u32 *formats,
|
||||
@ -1326,6 +1333,8 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
|
||||
* @dev: DRM device
|
||||
*
|
||||
* Called by a driver the first time a DVI-I connector is made.
|
||||
*
|
||||
* Returns: %0
|
||||
*/
|
||||
int drm_mode_create_dvi_i_properties(struct drm_device *dev)
|
||||
{
|
||||
@ -1397,6 +1406,8 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
|
||||
* Game:
|
||||
* Content type is game
|
||||
*
|
||||
* The meaning of each content type is defined in CTA-861-G table 15.
|
||||
*
|
||||
* Drivers can set up this property by calling
|
||||
* drm_connector_attach_content_type_property(). Decoding to
|
||||
* infoframe values is done through drm_hdmi_avi_infoframe_content_type().
|
||||
@ -1407,6 +1418,8 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
|
||||
* @connector: connector to attach content type property on.
|
||||
*
|
||||
* Called by a driver the first time a HDMI connector is made.
|
||||
*
|
||||
* Returns: %0
|
||||
*/
|
||||
int drm_connector_attach_content_type_property(struct drm_connector *connector)
|
||||
{
|
||||
@ -1487,6 +1500,9 @@ EXPORT_SYMBOL(drm_connector_attach_tv_margin_properties);
|
||||
* creates the TV margin properties for a given device. No need to call this
|
||||
* function for an SDTV connector, it's already called from
|
||||
* drm_mode_create_tv_properties().
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_mode_create_tv_margin_properties(struct drm_device *dev)
|
||||
{
|
||||
@ -1527,6 +1543,9 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
|
||||
* the TV specific connector properties for a given device. Caller is
|
||||
* responsible for allocating a list of format names and passing them to
|
||||
* this routine.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_mode_create_tv_properties(struct drm_device *dev,
|
||||
unsigned int num_modes,
|
||||
@ -1622,6 +1641,8 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
|
||||
* Atomic drivers should use drm_connector_attach_scaling_mode_property()
|
||||
* instead to correctly assign &drm_connector_state.scaling_mode
|
||||
* in the atomic state.
|
||||
*
|
||||
* Returns: %0
|
||||
*/
|
||||
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
|
||||
{
|
||||
@ -1939,6 +1960,9 @@ EXPORT_SYMBOL(drm_mode_create_content_type_property);
|
||||
* @dev: DRM device
|
||||
*
|
||||
* Create the suggested x/y offset property for connectors.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
|
||||
{
|
||||
@ -2312,8 +2336,8 @@ int drm_connector_set_panel_orientation(
|
||||
EXPORT_SYMBOL(drm_connector_set_panel_orientation);
|
||||
|
||||
/**
|
||||
* drm_connector_set_panel_orientation_with_quirk -
|
||||
* set the connector's panel_orientation after checking for quirks
|
||||
* drm_connector_set_panel_orientation_with_quirk - set the
|
||||
* connector's panel_orientation after checking for quirks
|
||||
* @connector: connector for which to init the panel-orientation property.
|
||||
* @panel_orientation: drm_panel_orientation value to set
|
||||
* @width: width in pixels of the panel, used for panel quirk detection
|
||||
@ -2597,7 +2621,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
|
||||
|
||||
/**
|
||||
* drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
|
||||
* @connector: connector to report the event on
|
||||
* @connector_fwnode: fwnode_handle to report the event on
|
||||
*
|
||||
* On some hardware a hotplug event notification may come from outside the display
|
||||
* driver / device. An example of this is some USB Type-C setups where the hardware
|
||||
|
@ -1340,31 +1340,15 @@ int drm_gem_fence_array_add_implicit(struct xarray *fence_array,
|
||||
struct drm_gem_object *obj,
|
||||
bool write)
|
||||
{
|
||||
int ret;
|
||||
struct dma_fence **fences;
|
||||
unsigned int i, fence_count;
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int ret = 0;
|
||||
|
||||
if (!write) {
|
||||
struct dma_fence *fence =
|
||||
dma_resv_get_excl_unlocked(obj->resv);
|
||||
|
||||
return drm_gem_fence_array_add(fence_array, fence);
|
||||
}
|
||||
|
||||
ret = dma_resv_get_fences(obj->resv, NULL,
|
||||
&fence_count, &fences);
|
||||
if (ret || !fence_count)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < fence_count; i++) {
|
||||
ret = drm_gem_fence_array_add(fence_array, fences[i]);
|
||||
dma_resv_for_each_fence(&cursor, obj->resv, write, fence) {
|
||||
ret = drm_gem_fence_array_add(fence_array, fence);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
for (; i < fence_count; i++)
|
||||
dma_fence_put(fences[i]);
|
||||
kfree(fences);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_fence_array_add_implicit);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_modeset_lock.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
/**
|
||||
* DOC: kms locking
|
||||
@ -77,6 +78,45 @@
|
||||
|
||||
static DEFINE_WW_CLASS(crtc_ww_class);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_DEBUG_MODESET_LOCK)
|
||||
static noinline depot_stack_handle_t __stack_depot_save(void)
|
||||
{
|
||||
unsigned long entries[8];
|
||||
unsigned int n;
|
||||
|
||||
n = stack_trace_save(entries, ARRAY_SIZE(entries), 1);
|
||||
|
||||
return stack_depot_save(entries, n, GFP_NOWAIT | __GFP_NOWARN);
|
||||
}
|
||||
|
||||
static void __stack_depot_print(depot_stack_handle_t stack_depot)
|
||||
{
|
||||
struct drm_printer p = drm_debug_printer("drm_modeset_lock");
|
||||
unsigned long *entries;
|
||||
unsigned int nr_entries;
|
||||
char *buf;
|
||||
|
||||
buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
nr_entries = stack_depot_fetch(stack_depot, &entries);
|
||||
stack_trace_snprint(buf, PAGE_SIZE, entries, nr_entries, 2);
|
||||
|
||||
drm_printf(&p, "attempting to lock a contended lock without backoff:\n%s", buf);
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
#else /* CONFIG_DRM_DEBUG_MODESET_LOCK */
|
||||
static depot_stack_handle_t __stack_depot_save(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void __stack_depot_print(depot_stack_handle_t stack_depot)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_DRM_DEBUG_MODESET_LOCK */
|
||||
|
||||
/**
|
||||
* drm_modeset_lock_all - take all modeset locks
|
||||
* @dev: DRM device
|
||||
@ -225,7 +265,9 @@ EXPORT_SYMBOL(drm_modeset_acquire_fini);
|
||||
*/
|
||||
void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
WARN_ON(ctx->contended);
|
||||
if (WARN_ON(ctx->contended))
|
||||
__stack_depot_print(ctx->stack_depot);
|
||||
|
||||
while (!list_empty(&ctx->locked)) {
|
||||
struct drm_modeset_lock *lock;
|
||||
|
||||
@ -243,7 +285,8 @@ static inline int modeset_lock(struct drm_modeset_lock *lock,
|
||||
{
|
||||
int ret;
|
||||
|
||||
WARN_ON(ctx->contended);
|
||||
if (WARN_ON(ctx->contended))
|
||||
__stack_depot_print(ctx->stack_depot);
|
||||
|
||||
if (ctx->trylock_only) {
|
||||
lockdep_assert_held(&ctx->ww_ctx);
|
||||
@ -274,6 +317,7 @@ static inline int modeset_lock(struct drm_modeset_lock *lock,
|
||||
ret = 0;
|
||||
} else if (ret == -EDEADLK) {
|
||||
ctx->contended = lock;
|
||||
ctx->stack_depot = __stack_depot_save();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -296,6 +340,7 @@ int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx)
|
||||
struct drm_modeset_lock *contended = ctx->contended;
|
||||
|
||||
ctx->contended = NULL;
|
||||
ctx->stack_depot = 0;
|
||||
|
||||
if (WARN_ON(!contended))
|
||||
return 0;
|
||||
|
@ -123,7 +123,6 @@ static int drm_plane_helper_check_update(struct drm_plane *plane,
|
||||
.crtc_w = drm_rect_width(dst),
|
||||
.crtc_h = drm_rect_height(dst),
|
||||
.rotation = rotation,
|
||||
.visible = *visible,
|
||||
};
|
||||
struct drm_crtc_state crtc_state = {
|
||||
.crtc = crtc,
|
||||
|
@ -1537,38 +1537,14 @@ i915_request_await_object(struct i915_request *to,
|
||||
struct drm_i915_gem_object *obj,
|
||||
bool write)
|
||||
{
|
||||
struct dma_fence *excl;
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int ret = 0;
|
||||
|
||||
if (write) {
|
||||
struct dma_fence **shared;
|
||||
unsigned int count, i;
|
||||
|
||||
ret = dma_resv_get_fences(obj->base.resv, &excl, &count,
|
||||
&shared);
|
||||
dma_resv_for_each_fence(&cursor, obj->base.resv, write, fence) {
|
||||
ret = i915_request_await_dma_fence(to, fence);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = i915_request_await_dma_fence(to, shared[i]);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
dma_fence_put(shared[i]);
|
||||
}
|
||||
|
||||
for (; i < count; i++)
|
||||
dma_fence_put(shared[i]);
|
||||
kfree(shared);
|
||||
} else {
|
||||
excl = dma_resv_get_excl_unlocked(obj->base.resv);
|
||||
}
|
||||
|
||||
if (excl) {
|
||||
if (ret == 0)
|
||||
ret = i915_request_await_dma_fence(to, excl);
|
||||
|
||||
dma_fence_put(excl);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -88,7 +88,7 @@ static void mxsfb_set_formats(struct mxsfb_drm_private *mxsfb,
|
||||
ctrl |= CTRL_BUS_WIDTH_24;
|
||||
break;
|
||||
default:
|
||||
dev_err(drm->dev, "Unknown media bus format %d\n", bus_format);
|
||||
dev_err(drm->dev, "Unknown media bus format 0x%x\n", bus_format);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -362,6 +362,12 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
drm_atomic_get_new_bridge_state(state,
|
||||
mxsfb->bridge);
|
||||
bus_format = bridge_state->input_bus_cfg.format;
|
||||
if (bus_format == MEDIA_BUS_FMT_FIXED) {
|
||||
dev_warn_once(drm->dev,
|
||||
"Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"
|
||||
"Please fix bridge driver by handling atomic_get_input_bus_fmts.\n");
|
||||
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no bridge, use bus format from connector */
|
||||
|
@ -1249,7 +1249,6 @@ nouveau_ttm_tt_populate(struct ttm_device *bdev,
|
||||
{
|
||||
struct ttm_tt *ttm_dma = (void *)ttm;
|
||||
struct nouveau_drm *drm;
|
||||
struct device *dev;
|
||||
bool slave = !!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL);
|
||||
|
||||
if (ttm_tt_is_populated(ttm))
|
||||
@ -1262,7 +1261,6 @@ nouveau_ttm_tt_populate(struct ttm_device *bdev,
|
||||
}
|
||||
|
||||
drm = nouveau_bdev(bdev);
|
||||
dev = drm->dev->dev;
|
||||
|
||||
return ttm_pool_alloc(&drm->ttm.bdev.pool, ttm, ctx);
|
||||
}
|
||||
@ -1272,7 +1270,6 @@ nouveau_ttm_tt_unpopulate(struct ttm_device *bdev,
|
||||
struct ttm_tt *ttm)
|
||||
{
|
||||
struct nouveau_drm *drm;
|
||||
struct device *dev;
|
||||
bool slave = !!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL);
|
||||
|
||||
if (slave)
|
||||
@ -1281,7 +1278,6 @@ nouveau_ttm_tt_unpopulate(struct ttm_device *bdev,
|
||||
nouveau_ttm_tt_unbind(bdev, ttm);
|
||||
|
||||
drm = nouveau_bdev(bdev);
|
||||
dev = drm->dev->dev;
|
||||
|
||||
return ttm_pool_free(&drm->ttm.bdev.pool, ttm);
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
|
||||
struct ttm_buffer_object *bo = &nvbo->bo;
|
||||
uint32_t domains = valid_domains & nvbo->valid_domains &
|
||||
(write_domains ? write_domains : read_domains);
|
||||
uint32_t pref_domains = 0;;
|
||||
uint32_t pref_domains = 0;
|
||||
|
||||
if (!domains)
|
||||
return -EINVAL;
|
||||
|
@ -21,7 +21,6 @@
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
#include "priv.h"
|
||||
#include <core/firmware.h>
|
||||
|
||||
static void *
|
||||
|
@ -299,7 +299,7 @@ nvkm_uvmm_mthd_page(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
|
||||
page = uvmm->vmm->func->page;
|
||||
for (nr = 0; page[nr].shift; nr++);
|
||||
|
||||
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
|
||||
if (!(nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
|
||||
if ((index = args->v0.index) >= nr)
|
||||
return -EINVAL;
|
||||
type = page[index].type;
|
||||
|
@ -488,7 +488,7 @@ gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, u32 argc)
|
||||
struct gp100_vmm_fault_cancel_v0 v0;
|
||||
} *args = argv;
|
||||
int ret = -ENOSYS;
|
||||
u32 inst, aper;
|
||||
u32 aper;
|
||||
|
||||
if ((ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false)))
|
||||
return ret;
|
||||
@ -502,7 +502,7 @@ gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, u32 argc)
|
||||
args->v0.inst |= 0x80000000;
|
||||
|
||||
if (!WARN_ON(nvkm_gr_ctxsw_pause(device))) {
|
||||
if ((inst = nvkm_gr_ctxsw_inst(device)) == args->v0.inst) {
|
||||
if (nvkm_gr_ctxsw_inst(device) == args->v0.inst) {
|
||||
gf100_vmm_invalidate(vmm, 0x0000001b
|
||||
/* CANCEL_TARGETED. */ |
|
||||
(args->v0.hub << 20) |
|
||||
|
@ -520,6 +520,16 @@ config DRM_PANEL_SHARP_LS043T1LE01
|
||||
Say Y here if you want to enable support for Sharp LS043T1LE01 qHD
|
||||
(540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard
|
||||
|
||||
config DRM_PANEL_SHARP_LS060T1SX01
|
||||
tristate "Sharp LS060T1SX01 FullHD video mode panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Say Y here if you want to enable support for Sharp LS060T1SX01 6.0"
|
||||
FullHD (1080x1920) DSI panel as found in Dragonboard Display Adapter
|
||||
Bundle.
|
||||
|
||||
config DRM_PANEL_SITRONIX_ST7701
|
||||
tristate "Sitronix ST7701 panel driver"
|
||||
depends on OF
|
||||
|
@ -53,6 +53,7 @@ obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
|
||||
obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
|
||||
obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
|
||||
obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
|
||||
obj-$(CONFIG_DRM_PANEL_SHARP_LS060T1SX01) += panel-sharp-ls060t1sx01.o
|
||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
|
||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o
|
||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/media-bus-format.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@ -220,6 +221,10 @@ static const struct drm_display_mode default_mode_ys = {
|
||||
.height_mm = 130,
|
||||
};
|
||||
|
||||
static const u32 mantix_bus_formats[] = {
|
||||
MEDIA_BUS_FMT_RGB888_1X24,
|
||||
};
|
||||
|
||||
static int mantix_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@ -241,6 +246,10 @@ static int mantix_get_modes(struct drm_panel *panel,
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
drm_display_info_set_bus_formats(&connector->display_info,
|
||||
mantix_bus_formats,
|
||||
ARRAY_SIZE(mantix_bus_formats));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,8 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
static int s6e63m0_dsi_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
mipi_dsi_detach(dsi);
|
||||
return s6e63m0_remove(&dsi->dev);
|
||||
s6e63m0_remove(&dsi->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e63m0_dsi_of_match[] = {
|
||||
|
@ -64,7 +64,8 @@ static int s6e63m0_spi_probe(struct spi_device *spi)
|
||||
|
||||
static int s6e63m0_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
return s6e63m0_remove(&spi->dev);
|
||||
s6e63m0_remove(&spi->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e63m0_spi_of_match[] = {
|
||||
|
@ -749,13 +749,11 @@ int s6e63m0_probe(struct device *dev, void *trsp,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(s6e63m0_probe);
|
||||
|
||||
int s6e63m0_remove(struct device *dev)
|
||||
void s6e63m0_remove(struct device *dev)
|
||||
{
|
||||
struct s6e63m0 *ctx = dev_get_drvdata(dev);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(s6e63m0_remove);
|
||||
|
||||
|
@ -35,6 +35,6 @@ int s6e63m0_probe(struct device *dev, void *trsp,
|
||||
const u8 *data,
|
||||
size_t len),
|
||||
bool dsi_mode);
|
||||
int s6e63m0_remove(struct device *dev);
|
||||
void s6e63m0_remove(struct device *dev);
|
||||
|
||||
#endif /* _PANEL_SAMSUNG_S6E63M0_H */
|
||||
|
333
drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c
Normal file
333
drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c
Normal file
@ -0,0 +1,333 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2021 Linaro Ltd.
|
||||
* Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree:
|
||||
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct sharp_ls060 {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator *vddi_supply;
|
||||
struct regulator *vddh_supply;
|
||||
struct regulator *avdd_supply;
|
||||
struct regulator *avee_supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline struct sharp_ls060 *to_sharp_ls060(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct sharp_ls060, panel);
|
||||
}
|
||||
|
||||
#define dsi_dcs_write_seq(dsi, seq...) ({ \
|
||||
static const u8 d[] = { seq }; \
|
||||
\
|
||||
mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
|
||||
})
|
||||
|
||||
static void sharp_ls060_reset(struct sharp_ls060 *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
|
||||
static int sharp_ls060_on(struct sharp_ls060 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = dsi_dcs_write_seq(dsi, 0xbb, 0x13);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to send command: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to send command: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(120);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharp_ls060_off(struct sharp_ls060 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(121);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharp_ls060_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct sharp_ls060 *ctx = to_sharp_ls060(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(ctx->vddi_supply);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regulator_enable(ctx->avdd_supply);
|
||||
if (ret < 0)
|
||||
goto err_avdd;
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
ret = regulator_enable(ctx->avee_supply);
|
||||
if (ret < 0)
|
||||
goto err_avee;
|
||||
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
ret = regulator_enable(ctx->vddh_supply);
|
||||
if (ret < 0)
|
||||
goto err_vddh;
|
||||
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
sharp_ls060_reset(ctx);
|
||||
|
||||
ret = sharp_ls060_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
goto err_on;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_on:
|
||||
regulator_disable(ctx->vddh_supply);
|
||||
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
err_vddh:
|
||||
regulator_disable(ctx->avee_supply);
|
||||
|
||||
err_avee:
|
||||
regulator_disable(ctx->avdd_supply);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
|
||||
err_avdd:
|
||||
regulator_disable(ctx->vddi_supply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sharp_ls060_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct sharp_ls060 *ctx = to_sharp_ls060(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = sharp_ls060_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
regulator_disable(ctx->vddh_supply);
|
||||
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
regulator_disable(ctx->avee_supply);
|
||||
regulator_disable(ctx->avdd_supply);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
|
||||
regulator_disable(ctx->vddi_supply);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode sharp_ls060_mode = {
|
||||
.clock = (1080 + 96 + 16 + 64) * (1920 + 4 + 1 + 16) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 96,
|
||||
.hsync_end = 1080 + 96 + 16,
|
||||
.htotal = 1080 + 96 + 16 + 64,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 4,
|
||||
.vsync_end = 1920 + 4 + 1,
|
||||
.vtotal = 1920 + 4 + 1 + 16,
|
||||
.width_mm = 75,
|
||||
.height_mm = 132,
|
||||
};
|
||||
|
||||
static int sharp_ls060_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &sharp_ls060_mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs sharp_ls060_panel_funcs = {
|
||||
.prepare = sharp_ls060_prepare,
|
||||
.unprepare = sharp_ls060_unprepare,
|
||||
.get_modes = sharp_ls060_get_modes,
|
||||
};
|
||||
|
||||
static int sharp_ls060_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct sharp_ls060 *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->vddi_supply = devm_regulator_get(dev, "vddi");
|
||||
if (IS_ERR(ctx->vddi_supply))
|
||||
return PTR_ERR(ctx->vddi_supply);
|
||||
|
||||
ctx->vddh_supply = devm_regulator_get(dev, "vddh");
|
||||
if (IS_ERR(ctx->vddh_supply))
|
||||
return PTR_ERR(ctx->vddh_supply);
|
||||
|
||||
ctx->avdd_supply = devm_regulator_get(dev, "avdd");
|
||||
if (IS_ERR(ctx->avdd_supply))
|
||||
return PTR_ERR(ctx->avdd_supply);
|
||||
|
||||
ctx->avee_supply = devm_regulator_get(dev, "avee");
|
||||
if (IS_ERR(ctx->avee_supply))
|
||||
return PTR_ERR(ctx->avee_supply);
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
ctx->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &sharp_ls060_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ret = drm_panel_of_backlight(&ctx->panel);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
drm_panel_remove(&ctx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharp_ls060_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct sharp_ls060 *ctx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(dsi);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sharp_ls060t1sx01_of_match[] = {
|
||||
{ .compatible = "sharp,ls060t1sx01" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sharp_ls060t1sx01_of_match);
|
||||
|
||||
static struct mipi_dsi_driver sharp_ls060_driver = {
|
||||
.probe = sharp_ls060_probe,
|
||||
.remove = sharp_ls060_remove,
|
||||
.driver = {
|
||||
.name = "panel-sharp-ls060t1sx01",
|
||||
.of_match_table = sharp_ls060t1sx01_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(sharp_ls060_driver);
|
||||
|
||||
MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
|
||||
MODULE_DESCRIPTION("DRM driver for Sharp LS060T1SX01 1080p video mode dsi panel");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -2370,6 +2370,38 @@ static const struct panel_desc logictechno_lt170410_2whc = {
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode logictechno_lttd800480070_l2rt_mode = {
|
||||
.clock = 33000,
|
||||
.hdisplay = 800,
|
||||
.hsync_start = 800 + 112,
|
||||
.hsync_end = 800 + 112 + 3,
|
||||
.htotal = 800 + 112 + 3 + 85,
|
||||
.vdisplay = 480,
|
||||
.vsync_start = 480 + 38,
|
||||
.vsync_end = 480 + 38 + 3,
|
||||
.vtotal = 480 + 38 + 3 + 29,
|
||||
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc logictechno_lttd800480070_l2rt = {
|
||||
.modes = &logictechno_lttd800480070_l2rt_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 154,
|
||||
.height = 86,
|
||||
},
|
||||
.delay = {
|
||||
.prepare = 45,
|
||||
.enable = 100,
|
||||
.disable = 100,
|
||||
.unprepare = 45
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
|
||||
.bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
|
||||
.connector_type = DRM_MODE_CONNECTOR_DPI,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode logictechno_lttd800480070_l6wh_rt_mode = {
|
||||
.clock = 33000,
|
||||
.hdisplay = 800,
|
||||
@ -3750,6 +3782,9 @@ static const struct of_device_id platform_of_match[] = {
|
||||
}, {
|
||||
.compatible = "logictechno,lt170410-2whc",
|
||||
.data = &logictechno_lt170410_2whc,
|
||||
}, {
|
||||
.compatible = "logictechno,lttd800480070-l2rt",
|
||||
.data = &logictechno_lttd800480070_l2rt,
|
||||
}, {
|
||||
.compatible = "logictechno,lttd800480070-l6wh-rt",
|
||||
.data = &logictechno_lttd800480070_l6wh_rt,
|
||||
|
@ -453,6 +453,10 @@ disable_vcc:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const u32 mantix_bus_formats[] = {
|
||||
MEDIA_BUS_FMT_RGB888_1X24,
|
||||
};
|
||||
|
||||
static int st7703_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@ -474,6 +478,10 @@ static int st7703_get_modes(struct drm_panel *panel,
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
drm_display_info_set_bus_formats(&connector->display_info,
|
||||
mantix_bus_formats,
|
||||
ARRAY_SIZE(mantix_bus_formats));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -699,30 +699,16 @@ int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job,
|
||||
struct drm_gem_object *obj,
|
||||
bool write)
|
||||
{
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int ret;
|
||||
struct dma_fence **fences;
|
||||
unsigned int i, fence_count;
|
||||
|
||||
if (!write) {
|
||||
struct dma_fence *fence = dma_resv_get_excl_unlocked(obj->resv);
|
||||
|
||||
return drm_sched_job_add_dependency(job, fence);
|
||||
}
|
||||
|
||||
ret = dma_resv_get_fences(obj->resv, NULL, &fence_count, &fences);
|
||||
if (ret || !fence_count)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < fence_count; i++) {
|
||||
ret = drm_sched_job_add_dependency(job, fences[i]);
|
||||
dma_resv_for_each_fence(&cursor, obj->resv, write, fence) {
|
||||
ret = drm_sched_job_add_dependency(job, fence);
|
||||
if (ret)
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (; i < fence_count; i++)
|
||||
dma_fence_put(fences[i]);
|
||||
kfree(fences);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sched_job_add_implicit_dependencies);
|
||||
|
||||
|
@ -269,23 +269,15 @@ static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
|
||||
static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct dma_resv *resv = &bo->base._resv;
|
||||
struct dma_resv_list *fobj;
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
int i;
|
||||
|
||||
rcu_read_lock();
|
||||
fobj = dma_resv_shared_list(resv);
|
||||
fence = dma_resv_excl_fence(resv);
|
||||
if (fence && !fence->ops->signaled)
|
||||
dma_fence_enable_sw_signaling(fence);
|
||||
|
||||
for (i = 0; fobj && i < fobj->shared_count; ++i) {
|
||||
fence = rcu_dereference(fobj->shared[i]);
|
||||
|
||||
dma_resv_iter_begin(&cursor, resv, true);
|
||||
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||
if (!fence->ops->signaled)
|
||||
dma_fence_enable_sw_signaling(fence);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
dma_resv_iter_end(&cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -487,8 +487,8 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
|
||||
for (i = 0; i < se->in_sync_count; i++) {
|
||||
struct drm_v3d_sem in;
|
||||
|
||||
ret = copy_from_user(&in, handle++, sizeof(in));
|
||||
if (ret) {
|
||||
if (copy_from_user(&in, handle++, sizeof(in))) {
|
||||
ret = -EFAULT;
|
||||
DRM_DEBUG("Failed to copy wait dep handle.\n");
|
||||
goto fail_deps;
|
||||
}
|
||||
@ -609,8 +609,8 @@ v3d_get_multisync_post_deps(struct drm_file *file_priv,
|
||||
for (i = 0; i < count; i++) {
|
||||
struct drm_v3d_sem out;
|
||||
|
||||
ret = copy_from_user(&out, post_deps++, sizeof(out));
|
||||
if (ret) {
|
||||
if (copy_from_user(&out, post_deps++, sizeof(out))) {
|
||||
ret = -EFAULT;
|
||||
DRM_DEBUG("Failed to copy post dep handles\n");
|
||||
goto fail;
|
||||
}
|
||||
@ -646,9 +646,8 @@ v3d_get_multisync_submit_deps(struct drm_file *file_priv,
|
||||
struct v3d_submit_ext *se = data;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&multisync, ext, sizeof(multisync));
|
||||
if (ret)
|
||||
return ret;
|
||||
if (copy_from_user(&multisync, ext, sizeof(multisync)))
|
||||
return -EFAULT;
|
||||
|
||||
if (multisync.pad)
|
||||
return -EINVAL;
|
||||
|
@ -308,8 +308,10 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev,
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
virtio_gpu_fb = kzalloc(sizeof(*virtio_gpu_fb), GFP_KERNEL);
|
||||
if (virtio_gpu_fb == NULL)
|
||||
if (virtio_gpu_fb == NULL) {
|
||||
drm_gem_object_put(obj);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj);
|
||||
if (ret) {
|
||||
|
@ -43,21 +43,6 @@ static void update_attr(u8 *dst, u8 *src, int attribute,
|
||||
}
|
||||
}
|
||||
|
||||
static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width)
|
||||
{
|
||||
struct fb_copyarea area;
|
||||
|
||||
area.sx = sx * vc->vc_font.width;
|
||||
area.sy = sy * vc->vc_font.height;
|
||||
area.dx = dx * vc->vc_font.width;
|
||||
area.dy = dy * vc->vc_font.height;
|
||||
area.height = height * vc->vc_font.height;
|
||||
area.width = width * vc->vc_font.width;
|
||||
|
||||
info->fbops->fb_copyarea(info, &area);
|
||||
}
|
||||
|
||||
static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width)
|
||||
{
|
||||
@ -393,7 +378,6 @@ static int bit_update_start(struct fb_info *info)
|
||||
|
||||
void fbcon_set_bitops(struct fbcon_ops *ops)
|
||||
{
|
||||
ops->bmove = bit_bmove;
|
||||
ops->clear = bit_clear;
|
||||
ops->putcs = bit_putcs;
|
||||
ops->clear_margins = bit_clear_margins;
|
||||
|
@ -173,8 +173,6 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
|
||||
int count, int ypos, int xpos);
|
||||
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
|
||||
static void fbcon_cursor(struct vc_data *vc, int mode);
|
||||
static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
|
||||
int height, int width);
|
||||
static int fbcon_switch(struct vc_data *vc);
|
||||
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
|
||||
static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
|
||||
@ -182,16 +180,8 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
|
||||
/*
|
||||
* Internal routines
|
||||
*/
|
||||
static __inline__ void ywrap_up(struct vc_data *vc, int count);
|
||||
static __inline__ void ywrap_down(struct vc_data *vc, int count);
|
||||
static __inline__ void ypan_up(struct vc_data *vc, int count);
|
||||
static __inline__ void ypan_down(struct vc_data *vc, int count);
|
||||
static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
|
||||
int dy, int dx, int height, int width, u_int y_break);
|
||||
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
||||
int unit);
|
||||
static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
|
||||
int line, int count, int dy);
|
||||
static void fbcon_modechanged(struct fb_info *info);
|
||||
static void fbcon_set_all_vcs(struct fb_info *info);
|
||||
static void fbcon_start(void);
|
||||
@ -1135,14 +1125,6 @@ static void fbcon_init(struct vc_data *vc, int init)
|
||||
|
||||
ops->graphics = 0;
|
||||
|
||||
/*
|
||||
* No more hw acceleration for fbcon.
|
||||
*
|
||||
* FIXME: Garbage collect all the now dead code after sufficient time
|
||||
* has passed.
|
||||
*/
|
||||
p->scrollmode = SCROLL_REDRAW;
|
||||
|
||||
/*
|
||||
* ++guenther: console.c:vc_allocate() relies on initializing
|
||||
* vc_{cols,rows}, but we must not set those if we are only
|
||||
@ -1229,14 +1211,13 @@ finished:
|
||||
* This system is now divided into two levels because of complications
|
||||
* caused by hardware scrolling. Top level functions:
|
||||
*
|
||||
* fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
|
||||
* fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
|
||||
*
|
||||
* handles y values in range [0, scr_height-1] that correspond to real
|
||||
* screen positions. y_wrap shift means that first line of bitmap may be
|
||||
* anywhere on this display. These functions convert lineoffsets to
|
||||
* bitmap offsets and deal with the wrap-around case by splitting blits.
|
||||
*
|
||||
* fbcon_bmove_physical_8() -- These functions fast implementations
|
||||
* fbcon_clear_physical_8() -- of original fbcon_XXX fns.
|
||||
* fbcon_putc_physical_8() -- (font width != 8) may be added later
|
||||
*
|
||||
@ -1409,224 +1390,6 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void ywrap_up(struct vc_data *vc, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
|
||||
p->yscroll += count;
|
||||
if (p->yscroll >= p->vrows) /* Deal with wrap */
|
||||
p->yscroll -= p->vrows;
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode |= FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
scrollback_max += count;
|
||||
if (scrollback_max > scrollback_phys_max)
|
||||
scrollback_max = scrollback_phys_max;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static __inline__ void ywrap_down(struct vc_data *vc, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
|
||||
p->yscroll -= count;
|
||||
if (p->yscroll < 0) /* Deal with wrap */
|
||||
p->yscroll += p->vrows;
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode |= FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
scrollback_max -= count;
|
||||
if (scrollback_max < 0)
|
||||
scrollback_max = 0;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static __inline__ void ypan_up(struct vc_data *vc, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
|
||||
p->yscroll += count;
|
||||
if (p->yscroll > p->vrows - vc->vc_rows) {
|
||||
ops->bmove(vc, info, p->vrows - vc->vc_rows,
|
||||
0, 0, 0, vc->vc_rows, vc->vc_cols);
|
||||
p->yscroll -= p->vrows - vc->vc_rows;
|
||||
}
|
||||
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
fbcon_clear_margins(vc, 1);
|
||||
scrollback_max += count;
|
||||
if (scrollback_max > scrollback_phys_max)
|
||||
scrollback_max = scrollback_phys_max;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
|
||||
p->yscroll += count;
|
||||
|
||||
if (p->yscroll > p->vrows - vc->vc_rows) {
|
||||
p->yscroll -= p->vrows - vc->vc_rows;
|
||||
fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
|
||||
}
|
||||
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
fbcon_clear_margins(vc, 1);
|
||||
scrollback_max += count;
|
||||
if (scrollback_max > scrollback_phys_max)
|
||||
scrollback_max = scrollback_phys_max;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static __inline__ void ypan_down(struct vc_data *vc, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
|
||||
p->yscroll -= count;
|
||||
if (p->yscroll < 0) {
|
||||
ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
|
||||
0, vc->vc_rows, vc->vc_cols);
|
||||
p->yscroll += p->vrows - vc->vc_rows;
|
||||
}
|
||||
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
fbcon_clear_margins(vc, 1);
|
||||
scrollback_max -= count;
|
||||
if (scrollback_max < 0)
|
||||
scrollback_max = 0;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
|
||||
p->yscroll -= count;
|
||||
|
||||
if (p->yscroll < 0) {
|
||||
p->yscroll += p->vrows - vc->vc_rows;
|
||||
fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
|
||||
}
|
||||
|
||||
ops->var.xoffset = 0;
|
||||
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
||||
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
ops->update_start(info);
|
||||
fbcon_clear_margins(vc, 1);
|
||||
scrollback_max -= count;
|
||||
if (scrollback_max < 0)
|
||||
scrollback_max = 0;
|
||||
scrollback_current = 0;
|
||||
}
|
||||
|
||||
static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
|
||||
int line, int count, int dy)
|
||||
{
|
||||
unsigned short *s = (unsigned short *)
|
||||
(vc->vc_origin + vc->vc_size_row * line);
|
||||
|
||||
while (count--) {
|
||||
unsigned short *start = s;
|
||||
unsigned short *le = advance_row(s, 1);
|
||||
unsigned short c;
|
||||
int x = 0;
|
||||
unsigned short attr = 1;
|
||||
|
||||
do {
|
||||
c = scr_readw(s);
|
||||
if (attr != (c & 0xff00)) {
|
||||
attr = c & 0xff00;
|
||||
if (s > start) {
|
||||
fbcon_putcs(vc, start, s - start,
|
||||
dy, x);
|
||||
x += s - start;
|
||||
start = s;
|
||||
}
|
||||
}
|
||||
console_conditional_schedule();
|
||||
s++;
|
||||
} while (s < le);
|
||||
if (s > start)
|
||||
fbcon_putcs(vc, start, s - start, dy, x);
|
||||
console_conditional_schedule();
|
||||
dy++;
|
||||
}
|
||||
}
|
||||
|
||||
static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
|
||||
struct fbcon_display *p, int line, int count, int ycount)
|
||||
{
|
||||
int offset = ycount * vc->vc_cols;
|
||||
unsigned short *d = (unsigned short *)
|
||||
(vc->vc_origin + vc->vc_size_row * line);
|
||||
unsigned short *s = d + offset;
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
|
||||
while (count--) {
|
||||
unsigned short *start = s;
|
||||
unsigned short *le = advance_row(s, 1);
|
||||
unsigned short c;
|
||||
int x = 0;
|
||||
|
||||
do {
|
||||
c = scr_readw(s);
|
||||
|
||||
if (c == scr_readw(d)) {
|
||||
if (s > start) {
|
||||
ops->bmove(vc, info, line + ycount, x,
|
||||
line, x, 1, s-start);
|
||||
x += s - start + 1;
|
||||
start = s + 1;
|
||||
} else {
|
||||
x++;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
scr_writew(c, d);
|
||||
console_conditional_schedule();
|
||||
s++;
|
||||
d++;
|
||||
} while (s < le);
|
||||
if (s > start)
|
||||
ops->bmove(vc, info, line + ycount, x, line, x, 1,
|
||||
s-start);
|
||||
console_conditional_schedule();
|
||||
if (ycount > 0)
|
||||
line++;
|
||||
else {
|
||||
line--;
|
||||
/* NOTE: We subtract two lines from these pointers */
|
||||
s -= vc->vc_size_row;
|
||||
d -= vc->vc_size_row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p,
|
||||
int line, int count, int offset)
|
||||
{
|
||||
@ -1687,7 +1450,6 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
|
||||
|
||||
if (fbcon_is_inactive(vc, info))
|
||||
return true;
|
||||
@ -1704,249 +1466,32 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
|
||||
case SM_UP:
|
||||
if (count > vc->vc_rows) /* Maximum realistic size */
|
||||
count = vc->vc_rows;
|
||||
if (logo_shown >= 0)
|
||||
goto redraw_up;
|
||||
switch (p->scrollmode) {
|
||||
case SCROLL_MOVE:
|
||||
fbcon_redraw_blit(vc, info, p, t, b - t - count,
|
||||
count);
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
(b - count)),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
|
||||
case SCROLL_WRAP_MOVE:
|
||||
if (b - t - count > 3 * vc->vc_rows >> 2) {
|
||||
if (t > 0)
|
||||
fbcon_bmove(vc, 0, 0, count, 0, t,
|
||||
vc->vc_cols);
|
||||
ywrap_up(vc, count);
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_bmove(vc, b - count, 0, b, 0,
|
||||
vc->vc_rows - b,
|
||||
vc->vc_cols);
|
||||
} else if (info->flags & FBINFO_READS_FAST)
|
||||
fbcon_bmove(vc, t + count, 0, t, 0,
|
||||
b - t - count, vc->vc_cols);
|
||||
else
|
||||
goto redraw_up;
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_PAN_REDRAW:
|
||||
if ((p->yscroll + count <=
|
||||
2 * (p->vrows - vc->vc_rows))
|
||||
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
||||
|| (scroll_partial
|
||||
&& (b - t - count >
|
||||
3 * vc->vc_rows >> 2)))) {
|
||||
if (t > 0)
|
||||
fbcon_redraw_move(vc, p, 0, t, count);
|
||||
ypan_up_redraw(vc, t, count);
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_redraw_move(vc, p, b,
|
||||
vc->vc_rows - b, b);
|
||||
} else
|
||||
fbcon_redraw_move(vc, p, t + count, b - t - count, t);
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_PAN_MOVE:
|
||||
if ((p->yscroll + count <=
|
||||
2 * (p->vrows - vc->vc_rows))
|
||||
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
||||
|| (scroll_partial
|
||||
&& (b - t - count >
|
||||
3 * vc->vc_rows >> 2)))) {
|
||||
if (t > 0)
|
||||
fbcon_bmove(vc, 0, 0, count, 0, t,
|
||||
vc->vc_cols);
|
||||
ypan_up(vc, count);
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_bmove(vc, b - count, 0, b, 0,
|
||||
vc->vc_rows - b,
|
||||
vc->vc_cols);
|
||||
} else if (info->flags & FBINFO_READS_FAST)
|
||||
fbcon_bmove(vc, t + count, 0, t, 0,
|
||||
b - t - count, vc->vc_cols);
|
||||
else
|
||||
goto redraw_up;
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_REDRAW:
|
||||
redraw_up:
|
||||
fbcon_redraw(vc, p, t, b - t - count,
|
||||
count * vc->vc_cols);
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
(b - count)),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
fbcon_redraw(vc, p, t, b - t - count,
|
||||
count * vc->vc_cols);
|
||||
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
(b - count)),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
|
||||
case SM_DOWN:
|
||||
if (count > vc->vc_rows) /* Maximum realistic size */
|
||||
count = vc->vc_rows;
|
||||
if (logo_shown >= 0)
|
||||
goto redraw_down;
|
||||
switch (p->scrollmode) {
|
||||
case SCROLL_MOVE:
|
||||
fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
|
||||
-count);
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
t),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
|
||||
case SCROLL_WRAP_MOVE:
|
||||
if (b - t - count > 3 * vc->vc_rows >> 2) {
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_bmove(vc, b, 0, b - count, 0,
|
||||
vc->vc_rows - b,
|
||||
vc->vc_cols);
|
||||
ywrap_down(vc, count);
|
||||
if (t > 0)
|
||||
fbcon_bmove(vc, count, 0, 0, 0, t,
|
||||
vc->vc_cols);
|
||||
} else if (info->flags & FBINFO_READS_FAST)
|
||||
fbcon_bmove(vc, t, 0, t + count, 0,
|
||||
b - t - count, vc->vc_cols);
|
||||
else
|
||||
goto redraw_down;
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_PAN_MOVE:
|
||||
if ((count - p->yscroll <= p->vrows - vc->vc_rows)
|
||||
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
||||
|| (scroll_partial
|
||||
&& (b - t - count >
|
||||
3 * vc->vc_rows >> 2)))) {
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_bmove(vc, b, 0, b - count, 0,
|
||||
vc->vc_rows - b,
|
||||
vc->vc_cols);
|
||||
ypan_down(vc, count);
|
||||
if (t > 0)
|
||||
fbcon_bmove(vc, count, 0, 0, 0, t,
|
||||
vc->vc_cols);
|
||||
} else if (info->flags & FBINFO_READS_FAST)
|
||||
fbcon_bmove(vc, t, 0, t + count, 0,
|
||||
b - t - count, vc->vc_cols);
|
||||
else
|
||||
goto redraw_down;
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_PAN_REDRAW:
|
||||
if ((count - p->yscroll <= p->vrows - vc->vc_rows)
|
||||
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
||||
|| (scroll_partial
|
||||
&& (b - t - count >
|
||||
3 * vc->vc_rows >> 2)))) {
|
||||
if (vc->vc_rows - b > 0)
|
||||
fbcon_redraw_move(vc, p, b, vc->vc_rows - b,
|
||||
b - count);
|
||||
ypan_down_redraw(vc, t, count);
|
||||
if (t > 0)
|
||||
fbcon_redraw_move(vc, p, count, t, 0);
|
||||
} else
|
||||
fbcon_redraw_move(vc, p, t, b - t - count, t + count);
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
break;
|
||||
|
||||
case SCROLL_REDRAW:
|
||||
redraw_down:
|
||||
fbcon_redraw(vc, p, b - 1, b - t - count,
|
||||
-count * vc->vc_cols);
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
t),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
}
|
||||
fbcon_redraw(vc, p, b - 1, b - t - count,
|
||||
-count * vc->vc_cols);
|
||||
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
||||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
t),
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
|
||||
int height, int width)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_display *p = &fb_display[vc->vc_num];
|
||||
|
||||
if (fbcon_is_inactive(vc, info))
|
||||
return;
|
||||
|
||||
if (!width || !height)
|
||||
return;
|
||||
|
||||
/* Split blits that cross physical y_wrap case.
|
||||
* Pathological case involves 4 blits, better to use recursive
|
||||
* code rather than unrolled case
|
||||
*
|
||||
* Recursive invocations don't need to erase the cursor over and
|
||||
* over again, so we use fbcon_bmove_rec()
|
||||
*/
|
||||
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
|
||||
p->vrows - p->yscroll);
|
||||
}
|
||||
|
||||
static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
|
||||
int dy, int dx, int height, int width, u_int y_break)
|
||||
{
|
||||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
u_int b;
|
||||
|
||||
if (sy < y_break && sy + height > y_break) {
|
||||
b = y_break - sy;
|
||||
if (dy < sy) { /* Avoid trashing self */
|
||||
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
||||
y_break);
|
||||
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
||||
height - b, width, y_break);
|
||||
} else {
|
||||
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
||||
height - b, width, y_break);
|
||||
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
||||
y_break);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (dy < y_break && dy + height > y_break) {
|
||||
b = y_break - dy;
|
||||
if (dy < sy) { /* Avoid trashing self */
|
||||
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
||||
y_break);
|
||||
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
||||
height - b, width, y_break);
|
||||
} else {
|
||||
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
||||
height - b, width, y_break);
|
||||
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
||||
y_break);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
|
||||
height, width);
|
||||
}
|
||||
|
||||
static void updatescrollmode(struct fbcon_display *p,
|
||||
struct fb_info *info,
|
||||
struct vc_data *vc)
|
||||
@ -2119,21 +1664,7 @@ static int fbcon_switch(struct vc_data *vc)
|
||||
|
||||
updatescrollmode(p, info, vc);
|
||||
|
||||
switch (p->scrollmode) {
|
||||
case SCROLL_WRAP_MOVE:
|
||||
scrollback_phys_max = p->vrows - vc->vc_rows;
|
||||
break;
|
||||
case SCROLL_PAN_MOVE:
|
||||
case SCROLL_PAN_REDRAW:
|
||||
scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
|
||||
if (scrollback_phys_max < 0)
|
||||
scrollback_phys_max = 0;
|
||||
break;
|
||||
default:
|
||||
scrollback_phys_max = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
scrollback_phys_max = 0;
|
||||
scrollback_max = 0;
|
||||
scrollback_current = 0;
|
||||
|
||||
|
@ -29,7 +29,6 @@ struct fbcon_display {
|
||||
/* Filled in by the low-level console driver */
|
||||
const u_char *fontdata;
|
||||
int userfont; /* != 0 if fontdata kmalloc()ed */
|
||||
u_short scrollmode; /* Scroll Method */
|
||||
u_short inverse; /* != 0 text black on white as default */
|
||||
short yscroll; /* Hardware scrolling */
|
||||
int vrows; /* number of virtual rows */
|
||||
@ -52,8 +51,6 @@ struct fbcon_display {
|
||||
};
|
||||
|
||||
struct fbcon_ops {
|
||||
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width);
|
||||
void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width);
|
||||
void (*putcs)(struct vc_data *vc, struct fb_info *info,
|
||||
@ -152,62 +149,6 @@ static inline int attr_col_ec(int shift, struct vc_data *vc,
|
||||
#define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
|
||||
#define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
|
||||
|
||||
/*
|
||||
* Scroll Method
|
||||
*/
|
||||
|
||||
/* There are several methods fbcon can use to move text around the screen:
|
||||
*
|
||||
* Operation Pan Wrap
|
||||
*---------------------------------------------
|
||||
* SCROLL_MOVE copyarea No No
|
||||
* SCROLL_PAN_MOVE copyarea Yes No
|
||||
* SCROLL_WRAP_MOVE copyarea No Yes
|
||||
* SCROLL_REDRAW imageblit No No
|
||||
* SCROLL_PAN_REDRAW imageblit Yes No
|
||||
* SCROLL_WRAP_REDRAW imageblit No Yes
|
||||
*
|
||||
* (SCROLL_WRAP_REDRAW is not implemented yet)
|
||||
*
|
||||
* In general, fbcon will choose the best scrolling
|
||||
* method based on the rule below:
|
||||
*
|
||||
* Pan/Wrap > accel imageblit > accel copyarea >
|
||||
* soft imageblit > (soft copyarea)
|
||||
*
|
||||
* Exception to the rule: Pan + accel copyarea is
|
||||
* preferred over Pan + accel imageblit.
|
||||
*
|
||||
* The above is typical for PCI/AGP cards. Unless
|
||||
* overridden, fbcon will never use soft copyarea.
|
||||
*
|
||||
* If you need to override the above rule, set the
|
||||
* appropriate flags in fb_info->flags. For example,
|
||||
* to prefer copyarea over imageblit, set
|
||||
* FBINFO_READS_FAST.
|
||||
*
|
||||
* Other notes:
|
||||
* + use the hardware engine to move the text
|
||||
* (hw-accelerated copyarea() and fillrect())
|
||||
* + use hardware-supported panning on a large virtual screen
|
||||
* + amifb can not only pan, but also wrap the display by N lines
|
||||
* (i.e. visible line i = physical line (i+N) % yres).
|
||||
* + read what's already rendered on the screen and
|
||||
* write it in a different place (this is cfb_copyarea())
|
||||
* + re-render the text to the screen
|
||||
*
|
||||
* Whether to use wrapping or panning can only be figured out at
|
||||
* runtime (when we know whether our font height is a multiple
|
||||
* of the pan/wrap step)
|
||||
*
|
||||
*/
|
||||
|
||||
#define SCROLL_MOVE 0x001
|
||||
#define SCROLL_PAN_MOVE 0x002
|
||||
#define SCROLL_WRAP_MOVE 0x003
|
||||
#define SCROLL_REDRAW 0x004
|
||||
#define SCROLL_PAN_REDRAW 0x005
|
||||
|
||||
#ifdef CONFIG_FB_TILEBLITTING
|
||||
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
|
||||
#endif
|
||||
|
@ -59,31 +59,12 @@ static void ccw_update_attr(u8 *dst, u8 *src, int attribute,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_copyarea area;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
|
||||
area.sx = sy * vc->vc_font.height;
|
||||
area.sy = vyres - ((sx + width) * vc->vc_font.width);
|
||||
area.dx = dy * vc->vc_font.height;
|
||||
area.dy = vyres - ((dx + width) * vc->vc_font.width);
|
||||
area.width = height * vc->vc_font.height;
|
||||
area.height = width * vc->vc_font.width;
|
||||
|
||||
info->fbops->fb_copyarea(info, &area);
|
||||
}
|
||||
|
||||
static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_fillrect region;
|
||||
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
|
||||
region.color = attr_bgcol_ec(bgshift,vc,info);
|
||||
region.dx = sy * vc->vc_font.height;
|
||||
@ -140,7 +121,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
|
||||
u32 cnt, pitch, size;
|
||||
u32 attribute = get_attribute(info, scr_readw(s));
|
||||
u8 *dst, *buf = NULL;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -229,7 +210,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
|
||||
int err = 1, dx, dy;
|
||||
char *src;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -387,7 +368,7 @@ static int ccw_update_start(struct fb_info *info)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
u32 yoffset;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
int err;
|
||||
|
||||
yoffset = (vyres - info->var.yres) - ops->var.xoffset;
|
||||
@ -402,7 +383,6 @@ static int ccw_update_start(struct fb_info *info)
|
||||
|
||||
void fbcon_rotate_ccw(struct fbcon_ops *ops)
|
||||
{
|
||||
ops->bmove = ccw_bmove;
|
||||
ops->clear = ccw_clear;
|
||||
ops->putcs = ccw_putcs;
|
||||
ops->clear_margins = ccw_clear_margins;
|
||||
|
@ -44,31 +44,12 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_copyarea area;
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
|
||||
area.sx = vxres - ((sy + height) * vc->vc_font.height);
|
||||
area.sy = sx * vc->vc_font.width;
|
||||
area.dx = vxres - ((dy + height) * vc->vc_font.height);
|
||||
area.dy = dx * vc->vc_font.width;
|
||||
area.width = height * vc->vc_font.height;
|
||||
area.height = width * vc->vc_font.width;
|
||||
|
||||
info->fbops->fb_copyarea(info, &area);
|
||||
}
|
||||
|
||||
static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_fillrect region;
|
||||
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
region.color = attr_bgcol_ec(bgshift,vc,info);
|
||||
region.dx = vxres - ((sy + height) * vc->vc_font.height);
|
||||
@ -125,7 +106,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
|
||||
u32 cnt, pitch, size;
|
||||
u32 attribute = get_attribute(info, scr_readw(s));
|
||||
u8 *dst, *buf = NULL;
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -212,7 +193,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
|
||||
int err = 1, dx, dy;
|
||||
char *src;
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -369,7 +350,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||
static int cw_update_start(struct fb_info *info)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vxres = info->var.xres;
|
||||
u32 xoffset;
|
||||
int err;
|
||||
|
||||
@ -385,7 +366,6 @@ static int cw_update_start(struct fb_info *info)
|
||||
|
||||
void fbcon_rotate_cw(struct fbcon_ops *ops)
|
||||
{
|
||||
ops->bmove = cw_bmove;
|
||||
ops->clear = cw_clear;
|
||||
ops->putcs = cw_putcs;
|
||||
ops->clear_margins = cw_clear_margins;
|
||||
|
@ -11,15 +11,6 @@
|
||||
#ifndef _FBCON_ROTATE_H
|
||||
#define _FBCON_ROTATE_H
|
||||
|
||||
#define GETVYRES(s,i) ({ \
|
||||
(s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
|
||||
(i)->var.yres : (i)->var.yres_virtual; })
|
||||
|
||||
#define GETVXRES(s,i) ({ \
|
||||
(s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
|
||||
(i)->var.xres : (i)->var.xres_virtual; })
|
||||
|
||||
|
||||
static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
|
||||
{
|
||||
u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
|
||||
|
@ -44,33 +44,13 @@ static void ud_update_attr(u8 *dst, u8 *src, int attribute,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_copyarea area;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
|
||||
area.sy = vyres - ((sy + height) * vc->vc_font.height);
|
||||
area.sx = vxres - ((sx + width) * vc->vc_font.width);
|
||||
area.dy = vyres - ((dy + height) * vc->vc_font.height);
|
||||
area.dx = vxres - ((dx + width) * vc->vc_font.width);
|
||||
area.height = height * vc->vc_font.height;
|
||||
area.width = width * vc->vc_font.width;
|
||||
|
||||
info->fbops->fb_copyarea(info, &area);
|
||||
}
|
||||
|
||||
static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
struct fb_fillrect region;
|
||||
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
region.color = attr_bgcol_ec(bgshift,vc,info);
|
||||
region.dy = vyres - ((sy + height) * vc->vc_font.height);
|
||||
@ -162,8 +142,8 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
|
||||
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
|
||||
u32 attribute = get_attribute(info, scr_readw(s));
|
||||
u8 *dst, *buf = NULL;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -259,8 +239,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
|
||||
int err = 1, dx, dy;
|
||||
char *src;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
u32 vxres = info->var.xres;
|
||||
|
||||
if (!ops->fontbuffer)
|
||||
return;
|
||||
@ -410,8 +390,8 @@ static int ud_update_start(struct fb_info *info)
|
||||
{
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
int xoffset, yoffset;
|
||||
u32 vyres = GETVYRES(ops->p->scrollmode, info);
|
||||
u32 vxres = GETVXRES(ops->p->scrollmode, info);
|
||||
u32 vyres = info->var.yres;
|
||||
u32 vxres = info->var.xres;
|
||||
int err;
|
||||
|
||||
xoffset = vxres - info->var.xres - ops->var.xoffset;
|
||||
@ -429,7 +409,6 @@ static int ud_update_start(struct fb_info *info)
|
||||
|
||||
void fbcon_rotate_ud(struct fbcon_ops *ops)
|
||||
{
|
||||
ops->bmove = ud_bmove;
|
||||
ops->clear = ud_clear;
|
||||
ops->putcs = ud_putcs;
|
||||
ops->clear_margins = ud_clear_margins;
|
||||
|
@ -1702,8 +1702,11 @@ static void do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
{
|
||||
unlink_framebuffer(fb_info);
|
||||
if (fb_info->pixmap.addr &&
|
||||
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
|
||||
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) {
|
||||
kfree(fb_info->pixmap.addr);
|
||||
fb_info->pixmap.addr = NULL;
|
||||
}
|
||||
|
||||
fb_destroy_modelist(&fb_info->modelist);
|
||||
registered_fb[fb_info->node] = NULL;
|
||||
num_registered_fb--;
|
||||
|
@ -16,21 +16,6 @@
|
||||
#include <asm/types.h>
|
||||
#include "fbcon.h"
|
||||
|
||||
static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int dy, int dx, int height, int width)
|
||||
{
|
||||
struct fb_tilearea area;
|
||||
|
||||
area.sx = sx;
|
||||
area.sy = sy;
|
||||
area.dx = dx;
|
||||
area.dy = dy;
|
||||
area.height = height;
|
||||
area.width = width;
|
||||
|
||||
info->tileops->fb_tilecopy(info, &area);
|
||||
}
|
||||
|
||||
static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
|
||||
int sx, int height, int width)
|
||||
{
|
||||
@ -133,7 +118,6 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
|
||||
struct fb_tilemap map;
|
||||
struct fbcon_ops *ops = info->fbcon_par;
|
||||
|
||||
ops->bmove = tile_bmove;
|
||||
ops->clear = tile_clear;
|
||||
ops->putcs = tile_putcs;
|
||||
ops->clear_margins = tile_clear_margins;
|
||||
|
@ -505,15 +505,15 @@ void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
|
||||
}
|
||||
|
||||
/**
|
||||
* xxxfb_copyarea - REQUIRED function. Can use generic routines if
|
||||
* non acclerated hardware and packed pixel based.
|
||||
* xxxfb_copyarea - OBSOLETE function.
|
||||
* Copies one area of the screen to another area.
|
||||
* Will be deleted in a future version
|
||||
*
|
||||
* @info: frame buffer structure that represents a single frame buffer
|
||||
* @area: Structure providing the data to copy the framebuffer contents
|
||||
* from one region to another.
|
||||
*
|
||||
* This drawing operation copies a rectangular area from one area of the
|
||||
* This drawing operation copied a rectangular area from one area of the
|
||||
* screen to another area.
|
||||
*/
|
||||
void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
|
||||
@ -645,9 +645,9 @@ static const struct fb_ops xxxfb_ops = {
|
||||
.fb_setcolreg = xxxfb_setcolreg,
|
||||
.fb_blank = xxxfb_blank,
|
||||
.fb_pan_display = xxxfb_pan_display,
|
||||
.fb_fillrect = xxxfb_fillrect, /* Needed !!! */
|
||||
.fb_copyarea = xxxfb_copyarea, /* Needed !!! */
|
||||
.fb_imageblit = xxxfb_imageblit, /* Needed !!! */
|
||||
.fb_fillrect = xxxfb_fillrect, /* Needed !!! */
|
||||
.fb_copyarea = xxxfb_copyarea, /* Obsolete */
|
||||
.fb_imageblit = xxxfb_imageblit, /* Needed !!! */
|
||||
.fb_cursor = xxxfb_cursor, /* Optional !!! */
|
||||
.fb_sync = xxxfb_sync,
|
||||
.fb_ioctl = xxxfb_ioctl,
|
||||
|
@ -24,6 +24,8 @@
|
||||
#ifndef DRM_MODESET_LOCK_H_
|
||||
#define DRM_MODESET_LOCK_H_
|
||||
|
||||
#include <linux/types.h> /* stackdepot.h is not self-contained */
|
||||
#include <linux/stackdepot.h>
|
||||
#include <linux/ww_mutex.h>
|
||||
|
||||
struct drm_modeset_lock;
|
||||
@ -51,6 +53,12 @@ struct drm_modeset_acquire_ctx {
|
||||
*/
|
||||
struct drm_modeset_lock *contended;
|
||||
|
||||
/*
|
||||
* Stack depot for debugging when a contended lock was not backed off
|
||||
* from.
|
||||
*/
|
||||
depot_stack_handle_t stack_depot;
|
||||
|
||||
/*
|
||||
* list of held locks (drm_modeset_lock)
|
||||
*/
|
||||
|
@ -351,9 +351,10 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
|
||||
* @bo: Pointer to a ttm_buffer_object to be initialized.
|
||||
* @size: Requested size of buffer object.
|
||||
* @type: Requested type of buffer object.
|
||||
* @flags: Initial placement flags.
|
||||
* @placement: Initial placement for buffer object.
|
||||
* @page_alignment: Data alignment in pages.
|
||||
* @ctx: TTM operation context for memory allocation.
|
||||
* @sg: Scatter-gather table.
|
||||
* @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
|
||||
* @destroy: Destroy function. Use NULL for kfree().
|
||||
*
|
||||
@ -394,7 +395,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
|
||||
* @bo: Pointer to a ttm_buffer_object to be initialized.
|
||||
* @size: Requested size of buffer object.
|
||||
* @type: Requested type of buffer object.
|
||||
* @flags: Initial placement flags.
|
||||
* @placement: Initial placement for buffer object.
|
||||
* @page_alignment: Data alignment in pages.
|
||||
* @interruptible: If needing to sleep to wait for GPU resources,
|
||||
* sleep interruptible.
|
||||
@ -402,6 +403,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
|
||||
* holds a pointer to a persistent shmem object. Typically, this would
|
||||
* point to the shmem object backing a GEM object if TTM is used to back a
|
||||
* GEM user interface.
|
||||
* @sg: Scatter-gather table.
|
||||
* @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
|
||||
* @destroy: Destroy function. Use NULL for kfree().
|
||||
*
|
||||
|
@ -170,15 +170,20 @@ struct dma_resv_iter {
|
||||
/** @index: index into the shared fences */
|
||||
unsigned int index;
|
||||
|
||||
/** @fences: the shared fences */
|
||||
/** @fences: the shared fences; private, *MUST* not dereference */
|
||||
struct dma_resv_list *fences;
|
||||
|
||||
/** @shared_count: number of shared fences */
|
||||
unsigned int shared_count;
|
||||
|
||||
/** @is_restarted: true if this is the first returned fence */
|
||||
bool is_restarted;
|
||||
};
|
||||
|
||||
struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor);
|
||||
struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor);
|
||||
struct dma_fence *dma_resv_iter_first(struct dma_resv_iter *cursor);
|
||||
struct dma_fence *dma_resv_iter_next(struct dma_resv_iter *cursor);
|
||||
|
||||
/**
|
||||
* dma_resv_iter_begin - initialize a dma_resv_iter object
|
||||
@ -244,6 +249,24 @@ static inline bool dma_resv_iter_is_restarted(struct dma_resv_iter *cursor)
|
||||
for (fence = dma_resv_iter_first_unlocked(cursor); \
|
||||
fence; fence = dma_resv_iter_next_unlocked(cursor))
|
||||
|
||||
/**
|
||||
* dma_resv_for_each_fence - fence iterator
|
||||
* @cursor: a struct dma_resv_iter pointer
|
||||
* @obj: a dma_resv object pointer
|
||||
* @all_fences: true if all fences should be returned
|
||||
* @fence: the current fence
|
||||
*
|
||||
* Iterate over the fences in a struct dma_resv object while holding the
|
||||
* &dma_resv.lock. @all_fences controls if the shared fences are returned as
|
||||
* well. The cursor initialisation is part of the iterator and the fence stays
|
||||
* valid as long as the lock is held and so no extra reference to the fence is
|
||||
* taken.
|
||||
*/
|
||||
#define dma_resv_for_each_fence(cursor, obj, all_fences, fence) \
|
||||
for (dma_resv_iter_begin(cursor, obj, all_fences), \
|
||||
fence = dma_resv_iter_first(cursor); fence; \
|
||||
fence = dma_resv_iter_next(cursor))
|
||||
|
||||
#define dma_resv_held(obj) lockdep_is_held(&(obj)->lock.base)
|
||||
#define dma_resv_assert_held(obj) lockdep_assert_held(&(obj)->lock.base)
|
||||
|
||||
|
@ -262,7 +262,7 @@ struct fb_ops {
|
||||
|
||||
/* Draws a rectangle */
|
||||
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
|
||||
/* Copy data from area to another */
|
||||
/* Copy data from area to another. Obsolete. */
|
||||
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
|
||||
/* Draws a image to the display */
|
||||
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
|
||||
|
Loading…
Reference in New Issue
Block a user