/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef LINESHADER_H #define LINESHADER_H #include #include #include #include #include #include #include "log.h" #include "nextpnr.h" NEXTPNR_NAMESPACE_BEGIN // Vertex2DPOD is a structure of X, Y coordinates that can be passed to OpenGL // directly. NPNR_PACKED_STRUCT(struct Vertex2DPOD { GLfloat x; GLfloat y; Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {} }); // LineShaderData is a built set of vertices that can be rendered by the // LineShader. // Each LineShaderData can have its' own color and thickness. struct LineShaderData { std::vector vertices; std::vector normals; std::vector miters; std::vector indices; int last_render = 0; void clear(void) { vertices.clear(); normals.clear(); miters.clear(); indices.clear(); } }; // PolyLine is a set of segments defined by points, that can be built to a // ShaderLine for GPU rendering. class PolyLine { private: std::vector points_; bool closed_; void buildPoint(LineShaderData *building, const QVector2D *prev, const QVector2D *cur, const QVector2D *next) const; public: // Create an empty PolyLine. PolyLine(bool closed = false) : closed_(closed) {} // Create a non-closed polyline consisting of one segment. PolyLine(float x0, float y0, float x1, float y1) : closed_(false) { point(x0, y0); point(x1, y1); } // Add a point to the PolyLine. void point(float x, float y) { points_.push_back(QVector2D(x, y)); } // Built PolyLine to shader data. void build(LineShaderData &target) const; // Set whether line is closed (ie. a loop). void setClosed(bool closed) { closed_ = closed; } }; // LineShader is an OpenGL shader program that renders LineShaderData on the // GPU. // The LineShader expects two vertices per line point. It will push those // vertices along the given normal * miter. This is used to 'stretch' the line // to be as wide as the given thickness. The normal and miter are calculated // by the PolyLine build method in order to construct a constant thickness line // with miter edge joints. // // +------+------+ // // | // PolyLine.build() // | // V // // ^ ^ ^ // | | | <--- normal vectors (x2, pointing in the same // +/+----+/+----+/+ direction) // // | // vertex shader // | // V // // +------+------+ ^ by normal * miter * thickness/2 // | | | // +------+------+ V by normal * miter * thickness/2 // // (miter is flipped for every second vertex generated) class LineShader { private: QObject *parent_; QOpenGLShaderProgram *program_; // GL attribute locations. struct { // original position of line vertex GLuint position; // normal by which vertex should be translated GLuint normal; // scalar defining: // - how stretched the normal vector should be to // compensate for bends // - which way the normal should be applied (+1 for one vertex, -1 // for the other) GLuint miter; } attributes_; // GL buffers struct Buffers { QOpenGLBuffer position; QOpenGLBuffer normal; QOpenGLBuffer miter; QOpenGLBuffer index; QOpenGLVertexArrayObject vao; int indices = 0; int last_vbo_update = 0; }; std::array buffers_; // GL uniform locations. struct { // combines m/v/p matrix to apply GLuint projection; // desired thickness of line GLuint thickness; // color of line GLuint color; } uniforms_; public: LineShader(QObject *parent) : parent_(parent), program_(nullptr) {} static constexpr const char *vertexShaderSource_ = "#version 150\n" "in highp vec2 position;\n" "in highp vec2 normal;\n" "in highp float miter;\n" "uniform highp float thickness;\n" "uniform highp mat4 projection;\n" "void main() {\n" " vec2 p = position.xy + vec2(normal * thickness/2.0 / miter);\n" " gl_Position = projection * vec4(p, 0.0, 1.0);\n" "}\n"; static conste
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -60,8 +60,14 @@ static const struct ath5k_ini ar5210_ini
 	{ AR5K_IMR,		0 },
 	{ AR5K_IER,		AR5K_IER_DISABLE },
 	{ AR5K_BSR,		0, AR5K_INI_READ },
+#ifndef CONFIG_ATHEROS_AR71XX
 	{ AR5K_TXCFG,		AR5K_DMASIZE_128B },
 	{ AR5K_RXCFG,		AR5K_DMASIZE_128B },
+#else
+	/* WAR for AR71xx PCI bug */
+	{ AR5K_TXCFG,		AR5K_DMASIZE_128B },
+	{ AR5K_RXCFG,		AR5K_DMASIZE_4B },
+#endif
 	{ AR5K_CFG,		AR5K_INIT_CFG },
 	{ AR5K_TOPS,		8 },
 	{ AR5K_RXNOFRM,		8 },
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -858,10 +858,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah)
 	 * guess we can tweak it and see how it goes ;-)
 	 */
 	if (ah->ah_version != AR5K_AR5210) {
+#ifndef CONFIG_ATHEROS_AR71XX
 		AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
 			AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
 		AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
 			AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+#else
+		/* WAR for AR71xx PCI bug */
+		AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+			AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+		AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+			AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B);
+#endif
 	}
 
 	/* Pre-enable interrupts on 5211/5212*/